Fossil SCM

Fix accidental fork.

danield 2021-11-17 15:52 trunk merge
Commit bd7f2727ba25912ee0fd86dca7574d28c91405b068e8794f6ffc9a9d3e7c0fe3
+14
--- src/chat.c
+++ src/chat.c
@@ -352,10 +352,22 @@
352352
** On success it responds with an empty response: the new message
353353
** should be fetched via /chat-poll. On error, e.g. login expiry,
354354
** it emits a JSON response in the same form as described for
355355
** /chat-poll errors, but as a standalone object instead of a
356356
** list of objects.
357
+**
358
+** Requests to this page should be POST, not GET. POST parameters
359
+** include:
360
+**
361
+** msg The (Markdown) text of the message to be sent
362
+**
363
+** file The content of the file attachment
364
+**
365
+** lmtime ISO-8601 formatted date-time string showing the local time
366
+** of the sender.
367
+**
368
+** At least one of the "msg" or "file" POST parameters must be provided.
357369
*/
358370
void chat_send_webpage(void){
359371
int nByte;
360372
const char *zMsg;
361373
const char *zUserName;
@@ -765,11 +777,13 @@
765777
**
766778
** This routine both deletes the identified chat entry and also inserts
767779
** a new entry with the current timestamp and with:
768780
**
769781
** * xmsg = NULL
782
+**
770783
** * file = NULL
784
+**
771785
** * mdel = The msgid of the row that was deleted
772786
**
773787
** This new entry will then be propagated to all listeners so that they
774788
** will know to delete their copies of the message too.
775789
*/
776790
--- src/chat.c
+++ src/chat.c
@@ -352,10 +352,22 @@
352 ** On success it responds with an empty response: the new message
353 ** should be fetched via /chat-poll. On error, e.g. login expiry,
354 ** it emits a JSON response in the same form as described for
355 ** /chat-poll errors, but as a standalone object instead of a
356 ** list of objects.
 
 
 
 
 
 
 
 
 
 
 
 
357 */
358 void chat_send_webpage(void){
359 int nByte;
360 const char *zMsg;
361 const char *zUserName;
@@ -765,11 +777,13 @@
765 **
766 ** This routine both deletes the identified chat entry and also inserts
767 ** a new entry with the current timestamp and with:
768 **
769 ** * xmsg = NULL
 
770 ** * file = NULL
 
771 ** * mdel = The msgid of the row that was deleted
772 **
773 ** This new entry will then be propagated to all listeners so that they
774 ** will know to delete their copies of the message too.
775 */
776
--- src/chat.c
+++ src/chat.c
@@ -352,10 +352,22 @@
352 ** On success it responds with an empty response: the new message
353 ** should be fetched via /chat-poll. On error, e.g. login expiry,
354 ** it emits a JSON response in the same form as described for
355 ** /chat-poll errors, but as a standalone object instead of a
356 ** list of objects.
357 **
358 ** Requests to this page should be POST, not GET. POST parameters
359 ** include:
360 **
361 ** msg The (Markdown) text of the message to be sent
362 **
363 ** file The content of the file attachment
364 **
365 ** lmtime ISO-8601 formatted date-time string showing the local time
366 ** of the sender.
367 **
368 ** At least one of the "msg" or "file" POST parameters must be provided.
369 */
370 void chat_send_webpage(void){
371 int nByte;
372 const char *zMsg;
373 const char *zUserName;
@@ -765,11 +777,13 @@
777 **
778 ** This routine both deletes the identified chat entry and also inserts
779 ** a new entry with the current timestamp and with:
780 **
781 ** * xmsg = NULL
782 **
783 ** * file = NULL
784 **
785 ** * mdel = The msgid of the row that was deleted
786 **
787 ** This new entry will then be propagated to all listeners so that they
788 ** will know to delete their copies of the message too.
789 */
790
+14 -4
--- src/checkin.c
+++ src/checkin.c
@@ -1349,12 +1349,13 @@
13491349
diff_options(&DCfg, 0, 1);
13501350
DCfg.diffFlags |= DIFF_VERBOSE;
13511351
if( g.aCommitFile ){
13521352
FileDirList *diffFiles;
13531353
int i;
1354
- diffFiles = fossil_malloc_zero((g.argc-1) * sizeof(*diffFiles));
1355
- for( i=0; g.aCommitFile[i]!=0; ++i ){
1354
+ for(i=0; g.aCommitFile[i]!=0; ++i){}
1355
+ diffFiles = fossil_malloc_zero((i+1) * sizeof(*diffFiles));
1356
+ for(i=0; g.aCommitFile[i]!=0; ++i){
13561357
diffFiles[i].zName = db_text(0,
13571358
"SELECT pathname FROM vfile WHERE id=%d", g.aCommitFile[i]);
13581359
if( fossil_strcmp(diffFiles[i].zName, "." )==0 ){
13591360
diffFiles[0].zName[0] = '.';
13601361
diffFiles[0].zName[1] = 0;
@@ -1361,11 +1362,11 @@
13611362
break;
13621363
}
13631364
diffFiles[i].nName = strlen(diffFiles[i].zName);
13641365
diffFiles[i].nUsed = 0;
13651366
}
1366
- diff_against_disk(0, &DCfg, diffFiles, &prompt);
1367
+ diff_against_disk(0, &DCfg, diffFiles, &prompt);
13671368
for( i=0; diffFiles[i].zName; ++i ){
13681369
fossil_free(diffFiles[i].zName);
13691370
}
13701371
fossil_free(diffFiles);
13711372
}else{
@@ -2133,10 +2134,14 @@
21332134
** --close close the branch being committed
21342135
** --date-override DATETIME DATE to use instead of 'now'
21352136
** --delta use a delta manifest in the commit process
21362137
** --hash verify file status using hashing rather
21372138
** than relying on file mtimes
2139
+** --ignore-clock-skew If a clock skew is detected, ignore it and
2140
+** behave as if the user had entered 'yes' to
2141
+** the question of whether to proceed despite
2142
+** the skew.
21382143
** --integrate close all merged-in branches
21392144
** -m|--comment COMMENT-TEXT use COMMENT-TEXT as commit comment
21402145
** -M|--message-file FILE read the commit comment from given file
21412146
** --mimetype MIMETYPE mimetype of check-in comment
21422147
** -n|--dry-run If given, display instead of run actions
@@ -2206,10 +2211,11 @@
22062211
int abortCommit = 0; /* Abort the commit due to text format conversions */
22072212
Blob ans; /* Answer to continuation prompts */
22082213
char cReply; /* First character of ans */
22092214
int bRecheck = 0; /* Repeat fork and closed-branch checks*/
22102215
int bAutoBrClr = 0; /* Value of "--branchcolor" is "auto" */
2216
+ int bIgnoreSkew = 0; /* --ignore-clock-skew flag */
22112217
22122218
memset(&sCiInfo, 0, sizeof(sCiInfo));
22132219
url_proxy_options();
22142220
/* --sha1sum is an undocumented alias for --hash for backwards compatiblity */
22152221
useHash = find_option("hash",0,0)!=0 || find_option("sha1sum",0,0)!=0;
@@ -2263,10 +2269,11 @@
22632269
sCiInfo.zUserOvrd = find_option("user-override",0,1);
22642270
db_must_be_within_tree();
22652271
noSign = db_get_boolean("omitsign", 0)|noSign;
22662272
if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
22672273
useCksum = db_get_boolean("repo-cksum", 1);
2274
+ bIgnoreSkew = find_option("ignore-clock-skew",0,0)!=0;
22682275
outputManifest = db_get_manifest_setting();
22692276
verify_all_options();
22702277
22712278
/* Get the ID of the parent manifest artifact */
22722279
vid = db_lget_int("checkout", 0);
@@ -2346,11 +2353,14 @@
23462353
23472354
/* Require confirmation to continue with the check-in if there is
23482355
** clock skew
23492356
*/
23502357
if( g.clockSkewSeen ){
2351
- if( !noPrompt ){
2358
+ if( bIgnoreSkew!=0 ){
2359
+ cReply = 'y';
2360
+ fossil_warning("Clock skew ignored due to --ignore-clock-skew.");
2361
+ }else if( !noPrompt ){
23522362
prompt_user("continue in spite of time skew (y/N)? ", &ans);
23532363
cReply = blob_str(&ans)[0];
23542364
blob_reset(&ans);
23552365
}else{
23562366
fossil_print("Abandoning commit due to time skew\n");
23572367
--- src/checkin.c
+++ src/checkin.c
@@ -1349,12 +1349,13 @@
1349 diff_options(&DCfg, 0, 1);
1350 DCfg.diffFlags |= DIFF_VERBOSE;
1351 if( g.aCommitFile ){
1352 FileDirList *diffFiles;
1353 int i;
1354 diffFiles = fossil_malloc_zero((g.argc-1) * sizeof(*diffFiles));
1355 for( i=0; g.aCommitFile[i]!=0; ++i ){
 
1356 diffFiles[i].zName = db_text(0,
1357 "SELECT pathname FROM vfile WHERE id=%d", g.aCommitFile[i]);
1358 if( fossil_strcmp(diffFiles[i].zName, "." )==0 ){
1359 diffFiles[0].zName[0] = '.';
1360 diffFiles[0].zName[1] = 0;
@@ -1361,11 +1362,11 @@
1361 break;
1362 }
1363 diffFiles[i].nName = strlen(diffFiles[i].zName);
1364 diffFiles[i].nUsed = 0;
1365 }
1366 diff_against_disk(0, &DCfg, diffFiles, &prompt);
1367 for( i=0; diffFiles[i].zName; ++i ){
1368 fossil_free(diffFiles[i].zName);
1369 }
1370 fossil_free(diffFiles);
1371 }else{
@@ -2133,10 +2134,14 @@
2133 ** --close close the branch being committed
2134 ** --date-override DATETIME DATE to use instead of 'now'
2135 ** --delta use a delta manifest in the commit process
2136 ** --hash verify file status using hashing rather
2137 ** than relying on file mtimes
 
 
 
 
2138 ** --integrate close all merged-in branches
2139 ** -m|--comment COMMENT-TEXT use COMMENT-TEXT as commit comment
2140 ** -M|--message-file FILE read the commit comment from given file
2141 ** --mimetype MIMETYPE mimetype of check-in comment
2142 ** -n|--dry-run If given, display instead of run actions
@@ -2206,10 +2211,11 @@
2206 int abortCommit = 0; /* Abort the commit due to text format conversions */
2207 Blob ans; /* Answer to continuation prompts */
2208 char cReply; /* First character of ans */
2209 int bRecheck = 0; /* Repeat fork and closed-branch checks*/
2210 int bAutoBrClr = 0; /* Value of "--branchcolor" is "auto" */
 
2211
2212 memset(&sCiInfo, 0, sizeof(sCiInfo));
2213 url_proxy_options();
2214 /* --sha1sum is an undocumented alias for --hash for backwards compatiblity */
2215 useHash = find_option("hash",0,0)!=0 || find_option("sha1sum",0,0)!=0;
@@ -2263,10 +2269,11 @@
2263 sCiInfo.zUserOvrd = find_option("user-override",0,1);
2264 db_must_be_within_tree();
2265 noSign = db_get_boolean("omitsign", 0)|noSign;
2266 if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
2267 useCksum = db_get_boolean("repo-cksum", 1);
 
2268 outputManifest = db_get_manifest_setting();
2269 verify_all_options();
2270
2271 /* Get the ID of the parent manifest artifact */
2272 vid = db_lget_int("checkout", 0);
@@ -2346,11 +2353,14 @@
2346
2347 /* Require confirmation to continue with the check-in if there is
2348 ** clock skew
2349 */
2350 if( g.clockSkewSeen ){
2351 if( !noPrompt ){
 
 
 
2352 prompt_user("continue in spite of time skew (y/N)? ", &ans);
2353 cReply = blob_str(&ans)[0];
2354 blob_reset(&ans);
2355 }else{
2356 fossil_print("Abandoning commit due to time skew\n");
2357
--- src/checkin.c
+++ src/checkin.c
@@ -1349,12 +1349,13 @@
1349 diff_options(&DCfg, 0, 1);
1350 DCfg.diffFlags |= DIFF_VERBOSE;
1351 if( g.aCommitFile ){
1352 FileDirList *diffFiles;
1353 int i;
1354 for(i=0; g.aCommitFile[i]!=0; ++i){}
1355 diffFiles = fossil_malloc_zero((i+1) * sizeof(*diffFiles));
1356 for(i=0; g.aCommitFile[i]!=0; ++i){
1357 diffFiles[i].zName = db_text(0,
1358 "SELECT pathname FROM vfile WHERE id=%d", g.aCommitFile[i]);
1359 if( fossil_strcmp(diffFiles[i].zName, "." )==0 ){
1360 diffFiles[0].zName[0] = '.';
1361 diffFiles[0].zName[1] = 0;
@@ -1361,11 +1362,11 @@
1362 break;
1363 }
1364 diffFiles[i].nName = strlen(diffFiles[i].zName);
1365 diffFiles[i].nUsed = 0;
1366 }
1367 diff_against_disk(0, &DCfg, diffFiles, &prompt);
1368 for( i=0; diffFiles[i].zName; ++i ){
1369 fossil_free(diffFiles[i].zName);
1370 }
1371 fossil_free(diffFiles);
1372 }else{
@@ -2133,10 +2134,14 @@
2134 ** --close close the branch being committed
2135 ** --date-override DATETIME DATE to use instead of 'now'
2136 ** --delta use a delta manifest in the commit process
2137 ** --hash verify file status using hashing rather
2138 ** than relying on file mtimes
2139 ** --ignore-clock-skew If a clock skew is detected, ignore it and
2140 ** behave as if the user had entered 'yes' to
2141 ** the question of whether to proceed despite
2142 ** the skew.
2143 ** --integrate close all merged-in branches
2144 ** -m|--comment COMMENT-TEXT use COMMENT-TEXT as commit comment
2145 ** -M|--message-file FILE read the commit comment from given file
2146 ** --mimetype MIMETYPE mimetype of check-in comment
2147 ** -n|--dry-run If given, display instead of run actions
@@ -2206,10 +2211,11 @@
2211 int abortCommit = 0; /* Abort the commit due to text format conversions */
2212 Blob ans; /* Answer to continuation prompts */
2213 char cReply; /* First character of ans */
2214 int bRecheck = 0; /* Repeat fork and closed-branch checks*/
2215 int bAutoBrClr = 0; /* Value of "--branchcolor" is "auto" */
2216 int bIgnoreSkew = 0; /* --ignore-clock-skew flag */
2217
2218 memset(&sCiInfo, 0, sizeof(sCiInfo));
2219 url_proxy_options();
2220 /* --sha1sum is an undocumented alias for --hash for backwards compatiblity */
2221 useHash = find_option("hash",0,0)!=0 || find_option("sha1sum",0,0)!=0;
@@ -2263,10 +2269,11 @@
2269 sCiInfo.zUserOvrd = find_option("user-override",0,1);
2270 db_must_be_within_tree();
2271 noSign = db_get_boolean("omitsign", 0)|noSign;
2272 if( db_get_boolean("clearsign", 0)==0 ){ noSign = 1; }
2273 useCksum = db_get_boolean("repo-cksum", 1);
2274 bIgnoreSkew = find_option("ignore-clock-skew",0,0)!=0;
2275 outputManifest = db_get_manifest_setting();
2276 verify_all_options();
2277
2278 /* Get the ID of the parent manifest artifact */
2279 vid = db_lget_int("checkout", 0);
@@ -2346,11 +2353,14 @@
2353
2354 /* Require confirmation to continue with the check-in if there is
2355 ** clock skew
2356 */
2357 if( g.clockSkewSeen ){
2358 if( bIgnoreSkew!=0 ){
2359 cReply = 'y';
2360 fossil_warning("Clock skew ignored due to --ignore-clock-skew.");
2361 }else if( !noPrompt ){
2362 prompt_user("continue in spite of time skew (y/N)? ", &ans);
2363 cReply = blob_str(&ans)[0];
2364 blob_reset(&ans);
2365 }else{
2366 fossil_print("Abandoning commit due to time skew\n");
2367
+59 -1
--- src/db.c
+++ src/db.c
@@ -2125,26 +2125,77 @@
21252125
** Returns non-zero if support for symlinks is currently enabled.
21262126
*/
21272127
int db_allow_symlinks(void){
21282128
return g.allowSymlinks;
21292129
}
2130
+
2131
+/*
2132
+** Return TRUE if the file in the argument seems like it might be an
2133
+** SQLite database file that contains a Fossil repository schema.
2134
+*/
2135
+int db_looks_like_a_repository(const char *zDbName){
2136
+ sqlite3 *db = 0;
2137
+ i64 sz;
2138
+ int rc;
2139
+ int res = 0;
2140
+ sqlite3_stmt *pStmt = 0;
2141
+
2142
+ sz = file_size(zDbName, ExtFILE);
2143
+ if( sz<16834 ) return 0;
2144
+ if( sz & 0x1ff ) return 0;
2145
+ rc = sqlite3_open(zDbName, &db);
2146
+ if( rc ) goto is_repo_end;
2147
+ rc = sqlite3_prepare_v2(db,
2148
+ "SELECT count(*) FROM sqlite_schema"
2149
+ " WHERE name COLLATE nocase IN"
2150
+ "('blob','delta','rcvfrom','user','config','mlink','plink');",
2151
+ -1, &pStmt, 0);
2152
+ if( rc ) goto is_repo_end;
2153
+ rc = sqlite3_step(pStmt);
2154
+ if( rc!=SQLITE_ROW ) goto is_repo_end;
2155
+ if( sqlite3_column_int(pStmt, 0)!=7 ) goto is_repo_end;
2156
+ res = 1;
2157
+
2158
+is_repo_end:
2159
+ sqlite3_finalize(pStmt);
2160
+ sqlite3_close(db);
2161
+ return res;
2162
+}
2163
+
2164
+/*
2165
+** COMMAND: test-is-repo
2166
+*/
2167
+void test_is_repo(void){
2168
+ int i;
2169
+ for(i=2; i<g.argc; i++){
2170
+ fossil_print("%s: %s\n",
2171
+ db_looks_like_a_repository(g.argv[i]) ? "yes" : " no",
2172
+ g.argv[i]
2173
+ );
2174
+ }
2175
+}
2176
+
21302177
21312178
/*
21322179
** Open the repository database given by zDbName. If zDbName==NULL then
21332180
** get the name from the already open local database.
21342181
*/
21352182
void db_open_repository(const char *zDbName){
2183
+ i64 sz;
21362184
if( g.repositoryOpen ) return;
21372185
if( zDbName==0 ){
21382186
if( g.localOpen ){
21392187
zDbName = db_repository_filename();
21402188
}
21412189
if( zDbName==0 ){
21422190
db_err("unable to find the name of a repository database");
21432191
}
21442192
}
2145
- if( file_access(zDbName, R_OK) || file_size(zDbName, ExtFILE)<1024 ){
2193
+ if( file_access(zDbName, R_OK)
2194
+ || (sz = file_size(zDbName, ExtFILE))<16384
2195
+ || (sz&0x1ff)!=0
2196
+ ){
21462197
if( file_access(zDbName, F_OK) ){
21472198
#ifdef FOSSIL_ENABLE_JSON
21482199
g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
21492200
#endif
21502201
fossil_fatal("repository does not exist or"
@@ -3509,10 +3560,12 @@
35093560
** --repodir DIR If REPOSITORY is a URI that will be cloned, store
35103561
** the clone in DIR rather than in "."
35113562
** --setmtime Set timestamps of all files to match their SCM-side
35123563
** times (the timestamp of the last checkin which modified
35133564
** them).
3565
+** --verbose If passed a URI then this flag is passed on to the clone
3566
+** operation, otherwise it has no effect.
35143567
** --workdir DIR Use DIR as the working directory instead of ".". The DIR
35153568
** directory is created if it does not exist.
35163569
**
35173570
** See also: [[close]], [[clone]]
35183571
*/
@@ -3529,10 +3582,11 @@
35293582
const char *zRepoDir = 0; /* --repodir value */
35303583
char *zPwd; /* Initial working directory */
35313584
int isUri = 0; /* True if REPOSITORY is a URI */
35323585
int nLocal; /* Number of preexisting files in cwd */
35333586
int bNosync = 0; /* --nosync. Omit auto-sync */
3587
+ int bVerbose = 0; /* --verbose option for clone */
35343588
35353589
url_proxy_options();
35363590
emptyFlag = find_option("empty",0,0)!=0;
35373591
keepFlag = find_option("keep",0,0)!=0;
35383592
forceMissingFlag = find_option("force-missing",0,0)!=0;
@@ -3540,10 +3594,11 @@
35403594
setmtimeFlag = find_option("setmtime",0,0)!=0;
35413595
zWorkDir = find_option("workdir",0,1);
35423596
zRepoDir = find_option("repodir",0,1);
35433597
bForce = find_option("force","f",0)!=0;
35443598
bNosync = find_option("nosync",0,0)!=0;
3599
+ bVerbose = find_option("verbose",0,0)!=0;
35453600
zPwd = file_getcwd(0,0);
35463601
35473602
35483603
/* We should be done with options.. */
35493604
verify_all_options();
@@ -3611,10 +3666,13 @@
36113666
zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
36123667
fossil_free(zNewBase);
36133668
blob_init(&cmd, 0, 0);
36143669
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
36153670
blob_append(&cmd, " clone", -1);
3671
+ if(0!=bVerbose){
3672
+ blob_append(&cmd, " --verbose", -1);
3673
+ }
36163674
blob_append_escaped_arg(&cmd, zUri, 1);
36173675
blob_append_escaped_arg(&cmd, zRepo, 1);
36183676
zCmd = blob_str(&cmd);
36193677
fossil_print("%s\n", zCmd);
36203678
if( zWorkDir ) file_chdir(zPwd, 0);
36213679
--- src/db.c
+++ src/db.c
@@ -2125,26 +2125,77 @@
2125 ** Returns non-zero if support for symlinks is currently enabled.
2126 */
2127 int db_allow_symlinks(void){
2128 return g.allowSymlinks;
2129 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2130
2131 /*
2132 ** Open the repository database given by zDbName. If zDbName==NULL then
2133 ** get the name from the already open local database.
2134 */
2135 void db_open_repository(const char *zDbName){
 
2136 if( g.repositoryOpen ) return;
2137 if( zDbName==0 ){
2138 if( g.localOpen ){
2139 zDbName = db_repository_filename();
2140 }
2141 if( zDbName==0 ){
2142 db_err("unable to find the name of a repository database");
2143 }
2144 }
2145 if( file_access(zDbName, R_OK) || file_size(zDbName, ExtFILE)<1024 ){
 
 
 
2146 if( file_access(zDbName, F_OK) ){
2147 #ifdef FOSSIL_ENABLE_JSON
2148 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2149 #endif
2150 fossil_fatal("repository does not exist or"
@@ -3509,10 +3560,12 @@
3509 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3510 ** the clone in DIR rather than in "."
3511 ** --setmtime Set timestamps of all files to match their SCM-side
3512 ** times (the timestamp of the last checkin which modified
3513 ** them).
 
 
3514 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3515 ** directory is created if it does not exist.
3516 **
3517 ** See also: [[close]], [[clone]]
3518 */
@@ -3529,10 +3582,11 @@
3529 const char *zRepoDir = 0; /* --repodir value */
3530 char *zPwd; /* Initial working directory */
3531 int isUri = 0; /* True if REPOSITORY is a URI */
3532 int nLocal; /* Number of preexisting files in cwd */
3533 int bNosync = 0; /* --nosync. Omit auto-sync */
 
3534
3535 url_proxy_options();
3536 emptyFlag = find_option("empty",0,0)!=0;
3537 keepFlag = find_option("keep",0,0)!=0;
3538 forceMissingFlag = find_option("force-missing",0,0)!=0;
@@ -3540,10 +3594,11 @@
3540 setmtimeFlag = find_option("setmtime",0,0)!=0;
3541 zWorkDir = find_option("workdir",0,1);
3542 zRepoDir = find_option("repodir",0,1);
3543 bForce = find_option("force","f",0)!=0;
3544 bNosync = find_option("nosync",0,0)!=0;
 
3545 zPwd = file_getcwd(0,0);
3546
3547
3548 /* We should be done with options.. */
3549 verify_all_options();
@@ -3611,10 +3666,13 @@
3611 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3612 fossil_free(zNewBase);
3613 blob_init(&cmd, 0, 0);
3614 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
3615 blob_append(&cmd, " clone", -1);
 
 
 
3616 blob_append_escaped_arg(&cmd, zUri, 1);
3617 blob_append_escaped_arg(&cmd, zRepo, 1);
3618 zCmd = blob_str(&cmd);
3619 fossil_print("%s\n", zCmd);
3620 if( zWorkDir ) file_chdir(zPwd, 0);
3621
--- src/db.c
+++ src/db.c
@@ -2125,26 +2125,77 @@
2125 ** Returns non-zero if support for symlinks is currently enabled.
2126 */
2127 int db_allow_symlinks(void){
2128 return g.allowSymlinks;
2129 }
2130
2131 /*
2132 ** Return TRUE if the file in the argument seems like it might be an
2133 ** SQLite database file that contains a Fossil repository schema.
2134 */
2135 int db_looks_like_a_repository(const char *zDbName){
2136 sqlite3 *db = 0;
2137 i64 sz;
2138 int rc;
2139 int res = 0;
2140 sqlite3_stmt *pStmt = 0;
2141
2142 sz = file_size(zDbName, ExtFILE);
2143 if( sz<16834 ) return 0;
2144 if( sz & 0x1ff ) return 0;
2145 rc = sqlite3_open(zDbName, &db);
2146 if( rc ) goto is_repo_end;
2147 rc = sqlite3_prepare_v2(db,
2148 "SELECT count(*) FROM sqlite_schema"
2149 " WHERE name COLLATE nocase IN"
2150 "('blob','delta','rcvfrom','user','config','mlink','plink');",
2151 -1, &pStmt, 0);
2152 if( rc ) goto is_repo_end;
2153 rc = sqlite3_step(pStmt);
2154 if( rc!=SQLITE_ROW ) goto is_repo_end;
2155 if( sqlite3_column_int(pStmt, 0)!=7 ) goto is_repo_end;
2156 res = 1;
2157
2158 is_repo_end:
2159 sqlite3_finalize(pStmt);
2160 sqlite3_close(db);
2161 return res;
2162 }
2163
2164 /*
2165 ** COMMAND: test-is-repo
2166 */
2167 void test_is_repo(void){
2168 int i;
2169 for(i=2; i<g.argc; i++){
2170 fossil_print("%s: %s\n",
2171 db_looks_like_a_repository(g.argv[i]) ? "yes" : " no",
2172 g.argv[i]
2173 );
2174 }
2175 }
2176
2177
2178 /*
2179 ** Open the repository database given by zDbName. If zDbName==NULL then
2180 ** get the name from the already open local database.
2181 */
2182 void db_open_repository(const char *zDbName){
2183 i64 sz;
2184 if( g.repositoryOpen ) return;
2185 if( zDbName==0 ){
2186 if( g.localOpen ){
2187 zDbName = db_repository_filename();
2188 }
2189 if( zDbName==0 ){
2190 db_err("unable to find the name of a repository database");
2191 }
2192 }
2193 if( file_access(zDbName, R_OK)
2194 || (sz = file_size(zDbName, ExtFILE))<16384
2195 || (sz&0x1ff)!=0
2196 ){
2197 if( file_access(zDbName, F_OK) ){
2198 #ifdef FOSSIL_ENABLE_JSON
2199 g.json.resultCode = FSL_JSON_E_DB_NOT_FOUND;
2200 #endif
2201 fossil_fatal("repository does not exist or"
@@ -3509,10 +3560,12 @@
3560 ** --repodir DIR If REPOSITORY is a URI that will be cloned, store
3561 ** the clone in DIR rather than in "."
3562 ** --setmtime Set timestamps of all files to match their SCM-side
3563 ** times (the timestamp of the last checkin which modified
3564 ** them).
3565 ** --verbose If passed a URI then this flag is passed on to the clone
3566 ** operation, otherwise it has no effect.
3567 ** --workdir DIR Use DIR as the working directory instead of ".". The DIR
3568 ** directory is created if it does not exist.
3569 **
3570 ** See also: [[close]], [[clone]]
3571 */
@@ -3529,10 +3582,11 @@
3582 const char *zRepoDir = 0; /* --repodir value */
3583 char *zPwd; /* Initial working directory */
3584 int isUri = 0; /* True if REPOSITORY is a URI */
3585 int nLocal; /* Number of preexisting files in cwd */
3586 int bNosync = 0; /* --nosync. Omit auto-sync */
3587 int bVerbose = 0; /* --verbose option for clone */
3588
3589 url_proxy_options();
3590 emptyFlag = find_option("empty",0,0)!=0;
3591 keepFlag = find_option("keep",0,0)!=0;
3592 forceMissingFlag = find_option("force-missing",0,0)!=0;
@@ -3540,10 +3594,11 @@
3594 setmtimeFlag = find_option("setmtime",0,0)!=0;
3595 zWorkDir = find_option("workdir",0,1);
3596 zRepoDir = find_option("repodir",0,1);
3597 bForce = find_option("force","f",0)!=0;
3598 bNosync = find_option("nosync",0,0)!=0;
3599 bVerbose = find_option("verbose",0,0)!=0;
3600 zPwd = file_getcwd(0,0);
3601
3602
3603 /* We should be done with options.. */
3604 verify_all_options();
@@ -3611,10 +3666,13 @@
3666 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3667 fossil_free(zNewBase);
3668 blob_init(&cmd, 0, 0);
3669 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
3670 blob_append(&cmd, " clone", -1);
3671 if(0!=bVerbose){
3672 blob_append(&cmd, " --verbose", -1);
3673 }
3674 blob_append_escaped_arg(&cmd, zUri, 1);
3675 blob_append_escaped_arg(&cmd, zRepo, 1);
3676 zCmd = blob_str(&cmd);
3677 fossil_print("%s\n", zCmd);
3678 if( zWorkDir ) file_chdir(zPwd, 0);
3679
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178178
socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179179
rc = 1;
180180
#endif
181181
}else if( pUrlData->isFile ){
182182
sqlite3_uint64 iRandId;
183
+ if( !db_looks_like_a_repository(pUrlData->name) ){
184
+ fossil_fatal("not a fossil repository: \"%s\"", pUrlData->name);
185
+ }
183186
sqlite3_randomness(sizeof(iRandId), &iRandId);
184187
transport.zOutFile = mprintf("%s-%llu-out.http",
185188
g.zRepositoryName, iRandId);
186189
transport.zInFile = mprintf("%s-%llu-in.http",
187190
g.zRepositoryName, iRandId);
188191
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178 socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179 rc = 1;
180 #endif
181 }else if( pUrlData->isFile ){
182 sqlite3_uint64 iRandId;
 
 
 
183 sqlite3_randomness(sizeof(iRandId), &iRandId);
184 transport.zOutFile = mprintf("%s-%llu-out.http",
185 g.zRepositoryName, iRandId);
186 transport.zInFile = mprintf("%s-%llu-in.http",
187 g.zRepositoryName, iRandId);
188
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178 socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179 rc = 1;
180 #endif
181 }else if( pUrlData->isFile ){
182 sqlite3_uint64 iRandId;
183 if( !db_looks_like_a_repository(pUrlData->name) ){
184 fossil_fatal("not a fossil repository: \"%s\"", pUrlData->name);
185 }
186 sqlite3_randomness(sizeof(iRandId), &iRandId);
187 transport.zOutFile = mprintf("%s-%llu-out.http",
188 g.zRepositoryName, iRandId);
189 transport.zInFile = mprintf("%s-%llu-in.http",
190 g.zRepositoryName, iRandId);
191
+1
--- src/info.c
+++ src/info.c
@@ -2538,10 +2538,11 @@
25382538
zMime = mimetype_from_name(zName);
25392539
style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
25402540
zName, zCI);
25412541
style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
25422542
zName, zCI);
2543
+ style_submenu_element("Doc", "%R/doc/%T/%T", zCI, zName);
25432544
blob_init(&downloadName, zName, -1);
25442545
objType = OBJTYPE_CONTENT;
25452546
}else{
25462547
@ <h2>Artifact
25472548
style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
25482549
--- src/info.c
+++ src/info.c
@@ -2538,10 +2538,11 @@
2538 zMime = mimetype_from_name(zName);
2539 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2540 zName, zCI);
2541 style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2542 zName, zCI);
 
2543 blob_init(&downloadName, zName, -1);
2544 objType = OBJTYPE_CONTENT;
2545 }else{
2546 @ <h2>Artifact
2547 style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
2548
--- src/info.c
+++ src/info.c
@@ -2538,10 +2538,11 @@
2538 zMime = mimetype_from_name(zName);
2539 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2540 zName, zCI);
2541 style_submenu_element("Blame", "%R/blame?filename=%T&checkin=%T",
2542 zName, zCI);
2543 style_submenu_element("Doc", "%R/doc/%T/%T", zCI, zName);
2544 blob_init(&downloadName, zName, -1);
2545 objType = OBJTYPE_CONTENT;
2546 }else{
2547 @ <h2>Artifact
2548 style_copy_button(1, "hash-ar", 0, 2, "%s", zUuid);
2549
+330 -131
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -452,11 +452,11 @@
452452
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453453
** [sqlite_version()] and [sqlite_source_id()].
454454
*/
455455
#define SQLITE_VERSION "3.37.0"
456456
#define SQLITE_VERSION_NUMBER 3037000
457
-#define SQLITE_SOURCE_ID "2021-11-04 14:04:20 9147390d9885a37a62edc1058f313434627f1b59965c890877d2cb119e355c78"
457
+#define SQLITE_SOURCE_ID "2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -913,10 +913,11 @@
913913
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
914914
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
915915
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
916916
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
917917
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
918
+#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
918919
919920
/* Reserved: 0x00F00000 */
920921
/* Legacy compatibility: */
921922
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
922923
@@ -3732,10 +3733,18 @@
37323733
**
37333734
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
37343735
** <dd>The database is opened [shared cache] disabled, overriding
37353736
** the default shared cache setting provided by
37363737
** [sqlite3_enable_shared_cache()].)^
3738
+**
3739
+** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt>
3740
+** <dd>The database connection comes up in "extended result code mode".
3741
+** In other words, the database behaves has if
3742
+** [sqlite3_extended_result_codes(db,1)] where called on the database
3743
+** connection as soon as the connection is created. In addition to setting
3744
+** the extended result code mode, this flag also causes [sqlite3_open_v2()]
3745
+** to return an extended result code.</dd>
37373746
**
37383747
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
37393748
** <dd>The database filename is not allowed to be a symbolic link</dd>
37403749
** </dl>)^
37413750
**
@@ -16649,10 +16658,11 @@
1664916658
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
1665016659
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
1665116660
#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
1665216661
/* DELETE, or UPDATE and return */
1665316662
/* the count using a callback. */
16663
+#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
1665416664
1665516665
/* Flags used only if debugging */
1665616666
#ifdef SQLITE_DEBUG
1665716667
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
1665816668
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -18901,12 +18911,12 @@
1890118911
union { /* Extra data for callback */
1890218912
NameContext *pNC; /* Naming context */
1890318913
int n; /* A counter */
1890418914
int iCur; /* A cursor number */
1890518915
SrcList *pSrcList; /* FROM clause */
18906
- struct SrcCount *pSrcCount; /* Counting column references */
1890718916
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
18917
+ struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */
1890818918
int *aiCol; /* array of column indexes */
1890918919
struct IdxCover *pIdxCover; /* Check for index coverage */
1891018920
struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
1891118921
ExprList *pGroupBy; /* GROUP BY clause */
1891218922
Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19560,11 +19570,11 @@
1956019570
SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
1956119571
SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
1956219572
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
1956319573
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
1956419574
SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19565
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
19575
+SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*);
1956619576
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
1956719577
#ifndef SQLITE_UNTESTABLE
1956819578
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
1956919579
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
1957019580
#endif
@@ -22193,11 +22203,15 @@
2219322203
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
2219422204
#endif
2219522205
SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
2219622206
SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
2219722207
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
22208
+#ifndef SQLITE_OMIT_INCRBLOB
2219822209
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
22210
+#else
22211
+SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int);
22212
+#endif
2219922213
#ifdef SQLITE_DEBUG
2220022214
SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
2220122215
#endif
2220222216
SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
2220322217
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
@@ -48826,12 +48840,13 @@
4882648840
*/
4882748841
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
4882848842
MemStore *p = ((MemFile*)pFile)->pStore;
4882948843
int rc = SQLITE_OK;
4883048844
memdbEnter(p);
48831
- if( NEVER(size>p->sz) ){
48832
- rc = SQLITE_FULL;
48845
+ if( size>p->sz ){
48846
+ /* This can only happen with a corrupt wal mode db */
48847
+ rc = SQLITE_CORRUPT;
4883348848
}else{
4883448849
p->sz = size;
4883548850
}
4883648851
memdbLeave(p);
4883748852
return rc;
@@ -67031,11 +67046,11 @@
6703167046
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
6703267047
sz2 = get2byte(&data[iFree2+2]);
6703367048
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
6703467049
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
6703567050
sz += sz2;
67036
- }else if( iFree+sz>usableSize ){
67051
+ }else if( NEVER(iFree+sz>usableSize) ){
6703767052
return SQLITE_CORRUPT_PAGE(pPage);
6703867053
}
6703967054
6704067055
cbrk = top+sz;
6704167056
assert( cbrk+(iFree-top) <= usableSize );
@@ -72654,11 +72669,11 @@
7265472669
int k; /* Current slot in pCArray->apEnd[] */
7265572670
u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */
7265672671
7265772672
assert( i<iEnd );
7265872673
j = get2byte(&aData[hdr+5]);
72659
- if( j>(u32)usableSize ){ j = 0; }
72674
+ if( NEVER(j>(u32)usableSize) ){ j = 0; }
7266072675
memcpy(&pTmp[j], &aData[j], usableSize - j);
7266172676
7266272677
for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
7266372678
pSrcEnd = pCArray->apEnd[k];
7266472679
@@ -78041,19 +78056,35 @@
7804178056
7804278057
/*
7804378058
** Delete any previous value and set the value to be a BLOB of length
7804478059
** n containing all zeros.
7804578060
*/
78061
+#ifndef SQLITE_OMIT_INCRBLOB
7804678062
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
7804778063
sqlite3VdbeMemRelease(pMem);
7804878064
pMem->flags = MEM_Blob|MEM_Zero;
7804978065
pMem->n = 0;
7805078066
if( n<0 ) n = 0;
7805178067
pMem->u.nZero = n;
7805278068
pMem->enc = SQLITE_UTF8;
7805378069
pMem->z = 0;
7805478070
}
78071
+#else
78072
+SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78073
+ int nByte = n>0?n:1;
78074
+ if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
78075
+ return SQLITE_NOMEM_BKPT;
78076
+ }
78077
+ assert( pMem->z!=0 );
78078
+ assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte );
78079
+ memset(pMem->z, 0, nByte);
78080
+ pMem->n = n>0?n:0;
78081
+ pMem->flags = MEM_Blob;
78082
+ pMem->enc = SQLITE_UTF8;
78083
+ return SQLITE_OK;
78084
+}
78085
+#endif
7805578086
7805678087
/*
7805778088
** The pMem is known to contain content that needs to be destroyed prior
7805878089
** to a value change. So invoke the destructor, then set the value to
7805978090
** a 64-bit integer.
@@ -82178,13 +82209,19 @@
8217882209
8217982210
/* Lock all btrees used by the statement */
8218082211
sqlite3VdbeEnter(p);
8218182212
8218282213
/* Check for one of the special errors */
82183
- mrc = p->rc & 0xff;
82184
- isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
82185
- || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
82214
+ if( p->rc ){
82215
+ mrc = p->rc & 0xff;
82216
+ isSpecialError = mrc==SQLITE_NOMEM
82217
+ || mrc==SQLITE_IOERR
82218
+ || mrc==SQLITE_INTERRUPT
82219
+ || mrc==SQLITE_FULL;
82220
+ }else{
82221
+ mrc = isSpecialError = 0;
82222
+ }
8218682223
if( isSpecialError ){
8218782224
/* If the query was read-only and the error code is SQLITE_INTERRUPT,
8218882225
** no rollback is necessary. Otherwise, at least a savepoint
8218982226
** transaction must be rolled back to restore the database to a
8219082227
** consistent state.
@@ -82232,10 +82269,13 @@
8223282269
if( NEVER(p->readOnly) ){
8223382270
sqlite3VdbeLeave(p);
8223482271
return SQLITE_ERROR;
8223582272
}
8223682273
rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82274
+ }else if( db->flags & SQLITE_CorruptRdOnly ){
82275
+ rc = SQLITE_CORRUPT;
82276
+ db->flags &= ~SQLITE_CorruptRdOnly;
8223782277
}else{
8223882278
/* The auto-commit flag is true, the vdbe program was successful
8223982279
** or hit an 'OR FAIL' constraint and there are no deferred foreign
8224082280
** key constraints to hold up the transaction. This means a commit
8224182281
** is required. */
@@ -84336,10 +84376,12 @@
8433684376
}else{
8433784377
iKey2 = iKey1;
8433884378
}
8433984379
}
8434084380
84381
+ assert( pCsr!=0 );
84382
+ assert( pCsr->eCurType==CURTYPE_BTREE );
8434184383
assert( pCsr->nField==pTab->nCol
8434284384
|| (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
8434384385
);
8434484386
8434584387
preupdate.v = v;
@@ -84914,12 +84956,16 @@
8491484956
Mem *pOut = pCtx->pOut;
8491584957
assert( sqlite3_mutex_held(pOut->db->mutex) );
8491684958
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
8491784959
return SQLITE_TOOBIG;
8491884960
}
84961
+#ifndef SQLITE_OMIT_INCRBLOB
8491984962
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
8492084963
return SQLITE_OK;
84964
+#else
84965
+ return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84966
+#endif
8492184967
}
8492284968
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
8492384969
pCtx->isError = errCode ? errCode : -1;
8492484970
#ifdef SQLITE_DEBUG
8492584971
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85927,11 +85973,15 @@
8592785973
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
8592885974
int rc;
8592985975
Vdbe *p = (Vdbe *)pStmt;
8593085976
rc = vdbeUnbind(p, i);
8593185977
if( rc==SQLITE_OK ){
85978
+#ifndef SQLITE_OMIT_INCRBLOB
8593285979
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
85980
+#else
85981
+ rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
85982
+#endif
8593385983
sqlite3_mutex_leave(p->db->mutex);
8593485984
}
8593585985
return rc;
8593685986
}
8593785987
SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86215,10 +86265,11 @@
8621586265
/* If the old.* record has not yet been loaded into memory, do so now. */
8621686266
if( p->pUnpacked==0 ){
8621786267
u32 nRec;
8621886268
u8 *aRec;
8621986269
86270
+ assert( p->pCsr->eCurType==CURTYPE_BTREE );
8622086271
nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
8622186272
aRec = sqlite3DbMallocRaw(db, nRec);
8622286273
if( !aRec ) goto preupdate_old_out;
8622386274
rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
8622486275
if( rc==SQLITE_OK ){
@@ -90298,12 +90349,19 @@
9029890349
assert( p->readOnly==0 || pOp->p2==0 );
9029990350
assert( pOp->p2>=0 && pOp->p2<=2 );
9030090351
assert( pOp->p1>=0 && pOp->p1<db->nDb );
9030190352
assert( DbMaskTest(p->btreeMask, pOp->p1) );
9030290353
assert( rc==SQLITE_OK );
90303
- if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
90304
- rc = SQLITE_READONLY;
90354
+ if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){
90355
+ if( db->flags & SQLITE_QueryOnly ){
90356
+ /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */
90357
+ rc = SQLITE_READONLY;
90358
+ }else{
90359
+ /* Writes prohibited due to a prior SQLITE_CORRUPT in the current
90360
+ ** transaction */
90361
+ rc = SQLITE_CORRUPT;
90362
+ }
9030590363
goto abort_due_to_error;
9030690364
}
9030790365
pBt = db->aDb[pOp->p1].pBt;
9030890366
9030990367
if( pBt ){
@@ -94368,10 +94426,11 @@
9436894426
pQuery = &aMem[pOp->p3];
9436994427
pArgc = &pQuery[1];
9437094428
pCur = p->apCsr[pOp->p1];
9437194429
assert( memIsValid(pQuery) );
9437294430
REGISTER_TRACE(pOp->p3, pQuery);
94431
+ assert( pCur!=0 );
9437394432
assert( pCur->eCurType==CURTYPE_VTAB );
9437494433
pVCur = pCur->uc.pVCur;
9437594434
pVtab = pVCur->pVtab;
9437694435
pModule = pVtab->pModule;
9437794436
@@ -94416,10 +94475,11 @@
9441694475
const sqlite3_module *pModule;
9441794476
Mem *pDest;
9441894477
sqlite3_context sContext;
9441994478
9442094479
VdbeCursor *pCur = p->apCsr[pOp->p1];
94480
+ assert( pCur!=0 );
9442194481
assert( pCur->eCurType==CURTYPE_VTAB );
9442294482
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
9442394483
pDest = &aMem[pOp->p3];
9442494484
memAboutToChange(p, pDest);
9442594485
if( pCur->nullRow ){
@@ -94469,10 +94529,11 @@
9446994529
const sqlite3_module *pModule;
9447094530
int res;
9447194531
VdbeCursor *pCur;
9447294532
9447394533
pCur = p->apCsr[pOp->p1];
94534
+ assert( pCur!=0 );
9447494535
assert( pCur->eCurType==CURTYPE_VTAB );
9447594536
if( pCur->nullRow ){
9447694537
break;
9447794538
}
9447894539
pVtab = pCur->uc.pVCur->pVtab;
@@ -94564,11 +94625,11 @@
9456494625
case OP_VUpdate: {
9456594626
sqlite3_vtab *pVtab;
9456694627
const sqlite3_module *pModule;
9456794628
int nArg;
9456894629
int i;
94569
- sqlite_int64 rowid;
94630
+ sqlite_int64 rowid = 0;
9457094631
Mem **apArg;
9457194632
Mem *pX;
9457294633
9457394634
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
9457494635
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -95011,11 +95072,18 @@
9501195072
rc = SQLITE_CORRUPT_BKPT;
9501295073
}
9501395074
assert( rc );
9501495075
#ifdef SQLITE_DEBUG
9501595076
if( db->flags & SQLITE_VdbeTrace ){
95016
- printf("ABORT-due-to-error. rc=%d\n", rc);
95077
+ const char *zTrace = p->zSql;
95078
+ if( zTrace==0 ){
95079
+ if( aOp[0].opcode==OP_Trace ){
95080
+ zTrace = aOp[0].p4.z;
95081
+ }
95082
+ if( zTrace==0 ) zTrace = "???";
95083
+ }
95084
+ printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace);
9501795085
}
9501895086
#endif
9501995087
if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
9502095088
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
9502195089
}
@@ -95024,10 +95092,13 @@
9502495092
testcase( sqlite3GlobalConfig.xLog!=0 );
9502595093
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
9502695094
(int)(pOp - aOp), p->zSql, p->zErrMsg);
9502795095
sqlite3VdbeHalt(p);
9502895096
if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
95097
+ if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
95098
+ db->flags |= SQLITE_CorruptRdOnly;
95099
+ }
9502995100
rc = SQLITE_ERROR;
9503095101
if( resetSchemaOnFault>0 ){
9503195102
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
9503295103
}
9503395104
@@ -95155,11 +95226,14 @@
9515595226
}else{
9515695227
rc = sqlite3_step(p->pStmt);
9515795228
}
9515895229
if( rc==SQLITE_ROW ){
9515995230
VdbeCursor *pC = v->apCsr[0];
95160
- u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
95231
+ u32 type;
95232
+ assert( pC!=0 );
95233
+ assert( pC->eCurType==CURTYPE_BTREE );
95234
+ type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
9516195235
testcase( pC->nHdrParsed==p->iCol );
9516295236
testcase( pC->nHdrParsed==p->iCol+1 );
9516395237
if( type<12 ){
9516495238
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
9516595239
type==0?"null": type==7?"real": "integer"
@@ -95500,10 +95574,12 @@
9550095574
** using the incremental-blob API, this works. For the sessions module
9550195575
** anyhow.
9550295576
*/
9550395577
sqlite3_int64 iKey;
9550495578
iKey = sqlite3BtreeIntegerKey(p->pCsr);
95579
+ assert( v->apCsr[0]!=0 );
95580
+ assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
9550595581
sqlite3VdbePreUpdateHook(
9550695582
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
9550795583
);
9550895584
}
9550995585
#endif
@@ -100579,19 +100655,22 @@
100579100655
sqlite3WindowLink(pSel, pWin);
100580100656
pNC->ncFlags |= NC_HasWin;
100581100657
}else
100582100658
#endif /* SQLITE_OMIT_WINDOWFUNC */
100583100659
{
100584
- NameContext *pNC2 = pNC;
100660
+ NameContext *pNC2; /* For looping up thru outer contexts */
100585100661
pExpr->op = TK_AGG_FUNCTION;
100586100662
pExpr->op2 = 0;
100587100663
#ifndef SQLITE_OMIT_WINDOWFUNC
100588100664
if( ExprHasProperty(pExpr, EP_WinFunc) ){
100589100665
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100590100666
}
100591100667
#endif
100592
- while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
100668
+ pNC2 = pNC;
100669
+ while( pNC2
100670
+ && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
100671
+ ){
100593100672
pExpr->op2++;
100594100673
pNC2 = pNC2->pNext;
100595100674
}
100596100675
assert( pDef!=0 || IN_RENAME_OBJECT );
100597100676
if( pNC2 && pDef ){
@@ -101557,12 +101636,12 @@
101557101636
101558101637
/*
101559101638
** Return the affinity character for a single column of a table.
101560101639
*/
101561101640
SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101562
- assert( iCol<pTab->nCol );
101563
- return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
101641
+ if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER;
101642
+ return pTab->aCol[iCol].affinity;
101564101643
}
101565101644
101566101645
/*
101567101646
** Return the 'affinity' of the expression pExpr if any.
101568101647
**
@@ -104338,11 +104417,12 @@
104338104417
Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104339104418
Expr *pRhs = pEList->a[i].pExpr;
104340104419
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104341104420
int j;
104342104421
104343
- assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
104422
+ assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104423
+ || pParse->nErr || db->mallocFailed );
104344104424
for(j=0; j<nExpr; j++){
104345104425
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104346104426
assert( pIdx->azColl[j] );
104347104427
if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104348104428
continue;
@@ -107414,93 +107494,128 @@
107414107494
sqlite3WalkExpr(&w, pExpr);
107415107495
return !w.eCode;
107416107496
}
107417107497
107418107498
107419
-/*
107420
-** An instance of the following structure is used by the tree walker
107421
-** to count references to table columns in the arguments of an
107422
-** aggregate function, in order to implement the
107423
-** sqlite3FunctionThisSrc() routine.
107499
+/* Structure used to pass information throught the Walker in order to
107500
+** implement sqlite3ReferencesSrcList().
107424107501
*/
107425
-struct SrcCount {
107426
- SrcList *pSrc; /* One particular FROM clause in a nested query */
107427
- int iSrcInner; /* Smallest cursor number in this context */
107428
- int nThis; /* Number of references to columns in pSrcList */
107429
- int nOther; /* Number of references to columns in other FROM clauses */
107502
+struct RefSrcList {
107503
+ sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */
107504
+ SrcList *pRef; /* Looking for references to these tables */
107505
+ int nExclude; /* Number of tables to exclude from the search */
107506
+ int *aiExclude; /* Cursor IDs for tables to exclude from the search */
107430107507
};
107431107508
107432107509
/*
107433
-** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
107434
-** SELECT with a FROM clause encountered during this iteration, set
107435
-** SrcCount.iSrcInner to the cursor number of the leftmost object in
107436
-** the FROM cause.
107510
+** Walker SELECT callbacks for sqlite3ReferencesSrcList().
107511
+**
107512
+** When entering a new subquery on the pExpr argument, add all FROM clause
107513
+** entries for that subquery to the exclude list.
107514
+**
107515
+** When leaving the subquery, remove those entries from the exclude list.
107437107516
*/
107438
-static int selectSrcCount(Walker *pWalker, Select *pSel){
107439
- struct SrcCount *p = pWalker->u.pSrcCount;
107440
- if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
107441
- pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
107517
+static int selectRefEnter(Walker *pWalker, Select *pSelect){
107518
+ struct RefSrcList *p = pWalker->u.pRefSrcList;
107519
+ SrcList *pSrc = pSelect->pSrc;
107520
+ int i, j, *piNew;
107521
+ if( pSrc->nSrc==0 ) return WRC_Continue;
107522
+ j = p->nExclude;
107523
+ p->nExclude += pSrc->nSrc;
107524
+ piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int));
107525
+ if( piNew==0 ){
107526
+ p->nExclude = 0;
107527
+ return WRC_Abort;
107528
+ }else{
107529
+ p->aiExclude = piNew;
107530
+ }
107531
+ for(i=0; i<pSrc->nSrc; i++, j++){
107532
+ p->aiExclude[j] = pSrc->a[i].iCursor;
107442107533
}
107443107534
return WRC_Continue;
107444107535
}
107445
-
107446
-/*
107447
-** Count the number of references to columns.
107448
-*/
107449
-static int exprSrcCount(Walker *pWalker, Expr *pExpr){
107450
- /* There was once a NEVER() on the second term on the grounds that
107451
- ** sqlite3FunctionUsesThisSrc() was always called before
107452
- ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
107453
- ** been converted into TK_AGG_COLUMN. But this is no longer true due
107454
- ** to window functions - sqlite3WindowRewrite() may now indirectly call
107455
- ** FunctionUsesThisSrc() when creating a new sub-select. */
107456
- if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
107457
- int i;
107458
- struct SrcCount *p = pWalker->u.pSrcCount;
107459
- SrcList *pSrc = p->pSrc;
107536
+static void selectRefLeave(Walker *pWalker, Select *pSelect){
107537
+ struct RefSrcList *p = pWalker->u.pRefSrcList;
107538
+ SrcList *pSrc = pSelect->pSrc;
107539
+ if( p->nExclude ){
107540
+ assert( p->nExclude>=pSrc->nSrc );
107541
+ p->nExclude -= pSrc->nSrc;
107542
+ }
107543
+}
107544
+
107545
+/* This is the Walker EXPR callback for sqlite3ReferencesSrcList().
107546
+**
107547
+** Set the 0x01 bit of pWalker->eCode if there is a reference to any
107548
+** of the tables shown in RefSrcList.pRef.
107549
+**
107550
+** Set the 0x02 bit of pWalker->eCode if there is a reference to a
107551
+** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude.
107552
+*/
107553
+static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){
107554
+ if( pExpr->op==TK_COLUMN
107555
+ || pExpr->op==TK_AGG_COLUMN
107556
+ ){
107557
+ int i;
107558
+ struct RefSrcList *p = pWalker->u.pRefSrcList;
107559
+ SrcList *pSrc = p->pRef;
107460107560
int nSrc = pSrc ? pSrc->nSrc : 0;
107461107561
for(i=0; i<nSrc; i++){
107462
- if( pExpr->iTable==pSrc->a[i].iCursor ) break;
107463
- }
107464
- if( i<nSrc ){
107465
- p->nThis++;
107466
- }else if( pExpr->iTable<p->iSrcInner ){
107467
- /* In a well-formed parse tree (no name resolution errors),
107468
- ** TK_COLUMN nodes with smaller Expr.iTable values are in an
107469
- ** outer context. Those are the only ones to count as "other" */
107470
- p->nOther++;
107562
+ if( pExpr->iTable==pSrc->a[i].iCursor ){
107563
+ pWalker->eCode |= 1;
107564
+ return WRC_Continue;
107565
+ }
107566
+ }
107567
+ for(i=0; i<p->nExclude && p->aiExclude[i]!=pExpr->iTable; i++){}
107568
+ if( i>=p->nExclude ){
107569
+ pWalker->eCode |= 2;
107471107570
}
107472107571
}
107473107572
return WRC_Continue;
107474107573
}
107475107574
107476107575
/*
107477
-** Determine if any of the arguments to the pExpr Function reference
107478
-** pSrcList. Return true if they do. Also return true if the function
107479
-** has no arguments or has only constant arguments. Return false if pExpr
107480
-** references columns but not columns of tables found in pSrcList.
107576
+** Check to see if pExpr references any tables in pSrcList.
107577
+** Possible return values:
107578
+**
107579
+** 1 pExpr does references a table in pSrcList.
107580
+**
107581
+** 0 pExpr references some table that is not defined in either
107582
+** pSrcList or in subqueries of pExpr itself.
107583
+**
107584
+** -1 pExpr only references no tables at all, or it only
107585
+** references tables defined in subqueries of pExpr itself.
107586
+**
107587
+** As currently used, pExpr is always an aggregate function call. That
107588
+** fact is exploited for efficiency.
107481107589
*/
107482
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
107590
+SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
107483107591
Walker w;
107484
- struct SrcCount cnt;
107485
- assert( pExpr->op==TK_AGG_FUNCTION );
107592
+ struct RefSrcList x;
107486107593
memset(&w, 0, sizeof(w));
107487
- w.xExprCallback = exprSrcCount;
107488
- w.xSelectCallback = selectSrcCount;
107489
- w.u.pSrcCount = &cnt;
107490
- cnt.pSrc = pSrcList;
107491
- cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
107492
- cnt.nThis = 0;
107493
- cnt.nOther = 0;
107594
+ memset(&x, 0, sizeof(x));
107595
+ w.xExprCallback = exprRefToSrcList;
107596
+ w.xSelectCallback = selectRefEnter;
107597
+ w.xSelectCallback2 = selectRefLeave;
107598
+ w.u.pRefSrcList = &x;
107599
+ x.db = pParse->db;
107600
+ x.pRef = pSrcList;
107601
+ assert( pExpr->op==TK_AGG_FUNCTION );
107494107602
assert( ExprUseXList(pExpr) );
107495107603
sqlite3WalkExprList(&w, pExpr->x.pList);
107496107604
#ifndef SQLITE_OMIT_WINDOWFUNC
107497107605
if( ExprHasProperty(pExpr, EP_WinFunc) ){
107498107606
sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107499107607
}
107500107608
#endif
107501
- return cnt.nThis>0 || cnt.nOther==0;
107609
+ sqlite3DbFree(pParse->db, x.aiExclude);
107610
+ if( w.eCode & 0x01 ){
107611
+ return 1;
107612
+ }else if( w.eCode ){
107613
+ return 0;
107614
+ }else{
107615
+ return -1;
107616
+ }
107502107617
}
107503107618
107504107619
/*
107505107620
** This is a Walker expression node callback.
107506107621
**
@@ -115414,10 +115529,11 @@
115414115529
115415115530
assert( IsVirtual(pTab) );
115416115531
pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]);
115417115532
if( pMod==0 ) return;
115418115533
if( NEVER(pMod->pModule==0) ) return;
115534
+ if( pMod->pModule->iVersion<3 ) return;
115419115535
if( pMod->pModule->xShadowName==0 ) return;
115420115536
assert( pTab->zName!=0 );
115421115537
nName = sqlite3Strlen30(pTab->zName);
115422115538
for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){
115423115539
Table *pOther = sqliteHashData(k);
@@ -116321,10 +116437,13 @@
116321116437
if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
116322116438
return 1;
116323116439
}
116324116440
if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
116325116441
return 1;
116442
+ }
116443
+ if( pTab->tabFlags & TF_Eponymous ){
116444
+ return 1;
116326116445
}
116327116446
return 0;
116328116447
}
116329116448
116330116449
/*
@@ -127801,11 +127920,11 @@
127801127920
/* Version 3.34.0 and later */
127802127921
#define sqlite3_txn_state sqlite3_api->txn_state
127803127922
/* Version 3.36.1 and later */
127804127923
#define sqlite3_changes64 sqlite3_api->changes64
127805127924
#define sqlite3_total_changes64 sqlite3_api->total_changes64
127806
-* Version 3.37.0 and later */
127925
+/* Version 3.37.0 and later */
127807127926
#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
127808127927
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127809127928
127810127929
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127811127930
/* This case when the file really is being compiled as a loadable
@@ -135298,10 +135417,13 @@
135298135417
n = sqlite3Strlen30(pCol->zCnName);
135299135418
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
135300135419
if( pCol->zCnName ){
135301135420
memcpy(&pCol->zCnName[n+1], zType, m+1);
135302135421
pCol->colFlags |= COLFLAG_HASTYPE;
135422
+ }else{
135423
+ testcase( pCol->colFlags & COLFLAG_HASTYPE );
135424
+ pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
135303135425
}
135304135426
}
135305135427
if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
135306135428
pColl = sqlite3ExprCollSeq(pParse, p);
135307135429
if( pColl ){
@@ -138037,31 +138159,44 @@
138037138159
**
138038138160
** SELECT count(*) FROM <tbl>
138039138161
**
138040138162
** where table is a database table, not a sub-select or view. If the query
138041138163
** does match this pattern, then a pointer to the Table object representing
138042
-** <tbl> is returned. Otherwise, 0 is returned.
138164
+** <tbl> is returned. Otherwise, NULL is returned.
138165
+**
138166
+** This routine a condition for the count optimization. A correct answer
138167
+** is obtained (though perhaps more slowly) if this routine returns NULL when
138168
+** it could have returned a table pointer. But returning the pointer when
138169
+** NULL should have been returned can result in incorrect answers and/or
138170
+** crashes. So, when in doubt, return NULL.
138043138171
*/
138044138172
static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
138045138173
Table *pTab;
138046138174
Expr *pExpr;
138047138175
138048138176
assert( !p->pGroupBy );
138049138177
138050
- if( p->pWhere || p->pEList->nExpr!=1
138051
- || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
138178
+ if( p->pWhere
138179
+ || p->pEList->nExpr!=1
138180
+ || p->pSrc->nSrc!=1
138181
+ || p->pSrc->a[0].pSelect
138182
+ || pAggInfo->nFunc!=1
138052138183
){
138053138184
return 0;
138054138185
}
138055138186
pTab = p->pSrc->a[0].pTab;
138187
+ assert( pTab!=0 );
138188
+ assert( !IsView(pTab) );
138189
+ if( !IsOrdinaryTable(pTab) ) return 0;
138056138190
pExpr = p->pEList->a[0].pExpr;
138057
- assert( pTab && !IsView(pTab) && pExpr );
138058
-
138059
- if( IsVirtual(pTab) ) return 0;
138191
+ assert( pExpr!=0 );
138060138192
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
138061
- if( NEVER(pAggInfo->nFunc==0) ) return 0;
138193
+ if( pExpr->pAggInfo!=pAggInfo ) return 0;
138062138194
if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
138195
+ assert( pAggInfo->aFunc[0].pFExpr==pExpr );
138196
+ testcase( ExprHasProperty(pExpr, EP_Distinct) );
138197
+ testcase( ExprHasProperty(pExpr, EP_WinFunc) );
138063138198
if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
138064138199
138065138200
return pTab;
138066138201
}
138067138202
@@ -145189,11 +145324,14 @@
145189145324
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
145190145325
int rc = SQLITE_OK;
145191145326
Table *pTab;
145192145327
145193145328
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
145194
- if( pTab!=0 && ALWAYS(IsVirtual(pTab)) && ALWAYS(pTab->u.vtab.p!=0) ){
145329
+ if( ALWAYS(pTab!=0)
145330
+ && ALWAYS(IsVirtual(pTab))
145331
+ && ALWAYS(pTab->u.vtab.p!=0)
145332
+ ){
145195145333
VTable *p;
145196145334
int (*xDestroy)(sqlite3_vtab *);
145197145335
for(p=pTab->u.vtab.p; p; p=p->pNext){
145198145336
assert( p->pVtab );
145199145337
if( p->pVtab->nRef>0 ){
@@ -155813,10 +155951,11 @@
155813155951
** program.
155814155952
*/
155815155953
for(ii=0; ii<nTabList; ii++){
155816155954
int addrExplain;
155817155955
int wsFlags;
155956
+ if( pParse->nErr ) goto whereBeginError;
155818155957
pLevel = &pWInfo->a[ii];
155819155958
wsFlags = pLevel->pWLoop->wsFlags;
155820155959
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155821155960
if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155822155961
constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -157266,11 +157405,15 @@
157266157405
}
157267157406
}else{
157268157407
sqlite3SelectDelete(db, pSub);
157269157408
}
157270157409
if( db->mallocFailed ) rc = SQLITE_NOMEM;
157271
- sqlite3DbFree(db, pTab);
157410
+
157411
+ /* Defer deleting the temporary table pTab because if an error occurred,
157412
+ ** there could still be references to that table embedded in the
157413
+ ** result-set or ORDER BY clause of the SELECT statement p. */
157414
+ sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
157272157415
}
157273157416
157274157417
if( rc ){
157275157418
if( pParse->nErr==0 ){
157276157419
assert( pParse->db->mallocFailed );
@@ -160713,13 +160856,13 @@
160713160856
yyStackEntry *yystackEnd; /* Last entry in the stack */
160714160857
#endif
160715160858
};
160716160859
typedef struct yyParser yyParser;
160717160860
160861
+/* #include <assert.h> */
160718160862
#ifndef NDEBUG
160719160863
/* #include <stdio.h> */
160720
-/* #include <assert.h> */
160721160864
static FILE *yyTraceFILE = 0;
160722160865
static char *yyTracePrompt = 0;
160723160866
#endif /* NDEBUG */
160724160867
160725160868
#ifndef NDEBUG
@@ -164464,12 +164607,12 @@
164464164607
assert( yypParser->yytos>=yypParser->yystack );
164465164608
assert( yyact==yypParser->yytos->stateno );
164466164609
yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
164467164610
if( yyact >= YY_MIN_REDUCE ){
164468164611
unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
164469
- assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164470164612
#ifndef NDEBUG
164613
+ assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164471164614
if( yyTraceFILE ){
164472164615
int yysize = yyRuleInfoNRhs[yyruleno];
164473164616
if( yysize ){
164474164617
fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
164475164618
yyTracePrompt,
@@ -167854,11 +167997,11 @@
167854167997
sqlite3BtreeLeaveAll(db);
167855167998
167856167999
/* Any deferred constraint violations have now been resolved. */
167857168000
db->nDeferredCons = 0;
167858168001
db->nDeferredImmCons = 0;
167859
- db->flags &= ~(u64)SQLITE_DeferFKs;
168002
+ db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
167860168003
167861168004
/* If one has been configured, invoke the rollback-hook callback */
167862168005
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
167863168006
db->xRollbackCallback(db->pRollbackArg);
167864168007
}
@@ -169582,12 +169725,12 @@
169582169725
**
169583169726
** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
169584169727
** dealt with in the previous code block. Besides these, the only
169585169728
** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
169586169729
** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
169587
- ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
169588
- ** off all other flags.
169730
+ ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
169731
+ ** bits. Silently mask off all other flags.
169589169732
*/
169590169733
flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
169591169734
SQLITE_OPEN_EXCLUSIVE |
169592169735
SQLITE_OPEN_MAIN_DB |
169593169736
SQLITE_OPEN_TEMP_DB |
@@ -169618,11 +169761,11 @@
169618169761
if( isThreadsafe==0 ){
169619169762
sqlite3MutexWarnOnContention(db->mutex);
169620169763
}
169621169764
}
169622169765
sqlite3_mutex_enter(db->mutex);
169623
- db->errMask = 0xff;
169766
+ db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
169624169767
db->nDb = 2;
169625169768
db->eOpenState = SQLITE_STATE_BUSY;
169626169769
db->aDb = db->aDbStatic;
169627169770
db->lookaside.bDisable = 1;
169628169771
db->lookaside.sz = 0;
@@ -169850,12 +169993,12 @@
169850169993
assert( db->mutex!=0 || isThreadsafe==0
169851169994
|| sqlite3GlobalConfig.bFullMutex==0 );
169852169995
sqlite3_mutex_leave(db->mutex);
169853169996
}
169854169997
rc = sqlite3_errcode(db);
169855
- assert( db!=0 || rc==SQLITE_NOMEM );
169856
- if( rc==SQLITE_NOMEM ){
169998
+ assert( db!=0 || (rc&0xff)==SQLITE_NOMEM );
169999
+ if( (rc&0xff)==SQLITE_NOMEM ){
169857170000
sqlite3_close(db);
169858170001
db = 0;
169859170002
}else if( rc!=SQLITE_OK ){
169860170003
db->eOpenState = SQLITE_STATE_SICK;
169861170004
}
@@ -169866,11 +170009,11 @@
169866170009
void *pArg = sqlite3GlobalConfig.pSqllogArg;
169867170010
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
169868170011
}
169869170012
#endif
169870170013
sqlite3_free_filename(zOpen);
169871
- return rc & 0xff;
170014
+ return rc;
169872170015
}
169873170016
169874170017
169875170018
/*
169876170019
** Open a new database handle.
@@ -178416,10 +178559,13 @@
178416178559
while( rc==SQLITE_OK && !pNear->bEof ){
178417178560
fts3EvalNextRow(pCsr, pNear, &rc);
178418178561
if( bEofSave==0 && pNear->iDocid==iDocid ) break;
178419178562
}
178420178563
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
178564
+ if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
178565
+ rc = FTS_CORRUPT_VTAB;
178566
+ }
178421178567
}
178422178568
if( bTreeEof ){
178423178569
while( rc==SQLITE_OK && !pNear->bEof ){
178424178570
fts3EvalNextRow(pCsr, pNear, &rc);
178425178571
}
@@ -190106,17 +190252,17 @@
190106190252
int iEnd = 0;
190107190253
int iCurrent = 0;
190108190254
const char *zDoc;
190109190255
int nDoc;
190110190256
190111
- /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
190112
- ** no way that this operation can fail, so the return code from
190113
- ** fts3ExprIterate() can be discarded.
190257
+ /* Initialize the contents of sCtx.aTerm[] for column iCol. This
190258
+ ** operation may fail if the database contains corrupt records.
190114190259
*/
190115190260
sCtx.iCol = iCol;
190116190261
sCtx.iTerm = 0;
190117
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190262
+ rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190263
+ if( rc!=SQLITE_OK ) goto offsets_out;
190118190264
190119190265
/* Retreive the text stored in column iCol. If an SQL NULL is stored
190120190266
** in column iCol, jump immediately to the next iteration of the loop.
190121190267
** If an OOM occurs while retrieving the data (this can happen if SQLite
190122190268
** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -192676,12 +192822,15 @@
192676192822
}else{
192677192823
JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
192678192824
if( pNew==0 ) return 0;
192679192825
pTarget = &pParse->aNode[iTarget];
192680192826
if( pNew!=&pTarget[j+1] ){
192681
- assert( pTarget[j+1].eU==0 || pTarget[j+1].eU==1 );
192827
+ assert( pTarget[j+1].eU==0
192828
+ || pTarget[j+1].eU==1
192829
+ || pTarget[j+1].eU==2 );
192682192830
testcase( pTarget[j+1].eU==1 );
192831
+ testcase( pTarget[j+1].eU==2 );
192683192832
VVA( pTarget[j+1].eU = 5 );
192684192833
pTarget[j+1].u.pPatch = pNew;
192685192834
pTarget[j+1].jnFlags |= JNODE_PATCH;
192686192835
}
192687192836
}
@@ -201672,10 +201821,17 @@
201672201821
** Swap two objects of type TYPE.
201673201822
*/
201674201823
#if !defined(SQLITE_AMALGAMATION)
201675201824
# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
201676201825
#endif
201826
+
201827
+/*
201828
+** Name of the URI option that causes RBU to take an exclusive lock as
201829
+** part of the incremental checkpoint operation.
201830
+*/
201831
+#define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint"
201832
+
201677201833
201678201834
/*
201679201835
** The rbu_state table is used to save the state of a partially applied
201680201836
** update so that it can be resumed later. The table consists of integer
201681201837
** keys mapped to values as follows:
@@ -204319,17 +204475,23 @@
204319204475
204320204476
204321204477
/*
204322204478
** Open the database handle and attach the RBU database as "rbu". If an
204323204479
** error occurs, leave an error code and message in the RBU handle.
204480
+**
204481
+** If argument dbMain is not NULL, then it is a database handle already
204482
+** open on the target database. Use this handle instead of opening a new
204483
+** one.
204324204484
*/
204325
-static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
204485
+static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
204326204486
assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
204327204487
assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
204488
+ assert( dbMain==0 || rbuIsVacuum(p)==0 );
204328204489
204329204490
/* Open the RBU database */
204330204491
p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
204492
+ p->dbMain = dbMain;
204331204493
204332204494
if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
204333204495
sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
204334204496
if( p->zState==0 ){
204335204497
const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -204691,19 +204853,35 @@
204691204853
p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
204692204854
}
204693204855
204694204856
204695204857
/*
204696
-** Take an EXCLUSIVE lock on the database file.
204858
+** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if
204859
+** successful, or an SQLite error code otherwise.
204697204860
*/
204698
-static void rbuLockDatabase(sqlite3rbu *p){
204699
- sqlite3_file *pReal = p->pTargetFd->pReal;
204700
- assert( p->rc==SQLITE_OK );
204701
- p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
204702
- if( p->rc==SQLITE_OK ){
204703
- p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
204861
+static int rbuLockDatabase(sqlite3 *db){
204862
+ int rc = SQLITE_OK;
204863
+ sqlite3_file *fd = 0;
204864
+ sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
204865
+
204866
+ if( fd->pMethods ){
204867
+ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
204868
+ if( rc==SQLITE_OK ){
204869
+ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE);
204870
+ }
204704204871
}
204872
+ return rc;
204873
+}
204874
+
204875
+/*
204876
+** Return true if the database handle passed as the only argument
204877
+** was opened with the rbu_exclusive_checkpoint=1 URI parameter
204878
+** specified. Or false otherwise.
204879
+*/
204880
+static int rbuExclusiveCheckpoint(sqlite3 *db){
204881
+ const char *zUri = sqlite3_db_filename(db, 0);
204882
+ return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0);
204705204883
}
204706204884
204707204885
#if defined(_WIN32_WCE)
204708204886
static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
204709204887
int nChar;
@@ -204757,22 +204935,28 @@
204757204935
** in WAL mode). So no other connection may be writing the db.
204758204936
**
204759204937
** In order to ensure that there are no database readers, an EXCLUSIVE
204760204938
** lock is obtained here before the *-oal is moved to *-wal.
204761204939
*/
204762
- rbuLockDatabase(p);
204940
+ sqlite3 *dbMain = 0;
204941
+ rbuFileSuffix3(zBase, zWal);
204942
+ rbuFileSuffix3(zBase, zOal);
204943
+
204944
+ /* Re-open the databases. */
204945
+ rbuObjIterFinalize(&p->objiter);
204946
+ sqlite3_close(p->dbRbu);
204947
+ sqlite3_close(p->dbMain);
204948
+ p->dbMain = 0;
204949
+ p->dbRbu = 0;
204950
+
204951
+ dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
204952
+ if( dbMain ){
204953
+ assert( p->rc==SQLITE_OK );
204954
+ p->rc = rbuLockDatabase(dbMain);
204955
+ }
204956
+
204763204957
if( p->rc==SQLITE_OK ){
204764
- rbuFileSuffix3(zBase, zWal);
204765
- rbuFileSuffix3(zBase, zOal);
204766
-
204767
- /* Re-open the databases. */
204768
- rbuObjIterFinalize(&p->objiter);
204769
- sqlite3_close(p->dbRbu);
204770
- sqlite3_close(p->dbMain);
204771
- p->dbMain = 0;
204772
- p->dbRbu = 0;
204773
-
204774204958
#if defined(_WIN32_WCE)
204775204959
{
204776204960
LPWSTR zWideOal;
204777204961
LPWSTR zWideWal;
204778204962
@@ -204795,15 +204979,23 @@
204795204979
}
204796204980
}
204797204981
#else
204798204982
p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204799204983
#endif
204984
+ }
204800204985
204801
- if( p->rc==SQLITE_OK ){
204802
- rbuOpenDatabase(p, 0);
204803
- rbuSetupCheckpoint(p, 0);
204804
- }
204986
+ if( p->rc!=SQLITE_OK
204987
+ || rbuIsVacuum(p)
204988
+ || rbuExclusiveCheckpoint(dbMain)==0
204989
+ ){
204990
+ sqlite3_close(dbMain);
204991
+ dbMain = 0;
204992
+ }
204993
+
204994
+ if( p->rc==SQLITE_OK ){
204995
+ rbuOpenDatabase(p, dbMain, 0);
204996
+ rbuSetupCheckpoint(p, 0);
204805204997
}
204806204998
}
204807204999
204808205000
sqlite3_free(zWal);
204809205001
sqlite3_free(zOal);
@@ -205550,13 +205742,13 @@
205550205742
** to be a wal-mode db. But, this may have happened due to an earlier
205551205743
** RBU vacuum operation leaving an old wal file in the directory.
205552205744
** If this is the case, it will have been checkpointed and deleted
205553205745
** when the handle was closed and a second attempt to open the
205554205746
** database may succeed. */
205555
- rbuOpenDatabase(p, &bRetry);
205747
+ rbuOpenDatabase(p, 0, &bRetry);
205556205748
if( bRetry ){
205557
- rbuOpenDatabase(p, 0);
205749
+ rbuOpenDatabase(p, 0, 0);
205558205750
}
205559205751
}
205560205752
205561205753
if( p->rc==SQLITE_OK ){
205562205754
pState = rbuLoadState(p);
@@ -205647,10 +205839,18 @@
205647205839
}
205648205840
}
205649205841
}else if( p->eStage==RBU_STAGE_MOVE ){
205650205842
/* no-op */
205651205843
}else if( p->eStage==RBU_STAGE_CKPT ){
205844
+ if( !rbuIsVacuum(p) && rbuExclusiveCheckpoint(p->dbMain) ){
205845
+ /* If the rbu_exclusive_checkpoint=1 URI parameter was specified
205846
+ ** and an incremental checkpoint is being resumed, attempt an
205847
+ ** exclusive lock on the db file. If this fails, so be it. */
205848
+ p->eStage = RBU_STAGE_DONE;
205849
+ rbuLockDatabase(p->dbMain);
205850
+ p->eStage = RBU_STAGE_CKPT;
205851
+ }
205652205852
rbuSetupCheckpoint(p, pState);
205653205853
}else if( p->eStage==RBU_STAGE_DONE ){
205654205854
p->rc = SQLITE_DONE;
205655205855
}else{
205656205856
p->rc = SQLITE_CORRUPT;
@@ -205684,11 +205884,10 @@
205684205884
const char *zTarget,
205685205885
const char *zRbu,
205686205886
const char *zState
205687205887
){
205688205888
if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
205689
- /* TODO: Check that zTarget and zRbu are non-NULL */
205690205889
return openRbuHandle(zTarget, zRbu, zState);
205691205890
}
205692205891
205693205892
/*
205694205893
** Open a handle to begin or resume an RBU VACUUM operation.
@@ -215805,13 +216004,13 @@
215805216004
fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
215806216005
#endif
215807216006
};
215808216007
typedef struct fts5yyParser fts5yyParser;
215809216008
215810
-#ifndef NDEBUG
215811
-/* #include <stdio.h> */
215812216009
/* #include <assert.h> */
216010
+#ifndef NDEBUG
216011
+/* #include <stdio.h> */
215813216012
static FILE *fts5yyTraceFILE = 0;
215814216013
static char *fts5yyTracePrompt = 0;
215815216014
#endif /* NDEBUG */
215816216015
215817216016
#ifndef NDEBUG
@@ -216744,12 +216943,12 @@
216744216943
assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
216745216944
assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
216746216945
fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
216747216946
if( fts5yyact >= fts5YY_MIN_REDUCE ){
216748216947
unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
216749
- assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216750216948
#ifndef NDEBUG
216949
+ assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216751216950
if( fts5yyTraceFILE ){
216752216951
int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
216753216952
if( fts5yysize ){
216754216953
fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
216755216954
fts5yyTracePrompt,
@@ -232260,11 +232459,11 @@
232260232459
int nArg, /* Number of args */
232261232460
sqlite3_value **apUnused /* Function arguments */
232262232461
){
232263232462
assert( nArg==0 );
232264232463
UNUSED_PARAM2(nArg, apUnused);
232265
- sqlite3_result_text(pCtx, "fts5: 2021-11-02 17:55:01 1d9004cd015073853ce0ca811a68ea5411733eedee993b97a38a42ba139d7590", -1, SQLITE_TRANSIENT);
232464
+ sqlite3_result_text(pCtx, "fts5: 2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba", -1, SQLITE_TRANSIENT);
232266232465
}
232267232466
232268232467
/*
232269232468
** Return true if zName is the extension on one of the shadow tables used
232270232469
** by this module.
232271232470
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -452,11 +452,11 @@
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.37.0"
456 #define SQLITE_VERSION_NUMBER 3037000
457 #define SQLITE_SOURCE_ID "2021-11-04 14:04:20 9147390d9885a37a62edc1058f313434627f1b59965c890877d2cb119e355c78"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -913,10 +913,11 @@
913 #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
914 #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
915 #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
916 #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
917 #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
 
918
919 /* Reserved: 0x00F00000 */
920 /* Legacy compatibility: */
921 #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
922
@@ -3732,10 +3733,18 @@
3732 **
3733 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3734 ** <dd>The database is opened [shared cache] disabled, overriding
3735 ** the default shared cache setting provided by
3736 ** [sqlite3_enable_shared_cache()].)^
 
 
 
 
 
 
 
 
3737 **
3738 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3739 ** <dd>The database filename is not allowed to be a symbolic link</dd>
3740 ** </dl>)^
3741 **
@@ -16649,10 +16658,11 @@
16649 #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
16650 #define SQLITE_EnableView 0x80000000 /* Enable the use of views */
16651 #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
16652 /* DELETE, or UPDATE and return */
16653 /* the count using a callback. */
 
16654
16655 /* Flags used only if debugging */
16656 #ifdef SQLITE_DEBUG
16657 #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
16658 #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -18901,12 +18911,12 @@
18901 union { /* Extra data for callback */
18902 NameContext *pNC; /* Naming context */
18903 int n; /* A counter */
18904 int iCur; /* A cursor number */
18905 SrcList *pSrcList; /* FROM clause */
18906 struct SrcCount *pSrcCount; /* Counting column references */
18907 struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
 
18908 int *aiCol; /* array of column indexes */
18909 struct IdxCover *pIdxCover; /* Check for index coverage */
18910 struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
18911 ExprList *pGroupBy; /* GROUP BY clause */
18912 Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19560,11 +19570,11 @@
19560 SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
19561 SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
19562 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
19563 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
19564 SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19565 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
19566 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
19567 #ifndef SQLITE_UNTESTABLE
19568 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
19569 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
19570 #endif
@@ -22193,11 +22203,15 @@
22193 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
22194 #endif
22195 SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
22196 SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
22197 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
 
22198 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
 
 
 
22199 #ifdef SQLITE_DEBUG
22200 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
22201 #endif
22202 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
22203 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
@@ -48826,12 +48840,13 @@
48826 */
48827 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
48828 MemStore *p = ((MemFile*)pFile)->pStore;
48829 int rc = SQLITE_OK;
48830 memdbEnter(p);
48831 if( NEVER(size>p->sz) ){
48832 rc = SQLITE_FULL;
 
48833 }else{
48834 p->sz = size;
48835 }
48836 memdbLeave(p);
48837 return rc;
@@ -67031,11 +67046,11 @@
67031 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
67032 sz2 = get2byte(&data[iFree2+2]);
67033 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
67034 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
67035 sz += sz2;
67036 }else if( iFree+sz>usableSize ){
67037 return SQLITE_CORRUPT_PAGE(pPage);
67038 }
67039
67040 cbrk = top+sz;
67041 assert( cbrk+(iFree-top) <= usableSize );
@@ -72654,11 +72669,11 @@
72654 int k; /* Current slot in pCArray->apEnd[] */
72655 u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */
72656
72657 assert( i<iEnd );
72658 j = get2byte(&aData[hdr+5]);
72659 if( j>(u32)usableSize ){ j = 0; }
72660 memcpy(&pTmp[j], &aData[j], usableSize - j);
72661
72662 for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
72663 pSrcEnd = pCArray->apEnd[k];
72664
@@ -78041,19 +78056,35 @@
78041
78042 /*
78043 ** Delete any previous value and set the value to be a BLOB of length
78044 ** n containing all zeros.
78045 */
 
78046 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78047 sqlite3VdbeMemRelease(pMem);
78048 pMem->flags = MEM_Blob|MEM_Zero;
78049 pMem->n = 0;
78050 if( n<0 ) n = 0;
78051 pMem->u.nZero = n;
78052 pMem->enc = SQLITE_UTF8;
78053 pMem->z = 0;
78054 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78055
78056 /*
78057 ** The pMem is known to contain content that needs to be destroyed prior
78058 ** to a value change. So invoke the destructor, then set the value to
78059 ** a 64-bit integer.
@@ -82178,13 +82209,19 @@
82178
82179 /* Lock all btrees used by the statement */
82180 sqlite3VdbeEnter(p);
82181
82182 /* Check for one of the special errors */
82183 mrc = p->rc & 0xff;
82184 isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
82185 || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
 
 
 
 
 
 
82186 if( isSpecialError ){
82187 /* If the query was read-only and the error code is SQLITE_INTERRUPT,
82188 ** no rollback is necessary. Otherwise, at least a savepoint
82189 ** transaction must be rolled back to restore the database to a
82190 ** consistent state.
@@ -82232,10 +82269,13 @@
82232 if( NEVER(p->readOnly) ){
82233 sqlite3VdbeLeave(p);
82234 return SQLITE_ERROR;
82235 }
82236 rc = SQLITE_CONSTRAINT_FOREIGNKEY;
 
 
 
82237 }else{
82238 /* The auto-commit flag is true, the vdbe program was successful
82239 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
82240 ** key constraints to hold up the transaction. This means a commit
82241 ** is required. */
@@ -84336,10 +84376,12 @@
84336 }else{
84337 iKey2 = iKey1;
84338 }
84339 }
84340
 
 
84341 assert( pCsr->nField==pTab->nCol
84342 || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
84343 );
84344
84345 preupdate.v = v;
@@ -84914,12 +84956,16 @@
84914 Mem *pOut = pCtx->pOut;
84915 assert( sqlite3_mutex_held(pOut->db->mutex) );
84916 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
84917 return SQLITE_TOOBIG;
84918 }
 
84919 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84920 return SQLITE_OK;
 
 
 
84921 }
84922 SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
84923 pCtx->isError = errCode ? errCode : -1;
84924 #ifdef SQLITE_DEBUG
84925 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85927,11 +85973,15 @@
85927 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
85928 int rc;
85929 Vdbe *p = (Vdbe *)pStmt;
85930 rc = vdbeUnbind(p, i);
85931 if( rc==SQLITE_OK ){
 
85932 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
 
 
 
85933 sqlite3_mutex_leave(p->db->mutex);
85934 }
85935 return rc;
85936 }
85937 SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86215,10 +86265,11 @@
86215 /* If the old.* record has not yet been loaded into memory, do so now. */
86216 if( p->pUnpacked==0 ){
86217 u32 nRec;
86218 u8 *aRec;
86219
 
86220 nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
86221 aRec = sqlite3DbMallocRaw(db, nRec);
86222 if( !aRec ) goto preupdate_old_out;
86223 rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
86224 if( rc==SQLITE_OK ){
@@ -90298,12 +90349,19 @@
90298 assert( p->readOnly==0 || pOp->p2==0 );
90299 assert( pOp->p2>=0 && pOp->p2<=2 );
90300 assert( pOp->p1>=0 && pOp->p1<db->nDb );
90301 assert( DbMaskTest(p->btreeMask, pOp->p1) );
90302 assert( rc==SQLITE_OK );
90303 if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
90304 rc = SQLITE_READONLY;
 
 
 
 
 
 
 
90305 goto abort_due_to_error;
90306 }
90307 pBt = db->aDb[pOp->p1].pBt;
90308
90309 if( pBt ){
@@ -94368,10 +94426,11 @@
94368 pQuery = &aMem[pOp->p3];
94369 pArgc = &pQuery[1];
94370 pCur = p->apCsr[pOp->p1];
94371 assert( memIsValid(pQuery) );
94372 REGISTER_TRACE(pOp->p3, pQuery);
 
94373 assert( pCur->eCurType==CURTYPE_VTAB );
94374 pVCur = pCur->uc.pVCur;
94375 pVtab = pVCur->pVtab;
94376 pModule = pVtab->pModule;
94377
@@ -94416,10 +94475,11 @@
94416 const sqlite3_module *pModule;
94417 Mem *pDest;
94418 sqlite3_context sContext;
94419
94420 VdbeCursor *pCur = p->apCsr[pOp->p1];
 
94421 assert( pCur->eCurType==CURTYPE_VTAB );
94422 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
94423 pDest = &aMem[pOp->p3];
94424 memAboutToChange(p, pDest);
94425 if( pCur->nullRow ){
@@ -94469,10 +94529,11 @@
94469 const sqlite3_module *pModule;
94470 int res;
94471 VdbeCursor *pCur;
94472
94473 pCur = p->apCsr[pOp->p1];
 
94474 assert( pCur->eCurType==CURTYPE_VTAB );
94475 if( pCur->nullRow ){
94476 break;
94477 }
94478 pVtab = pCur->uc.pVCur->pVtab;
@@ -94564,11 +94625,11 @@
94564 case OP_VUpdate: {
94565 sqlite3_vtab *pVtab;
94566 const sqlite3_module *pModule;
94567 int nArg;
94568 int i;
94569 sqlite_int64 rowid;
94570 Mem **apArg;
94571 Mem *pX;
94572
94573 assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
94574 || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -95011,11 +95072,18 @@
95011 rc = SQLITE_CORRUPT_BKPT;
95012 }
95013 assert( rc );
95014 #ifdef SQLITE_DEBUG
95015 if( db->flags & SQLITE_VdbeTrace ){
95016 printf("ABORT-due-to-error. rc=%d\n", rc);
 
 
 
 
 
 
 
95017 }
95018 #endif
95019 if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
95020 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
95021 }
@@ -95024,10 +95092,13 @@
95024 testcase( sqlite3GlobalConfig.xLog!=0 );
95025 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
95026 (int)(pOp - aOp), p->zSql, p->zErrMsg);
95027 sqlite3VdbeHalt(p);
95028 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
 
 
 
95029 rc = SQLITE_ERROR;
95030 if( resetSchemaOnFault>0 ){
95031 sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
95032 }
95033
@@ -95155,11 +95226,14 @@
95155 }else{
95156 rc = sqlite3_step(p->pStmt);
95157 }
95158 if( rc==SQLITE_ROW ){
95159 VdbeCursor *pC = v->apCsr[0];
95160 u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
 
 
 
95161 testcase( pC->nHdrParsed==p->iCol );
95162 testcase( pC->nHdrParsed==p->iCol+1 );
95163 if( type<12 ){
95164 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
95165 type==0?"null": type==7?"real": "integer"
@@ -95500,10 +95574,12 @@
95500 ** using the incremental-blob API, this works. For the sessions module
95501 ** anyhow.
95502 */
95503 sqlite3_int64 iKey;
95504 iKey = sqlite3BtreeIntegerKey(p->pCsr);
 
 
95505 sqlite3VdbePreUpdateHook(
95506 v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
95507 );
95508 }
95509 #endif
@@ -100579,19 +100655,22 @@
100579 sqlite3WindowLink(pSel, pWin);
100580 pNC->ncFlags |= NC_HasWin;
100581 }else
100582 #endif /* SQLITE_OMIT_WINDOWFUNC */
100583 {
100584 NameContext *pNC2 = pNC;
100585 pExpr->op = TK_AGG_FUNCTION;
100586 pExpr->op2 = 0;
100587 #ifndef SQLITE_OMIT_WINDOWFUNC
100588 if( ExprHasProperty(pExpr, EP_WinFunc) ){
100589 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100590 }
100591 #endif
100592 while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
 
 
 
100593 pExpr->op2++;
100594 pNC2 = pNC2->pNext;
100595 }
100596 assert( pDef!=0 || IN_RENAME_OBJECT );
100597 if( pNC2 && pDef ){
@@ -101557,12 +101636,12 @@
101557
101558 /*
101559 ** Return the affinity character for a single column of a table.
101560 */
101561 SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101562 assert( iCol<pTab->nCol );
101563 return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
101564 }
101565
101566 /*
101567 ** Return the 'affinity' of the expression pExpr if any.
101568 **
@@ -104338,11 +104417,12 @@
104338 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104339 Expr *pRhs = pEList->a[i].pExpr;
104340 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104341 int j;
104342
104343 assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
 
104344 for(j=0; j<nExpr; j++){
104345 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104346 assert( pIdx->azColl[j] );
104347 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104348 continue;
@@ -107414,93 +107494,128 @@
107414 sqlite3WalkExpr(&w, pExpr);
107415 return !w.eCode;
107416 }
107417
107418
107419 /*
107420 ** An instance of the following structure is used by the tree walker
107421 ** to count references to table columns in the arguments of an
107422 ** aggregate function, in order to implement the
107423 ** sqlite3FunctionThisSrc() routine.
107424 */
107425 struct SrcCount {
107426 SrcList *pSrc; /* One particular FROM clause in a nested query */
107427 int iSrcInner; /* Smallest cursor number in this context */
107428 int nThis; /* Number of references to columns in pSrcList */
107429 int nOther; /* Number of references to columns in other FROM clauses */
107430 };
107431
107432 /*
107433 ** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
107434 ** SELECT with a FROM clause encountered during this iteration, set
107435 ** SrcCount.iSrcInner to the cursor number of the leftmost object in
107436 ** the FROM cause.
 
 
107437 */
107438 static int selectSrcCount(Walker *pWalker, Select *pSel){
107439 struct SrcCount *p = pWalker->u.pSrcCount;
107440 if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
107441 pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
 
 
 
 
 
 
 
 
 
 
 
 
107442 }
107443 return WRC_Continue;
107444 }
107445
107446 /*
107447 ** Count the number of references to columns.
107448 */
107449 static int exprSrcCount(Walker *pWalker, Expr *pExpr){
107450 /* There was once a NEVER() on the second term on the grounds that
107451 ** sqlite3FunctionUsesThisSrc() was always called before
107452 ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
107453 ** been converted into TK_AGG_COLUMN. But this is no longer true due
107454 ** to window functions - sqlite3WindowRewrite() may now indirectly call
107455 ** FunctionUsesThisSrc() when creating a new sub-select. */
107456 if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
107457 int i;
107458 struct SrcCount *p = pWalker->u.pSrcCount;
107459 SrcList *pSrc = p->pSrc;
 
 
 
 
 
 
 
 
 
107460 int nSrc = pSrc ? pSrc->nSrc : 0;
107461 for(i=0; i<nSrc; i++){
107462 if( pExpr->iTable==pSrc->a[i].iCursor ) break;
107463 }
107464 if( i<nSrc ){
107465 p->nThis++;
107466 }else if( pExpr->iTable<p->iSrcInner ){
107467 /* In a well-formed parse tree (no name resolution errors),
107468 ** TK_COLUMN nodes with smaller Expr.iTable values are in an
107469 ** outer context. Those are the only ones to count as "other" */
107470 p->nOther++;
107471 }
107472 }
107473 return WRC_Continue;
107474 }
107475
107476 /*
107477 ** Determine if any of the arguments to the pExpr Function reference
107478 ** pSrcList. Return true if they do. Also return true if the function
107479 ** has no arguments or has only constant arguments. Return false if pExpr
107480 ** references columns but not columns of tables found in pSrcList.
 
 
 
 
 
 
 
 
 
107481 */
107482 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
107483 Walker w;
107484 struct SrcCount cnt;
107485 assert( pExpr->op==TK_AGG_FUNCTION );
107486 memset(&w, 0, sizeof(w));
107487 w.xExprCallback = exprSrcCount;
107488 w.xSelectCallback = selectSrcCount;
107489 w.u.pSrcCount = &cnt;
107490 cnt.pSrc = pSrcList;
107491 cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
107492 cnt.nThis = 0;
107493 cnt.nOther = 0;
 
107494 assert( ExprUseXList(pExpr) );
107495 sqlite3WalkExprList(&w, pExpr->x.pList);
107496 #ifndef SQLITE_OMIT_WINDOWFUNC
107497 if( ExprHasProperty(pExpr, EP_WinFunc) ){
107498 sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107499 }
107500 #endif
107501 return cnt.nThis>0 || cnt.nOther==0;
 
 
 
 
 
 
 
107502 }
107503
107504 /*
107505 ** This is a Walker expression node callback.
107506 **
@@ -115414,10 +115529,11 @@
115414
115415 assert( IsVirtual(pTab) );
115416 pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]);
115417 if( pMod==0 ) return;
115418 if( NEVER(pMod->pModule==0) ) return;
 
115419 if( pMod->pModule->xShadowName==0 ) return;
115420 assert( pTab->zName!=0 );
115421 nName = sqlite3Strlen30(pTab->zName);
115422 for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){
115423 Table *pOther = sqliteHashData(k);
@@ -116321,10 +116437,13 @@
116321 if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
116322 return 1;
116323 }
116324 if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
116325 return 1;
 
 
 
116326 }
116327 return 0;
116328 }
116329
116330 /*
@@ -127801,11 +127920,11 @@
127801 /* Version 3.34.0 and later */
127802 #define sqlite3_txn_state sqlite3_api->txn_state
127803 /* Version 3.36.1 and later */
127804 #define sqlite3_changes64 sqlite3_api->changes64
127805 #define sqlite3_total_changes64 sqlite3_api->total_changes64
127806 * Version 3.37.0 and later */
127807 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
127808 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127809
127810 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127811 /* This case when the file really is being compiled as a loadable
@@ -135298,10 +135417,13 @@
135298 n = sqlite3Strlen30(pCol->zCnName);
135299 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
135300 if( pCol->zCnName ){
135301 memcpy(&pCol->zCnName[n+1], zType, m+1);
135302 pCol->colFlags |= COLFLAG_HASTYPE;
 
 
 
135303 }
135304 }
135305 if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
135306 pColl = sqlite3ExprCollSeq(pParse, p);
135307 if( pColl ){
@@ -138037,31 +138159,44 @@
138037 **
138038 ** SELECT count(*) FROM <tbl>
138039 **
138040 ** where table is a database table, not a sub-select or view. If the query
138041 ** does match this pattern, then a pointer to the Table object representing
138042 ** <tbl> is returned. Otherwise, 0 is returned.
 
 
 
 
 
 
138043 */
138044 static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
138045 Table *pTab;
138046 Expr *pExpr;
138047
138048 assert( !p->pGroupBy );
138049
138050 if( p->pWhere || p->pEList->nExpr!=1
138051 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
 
 
 
138052 ){
138053 return 0;
138054 }
138055 pTab = p->pSrc->a[0].pTab;
 
 
 
138056 pExpr = p->pEList->a[0].pExpr;
138057 assert( pTab && !IsView(pTab) && pExpr );
138058
138059 if( IsVirtual(pTab) ) return 0;
138060 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
138061 if( NEVER(pAggInfo->nFunc==0) ) return 0;
138062 if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
 
 
 
138063 if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
138064
138065 return pTab;
138066 }
138067
@@ -145189,11 +145324,14 @@
145189 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
145190 int rc = SQLITE_OK;
145191 Table *pTab;
145192
145193 pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
145194 if( pTab!=0 && ALWAYS(IsVirtual(pTab)) && ALWAYS(pTab->u.vtab.p!=0) ){
 
 
 
145195 VTable *p;
145196 int (*xDestroy)(sqlite3_vtab *);
145197 for(p=pTab->u.vtab.p; p; p=p->pNext){
145198 assert( p->pVtab );
145199 if( p->pVtab->nRef>0 ){
@@ -155813,10 +155951,11 @@
155813 ** program.
155814 */
155815 for(ii=0; ii<nTabList; ii++){
155816 int addrExplain;
155817 int wsFlags;
 
155818 pLevel = &pWInfo->a[ii];
155819 wsFlags = pLevel->pWLoop->wsFlags;
155820 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155821 if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155822 constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -157266,11 +157405,15 @@
157266 }
157267 }else{
157268 sqlite3SelectDelete(db, pSub);
157269 }
157270 if( db->mallocFailed ) rc = SQLITE_NOMEM;
157271 sqlite3DbFree(db, pTab);
 
 
 
 
157272 }
157273
157274 if( rc ){
157275 if( pParse->nErr==0 ){
157276 assert( pParse->db->mallocFailed );
@@ -160713,13 +160856,13 @@
160713 yyStackEntry *yystackEnd; /* Last entry in the stack */
160714 #endif
160715 };
160716 typedef struct yyParser yyParser;
160717
 
160718 #ifndef NDEBUG
160719 /* #include <stdio.h> */
160720 /* #include <assert.h> */
160721 static FILE *yyTraceFILE = 0;
160722 static char *yyTracePrompt = 0;
160723 #endif /* NDEBUG */
160724
160725 #ifndef NDEBUG
@@ -164464,12 +164607,12 @@
164464 assert( yypParser->yytos>=yypParser->yystack );
164465 assert( yyact==yypParser->yytos->stateno );
164466 yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
164467 if( yyact >= YY_MIN_REDUCE ){
164468 unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
164469 assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164470 #ifndef NDEBUG
 
164471 if( yyTraceFILE ){
164472 int yysize = yyRuleInfoNRhs[yyruleno];
164473 if( yysize ){
164474 fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
164475 yyTracePrompt,
@@ -167854,11 +167997,11 @@
167854 sqlite3BtreeLeaveAll(db);
167855
167856 /* Any deferred constraint violations have now been resolved. */
167857 db->nDeferredCons = 0;
167858 db->nDeferredImmCons = 0;
167859 db->flags &= ~(u64)SQLITE_DeferFKs;
167860
167861 /* If one has been configured, invoke the rollback-hook callback */
167862 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
167863 db->xRollbackCallback(db->pRollbackArg);
167864 }
@@ -169582,12 +169725,12 @@
169582 **
169583 ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
169584 ** dealt with in the previous code block. Besides these, the only
169585 ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
169586 ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
169587 ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
169588 ** off all other flags.
169589 */
169590 flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
169591 SQLITE_OPEN_EXCLUSIVE |
169592 SQLITE_OPEN_MAIN_DB |
169593 SQLITE_OPEN_TEMP_DB |
@@ -169618,11 +169761,11 @@
169618 if( isThreadsafe==0 ){
169619 sqlite3MutexWarnOnContention(db->mutex);
169620 }
169621 }
169622 sqlite3_mutex_enter(db->mutex);
169623 db->errMask = 0xff;
169624 db->nDb = 2;
169625 db->eOpenState = SQLITE_STATE_BUSY;
169626 db->aDb = db->aDbStatic;
169627 db->lookaside.bDisable = 1;
169628 db->lookaside.sz = 0;
@@ -169850,12 +169993,12 @@
169850 assert( db->mutex!=0 || isThreadsafe==0
169851 || sqlite3GlobalConfig.bFullMutex==0 );
169852 sqlite3_mutex_leave(db->mutex);
169853 }
169854 rc = sqlite3_errcode(db);
169855 assert( db!=0 || rc==SQLITE_NOMEM );
169856 if( rc==SQLITE_NOMEM ){
169857 sqlite3_close(db);
169858 db = 0;
169859 }else if( rc!=SQLITE_OK ){
169860 db->eOpenState = SQLITE_STATE_SICK;
169861 }
@@ -169866,11 +170009,11 @@
169866 void *pArg = sqlite3GlobalConfig.pSqllogArg;
169867 sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
169868 }
169869 #endif
169870 sqlite3_free_filename(zOpen);
169871 return rc & 0xff;
169872 }
169873
169874
169875 /*
169876 ** Open a new database handle.
@@ -178416,10 +178559,13 @@
178416 while( rc==SQLITE_OK && !pNear->bEof ){
178417 fts3EvalNextRow(pCsr, pNear, &rc);
178418 if( bEofSave==0 && pNear->iDocid==iDocid ) break;
178419 }
178420 assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
 
 
 
178421 }
178422 if( bTreeEof ){
178423 while( rc==SQLITE_OK && !pNear->bEof ){
178424 fts3EvalNextRow(pCsr, pNear, &rc);
178425 }
@@ -190106,17 +190252,17 @@
190106 int iEnd = 0;
190107 int iCurrent = 0;
190108 const char *zDoc;
190109 int nDoc;
190110
190111 /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
190112 ** no way that this operation can fail, so the return code from
190113 ** fts3ExprIterate() can be discarded.
190114 */
190115 sCtx.iCol = iCol;
190116 sCtx.iTerm = 0;
190117 (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
 
190118
190119 /* Retreive the text stored in column iCol. If an SQL NULL is stored
190120 ** in column iCol, jump immediately to the next iteration of the loop.
190121 ** If an OOM occurs while retrieving the data (this can happen if SQLite
190122 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -192676,12 +192822,15 @@
192676 }else{
192677 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
192678 if( pNew==0 ) return 0;
192679 pTarget = &pParse->aNode[iTarget];
192680 if( pNew!=&pTarget[j+1] ){
192681 assert( pTarget[j+1].eU==0 || pTarget[j+1].eU==1 );
 
 
192682 testcase( pTarget[j+1].eU==1 );
 
192683 VVA( pTarget[j+1].eU = 5 );
192684 pTarget[j+1].u.pPatch = pNew;
192685 pTarget[j+1].jnFlags |= JNODE_PATCH;
192686 }
192687 }
@@ -201672,10 +201821,17 @@
201672 ** Swap two objects of type TYPE.
201673 */
201674 #if !defined(SQLITE_AMALGAMATION)
201675 # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
201676 #endif
 
 
 
 
 
 
 
201677
201678 /*
201679 ** The rbu_state table is used to save the state of a partially applied
201680 ** update so that it can be resumed later. The table consists of integer
201681 ** keys mapped to values as follows:
@@ -204319,17 +204475,23 @@
204319
204320
204321 /*
204322 ** Open the database handle and attach the RBU database as "rbu". If an
204323 ** error occurs, leave an error code and message in the RBU handle.
 
 
 
 
204324 */
204325 static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
204326 assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
204327 assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
 
204328
204329 /* Open the RBU database */
204330 p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
 
204331
204332 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
204333 sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
204334 if( p->zState==0 ){
204335 const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -204691,19 +204853,35 @@
204691 p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
204692 }
204693
204694
204695 /*
204696 ** Take an EXCLUSIVE lock on the database file.
 
204697 */
204698 static void rbuLockDatabase(sqlite3rbu *p){
204699 sqlite3_file *pReal = p->pTargetFd->pReal;
204700 assert( p->rc==SQLITE_OK );
204701 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
204702 if( p->rc==SQLITE_OK ){
204703 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
 
 
 
 
204704 }
 
 
 
 
 
 
 
 
 
 
 
204705 }
204706
204707 #if defined(_WIN32_WCE)
204708 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
204709 int nChar;
@@ -204757,22 +204935,28 @@
204757 ** in WAL mode). So no other connection may be writing the db.
204758 **
204759 ** In order to ensure that there are no database readers, an EXCLUSIVE
204760 ** lock is obtained here before the *-oal is moved to *-wal.
204761 */
204762 rbuLockDatabase(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204763 if( p->rc==SQLITE_OK ){
204764 rbuFileSuffix3(zBase, zWal);
204765 rbuFileSuffix3(zBase, zOal);
204766
204767 /* Re-open the databases. */
204768 rbuObjIterFinalize(&p->objiter);
204769 sqlite3_close(p->dbRbu);
204770 sqlite3_close(p->dbMain);
204771 p->dbMain = 0;
204772 p->dbRbu = 0;
204773
204774 #if defined(_WIN32_WCE)
204775 {
204776 LPWSTR zWideOal;
204777 LPWSTR zWideWal;
204778
@@ -204795,15 +204979,23 @@
204795 }
204796 }
204797 #else
204798 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204799 #endif
 
204800
204801 if( p->rc==SQLITE_OK ){
204802 rbuOpenDatabase(p, 0);
204803 rbuSetupCheckpoint(p, 0);
204804 }
 
 
 
 
 
 
 
204805 }
204806 }
204807
204808 sqlite3_free(zWal);
204809 sqlite3_free(zOal);
@@ -205550,13 +205742,13 @@
205550 ** to be a wal-mode db. But, this may have happened due to an earlier
205551 ** RBU vacuum operation leaving an old wal file in the directory.
205552 ** If this is the case, it will have been checkpointed and deleted
205553 ** when the handle was closed and a second attempt to open the
205554 ** database may succeed. */
205555 rbuOpenDatabase(p, &bRetry);
205556 if( bRetry ){
205557 rbuOpenDatabase(p, 0);
205558 }
205559 }
205560
205561 if( p->rc==SQLITE_OK ){
205562 pState = rbuLoadState(p);
@@ -205647,10 +205839,18 @@
205647 }
205648 }
205649 }else if( p->eStage==RBU_STAGE_MOVE ){
205650 /* no-op */
205651 }else if( p->eStage==RBU_STAGE_CKPT ){
 
 
 
 
 
 
 
 
205652 rbuSetupCheckpoint(p, pState);
205653 }else if( p->eStage==RBU_STAGE_DONE ){
205654 p->rc = SQLITE_DONE;
205655 }else{
205656 p->rc = SQLITE_CORRUPT;
@@ -205684,11 +205884,10 @@
205684 const char *zTarget,
205685 const char *zRbu,
205686 const char *zState
205687 ){
205688 if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
205689 /* TODO: Check that zTarget and zRbu are non-NULL */
205690 return openRbuHandle(zTarget, zRbu, zState);
205691 }
205692
205693 /*
205694 ** Open a handle to begin or resume an RBU VACUUM operation.
@@ -215805,13 +216004,13 @@
215805 fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
215806 #endif
215807 };
215808 typedef struct fts5yyParser fts5yyParser;
215809
215810 #ifndef NDEBUG
215811 /* #include <stdio.h> */
215812 /* #include <assert.h> */
 
 
215813 static FILE *fts5yyTraceFILE = 0;
215814 static char *fts5yyTracePrompt = 0;
215815 #endif /* NDEBUG */
215816
215817 #ifndef NDEBUG
@@ -216744,12 +216943,12 @@
216744 assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
216745 assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
216746 fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
216747 if( fts5yyact >= fts5YY_MIN_REDUCE ){
216748 unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
216749 assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216750 #ifndef NDEBUG
 
216751 if( fts5yyTraceFILE ){
216752 int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
216753 if( fts5yysize ){
216754 fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
216755 fts5yyTracePrompt,
@@ -232260,11 +232459,11 @@
232260 int nArg, /* Number of args */
232261 sqlite3_value **apUnused /* Function arguments */
232262 ){
232263 assert( nArg==0 );
232264 UNUSED_PARAM2(nArg, apUnused);
232265 sqlite3_result_text(pCtx, "fts5: 2021-11-02 17:55:01 1d9004cd015073853ce0ca811a68ea5411733eedee993b97a38a42ba139d7590", -1, SQLITE_TRANSIENT);
232266 }
232267
232268 /*
232269 ** Return true if zName is the extension on one of the shadow tables used
232270 ** by this module.
232271
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -452,11 +452,11 @@
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.37.0"
456 #define SQLITE_VERSION_NUMBER 3037000
457 #define SQLITE_SOURCE_ID "2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -913,10 +913,11 @@
913 #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
914 #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
915 #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
916 #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
917 #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
918 #define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
919
920 /* Reserved: 0x00F00000 */
921 /* Legacy compatibility: */
922 #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
923
@@ -3732,10 +3733,18 @@
3733 **
3734 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3735 ** <dd>The database is opened [shared cache] disabled, overriding
3736 ** the default shared cache setting provided by
3737 ** [sqlite3_enable_shared_cache()].)^
3738 **
3739 ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt>
3740 ** <dd>The database connection comes up in "extended result code mode".
3741 ** In other words, the database behaves has if
3742 ** [sqlite3_extended_result_codes(db,1)] where called on the database
3743 ** connection as soon as the connection is created. In addition to setting
3744 ** the extended result code mode, this flag also causes [sqlite3_open_v2()]
3745 ** to return an extended result code.</dd>
3746 **
3747 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3748 ** <dd>The database filename is not allowed to be a symbolic link</dd>
3749 ** </dl>)^
3750 **
@@ -16649,10 +16658,11 @@
16658 #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
16659 #define SQLITE_EnableView 0x80000000 /* Enable the use of views */
16660 #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
16661 /* DELETE, or UPDATE and return */
16662 /* the count using a callback. */
16663 #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
16664
16665 /* Flags used only if debugging */
16666 #ifdef SQLITE_DEBUG
16667 #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
16668 #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -18901,12 +18911,12 @@
18911 union { /* Extra data for callback */
18912 NameContext *pNC; /* Naming context */
18913 int n; /* A counter */
18914 int iCur; /* A cursor number */
18915 SrcList *pSrcList; /* FROM clause */
 
18916 struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
18917 struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */
18918 int *aiCol; /* array of column indexes */
18919 struct IdxCover *pIdxCover; /* Check for index coverage */
18920 struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
18921 ExprList *pGroupBy; /* GROUP BY clause */
18922 Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19560,11 +19570,11 @@
19570 SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
19571 SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
19572 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
19573 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
19574 SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19575 SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*);
19576 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
19577 #ifndef SQLITE_UNTESTABLE
19578 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
19579 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
19580 #endif
@@ -22193,11 +22203,15 @@
22203 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
22204 #endif
22205 SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
22206 SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
22207 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
22208 #ifndef SQLITE_OMIT_INCRBLOB
22209 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
22210 #else
22211 SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int);
22212 #endif
22213 #ifdef SQLITE_DEBUG
22214 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
22215 #endif
22216 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
22217 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
@@ -48826,12 +48840,13 @@
48840 */
48841 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
48842 MemStore *p = ((MemFile*)pFile)->pStore;
48843 int rc = SQLITE_OK;
48844 memdbEnter(p);
48845 if( size>p->sz ){
48846 /* This can only happen with a corrupt wal mode db */
48847 rc = SQLITE_CORRUPT;
48848 }else{
48849 p->sz = size;
48850 }
48851 memdbLeave(p);
48852 return rc;
@@ -67031,11 +67046,11 @@
67046 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
67047 sz2 = get2byte(&data[iFree2+2]);
67048 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
67049 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
67050 sz += sz2;
67051 }else if( NEVER(iFree+sz>usableSize) ){
67052 return SQLITE_CORRUPT_PAGE(pPage);
67053 }
67054
67055 cbrk = top+sz;
67056 assert( cbrk+(iFree-top) <= usableSize );
@@ -72654,11 +72669,11 @@
72669 int k; /* Current slot in pCArray->apEnd[] */
72670 u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */
72671
72672 assert( i<iEnd );
72673 j = get2byte(&aData[hdr+5]);
72674 if( NEVER(j>(u32)usableSize) ){ j = 0; }
72675 memcpy(&pTmp[j], &aData[j], usableSize - j);
72676
72677 for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){}
72678 pSrcEnd = pCArray->apEnd[k];
72679
@@ -78041,19 +78056,35 @@
78056
78057 /*
78058 ** Delete any previous value and set the value to be a BLOB of length
78059 ** n containing all zeros.
78060 */
78061 #ifndef SQLITE_OMIT_INCRBLOB
78062 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78063 sqlite3VdbeMemRelease(pMem);
78064 pMem->flags = MEM_Blob|MEM_Zero;
78065 pMem->n = 0;
78066 if( n<0 ) n = 0;
78067 pMem->u.nZero = n;
78068 pMem->enc = SQLITE_UTF8;
78069 pMem->z = 0;
78070 }
78071 #else
78072 SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78073 int nByte = n>0?n:1;
78074 if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
78075 return SQLITE_NOMEM_BKPT;
78076 }
78077 assert( pMem->z!=0 );
78078 assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte );
78079 memset(pMem->z, 0, nByte);
78080 pMem->n = n>0?n:0;
78081 pMem->flags = MEM_Blob;
78082 pMem->enc = SQLITE_UTF8;
78083 return SQLITE_OK;
78084 }
78085 #endif
78086
78087 /*
78088 ** The pMem is known to contain content that needs to be destroyed prior
78089 ** to a value change. So invoke the destructor, then set the value to
78090 ** a 64-bit integer.
@@ -82178,13 +82209,19 @@
82209
82210 /* Lock all btrees used by the statement */
82211 sqlite3VdbeEnter(p);
82212
82213 /* Check for one of the special errors */
82214 if( p->rc ){
82215 mrc = p->rc & 0xff;
82216 isSpecialError = mrc==SQLITE_NOMEM
82217 || mrc==SQLITE_IOERR
82218 || mrc==SQLITE_INTERRUPT
82219 || mrc==SQLITE_FULL;
82220 }else{
82221 mrc = isSpecialError = 0;
82222 }
82223 if( isSpecialError ){
82224 /* If the query was read-only and the error code is SQLITE_INTERRUPT,
82225 ** no rollback is necessary. Otherwise, at least a savepoint
82226 ** transaction must be rolled back to restore the database to a
82227 ** consistent state.
@@ -82232,10 +82269,13 @@
82269 if( NEVER(p->readOnly) ){
82270 sqlite3VdbeLeave(p);
82271 return SQLITE_ERROR;
82272 }
82273 rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82274 }else if( db->flags & SQLITE_CorruptRdOnly ){
82275 rc = SQLITE_CORRUPT;
82276 db->flags &= ~SQLITE_CorruptRdOnly;
82277 }else{
82278 /* The auto-commit flag is true, the vdbe program was successful
82279 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
82280 ** key constraints to hold up the transaction. This means a commit
82281 ** is required. */
@@ -84336,10 +84376,12 @@
84376 }else{
84377 iKey2 = iKey1;
84378 }
84379 }
84380
84381 assert( pCsr!=0 );
84382 assert( pCsr->eCurType==CURTYPE_BTREE );
84383 assert( pCsr->nField==pTab->nCol
84384 || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
84385 );
84386
84387 preupdate.v = v;
@@ -84914,12 +84956,16 @@
84956 Mem *pOut = pCtx->pOut;
84957 assert( sqlite3_mutex_held(pOut->db->mutex) );
84958 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
84959 return SQLITE_TOOBIG;
84960 }
84961 #ifndef SQLITE_OMIT_INCRBLOB
84962 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84963 return SQLITE_OK;
84964 #else
84965 return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84966 #endif
84967 }
84968 SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
84969 pCtx->isError = errCode ? errCode : -1;
84970 #ifdef SQLITE_DEBUG
84971 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85927,11 +85973,15 @@
85973 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
85974 int rc;
85975 Vdbe *p = (Vdbe *)pStmt;
85976 rc = vdbeUnbind(p, i);
85977 if( rc==SQLITE_OK ){
85978 #ifndef SQLITE_OMIT_INCRBLOB
85979 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
85980 #else
85981 rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
85982 #endif
85983 sqlite3_mutex_leave(p->db->mutex);
85984 }
85985 return rc;
85986 }
85987 SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86215,10 +86265,11 @@
86265 /* If the old.* record has not yet been loaded into memory, do so now. */
86266 if( p->pUnpacked==0 ){
86267 u32 nRec;
86268 u8 *aRec;
86269
86270 assert( p->pCsr->eCurType==CURTYPE_BTREE );
86271 nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
86272 aRec = sqlite3DbMallocRaw(db, nRec);
86273 if( !aRec ) goto preupdate_old_out;
86274 rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
86275 if( rc==SQLITE_OK ){
@@ -90298,12 +90349,19 @@
90349 assert( p->readOnly==0 || pOp->p2==0 );
90350 assert( pOp->p2>=0 && pOp->p2<=2 );
90351 assert( pOp->p1>=0 && pOp->p1<db->nDb );
90352 assert( DbMaskTest(p->btreeMask, pOp->p1) );
90353 assert( rc==SQLITE_OK );
90354 if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){
90355 if( db->flags & SQLITE_QueryOnly ){
90356 /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */
90357 rc = SQLITE_READONLY;
90358 }else{
90359 /* Writes prohibited due to a prior SQLITE_CORRUPT in the current
90360 ** transaction */
90361 rc = SQLITE_CORRUPT;
90362 }
90363 goto abort_due_to_error;
90364 }
90365 pBt = db->aDb[pOp->p1].pBt;
90366
90367 if( pBt ){
@@ -94368,10 +94426,11 @@
94426 pQuery = &aMem[pOp->p3];
94427 pArgc = &pQuery[1];
94428 pCur = p->apCsr[pOp->p1];
94429 assert( memIsValid(pQuery) );
94430 REGISTER_TRACE(pOp->p3, pQuery);
94431 assert( pCur!=0 );
94432 assert( pCur->eCurType==CURTYPE_VTAB );
94433 pVCur = pCur->uc.pVCur;
94434 pVtab = pVCur->pVtab;
94435 pModule = pVtab->pModule;
94436
@@ -94416,10 +94475,11 @@
94475 const sqlite3_module *pModule;
94476 Mem *pDest;
94477 sqlite3_context sContext;
94478
94479 VdbeCursor *pCur = p->apCsr[pOp->p1];
94480 assert( pCur!=0 );
94481 assert( pCur->eCurType==CURTYPE_VTAB );
94482 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
94483 pDest = &aMem[pOp->p3];
94484 memAboutToChange(p, pDest);
94485 if( pCur->nullRow ){
@@ -94469,10 +94529,11 @@
94529 const sqlite3_module *pModule;
94530 int res;
94531 VdbeCursor *pCur;
94532
94533 pCur = p->apCsr[pOp->p1];
94534 assert( pCur!=0 );
94535 assert( pCur->eCurType==CURTYPE_VTAB );
94536 if( pCur->nullRow ){
94537 break;
94538 }
94539 pVtab = pCur->uc.pVCur->pVtab;
@@ -94564,11 +94625,11 @@
94625 case OP_VUpdate: {
94626 sqlite3_vtab *pVtab;
94627 const sqlite3_module *pModule;
94628 int nArg;
94629 int i;
94630 sqlite_int64 rowid = 0;
94631 Mem **apArg;
94632 Mem *pX;
94633
94634 assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
94635 || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -95011,11 +95072,18 @@
95072 rc = SQLITE_CORRUPT_BKPT;
95073 }
95074 assert( rc );
95075 #ifdef SQLITE_DEBUG
95076 if( db->flags & SQLITE_VdbeTrace ){
95077 const char *zTrace = p->zSql;
95078 if( zTrace==0 ){
95079 if( aOp[0].opcode==OP_Trace ){
95080 zTrace = aOp[0].p4.z;
95081 }
95082 if( zTrace==0 ) zTrace = "???";
95083 }
95084 printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace);
95085 }
95086 #endif
95087 if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
95088 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
95089 }
@@ -95024,10 +95092,13 @@
95092 testcase( sqlite3GlobalConfig.xLog!=0 );
95093 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
95094 (int)(pOp - aOp), p->zSql, p->zErrMsg);
95095 sqlite3VdbeHalt(p);
95096 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
95097 if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
95098 db->flags |= SQLITE_CorruptRdOnly;
95099 }
95100 rc = SQLITE_ERROR;
95101 if( resetSchemaOnFault>0 ){
95102 sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
95103 }
95104
@@ -95155,11 +95226,14 @@
95226 }else{
95227 rc = sqlite3_step(p->pStmt);
95228 }
95229 if( rc==SQLITE_ROW ){
95230 VdbeCursor *pC = v->apCsr[0];
95231 u32 type;
95232 assert( pC!=0 );
95233 assert( pC->eCurType==CURTYPE_BTREE );
95234 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
95235 testcase( pC->nHdrParsed==p->iCol );
95236 testcase( pC->nHdrParsed==p->iCol+1 );
95237 if( type<12 ){
95238 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
95239 type==0?"null": type==7?"real": "integer"
@@ -95500,10 +95574,12 @@
95574 ** using the incremental-blob API, this works. For the sessions module
95575 ** anyhow.
95576 */
95577 sqlite3_int64 iKey;
95578 iKey = sqlite3BtreeIntegerKey(p->pCsr);
95579 assert( v->apCsr[0]!=0 );
95580 assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
95581 sqlite3VdbePreUpdateHook(
95582 v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
95583 );
95584 }
95585 #endif
@@ -100579,19 +100655,22 @@
100655 sqlite3WindowLink(pSel, pWin);
100656 pNC->ncFlags |= NC_HasWin;
100657 }else
100658 #endif /* SQLITE_OMIT_WINDOWFUNC */
100659 {
100660 NameContext *pNC2; /* For looping up thru outer contexts */
100661 pExpr->op = TK_AGG_FUNCTION;
100662 pExpr->op2 = 0;
100663 #ifndef SQLITE_OMIT_WINDOWFUNC
100664 if( ExprHasProperty(pExpr, EP_WinFunc) ){
100665 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100666 }
100667 #endif
100668 pNC2 = pNC;
100669 while( pNC2
100670 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
100671 ){
100672 pExpr->op2++;
100673 pNC2 = pNC2->pNext;
100674 }
100675 assert( pDef!=0 || IN_RENAME_OBJECT );
100676 if( pNC2 && pDef ){
@@ -101557,12 +101636,12 @@
101636
101637 /*
101638 ** Return the affinity character for a single column of a table.
101639 */
101640 SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101641 if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER;
101642 return pTab->aCol[iCol].affinity;
101643 }
101644
101645 /*
101646 ** Return the 'affinity' of the expression pExpr if any.
101647 **
@@ -104338,11 +104417,12 @@
104417 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104418 Expr *pRhs = pEList->a[i].pExpr;
104419 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104420 int j;
104421
104422 assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104423 || pParse->nErr || db->mallocFailed );
104424 for(j=0; j<nExpr; j++){
104425 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104426 assert( pIdx->azColl[j] );
104427 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104428 continue;
@@ -107414,93 +107494,128 @@
107494 sqlite3WalkExpr(&w, pExpr);
107495 return !w.eCode;
107496 }
107497
107498
107499 /* Structure used to pass information throught the Walker in order to
107500 ** implement sqlite3ReferencesSrcList().
 
 
 
107501 */
107502 struct RefSrcList {
107503 sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */
107504 SrcList *pRef; /* Looking for references to these tables */
107505 int nExclude; /* Number of tables to exclude from the search */
107506 int *aiExclude; /* Cursor IDs for tables to exclude from the search */
107507 };
107508
107509 /*
107510 ** Walker SELECT callbacks for sqlite3ReferencesSrcList().
107511 **
107512 ** When entering a new subquery on the pExpr argument, add all FROM clause
107513 ** entries for that subquery to the exclude list.
107514 **
107515 ** When leaving the subquery, remove those entries from the exclude list.
107516 */
107517 static int selectRefEnter(Walker *pWalker, Select *pSelect){
107518 struct RefSrcList *p = pWalker->u.pRefSrcList;
107519 SrcList *pSrc = pSelect->pSrc;
107520 int i, j, *piNew;
107521 if( pSrc->nSrc==0 ) return WRC_Continue;
107522 j = p->nExclude;
107523 p->nExclude += pSrc->nSrc;
107524 piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int));
107525 if( piNew==0 ){
107526 p->nExclude = 0;
107527 return WRC_Abort;
107528 }else{
107529 p->aiExclude = piNew;
107530 }
107531 for(i=0; i<pSrc->nSrc; i++, j++){
107532 p->aiExclude[j] = pSrc->a[i].iCursor;
107533 }
107534 return WRC_Continue;
107535 }
107536 static void selectRefLeave(Walker *pWalker, Select *pSelect){
107537 struct RefSrcList *p = pWalker->u.pRefSrcList;
107538 SrcList *pSrc = pSelect->pSrc;
107539 if( p->nExclude ){
107540 assert( p->nExclude>=pSrc->nSrc );
107541 p->nExclude -= pSrc->nSrc;
107542 }
107543 }
107544
107545 /* This is the Walker EXPR callback for sqlite3ReferencesSrcList().
107546 **
107547 ** Set the 0x01 bit of pWalker->eCode if there is a reference to any
107548 ** of the tables shown in RefSrcList.pRef.
107549 **
107550 ** Set the 0x02 bit of pWalker->eCode if there is a reference to a
107551 ** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude.
107552 */
107553 static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){
107554 if( pExpr->op==TK_COLUMN
107555 || pExpr->op==TK_AGG_COLUMN
107556 ){
107557 int i;
107558 struct RefSrcList *p = pWalker->u.pRefSrcList;
107559 SrcList *pSrc = p->pRef;
107560 int nSrc = pSrc ? pSrc->nSrc : 0;
107561 for(i=0; i<nSrc; i++){
107562 if( pExpr->iTable==pSrc->a[i].iCursor ){
107563 pWalker->eCode |= 1;
107564 return WRC_Continue;
107565 }
107566 }
107567 for(i=0; i<p->nExclude && p->aiExclude[i]!=pExpr->iTable; i++){}
107568 if( i>=p->nExclude ){
107569 pWalker->eCode |= 2;
 
107570 }
107571 }
107572 return WRC_Continue;
107573 }
107574
107575 /*
107576 ** Check to see if pExpr references any tables in pSrcList.
107577 ** Possible return values:
107578 **
107579 ** 1 pExpr does references a table in pSrcList.
107580 **
107581 ** 0 pExpr references some table that is not defined in either
107582 ** pSrcList or in subqueries of pExpr itself.
107583 **
107584 ** -1 pExpr only references no tables at all, or it only
107585 ** references tables defined in subqueries of pExpr itself.
107586 **
107587 ** As currently used, pExpr is always an aggregate function call. That
107588 ** fact is exploited for efficiency.
107589 */
107590 SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
107591 Walker w;
107592 struct RefSrcList x;
 
107593 memset(&w, 0, sizeof(w));
107594 memset(&x, 0, sizeof(x));
107595 w.xExprCallback = exprRefToSrcList;
107596 w.xSelectCallback = selectRefEnter;
107597 w.xSelectCallback2 = selectRefLeave;
107598 w.u.pRefSrcList = &x;
107599 x.db = pParse->db;
107600 x.pRef = pSrcList;
107601 assert( pExpr->op==TK_AGG_FUNCTION );
107602 assert( ExprUseXList(pExpr) );
107603 sqlite3WalkExprList(&w, pExpr->x.pList);
107604 #ifndef SQLITE_OMIT_WINDOWFUNC
107605 if( ExprHasProperty(pExpr, EP_WinFunc) ){
107606 sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107607 }
107608 #endif
107609 sqlite3DbFree(pParse->db, x.aiExclude);
107610 if( w.eCode & 0x01 ){
107611 return 1;
107612 }else if( w.eCode ){
107613 return 0;
107614 }else{
107615 return -1;
107616 }
107617 }
107618
107619 /*
107620 ** This is a Walker expression node callback.
107621 **
@@ -115414,10 +115529,11 @@
115529
115530 assert( IsVirtual(pTab) );
115531 pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]);
115532 if( pMod==0 ) return;
115533 if( NEVER(pMod->pModule==0) ) return;
115534 if( pMod->pModule->iVersion<3 ) return;
115535 if( pMod->pModule->xShadowName==0 ) return;
115536 assert( pTab->zName!=0 );
115537 nName = sqlite3Strlen30(pTab->zName);
115538 for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){
115539 Table *pOther = sqliteHashData(k);
@@ -116321,10 +116437,13 @@
116437 if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
116438 return 1;
116439 }
116440 if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
116441 return 1;
116442 }
116443 if( pTab->tabFlags & TF_Eponymous ){
116444 return 1;
116445 }
116446 return 0;
116447 }
116448
116449 /*
@@ -127801,11 +127920,11 @@
127920 /* Version 3.34.0 and later */
127921 #define sqlite3_txn_state sqlite3_api->txn_state
127922 /* Version 3.36.1 and later */
127923 #define sqlite3_changes64 sqlite3_api->changes64
127924 #define sqlite3_total_changes64 sqlite3_api->total_changes64
127925 /* Version 3.37.0 and later */
127926 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
127927 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127928
127929 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127930 /* This case when the file really is being compiled as a loadable
@@ -135298,10 +135417,13 @@
135417 n = sqlite3Strlen30(pCol->zCnName);
135418 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
135419 if( pCol->zCnName ){
135420 memcpy(&pCol->zCnName[n+1], zType, m+1);
135421 pCol->colFlags |= COLFLAG_HASTYPE;
135422 }else{
135423 testcase( pCol->colFlags & COLFLAG_HASTYPE );
135424 pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
135425 }
135426 }
135427 if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
135428 pColl = sqlite3ExprCollSeq(pParse, p);
135429 if( pColl ){
@@ -138037,31 +138159,44 @@
138159 **
138160 ** SELECT count(*) FROM <tbl>
138161 **
138162 ** where table is a database table, not a sub-select or view. If the query
138163 ** does match this pattern, then a pointer to the Table object representing
138164 ** <tbl> is returned. Otherwise, NULL is returned.
138165 **
138166 ** This routine a condition for the count optimization. A correct answer
138167 ** is obtained (though perhaps more slowly) if this routine returns NULL when
138168 ** it could have returned a table pointer. But returning the pointer when
138169 ** NULL should have been returned can result in incorrect answers and/or
138170 ** crashes. So, when in doubt, return NULL.
138171 */
138172 static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
138173 Table *pTab;
138174 Expr *pExpr;
138175
138176 assert( !p->pGroupBy );
138177
138178 if( p->pWhere
138179 || p->pEList->nExpr!=1
138180 || p->pSrc->nSrc!=1
138181 || p->pSrc->a[0].pSelect
138182 || pAggInfo->nFunc!=1
138183 ){
138184 return 0;
138185 }
138186 pTab = p->pSrc->a[0].pTab;
138187 assert( pTab!=0 );
138188 assert( !IsView(pTab) );
138189 if( !IsOrdinaryTable(pTab) ) return 0;
138190 pExpr = p->pEList->a[0].pExpr;
138191 assert( pExpr!=0 );
 
 
138192 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
138193 if( pExpr->pAggInfo!=pAggInfo ) return 0;
138194 if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
138195 assert( pAggInfo->aFunc[0].pFExpr==pExpr );
138196 testcase( ExprHasProperty(pExpr, EP_Distinct) );
138197 testcase( ExprHasProperty(pExpr, EP_WinFunc) );
138198 if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
138199
138200 return pTab;
138201 }
138202
@@ -145189,11 +145324,14 @@
145324 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
145325 int rc = SQLITE_OK;
145326 Table *pTab;
145327
145328 pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
145329 if( ALWAYS(pTab!=0)
145330 && ALWAYS(IsVirtual(pTab))
145331 && ALWAYS(pTab->u.vtab.p!=0)
145332 ){
145333 VTable *p;
145334 int (*xDestroy)(sqlite3_vtab *);
145335 for(p=pTab->u.vtab.p; p; p=p->pNext){
145336 assert( p->pVtab );
145337 if( p->pVtab->nRef>0 ){
@@ -155813,10 +155951,11 @@
155951 ** program.
155952 */
155953 for(ii=0; ii<nTabList; ii++){
155954 int addrExplain;
155955 int wsFlags;
155956 if( pParse->nErr ) goto whereBeginError;
155957 pLevel = &pWInfo->a[ii];
155958 wsFlags = pLevel->pWLoop->wsFlags;
155959 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155960 if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155961 constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -157266,11 +157405,15 @@
157405 }
157406 }else{
157407 sqlite3SelectDelete(db, pSub);
157408 }
157409 if( db->mallocFailed ) rc = SQLITE_NOMEM;
157410
157411 /* Defer deleting the temporary table pTab because if an error occurred,
157412 ** there could still be references to that table embedded in the
157413 ** result-set or ORDER BY clause of the SELECT statement p. */
157414 sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
157415 }
157416
157417 if( rc ){
157418 if( pParse->nErr==0 ){
157419 assert( pParse->db->mallocFailed );
@@ -160713,13 +160856,13 @@
160856 yyStackEntry *yystackEnd; /* Last entry in the stack */
160857 #endif
160858 };
160859 typedef struct yyParser yyParser;
160860
160861 /* #include <assert.h> */
160862 #ifndef NDEBUG
160863 /* #include <stdio.h> */
 
160864 static FILE *yyTraceFILE = 0;
160865 static char *yyTracePrompt = 0;
160866 #endif /* NDEBUG */
160867
160868 #ifndef NDEBUG
@@ -164464,12 +164607,12 @@
164607 assert( yypParser->yytos>=yypParser->yystack );
164608 assert( yyact==yypParser->yytos->stateno );
164609 yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
164610 if( yyact >= YY_MIN_REDUCE ){
164611 unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
 
164612 #ifndef NDEBUG
164613 assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164614 if( yyTraceFILE ){
164615 int yysize = yyRuleInfoNRhs[yyruleno];
164616 if( yysize ){
164617 fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
164618 yyTracePrompt,
@@ -167854,11 +167997,11 @@
167997 sqlite3BtreeLeaveAll(db);
167998
167999 /* Any deferred constraint violations have now been resolved. */
168000 db->nDeferredCons = 0;
168001 db->nDeferredImmCons = 0;
168002 db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
168003
168004 /* If one has been configured, invoke the rollback-hook callback */
168005 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
168006 db->xRollbackCallback(db->pRollbackArg);
168007 }
@@ -169582,12 +169725,12 @@
169725 **
169726 ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
169727 ** dealt with in the previous code block. Besides these, the only
169728 ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
169729 ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
169730 ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
169731 ** bits. Silently mask off all other flags.
169732 */
169733 flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
169734 SQLITE_OPEN_EXCLUSIVE |
169735 SQLITE_OPEN_MAIN_DB |
169736 SQLITE_OPEN_TEMP_DB |
@@ -169618,11 +169761,11 @@
169761 if( isThreadsafe==0 ){
169762 sqlite3MutexWarnOnContention(db->mutex);
169763 }
169764 }
169765 sqlite3_mutex_enter(db->mutex);
169766 db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
169767 db->nDb = 2;
169768 db->eOpenState = SQLITE_STATE_BUSY;
169769 db->aDb = db->aDbStatic;
169770 db->lookaside.bDisable = 1;
169771 db->lookaside.sz = 0;
@@ -169850,12 +169993,12 @@
169993 assert( db->mutex!=0 || isThreadsafe==0
169994 || sqlite3GlobalConfig.bFullMutex==0 );
169995 sqlite3_mutex_leave(db->mutex);
169996 }
169997 rc = sqlite3_errcode(db);
169998 assert( db!=0 || (rc&0xff)==SQLITE_NOMEM );
169999 if( (rc&0xff)==SQLITE_NOMEM ){
170000 sqlite3_close(db);
170001 db = 0;
170002 }else if( rc!=SQLITE_OK ){
170003 db->eOpenState = SQLITE_STATE_SICK;
170004 }
@@ -169866,11 +170009,11 @@
170009 void *pArg = sqlite3GlobalConfig.pSqllogArg;
170010 sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
170011 }
170012 #endif
170013 sqlite3_free_filename(zOpen);
170014 return rc;
170015 }
170016
170017
170018 /*
170019 ** Open a new database handle.
@@ -178416,10 +178559,13 @@
178559 while( rc==SQLITE_OK && !pNear->bEof ){
178560 fts3EvalNextRow(pCsr, pNear, &rc);
178561 if( bEofSave==0 && pNear->iDocid==iDocid ) break;
178562 }
178563 assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
178564 if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
178565 rc = FTS_CORRUPT_VTAB;
178566 }
178567 }
178568 if( bTreeEof ){
178569 while( rc==SQLITE_OK && !pNear->bEof ){
178570 fts3EvalNextRow(pCsr, pNear, &rc);
178571 }
@@ -190106,17 +190252,17 @@
190252 int iEnd = 0;
190253 int iCurrent = 0;
190254 const char *zDoc;
190255 int nDoc;
190256
190257 /* Initialize the contents of sCtx.aTerm[] for column iCol. This
190258 ** operation may fail if the database contains corrupt records.
 
190259 */
190260 sCtx.iCol = iCol;
190261 sCtx.iTerm = 0;
190262 rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190263 if( rc!=SQLITE_OK ) goto offsets_out;
190264
190265 /* Retreive the text stored in column iCol. If an SQL NULL is stored
190266 ** in column iCol, jump immediately to the next iteration of the loop.
190267 ** If an OOM occurs while retrieving the data (this can happen if SQLite
190268 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -192676,12 +192822,15 @@
192822 }else{
192823 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
192824 if( pNew==0 ) return 0;
192825 pTarget = &pParse->aNode[iTarget];
192826 if( pNew!=&pTarget[j+1] ){
192827 assert( pTarget[j+1].eU==0
192828 || pTarget[j+1].eU==1
192829 || pTarget[j+1].eU==2 );
192830 testcase( pTarget[j+1].eU==1 );
192831 testcase( pTarget[j+1].eU==2 );
192832 VVA( pTarget[j+1].eU = 5 );
192833 pTarget[j+1].u.pPatch = pNew;
192834 pTarget[j+1].jnFlags |= JNODE_PATCH;
192835 }
192836 }
@@ -201672,10 +201821,17 @@
201821 ** Swap two objects of type TYPE.
201822 */
201823 #if !defined(SQLITE_AMALGAMATION)
201824 # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
201825 #endif
201826
201827 /*
201828 ** Name of the URI option that causes RBU to take an exclusive lock as
201829 ** part of the incremental checkpoint operation.
201830 */
201831 #define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint"
201832
201833
201834 /*
201835 ** The rbu_state table is used to save the state of a partially applied
201836 ** update so that it can be resumed later. The table consists of integer
201837 ** keys mapped to values as follows:
@@ -204319,17 +204475,23 @@
204475
204476
204477 /*
204478 ** Open the database handle and attach the RBU database as "rbu". If an
204479 ** error occurs, leave an error code and message in the RBU handle.
204480 **
204481 ** If argument dbMain is not NULL, then it is a database handle already
204482 ** open on the target database. Use this handle instead of opening a new
204483 ** one.
204484 */
204485 static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
204486 assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
204487 assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
204488 assert( dbMain==0 || rbuIsVacuum(p)==0 );
204489
204490 /* Open the RBU database */
204491 p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
204492 p->dbMain = dbMain;
204493
204494 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
204495 sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
204496 if( p->zState==0 ){
204497 const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -204691,19 +204853,35 @@
204853 p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
204854 }
204855
204856
204857 /*
204858 ** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if
204859 ** successful, or an SQLite error code otherwise.
204860 */
204861 static int rbuLockDatabase(sqlite3 *db){
204862 int rc = SQLITE_OK;
204863 sqlite3_file *fd = 0;
204864 sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
204865
204866 if( fd->pMethods ){
204867 rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
204868 if( rc==SQLITE_OK ){
204869 rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE);
204870 }
204871 }
204872 return rc;
204873 }
204874
204875 /*
204876 ** Return true if the database handle passed as the only argument
204877 ** was opened with the rbu_exclusive_checkpoint=1 URI parameter
204878 ** specified. Or false otherwise.
204879 */
204880 static int rbuExclusiveCheckpoint(sqlite3 *db){
204881 const char *zUri = sqlite3_db_filename(db, 0);
204882 return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0);
204883 }
204884
204885 #if defined(_WIN32_WCE)
204886 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
204887 int nChar;
@@ -204757,22 +204935,28 @@
204935 ** in WAL mode). So no other connection may be writing the db.
204936 **
204937 ** In order to ensure that there are no database readers, an EXCLUSIVE
204938 ** lock is obtained here before the *-oal is moved to *-wal.
204939 */
204940 sqlite3 *dbMain = 0;
204941 rbuFileSuffix3(zBase, zWal);
204942 rbuFileSuffix3(zBase, zOal);
204943
204944 /* Re-open the databases. */
204945 rbuObjIterFinalize(&p->objiter);
204946 sqlite3_close(p->dbRbu);
204947 sqlite3_close(p->dbMain);
204948 p->dbMain = 0;
204949 p->dbRbu = 0;
204950
204951 dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
204952 if( dbMain ){
204953 assert( p->rc==SQLITE_OK );
204954 p->rc = rbuLockDatabase(dbMain);
204955 }
204956
204957 if( p->rc==SQLITE_OK ){
 
 
 
 
 
 
 
 
 
 
204958 #if defined(_WIN32_WCE)
204959 {
204960 LPWSTR zWideOal;
204961 LPWSTR zWideWal;
204962
@@ -204795,15 +204979,23 @@
204979 }
204980 }
204981 #else
204982 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204983 #endif
204984 }
204985
204986 if( p->rc!=SQLITE_OK
204987 || rbuIsVacuum(p)
204988 || rbuExclusiveCheckpoint(dbMain)==0
204989 ){
204990 sqlite3_close(dbMain);
204991 dbMain = 0;
204992 }
204993
204994 if( p->rc==SQLITE_OK ){
204995 rbuOpenDatabase(p, dbMain, 0);
204996 rbuSetupCheckpoint(p, 0);
204997 }
204998 }
204999
205000 sqlite3_free(zWal);
205001 sqlite3_free(zOal);
@@ -205550,13 +205742,13 @@
205742 ** to be a wal-mode db. But, this may have happened due to an earlier
205743 ** RBU vacuum operation leaving an old wal file in the directory.
205744 ** If this is the case, it will have been checkpointed and deleted
205745 ** when the handle was closed and a second attempt to open the
205746 ** database may succeed. */
205747 rbuOpenDatabase(p, 0, &bRetry);
205748 if( bRetry ){
205749 rbuOpenDatabase(p, 0, 0);
205750 }
205751 }
205752
205753 if( p->rc==SQLITE_OK ){
205754 pState = rbuLoadState(p);
@@ -205647,10 +205839,18 @@
205839 }
205840 }
205841 }else if( p->eStage==RBU_STAGE_MOVE ){
205842 /* no-op */
205843 }else if( p->eStage==RBU_STAGE_CKPT ){
205844 if( !rbuIsVacuum(p) && rbuExclusiveCheckpoint(p->dbMain) ){
205845 /* If the rbu_exclusive_checkpoint=1 URI parameter was specified
205846 ** and an incremental checkpoint is being resumed, attempt an
205847 ** exclusive lock on the db file. If this fails, so be it. */
205848 p->eStage = RBU_STAGE_DONE;
205849 rbuLockDatabase(p->dbMain);
205850 p->eStage = RBU_STAGE_CKPT;
205851 }
205852 rbuSetupCheckpoint(p, pState);
205853 }else if( p->eStage==RBU_STAGE_DONE ){
205854 p->rc = SQLITE_DONE;
205855 }else{
205856 p->rc = SQLITE_CORRUPT;
@@ -205684,11 +205884,10 @@
205884 const char *zTarget,
205885 const char *zRbu,
205886 const char *zState
205887 ){
205888 if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
 
205889 return openRbuHandle(zTarget, zRbu, zState);
205890 }
205891
205892 /*
205893 ** Open a handle to begin or resume an RBU VACUUM operation.
@@ -215805,13 +216004,13 @@
216004 fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
216005 #endif
216006 };
216007 typedef struct fts5yyParser fts5yyParser;
216008
 
 
216009 /* #include <assert.h> */
216010 #ifndef NDEBUG
216011 /* #include <stdio.h> */
216012 static FILE *fts5yyTraceFILE = 0;
216013 static char *fts5yyTracePrompt = 0;
216014 #endif /* NDEBUG */
216015
216016 #ifndef NDEBUG
@@ -216744,12 +216943,12 @@
216943 assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
216944 assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
216945 fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
216946 if( fts5yyact >= fts5YY_MIN_REDUCE ){
216947 unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
 
216948 #ifndef NDEBUG
216949 assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216950 if( fts5yyTraceFILE ){
216951 int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
216952 if( fts5yysize ){
216953 fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
216954 fts5yyTracePrompt,
@@ -232260,11 +232459,11 @@
232459 int nArg, /* Number of args */
232460 sqlite3_value **apUnused /* Function arguments */
232461 ){
232462 assert( nArg==0 );
232463 UNUSED_PARAM2(nArg, apUnused);
232464 sqlite3_result_text(pCtx, "fts5: 2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba", -1, SQLITE_TRANSIENT);
232465 }
232466
232467 /*
232468 ** Return true if zName is the extension on one of the shadow tables used
232469 ** by this module.
232470
+10 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -146,11 +146,11 @@
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149149
#define SQLITE_VERSION "3.37.0"
150150
#define SQLITE_VERSION_NUMBER 3037000
151
-#define SQLITE_SOURCE_ID "2021-11-04 14:04:20 9147390d9885a37a62edc1058f313434627f1b59965c890877d2cb119e355c78"
151
+#define SQLITE_SOURCE_ID "2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -607,10 +607,11 @@
607607
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
608608
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
609609
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
610610
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
611611
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
612
+#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
612613
613614
/* Reserved: 0x00F00000 */
614615
/* Legacy compatibility: */
615616
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
616617
@@ -3426,10 +3427,18 @@
34263427
**
34273428
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
34283429
** <dd>The database is opened [shared cache] disabled, overriding
34293430
** the default shared cache setting provided by
34303431
** [sqlite3_enable_shared_cache()].)^
3432
+**
3433
+** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt>
3434
+** <dd>The database connection comes up in "extended result code mode".
3435
+** In other words, the database behaves has if
3436
+** [sqlite3_extended_result_codes(db,1)] where called on the database
3437
+** connection as soon as the connection is created. In addition to setting
3438
+** the extended result code mode, this flag also causes [sqlite3_open_v2()]
3439
+** to return an extended result code.</dd>
34313440
**
34323441
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
34333442
** <dd>The database filename is not allowed to be a symbolic link</dd>
34343443
** </dl>)^
34353444
**
34363445
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.37.0"
150 #define SQLITE_VERSION_NUMBER 3037000
151 #define SQLITE_SOURCE_ID "2021-11-04 14:04:20 9147390d9885a37a62edc1058f313434627f1b59965c890877d2cb119e355c78"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -607,10 +607,11 @@
607 #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
608 #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
609 #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
610 #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
611 #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
 
612
613 /* Reserved: 0x00F00000 */
614 /* Legacy compatibility: */
615 #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
616
@@ -3426,10 +3427,18 @@
3426 **
3427 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3428 ** <dd>The database is opened [shared cache] disabled, overriding
3429 ** the default shared cache setting provided by
3430 ** [sqlite3_enable_shared_cache()].)^
 
 
 
 
 
 
 
 
3431 **
3432 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3433 ** <dd>The database filename is not allowed to be a symbolic link</dd>
3434 ** </dl>)^
3435 **
3436
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -146,11 +146,11 @@
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.37.0"
150 #define SQLITE_VERSION_NUMBER 3037000
151 #define SQLITE_SOURCE_ID "2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -607,10 +607,11 @@
607 #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
608 #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
609 #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
610 #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
611 #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
612 #define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
613
614 /* Reserved: 0x00F00000 */
615 /* Legacy compatibility: */
616 #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
617
@@ -3426,10 +3427,18 @@
3427 **
3428 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3429 ** <dd>The database is opened [shared cache] disabled, overriding
3430 ** the default shared cache setting provided by
3431 ** [sqlite3_enable_shared_cache()].)^
3432 **
3433 ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt>
3434 ** <dd>The database connection comes up in "extended result code mode".
3435 ** In other words, the database behaves has if
3436 ** [sqlite3_extended_result_codes(db,1)] where called on the database
3437 ** connection as soon as the connection is created. In addition to setting
3438 ** the extended result code mode, this flag also causes [sqlite3_open_v2()]
3439 ** to return an extended result code.</dd>
3440 **
3441 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3442 ** <dd>The database filename is not allowed to be a symbolic link</dd>
3443 ** </dl>)^
3444 **
3445
+30 -1
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
5454
int i;
5555
Stmt q;
5656
5757
sync_explain(syncFlags);
5858
nErr = client_sync(syncFlags, configRcvMask, configSendMask, zAltPCode);
59
+ if( nErr==0 ) url_remember();
5960
if( (syncFlags & SYNC_ALLURL)==0 ) return nErr;
6061
nOther = 0;
6162
azOther = 0;
6263
db_prepare(&q,
6364
"SELECT substr(name,10) FROM config"
@@ -255,11 +256,10 @@
255256
if( urlFlags & URL_REMEMBER ){
256257
clone_ssh_db_set_options();
257258
}
258259
url_parse(zUrl, urlFlags);
259260
remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
260
- url_remember();
261261
if( g.url.protocol==0 ){
262262
if( urlOptional ) fossil_exit(0);
263263
usage("URL");
264264
}
265265
user_select();
@@ -613,10 +613,39 @@
613613
db_multi_exec("DELETE FROM config WHERE name glob 'sync-pw:*'");
614614
db_multi_exec("DELETE FROM config WHERE name = 'last-sync-pw'");
615615
db_protect_pop();
616616
db_commit_transaction();
617617
return;
618
+ }
619
+ if( strncmp(zArg, "config-data", nArg)==0 ){
620
+ /* Undocumented command: "fossil remote config-data"
621
+ **
622
+ ** Show the CONFIG table entries that relate to remembering remote URLs
623
+ */
624
+ Stmt q;
625
+ int n;
626
+ n = db_int(13,
627
+ "SELECT max(length(name))"
628
+ " FROM config"
629
+ " WHERE name GLOB 'sync-*:*' OR name GLOB 'last-sync-*'"
630
+ );
631
+ db_prepare(&q,
632
+ "SELECT name,"
633
+ " CASE WHEN name LIKE '%%sync-pw%%'"
634
+ " THEN printf('%%.*c',length(value),'*') ELSE value END"
635
+ " FROM config"
636
+ " WHERE name GLOB 'sync-*:*' OR name GLOB 'last-sync-*'"
637
+ " ORDER BY name LIKE '%%sync-pw%%', name"
638
+ );
639
+ while( db_step(&q)==SQLITE_ROW ){
640
+ fossil_print("%-*s %s\n",
641
+ n, db_column_text(&q,0),
642
+ db_column_text(&q,1)
643
+ );
644
+ }
645
+ db_finalize(&q);
646
+ return;
618647
}
619648
if( sqlite3_strlike("http://%",zArg,0)==0
620649
|| sqlite3_strlike("https://%",zArg,0)==0
621650
|| sqlite3_strlike("ssh:%",zArg,0)==0
622651
|| sqlite3_strlike("file:%",zArg,0)==0
623652
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
54 int i;
55 Stmt q;
56
57 sync_explain(syncFlags);
58 nErr = client_sync(syncFlags, configRcvMask, configSendMask, zAltPCode);
 
59 if( (syncFlags & SYNC_ALLURL)==0 ) return nErr;
60 nOther = 0;
61 azOther = 0;
62 db_prepare(&q,
63 "SELECT substr(name,10) FROM config"
@@ -255,11 +256,10 @@
255 if( urlFlags & URL_REMEMBER ){
256 clone_ssh_db_set_options();
257 }
258 url_parse(zUrl, urlFlags);
259 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
260 url_remember();
261 if( g.url.protocol==0 ){
262 if( urlOptional ) fossil_exit(0);
263 usage("URL");
264 }
265 user_select();
@@ -613,10 +613,39 @@
613 db_multi_exec("DELETE FROM config WHERE name glob 'sync-pw:*'");
614 db_multi_exec("DELETE FROM config WHERE name = 'last-sync-pw'");
615 db_protect_pop();
616 db_commit_transaction();
617 return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
618 }
619 if( sqlite3_strlike("http://%",zArg,0)==0
620 || sqlite3_strlike("https://%",zArg,0)==0
621 || sqlite3_strlike("ssh:%",zArg,0)==0
622 || sqlite3_strlike("file:%",zArg,0)==0
623
--- src/sync.c
+++ src/sync.c
@@ -54,10 +54,11 @@
54 int i;
55 Stmt q;
56
57 sync_explain(syncFlags);
58 nErr = client_sync(syncFlags, configRcvMask, configSendMask, zAltPCode);
59 if( nErr==0 ) url_remember();
60 if( (syncFlags & SYNC_ALLURL)==0 ) return nErr;
61 nOther = 0;
62 azOther = 0;
63 db_prepare(&q,
64 "SELECT substr(name,10) FROM config"
@@ -255,11 +256,10 @@
256 if( urlFlags & URL_REMEMBER ){
257 clone_ssh_db_set_options();
258 }
259 url_parse(zUrl, urlFlags);
260 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
 
261 if( g.url.protocol==0 ){
262 if( urlOptional ) fossil_exit(0);
263 usage("URL");
264 }
265 user_select();
@@ -613,10 +613,39 @@
613 db_multi_exec("DELETE FROM config WHERE name glob 'sync-pw:*'");
614 db_multi_exec("DELETE FROM config WHERE name = 'last-sync-pw'");
615 db_protect_pop();
616 db_commit_transaction();
617 return;
618 }
619 if( strncmp(zArg, "config-data", nArg)==0 ){
620 /* Undocumented command: "fossil remote config-data"
621 **
622 ** Show the CONFIG table entries that relate to remembering remote URLs
623 */
624 Stmt q;
625 int n;
626 n = db_int(13,
627 "SELECT max(length(name))"
628 " FROM config"
629 " WHERE name GLOB 'sync-*:*' OR name GLOB 'last-sync-*'"
630 );
631 db_prepare(&q,
632 "SELECT name,"
633 " CASE WHEN name LIKE '%%sync-pw%%'"
634 " THEN printf('%%.*c',length(value),'*') ELSE value END"
635 " FROM config"
636 " WHERE name GLOB 'sync-*:*' OR name GLOB 'last-sync-*'"
637 " ORDER BY name LIKE '%%sync-pw%%', name"
638 );
639 while( db_step(&q)==SQLITE_ROW ){
640 fossil_print("%-*s %s\n",
641 n, db_column_text(&q,0),
642 db_column_text(&q,1)
643 );
644 }
645 db_finalize(&q);
646 return;
647 }
648 if( sqlite3_strlike("http://%",zArg,0)==0
649 || sqlite3_strlike("https://%",zArg,0)==0
650 || sqlite3_strlike("ssh:%",zArg,0)==0
651 || sqlite3_strlike("file:%",zArg,0)==0
652
+48 -16
--- www/chat.md
+++ www/chat.md
@@ -121,10 +121,42 @@
121121
shows up in the list but has no messages which are currently visible
122122
because they were deleted, or an admin user who has not posted
123123
anything but deleted a message. That is a known minor cosmetic-only
124124
bug with a resolution of "will not fix."
125125
126
+### <a id="cli"></a> The `fossil chat` Command
127
+
128
+Type [fossil chat](/help?cmd=chat) from within any open check-out
129
+to bring up a chatroom for the project that is in that checkout.
130
+The new chat window will attempt to connect to the default sync
131
+target for that check-out (the server whose URL is shown by the
132
+[fossil remote](/help?cmd=remote) command).
133
+
134
+### <a id="robots"></a> Chat Messages From Robots
135
+
136
+The [fossil chat send](/help?cmd=chat) can be used by project-specific
137
+robots to send notifications to the chatroom. For example, on the
138
+[SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139
+feature, and indeed all of Fossil, was invented) there are long-running
140
+fuzz servers that sometimes run across obscure problems. Whenever this
141
+happens, a message is sent to the SQLite developers chatroom altering
142
+them to the problem.
143
+
144
+The recommended way to allow robots to send chat messages is to create
145
+a new user on the server for each robot. Give each such robot account
146
+the "C" privilege only. That means that the robot user account will be
147
+able to send chat messages, but not do anything else. Then, in the
148
+program or script that runs the robot, when it wants to send a chat
149
+message, have it run a command like this:
150
+
151
+> ~~~~
152
+fossil chat send --remote https://robot:[email protected]/fossil \
153
+ --message 'MESSAGE TEXT' --file file-to-attach.txt
154
+~~~~
155
+
156
+Substitute the appropriate project URL, robot account
157
+name and password, message text and file attachment, of course.
126158
127159
## Implementation Details
128160
129161
*You do not need to understand how Fossil chat works in order to use it.
130162
But many developers prefer to know how their tools work.
@@ -134,22 +166,22 @@
134166
and a small amount of javascript to run the chat session. The
135167
javascript uses XMLHttpRequest (XHR) to download chat content, post
136168
new content, or delete historical messages. The following web
137169
interfaces are used by the XHR:
138170
139
- * **/chat-poll** &rarr;
171
+ * [/chat-poll](/help?name=/chat-poll) &rarr;
140172
Downloads chat content as JSON.
141173
Chat messages are numbered sequentially.
142174
The client tells the server the largest chat message it currently
143175
holds, and the server sends back subsequent messages. If there
144176
are no subsequent messages, the /chat-poll page blocks until new
145177
messages are available.
146178
147
- * **/chat-send** &rarr;
179
+ * [/chat-send](/help?name=/chat-send) &rarr;
148180
Sends a new chat message to the server.
149181
150
- * **/chat-delete** &rarr;
182
+ * [/chat-delete](/help?name=/chat-delete) &rarr;
151183
Deletes a chat message.
152184
153185
Fossil chat uses the venerable "hanging GET" or
154186
"[long polling](wikipedia:/wiki/Push_technology#Long_polling)"
155187
technique to recieve asynchronous notification of new messages.
@@ -160,30 +192,30 @@
160192
[WebSockets](wikipedia:/wiki/WebSocket) might seem more appropriate for
161193
a chat system, but those technologies are not compatible with CGI.
162194
163195
Downloading of posted files and images uses a separate, non-XHR interface:
164196
165
- * **/chat-download** &rarr;
197
+ * [/chat-download](/help?name=/chat-download) &rarr;
166198
Fetches the file content associated with a post (one file per
167199
post, maximum). In the UI, this is accessed via links to uploaded
168200
files and via inlined image tags.
169201
170202
Chat messages are stored on the server-side in the CHAT table of
171203
the repository.
172204
173
-~~~
174
- CREATE TABLE repository.chat(
175
- msgid INTEGER PRIMARY KEY AUTOINCREMENT,
176
- mtime JULIANDAY,
177
- ltime TEXT,
178
- xfrom TEXT,
179
- xmsg TEXT,
180
- fname TEXT,
181
- fmime TEXT,
182
- mdel INT,
183
- file BLOB)
184
- );
205
+> ~~~
206
+CREATE TABLE repository.chat(
207
+ msgid INTEGER PRIMARY KEY AUTOINCREMENT,
208
+ mtime JULIANDAY, -- Time for this entry - Julianday Zulu
209
+ lmtime TEXT, -- Client YYYY-MM-DDZHH:MM:SS when message originally sent
210
+ xfrom TEXT, -- Login of the sender
211
+ xmsg TEXT, -- Raw, unformatted text of the message
212
+ fname TEXT, -- Filename of the uploaded file, or NULL
213
+ fmime TEXT, -- MIMEType of the upload file, or NULL
214
+ mdel INT, -- msgid of another message to delete
215
+ file BLOB -- Text of the uploaded file, or NULL
216
+);
185217
~~~
186218
187219
The CHAT table is not cross-linked with any other tables in the repository
188220
schema. An administrator can "DROP TABLE chat;" at any time, without
189221
harm (apart from deleting all chat history, of course). The CHAT table
190222
--- www/chat.md
+++ www/chat.md
@@ -121,10 +121,42 @@
121 shows up in the list but has no messages which are currently visible
122 because they were deleted, or an admin user who has not posted
123 anything but deleted a message. That is a known minor cosmetic-only
124 bug with a resolution of "will not fix."
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
127 ## Implementation Details
128
129 *You do not need to understand how Fossil chat works in order to use it.
130 But many developers prefer to know how their tools work.
@@ -134,22 +166,22 @@
134 and a small amount of javascript to run the chat session. The
135 javascript uses XMLHttpRequest (XHR) to download chat content, post
136 new content, or delete historical messages. The following web
137 interfaces are used by the XHR:
138
139 * **/chat-poll** &rarr;
140 Downloads chat content as JSON.
141 Chat messages are numbered sequentially.
142 The client tells the server the largest chat message it currently
143 holds, and the server sends back subsequent messages. If there
144 are no subsequent messages, the /chat-poll page blocks until new
145 messages are available.
146
147 * **/chat-send** &rarr;
148 Sends a new chat message to the server.
149
150 * **/chat-delete** &rarr;
151 Deletes a chat message.
152
153 Fossil chat uses the venerable "hanging GET" or
154 "[long polling](wikipedia:/wiki/Push_technology#Long_polling)"
155 technique to recieve asynchronous notification of new messages.
@@ -160,30 +192,30 @@
160 [WebSockets](wikipedia:/wiki/WebSocket) might seem more appropriate for
161 a chat system, but those technologies are not compatible with CGI.
162
163 Downloading of posted files and images uses a separate, non-XHR interface:
164
165 * **/chat-download** &rarr;
166 Fetches the file content associated with a post (one file per
167 post, maximum). In the UI, this is accessed via links to uploaded
168 files and via inlined image tags.
169
170 Chat messages are stored on the server-side in the CHAT table of
171 the repository.
172
173 ~~~
174 CREATE TABLE repository.chat(
175 msgid INTEGER PRIMARY KEY AUTOINCREMENT,
176 mtime JULIANDAY,
177 ltime TEXT,
178 xfrom TEXT,
179 xmsg TEXT,
180 fname TEXT,
181 fmime TEXT,
182 mdel INT,
183 file BLOB)
184 );
185 ~~~
186
187 The CHAT table is not cross-linked with any other tables in the repository
188 schema. An administrator can "DROP TABLE chat;" at any time, without
189 harm (apart from deleting all chat history, of course). The CHAT table
190
--- www/chat.md
+++ www/chat.md
@@ -121,10 +121,42 @@
121 shows up in the list but has no messages which are currently visible
122 because they were deleted, or an admin user who has not posted
123 anything but deleted a message. That is a known minor cosmetic-only
124 bug with a resolution of "will not fix."
125
126 ### <a id="cli"></a> The `fossil chat` Command
127
128 Type [fossil chat](/help?cmd=chat) from within any open check-out
129 to bring up a chatroom for the project that is in that checkout.
130 The new chat window will attempt to connect to the default sync
131 target for that check-out (the server whose URL is shown by the
132 [fossil remote](/help?cmd=remote) command).
133
134 ### <a id="robots"></a> Chat Messages From Robots
135
136 The [fossil chat send](/help?cmd=chat) can be used by project-specific
137 robots to send notifications to the chatroom. For example, on the
138 [SQLite project](https://sqlite.org/) (for which the Fossil chatroom
139 feature, and indeed all of Fossil, was invented) there are long-running
140 fuzz servers that sometimes run across obscure problems. Whenever this
141 happens, a message is sent to the SQLite developers chatroom altering
142 them to the problem.
143
144 The recommended way to allow robots to send chat messages is to create
145 a new user on the server for each robot. Give each such robot account
146 the "C" privilege only. That means that the robot user account will be
147 able to send chat messages, but not do anything else. Then, in the
148 program or script that runs the robot, when it wants to send a chat
149 message, have it run a command like this:
150
151 > ~~~~
152 fossil chat send --remote https://robot:[email protected]/fossil \
153 --message 'MESSAGE TEXT' --file file-to-attach.txt
154 ~~~~
155
156 Substitute the appropriate project URL, robot account
157 name and password, message text and file attachment, of course.
158
159 ## Implementation Details
160
161 *You do not need to understand how Fossil chat works in order to use it.
162 But many developers prefer to know how their tools work.
@@ -134,22 +166,22 @@
166 and a small amount of javascript to run the chat session. The
167 javascript uses XMLHttpRequest (XHR) to download chat content, post
168 new content, or delete historical messages. The following web
169 interfaces are used by the XHR:
170
171 * [/chat-poll](/help?name=/chat-poll) &rarr;
172 Downloads chat content as JSON.
173 Chat messages are numbered sequentially.
174 The client tells the server the largest chat message it currently
175 holds, and the server sends back subsequent messages. If there
176 are no subsequent messages, the /chat-poll page blocks until new
177 messages are available.
178
179 * [/chat-send](/help?name=/chat-send) &rarr;
180 Sends a new chat message to the server.
181
182 * [/chat-delete](/help?name=/chat-delete) &rarr;
183 Deletes a chat message.
184
185 Fossil chat uses the venerable "hanging GET" or
186 "[long polling](wikipedia:/wiki/Push_technology#Long_polling)"
187 technique to recieve asynchronous notification of new messages.
@@ -160,30 +192,30 @@
192 [WebSockets](wikipedia:/wiki/WebSocket) might seem more appropriate for
193 a chat system, but those technologies are not compatible with CGI.
194
195 Downloading of posted files and images uses a separate, non-XHR interface:
196
197 * [/chat-download](/help?name=/chat-download) &rarr;
198 Fetches the file content associated with a post (one file per
199 post, maximum). In the UI, this is accessed via links to uploaded
200 files and via inlined image tags.
201
202 Chat messages are stored on the server-side in the CHAT table of
203 the repository.
204
205 > ~~~
206 CREATE TABLE repository.chat(
207 msgid INTEGER PRIMARY KEY AUTOINCREMENT,
208 mtime JULIANDAY, -- Time for this entry - Julianday Zulu
209 lmtime TEXT, -- Client YYYY-MM-DDZHH:MM:SS when message originally sent
210 xfrom TEXT, -- Login of the sender
211 xmsg TEXT, -- Raw, unformatted text of the message
212 fname TEXT, -- Filename of the uploaded file, or NULL
213 fmime TEXT, -- MIMEType of the upload file, or NULL
214 mdel INT, -- msgid of another message to delete
215 file BLOB -- Text of the uploaded file, or NULL
216 );
217 ~~~
218
219 The CHAT table is not cross-linked with any other tables in the repository
220 schema. An administrator can "DROP TABLE chat;" at any time, without
221 harm (apart from deleting all chat history, of course). The CHAT table
222
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -24,16 +24,16 @@
2424
2525
<verbatim type="pikchr float-right">
2626
R1: cylinder "Remote" "Repository" fill 0xadd8e6 rad 70%
2727
R2: cylinder same "Remote" "Repository" at 2.5*R1.wid right of R1
2828
spline <-> from R1.e to 0.6<R1.se,R2.sw> then to 0.4<R1.ne,R2.nw> then to R2.w
29
- text "HTTP" at .5<R1.ne,R2.nw>
29
+ text "HTTPS" at .5<R1.ne,R2.nw>
3030
R3: cylinder same "Local" "Repository" fill 0x90ee90 \
3131
at dist(R1.e,R2.w) below .5<R1,R2>
32
- spline <-> from .5<R1.s,R1.se> to 0.6<R1.s,R3.w> to 0.5<R1.se,R3.n> to .5<R3.nw,R3.n> "HTTP" \
33
- behind R1
34
- spline <-> from R2.sw to .6<R2.sw,R3.n> to .5<R2.s,R3.e> to R3.ne "HTTP" ljust
32
+ spline <-> from .5<R1.s,R1.se> to 0.6<R1.s,R3.w> to 0.5<R1.se,R3.n> to .5<R3.nw,R3.n> \
33
+ "HTTPS" above behind R1
34
+ spline <-> from R2.sw to .6<R2.sw,R3.n> to .5<R2.s,R3.e> to R3.ne "HTTPS" ljust
3535
T1: line from 1.0cm heading 200 from R3.sw go 2.2cm heading 150 then 2.2cm west close \
3636
fill 0xffff00 "Local" below "Source Tree" below
3737
T2: line from 1.0cm heading 160 from R3.se same "Local" below "Source Tree" below
3838
line <-> from R3.sw to T1.start
3939
line <-> from R3.se to T2.start
@@ -91,11 +91,12 @@
9191
Fossil also has the concept of "cloning". A "clone" is like a "pull",
9292
except that instead of beginning with an existing local repository,
9393
a clone begins with nothing and creates a new local repository that
9494
is a duplicate of a remote repository.
9595
96
-Communication between repositories is via HTTP. Remote
96
+Communication between repositories is normally via HTTPS. (SSH is also
97
+supported, as is unencrypted HTTP.) Remote
9798
repositories are identified by URL. You can also point a web browser
9899
at a repository and get human-readable status, history, and tracking
99100
information about the project.
100101
101102
<h3 id="artifacts">2.1 Identification Of Artifacts</h3>
102103
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -24,16 +24,16 @@
24
25 <verbatim type="pikchr float-right">
26 R1: cylinder "Remote" "Repository" fill 0xadd8e6 rad 70%
27 R2: cylinder same "Remote" "Repository" at 2.5*R1.wid right of R1
28 spline <-> from R1.e to 0.6<R1.se,R2.sw> then to 0.4<R1.ne,R2.nw> then to R2.w
29 text "HTTP" at .5<R1.ne,R2.nw>
30 R3: cylinder same "Local" "Repository" fill 0x90ee90 \
31 at dist(R1.e,R2.w) below .5<R1,R2>
32 spline <-> from .5<R1.s,R1.se> to 0.6<R1.s,R3.w> to 0.5<R1.se,R3.n> to .5<R3.nw,R3.n> "HTTP" \
33 behind R1
34 spline <-> from R2.sw to .6<R2.sw,R3.n> to .5<R2.s,R3.e> to R3.ne "HTTP" ljust
35 T1: line from 1.0cm heading 200 from R3.sw go 2.2cm heading 150 then 2.2cm west close \
36 fill 0xffff00 "Local" below "Source Tree" below
37 T2: line from 1.0cm heading 160 from R3.se same "Local" below "Source Tree" below
38 line <-> from R3.sw to T1.start
39 line <-> from R3.se to T2.start
@@ -91,11 +91,12 @@
91 Fossil also has the concept of "cloning". A "clone" is like a "pull",
92 except that instead of beginning with an existing local repository,
93 a clone begins with nothing and creates a new local repository that
94 is a duplicate of a remote repository.
95
96 Communication between repositories is via HTTP. Remote
 
97 repositories are identified by URL. You can also point a web browser
98 at a repository and get human-readable status, history, and tracking
99 information about the project.
100
101 <h3 id="artifacts">2.1 Identification Of Artifacts</h3>
102
--- www/concepts.wiki
+++ www/concepts.wiki
@@ -24,16 +24,16 @@
24
25 <verbatim type="pikchr float-right">
26 R1: cylinder "Remote" "Repository" fill 0xadd8e6 rad 70%
27 R2: cylinder same "Remote" "Repository" at 2.5*R1.wid right of R1
28 spline <-> from R1.e to 0.6<R1.se,R2.sw> then to 0.4<R1.ne,R2.nw> then to R2.w
29 text "HTTPS" at .5<R1.ne,R2.nw>
30 R3: cylinder same "Local" "Repository" fill 0x90ee90 \
31 at dist(R1.e,R2.w) below .5<R1,R2>
32 spline <-> from .5<R1.s,R1.se> to 0.6<R1.s,R3.w> to 0.5<R1.se,R3.n> to .5<R3.nw,R3.n> \
33 "HTTPS" above behind R1
34 spline <-> from R2.sw to .6<R2.sw,R3.n> to .5<R2.s,R3.e> to R3.ne "HTTPS" ljust
35 T1: line from 1.0cm heading 200 from R3.sw go 2.2cm heading 150 then 2.2cm west close \
36 fill 0xffff00 "Local" below "Source Tree" below
37 T2: line from 1.0cm heading 160 from R3.se same "Local" below "Source Tree" below
38 line <-> from R3.sw to T1.start
39 line <-> from R3.se to T2.start
@@ -91,11 +91,12 @@
91 Fossil also has the concept of "cloning". A "clone" is like a "pull",
92 except that instead of beginning with an existing local repository,
93 a clone begins with nothing and creates a new local repository that
94 is a duplicate of a remote repository.
95
96 Communication between repositories is normally via HTTPS. (SSH is also
97 supported, as is unencrypted HTTP.) Remote
98 repositories are identified by URL. You can also point a web browser
99 at a repository and get human-readable status, history, and tracking
100 information about the project.
101
102 <h3 id="artifacts">2.1 Identification Of Artifacts</h3>
103
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -74,11 +74,11 @@
7474
<li><p>Fossil does not care what you name your repository files,
7575
though names ending with ".fossil" are recommended.
7676
<li><p>A single project typically has multiple, redundant repositories on
7777
separate machines.
7878
<li><p>All repositories stay synchronized with one another by exchanging
79
- information via HTTP or SSH.
79
+ information via HTTPS or SSH.
8080
<li><p>All repos for a single project redundantly store all information
8181
about that project. So if any one repo is lost due to a disk
8282
crash, all content is preserved in the surviving repos.
8383
<li><p>The usual arrangement is one repository per user. And since
8484
most users these days have their own computer, that means one
8585
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -74,11 +74,11 @@
74 <li><p>Fossil does not care what you name your repository files,
75 though names ending with ".fossil" are recommended.
76 <li><p>A single project typically has multiple, redundant repositories on
77 separate machines.
78 <li><p>All repositories stay synchronized with one another by exchanging
79 information via HTTP or SSH.
80 <li><p>All repos for a single project redundantly store all information
81 about that project. So if any one repo is lost due to a disk
82 crash, all content is preserved in the surviving repos.
83 <li><p>The usual arrangement is one repository per user. And since
84 most users these days have their own computer, that means one
85
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -74,11 +74,11 @@
74 <li><p>Fossil does not care what you name your repository files,
75 though names ending with ".fossil" are recommended.
76 <li><p>A single project typically has multiple, redundant repositories on
77 separate machines.
78 <li><p>All repositories stay synchronized with one another by exchanging
79 information via HTTPS or SSH.
80 <li><p>All repos for a single project redundantly store all information
81 about that project. So if any one repo is lost due to a disk
82 crash, all content is preserved in the surviving repos.
83 <li><p>The usual arrangement is one repository per user. And since
84 most users these days have their own computer, that means one
85

Keyboard Shortcuts

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