Fossil SCM

Merged latest trunk into strict branch.

stephan 2021-11-19 10:16 strict merge
Commit 845d3e86126afd1a2a9015a95231f83f1a7f4ced5a6a39b912f224080b8deece
+11 -1
--- src/cgi.c
+++ src/cgi.c
@@ -2318,14 +2318,24 @@
23182318
pTm = gmtime(&now);
23192319
if( pTm==0 ){
23202320
return mprintf("");
23212321
}else{
23222322
return mprintf("%04d-%02d-%02d %02d:%02d:%02d",
2323
- pTm->tm_year+1900, pTm->tm_mon, pTm->tm_mday,
2323
+ pTm->tm_year+1900, pTm->tm_mon+1, pTm->tm_mday,
23242324
pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
23252325
}
23262326
}
2327
+
2328
+/*
2329
+** COMMAND: test-date
2330
+**
2331
+** Show the current date and time in both RFC822 and ISO8601.
2332
+*/
2333
+void test_date(void){
2334
+ fossil_print("%z = ", cgi_iso8601_datestamp());
2335
+ fossil_print("%z\n", cgi_rfc822_datestamp(time(0)));
2336
+}
23272337
23282338
/*
23292339
** Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
23302340
** a Unix epoch time. <= zero is returned on failure.
23312341
**
23322342
--- src/cgi.c
+++ src/cgi.c
@@ -2318,14 +2318,24 @@
2318 pTm = gmtime(&now);
2319 if( pTm==0 ){
2320 return mprintf("");
2321 }else{
2322 return mprintf("%04d-%02d-%02d %02d:%02d:%02d",
2323 pTm->tm_year+1900, pTm->tm_mon, pTm->tm_mday,
2324 pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
2325 }
2326 }
 
 
 
 
 
 
 
 
 
 
2327
2328 /*
2329 ** Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
2330 ** a Unix epoch time. <= zero is returned on failure.
2331 **
2332
--- src/cgi.c
+++ src/cgi.c
@@ -2318,14 +2318,24 @@
2318 pTm = gmtime(&now);
2319 if( pTm==0 ){
2320 return mprintf("");
2321 }else{
2322 return mprintf("%04d-%02d-%02d %02d:%02d:%02d",
2323 pTm->tm_year+1900, pTm->tm_mon+1, pTm->tm_mday,
2324 pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
2325 }
2326 }
2327
2328 /*
2329 ** COMMAND: test-date
2330 **
2331 ** Show the current date and time in both RFC822 and ISO8601.
2332 */
2333 void test_date(void){
2334 fossil_print("%z = ", cgi_iso8601_datestamp());
2335 fossil_print("%z\n", cgi_rfc822_datestamp(time(0)));
2336 }
2337
2338 /*
2339 ** Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
2340 ** a Unix epoch time. <= zero is returned on failure.
2341 **
2342
+28 -7
--- 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
*/
@@ -804,27 +818,34 @@
804818
** URL shows when you run the "fossil remote" command) or to the URL
805819
** specified by the --remote option. If there is no default remote
806820
** Fossil repository and the --remote option is omitted, then this
807821
** command fails with an error.
808822
**
809
-** When there is no SUBCOMMAND (when this command is simply "fossil chat")
810
-** the response is to bring up a web-browser window to the chatroom
811
-** on the default system web-browser. You can accomplish the same by
812
-** typing the appropriate URL into the web-browser yourself. This
813
-** command is merely a convenience for command-line oriented people.
823
+** Subcommands:
824
+**
825
+** > fossil chat
814826
**
815
-** The following subcommands are supported:
827
+** When there is no SUBCOMMAND (when this command is simply "fossil chat")
828
+** the response is to bring up a web-browser window to the chatroom
829
+** on the default system web-browser. You can accomplish the same by
830
+** typing the appropriate URL into the web-browser yourself. This
831
+** command is merely a convenience for command-line oriented people.
816832
**
817833
** > fossil chat send [ARGUMENTS]
818834
**
819835
** This command sends a new message to the chatroom. The message
820836
** to be sent is determined by arguments as follows:
821837
**
822838
** -f|--file FILENAME File to attach to the message
823839
** -m|--message TEXT Text of the chat message
840
+** --remote URL Send to this remote URL
824841
** --unsafe Allow the use of unencrypted http://
825842
**
843
+** > fossil chat url
844
+**
845
+** Show the default URL used to access the chat server.
846
+**
826847
** Additional subcommands may be added in the future.
827848
*/
828849
void chat_command(void){
829850
const char *zUrl = find_option("remote",0,1);
830851
int urlFlags = 0;
@@ -948,11 +969,11 @@
948969
}
949970
fossil_fatal("unable to send the chat message");
950971
}
951972
blob_reset(&down);
952973
}else if( strcmp(g.argv[2],"url")==0 ){
953
- /* Undocumented command. Show the URL to access chat. */
974
+ /* Show the URL to access chat. */
954975
fossil_print("%s/chat\n", zUrl);
955976
}else{
956977
fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
957978
}
958979
}
959980
--- 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 */
@@ -804,27 +818,34 @@
804 ** URL shows when you run the "fossil remote" command) or to the URL
805 ** specified by the --remote option. If there is no default remote
806 ** Fossil repository and the --remote option is omitted, then this
807 ** command fails with an error.
808 **
809 ** When there is no SUBCOMMAND (when this command is simply "fossil chat")
810 ** the response is to bring up a web-browser window to the chatroom
811 ** on the default system web-browser. You can accomplish the same by
812 ** typing the appropriate URL into the web-browser yourself. This
813 ** command is merely a convenience for command-line oriented people.
814 **
815 ** The following subcommands are supported:
 
 
 
 
816 **
817 ** > fossil chat send [ARGUMENTS]
818 **
819 ** This command sends a new message to the chatroom. The message
820 ** to be sent is determined by arguments as follows:
821 **
822 ** -f|--file FILENAME File to attach to the message
823 ** -m|--message TEXT Text of the chat message
 
824 ** --unsafe Allow the use of unencrypted http://
825 **
 
 
 
 
826 ** Additional subcommands may be added in the future.
827 */
828 void chat_command(void){
829 const char *zUrl = find_option("remote",0,1);
830 int urlFlags = 0;
@@ -948,11 +969,11 @@
948 }
949 fossil_fatal("unable to send the chat message");
950 }
951 blob_reset(&down);
952 }else if( strcmp(g.argv[2],"url")==0 ){
953 /* Undocumented command. Show the URL to access chat. */
954 fossil_print("%s/chat\n", zUrl);
955 }else{
956 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
957 }
958 }
959
--- 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 */
@@ -804,27 +818,34 @@
818 ** URL shows when you run the "fossil remote" command) or to the URL
819 ** specified by the --remote option. If there is no default remote
820 ** Fossil repository and the --remote option is omitted, then this
821 ** command fails with an error.
822 **
823 ** Subcommands:
824 **
825 ** > fossil chat
 
 
826 **
827 ** When there is no SUBCOMMAND (when this command is simply "fossil chat")
828 ** the response is to bring up a web-browser window to the chatroom
829 ** on the default system web-browser. You can accomplish the same by
830 ** typing the appropriate URL into the web-browser yourself. This
831 ** command is merely a convenience for command-line oriented people.
832 **
833 ** > fossil chat send [ARGUMENTS]
834 **
835 ** This command sends a new message to the chatroom. The message
836 ** to be sent is determined by arguments as follows:
837 **
838 ** -f|--file FILENAME File to attach to the message
839 ** -m|--message TEXT Text of the chat message
840 ** --remote URL Send to this remote URL
841 ** --unsafe Allow the use of unencrypted http://
842 **
843 ** > fossil chat url
844 **
845 ** Show the default URL used to access the chat server.
846 **
847 ** Additional subcommands may be added in the future.
848 */
849 void chat_command(void){
850 const char *zUrl = find_option("remote",0,1);
851 int urlFlags = 0;
@@ -948,11 +969,11 @@
969 }
970 fossil_fatal("unable to send the chat message");
971 }
972 blob_reset(&down);
973 }else if( strcmp(g.argv[2],"url")==0 ){
974 /* Show the URL to access chat. */
975 fossil_print("%s/chat\n", zUrl);
976 }else{
977 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
978 }
979 }
980
+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
+71 -6
--- 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();
@@ -3582,11 +3637,13 @@
35823637
&& bForce==0
35833638
&& (nLocal = file_directory_size(".", 0, 1))>0
35843639
&& (nLocal>1 || isUri || !file_in_cwd(zRepo))
35853640
){
35863641
fossil_fatal("directory %s is not empty\n"
3587
- "use the -f or --force option to override", file_getcwd(0,0));
3642
+ "use the -f (--force) option to override\n"
3643
+ "or the -k (--keep) option to keep local files unchanged",
3644
+ file_getcwd(0,0));
35883645
}
35893646
35903647
if( db_open_local_v2(0, allowNested) ){
35913648
fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
35923649
}
@@ -3609,10 +3666,13 @@
36093666
zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
36103667
fossil_free(zNewBase);
36113668
blob_init(&cmd, 0, 0);
36123669
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
36133670
blob_append(&cmd, " clone", -1);
3671
+ if(0!=bVerbose){
3672
+ blob_append(&cmd, " --verbose", -1);
3673
+ }
36143674
blob_append_escaped_arg(&cmd, zUri, 1);
36153675
blob_append_escaped_arg(&cmd, zRepo, 1);
36163676
zCmd = blob_str(&cmd);
36173677
fossil_print("%s\n", zCmd);
36183678
if( zWorkDir ) file_chdir(zPwd, 0);
@@ -3807,15 +3867,20 @@
38073867
** If enabled, automatically pull the shunning list
38083868
** from a server to which the client autosyncs.
38093869
*/
38103870
/*
38113871
** SETTING: autosync width=16 default=on
3812
-** This setting can take either a boolean value or "pullonly"
3813
-** If enabled, automatically pull prior to commit
3872
+** This setting can be a boolean value (0, 1, on, off, true, false)
3873
+** or "pullonly" or "all".
3874
+**
3875
+** If not false, automatically pull prior to commit
38143876
** or update and automatically push after commit or
3815
-** tag or branch creation. If the value is "pullonly"
3816
-** then only pull operations occur automatically.
3877
+** tag or branch creation. Except, if the value is
3878
+** "pullonly" then only pull operations occur automatically.
3879
+** Normally, only the default remote is used, but if the
3880
+** value is "all" then push/pull operations occur on all
3881
+** remotes.
38173882
*/
38183883
/*
38193884
** SETTING: autosync-tries width=16 default=1
38203885
** If autosync is enabled setting this to a value greater
38213886
** than zero will cause autosync to try no more than this
38223887
--- 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();
@@ -3582,11 +3637,13 @@
3582 && bForce==0
3583 && (nLocal = file_directory_size(".", 0, 1))>0
3584 && (nLocal>1 || isUri || !file_in_cwd(zRepo))
3585 ){
3586 fossil_fatal("directory %s is not empty\n"
3587 "use the -f or --force option to override", file_getcwd(0,0));
 
 
3588 }
3589
3590 if( db_open_local_v2(0, allowNested) ){
3591 fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
3592 }
@@ -3609,10 +3666,13 @@
3609 zRepo = mprintf("%s/%s.fossil", zRepoDir, zNewBase);
3610 fossil_free(zNewBase);
3611 blob_init(&cmd, 0, 0);
3612 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
3613 blob_append(&cmd, " clone", -1);
 
 
 
3614 blob_append_escaped_arg(&cmd, zUri, 1);
3615 blob_append_escaped_arg(&cmd, zRepo, 1);
3616 zCmd = blob_str(&cmd);
3617 fossil_print("%s\n", zCmd);
3618 if( zWorkDir ) file_chdir(zPwd, 0);
@@ -3807,15 +3867,20 @@
3807 ** If enabled, automatically pull the shunning list
3808 ** from a server to which the client autosyncs.
3809 */
3810 /*
3811 ** SETTING: autosync width=16 default=on
3812 ** This setting can take either a boolean value or "pullonly"
3813 ** If enabled, automatically pull prior to commit
 
 
3814 ** or update and automatically push after commit or
3815 ** tag or branch creation. If the value is "pullonly"
3816 ** then only pull operations occur automatically.
 
 
 
3817 */
3818 /*
3819 ** SETTING: autosync-tries width=16 default=1
3820 ** If autosync is enabled setting this to a value greater
3821 ** than zero will cause autosync to try no more than this
3822
--- 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();
@@ -3582,11 +3637,13 @@
3637 && bForce==0
3638 && (nLocal = file_directory_size(".", 0, 1))>0
3639 && (nLocal>1 || isUri || !file_in_cwd(zRepo))
3640 ){
3641 fossil_fatal("directory %s is not empty\n"
3642 "use the -f (--force) option to override\n"
3643 "or the -k (--keep) option to keep local files unchanged",
3644 file_getcwd(0,0));
3645 }
3646
3647 if( db_open_local_v2(0, allowNested) ){
3648 fossil_fatal("there is already an open tree at %s", g.zLocalRoot);
3649 }
@@ -3609,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);
@@ -3807,15 +3867,20 @@
3867 ** If enabled, automatically pull the shunning list
3868 ** from a server to which the client autosyncs.
3869 */
3870 /*
3871 ** SETTING: autosync width=16 default=on
3872 ** This setting can be a boolean value (0, 1, on, off, true, false)
3873 ** or "pullonly" or "all".
3874 **
3875 ** If not false, automatically pull prior to commit
3876 ** or update and automatically push after commit or
3877 ** tag or branch creation. Except, if the value is
3878 ** "pullonly" then only pull operations occur automatically.
3879 ** Normally, only the default remote is used, but if the
3880 ** value is "all" then push/pull operations occur on all
3881 ** remotes.
3882 */
3883 /*
3884 ** SETTING: autosync-tries width=16 default=1
3885 ** If autosync is enabled setting this to a value greater
3886 ** than zero will cause autosync to try no more than this
3887
--- src/http_socket.c
+++ src/http_socket.c
@@ -243,13 +243,16 @@
243243
*/
244244
void socket_ssh_resolve_addr(UrlData *pUrlData){
245245
struct addrinfo *ai = 0;
246246
struct addrinfo hints;
247247
char zRemote[NI_MAXHOST];
248
+ memset(&hints, 0, sizeof(hints));
248249
hints.ai_family = AF_UNSPEC;
249250
hints.ai_socktype = SOCK_STREAM;
250251
hints.ai_protocol = IPPROTO_TCP;
252
+ fossil_free(g.zIpAddr);
253
+ g.zIpAddr = 0;
251254
if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0
252255
&& ai!=0
253256
&& getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote,
254257
sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){
255258
g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name);
256259
--- src/http_socket.c
+++ src/http_socket.c
@@ -243,13 +243,16 @@
243 */
244 void socket_ssh_resolve_addr(UrlData *pUrlData){
245 struct addrinfo *ai = 0;
246 struct addrinfo hints;
247 char zRemote[NI_MAXHOST];
 
248 hints.ai_family = AF_UNSPEC;
249 hints.ai_socktype = SOCK_STREAM;
250 hints.ai_protocol = IPPROTO_TCP;
 
 
251 if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0
252 && ai!=0
253 && getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote,
254 sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){
255 g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name);
256
--- src/http_socket.c
+++ src/http_socket.c
@@ -243,13 +243,16 @@
243 */
244 void socket_ssh_resolve_addr(UrlData *pUrlData){
245 struct addrinfo *ai = 0;
246 struct addrinfo hints;
247 char zRemote[NI_MAXHOST];
248 memset(&hints, 0, sizeof(hints));
249 hints.ai_family = AF_UNSPEC;
250 hints.ai_socktype = SOCK_STREAM;
251 hints.ai_protocol = IPPROTO_TCP;
252 fossil_free(g.zIpAddr);
253 g.zIpAddr = 0;
254 if( getaddrinfo(pUrlData->name, NULL, &hints, &ai)==0
255 && ai!=0
256 && getnameinfo(ai->ai_addr, ai->ai_addrlen, zRemote,
257 sizeof(zRemote), 0, 0, NI_NUMERICHOST)==0 ){
258 g.zIpAddr = mprintf("%s (%s)", zRemote, pUrlData->name);
259
+57 -5
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -89,10 +89,50 @@
8989
"authentication. Specify the pathname to a file containing the PEM "
9090
"encoded certificate and private key with the --ssl-identity option "
9191
"or the ssl-identity setting.");
9292
return 0; /* no cert available */
9393
}
94
+
95
+/*
96
+** Convert an OpenSSL ASN1_TIME to an ISO8601 timestamp.
97
+**
98
+** Per RFC 5280, ASN1 timestamps in X.509 certificates must
99
+** be in UTC (Zulu timezone) with no fractional seconds.
100
+**
101
+** If showUtc==1, add " UTC" at the end of the returned string. This is
102
+** not ISO8601-compliant, but makes the displayed value more user-friendly.
103
+*/
104
+static const char *ssl_asn1time_to_iso8601(ASN1_TIME *asn1_time,
105
+ int showUtc){
106
+ assert( showUtc==0 || showUtc==1 );
107
+ if( !ASN1_TIME_check(asn1_time) ){
108
+ return mprintf("Bad time value");
109
+ }else{
110
+ char res[20];
111
+ char *pr = res;
112
+ const char *pt = (char *)asn1_time->data;
113
+ /* 0123456789 1234
114
+ ** UTCTime: YYMMDDHHMMSSZ (YY >= 50 ? 19YY : 20YY)
115
+ ** GeneralizedTime: YYYYMMDDHHMMSSZ */
116
+ if( asn1_time->length < 15 ){
117
+ /* UTCTime, fill out century digits */
118
+ *pr++ = pt[0]>='5' ? '1' : '2';
119
+ *pr++ = pt[0]>='5' ? '9' : '0';
120
+ }else{
121
+ /* GeneralizedTime, copy century digits and advance source */
122
+ *pr++ = pt[0]; *pr++ = pt[1];
123
+ pt += 2;
124
+ }
125
+ *pr++ = pt[0]; *pr++ = pt[1]; *pr++ = '-';
126
+ *pr++ = pt[2]; *pr++ = pt[3]; *pr++ = '-';
127
+ *pr++ = pt[4]; *pr++ = pt[5]; *pr++ = ' ';
128
+ *pr++ = pt[6]; *pr++ = pt[7]; *pr++ = ':';
129
+ *pr++ = pt[8]; *pr++ = pt[9]; *pr++ = ':';
130
+ *pr++ = pt[10]; *pr++ = pt[11]; *pr = '\0';
131
+ return mprintf("%s%s", res, (showUtc ? " UTC" : ""));
132
+ }
133
+}
94134
95135
/*
96136
** Call this routine once before any other use of the SSL interface.
97137
** This routine does initial configuration of the SSL module.
98138
*/
@@ -101,11 +141,10 @@
101141
const char *identityFile;
102142
103143
if( sslIsInit==0 ){
104144
SSL_library_init();
105145
SSL_load_error_strings();
106
- ERR_load_BIO_strings();
107146
OpenSSL_add_all_algorithms();
108147
sslCtx = SSL_CTX_new(SSLv23_client_method());
109148
/* Disable SSLv2 and SSLv3 */
110149
SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
111150
@@ -338,10 +377,17 @@
338377
ssl_set_errmsg("No SSL certificate was presented by the peer");
339378
ssl_close();
340379
return 1;
341380
}
342381
382
+ /* Debugging hint: On unix-like system, run something like:
383
+ **
384
+ ** SSL_CERT_DIR=/tmp ./fossil sync
385
+ **
386
+ ** to cause certificate validation to fail, and thus test the fallback
387
+ ** logic.
388
+ */
343389
if( !sslNoCertVerify && SSL_get_verify_result(ssl)!=X509_V_OK ){
344390
int x, desclen;
345391
char *desc, *prompt;
346392
Blob ans;
347393
char cReply;
@@ -371,15 +417,19 @@
371417
/* Ignore the failure because an exception exists */
372418
ssl_one_time_exception(pUrlData, zHash);
373419
}else{
374420
/* Tell the user about the failure and ask what to do */
375421
mem = BIO_new(BIO_s_mem());
376
- BIO_puts(mem, " subject: ");
422
+ BIO_puts(mem, " subject: ");
377423
X509_NAME_print_ex(mem, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE);
378
- BIO_puts(mem, "\n issuer: ");
424
+ BIO_puts(mem, "\n issuer: ");
379425
X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE);
380
- BIO_printf(mem, "\n sha256: %s", zHash);
426
+ BIO_printf(mem, "\n notBefore: %s",
427
+ ssl_asn1time_to_iso8601(X509_get_notBefore(cert), 1));
428
+ BIO_printf(mem, "\n notAfter: %s",
429
+ ssl_asn1time_to_iso8601(X509_get_notAfter(cert), 1));
430
+ BIO_printf(mem, "\n sha256: %s", zHash);
381431
desclen = BIO_get_mem_data(mem, &desc);
382432
383433
prompt = mprintf("Unable to verify SSL cert from %s\n%.*s\n"
384434
"accept this cert and continue (y/N/fingerprint)? ",
385435
pUrlData->name, desclen, desc);
@@ -386,11 +436,13 @@
386436
BIO_free(mem);
387437
388438
prompt_user(prompt, &ans);
389439
free(prompt);
390440
cReply = blob_str(&ans)[0];
391
- if( cReply!='y' && cReply!='Y' && fossil_stricmp(blob_str(&ans),zHash)!=0 ){
441
+ if( cReply!='y' && cReply!='Y'
442
+ && fossil_stricmp(blob_str(&ans),zHash)!=0
443
+ ){
392444
X509_free(cert);
393445
ssl_set_errmsg("SSL cert declined");
394446
ssl_close();
395447
blob_reset(&ans);
396448
return 1;
397449
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -89,10 +89,50 @@
89 "authentication. Specify the pathname to a file containing the PEM "
90 "encoded certificate and private key with the --ssl-identity option "
91 "or the ssl-identity setting.");
92 return 0; /* no cert available */
93 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
95 /*
96 ** Call this routine once before any other use of the SSL interface.
97 ** This routine does initial configuration of the SSL module.
98 */
@@ -101,11 +141,10 @@
101 const char *identityFile;
102
103 if( sslIsInit==0 ){
104 SSL_library_init();
105 SSL_load_error_strings();
106 ERR_load_BIO_strings();
107 OpenSSL_add_all_algorithms();
108 sslCtx = SSL_CTX_new(SSLv23_client_method());
109 /* Disable SSLv2 and SSLv3 */
110 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
111
@@ -338,10 +377,17 @@
338 ssl_set_errmsg("No SSL certificate was presented by the peer");
339 ssl_close();
340 return 1;
341 }
342
 
 
 
 
 
 
 
343 if( !sslNoCertVerify && SSL_get_verify_result(ssl)!=X509_V_OK ){
344 int x, desclen;
345 char *desc, *prompt;
346 Blob ans;
347 char cReply;
@@ -371,15 +417,19 @@
371 /* Ignore the failure because an exception exists */
372 ssl_one_time_exception(pUrlData, zHash);
373 }else{
374 /* Tell the user about the failure and ask what to do */
375 mem = BIO_new(BIO_s_mem());
376 BIO_puts(mem, " subject: ");
377 X509_NAME_print_ex(mem, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE);
378 BIO_puts(mem, "\n issuer: ");
379 X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE);
380 BIO_printf(mem, "\n sha256: %s", zHash);
 
 
 
 
381 desclen = BIO_get_mem_data(mem, &desc);
382
383 prompt = mprintf("Unable to verify SSL cert from %s\n%.*s\n"
384 "accept this cert and continue (y/N/fingerprint)? ",
385 pUrlData->name, desclen, desc);
@@ -386,11 +436,13 @@
386 BIO_free(mem);
387
388 prompt_user(prompt, &ans);
389 free(prompt);
390 cReply = blob_str(&ans)[0];
391 if( cReply!='y' && cReply!='Y' && fossil_stricmp(blob_str(&ans),zHash)!=0 ){
 
 
392 X509_free(cert);
393 ssl_set_errmsg("SSL cert declined");
394 ssl_close();
395 blob_reset(&ans);
396 return 1;
397
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -89,10 +89,50 @@
89 "authentication. Specify the pathname to a file containing the PEM "
90 "encoded certificate and private key with the --ssl-identity option "
91 "or the ssl-identity setting.");
92 return 0; /* no cert available */
93 }
94
95 /*
96 ** Convert an OpenSSL ASN1_TIME to an ISO8601 timestamp.
97 **
98 ** Per RFC 5280, ASN1 timestamps in X.509 certificates must
99 ** be in UTC (Zulu timezone) with no fractional seconds.
100 **
101 ** If showUtc==1, add " UTC" at the end of the returned string. This is
102 ** not ISO8601-compliant, but makes the displayed value more user-friendly.
103 */
104 static const char *ssl_asn1time_to_iso8601(ASN1_TIME *asn1_time,
105 int showUtc){
106 assert( showUtc==0 || showUtc==1 );
107 if( !ASN1_TIME_check(asn1_time) ){
108 return mprintf("Bad time value");
109 }else{
110 char res[20];
111 char *pr = res;
112 const char *pt = (char *)asn1_time->data;
113 /* 0123456789 1234
114 ** UTCTime: YYMMDDHHMMSSZ (YY >= 50 ? 19YY : 20YY)
115 ** GeneralizedTime: YYYYMMDDHHMMSSZ */
116 if( asn1_time->length < 15 ){
117 /* UTCTime, fill out century digits */
118 *pr++ = pt[0]>='5' ? '1' : '2';
119 *pr++ = pt[0]>='5' ? '9' : '0';
120 }else{
121 /* GeneralizedTime, copy century digits and advance source */
122 *pr++ = pt[0]; *pr++ = pt[1];
123 pt += 2;
124 }
125 *pr++ = pt[0]; *pr++ = pt[1]; *pr++ = '-';
126 *pr++ = pt[2]; *pr++ = pt[3]; *pr++ = '-';
127 *pr++ = pt[4]; *pr++ = pt[5]; *pr++ = ' ';
128 *pr++ = pt[6]; *pr++ = pt[7]; *pr++ = ':';
129 *pr++ = pt[8]; *pr++ = pt[9]; *pr++ = ':';
130 *pr++ = pt[10]; *pr++ = pt[11]; *pr = '\0';
131 return mprintf("%s%s", res, (showUtc ? " UTC" : ""));
132 }
133 }
134
135 /*
136 ** Call this routine once before any other use of the SSL interface.
137 ** This routine does initial configuration of the SSL module.
138 */
@@ -101,11 +141,10 @@
141 const char *identityFile;
142
143 if( sslIsInit==0 ){
144 SSL_library_init();
145 SSL_load_error_strings();
 
146 OpenSSL_add_all_algorithms();
147 sslCtx = SSL_CTX_new(SSLv23_client_method());
148 /* Disable SSLv2 and SSLv3 */
149 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);
150
@@ -338,10 +377,17 @@
377 ssl_set_errmsg("No SSL certificate was presented by the peer");
378 ssl_close();
379 return 1;
380 }
381
382 /* Debugging hint: On unix-like system, run something like:
383 **
384 ** SSL_CERT_DIR=/tmp ./fossil sync
385 **
386 ** to cause certificate validation to fail, and thus test the fallback
387 ** logic.
388 */
389 if( !sslNoCertVerify && SSL_get_verify_result(ssl)!=X509_V_OK ){
390 int x, desclen;
391 char *desc, *prompt;
392 Blob ans;
393 char cReply;
@@ -371,15 +417,19 @@
417 /* Ignore the failure because an exception exists */
418 ssl_one_time_exception(pUrlData, zHash);
419 }else{
420 /* Tell the user about the failure and ask what to do */
421 mem = BIO_new(BIO_s_mem());
422 BIO_puts(mem, " subject: ");
423 X509_NAME_print_ex(mem, X509_get_subject_name(cert), 0, XN_FLAG_ONELINE);
424 BIO_puts(mem, "\n issuer: ");
425 X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 0, XN_FLAG_ONELINE);
426 BIO_printf(mem, "\n notBefore: %s",
427 ssl_asn1time_to_iso8601(X509_get_notBefore(cert), 1));
428 BIO_printf(mem, "\n notAfter: %s",
429 ssl_asn1time_to_iso8601(X509_get_notAfter(cert), 1));
430 BIO_printf(mem, "\n sha256: %s", zHash);
431 desclen = BIO_get_mem_data(mem, &desc);
432
433 prompt = mprintf("Unable to verify SSL cert from %s\n%.*s\n"
434 "accept this cert and continue (y/N/fingerprint)? ",
435 pUrlData->name, desclen, desc);
@@ -386,11 +436,13 @@
436 BIO_free(mem);
437
438 prompt_user(prompt, &ans);
439 free(prompt);
440 cReply = blob_str(&ans)[0];
441 if( cReply!='y' && cReply!='Y'
442 && fossil_stricmp(blob_str(&ans),zHash)!=0
443 ){
444 X509_free(cert);
445 ssl_set_errmsg("SSL cert declined");
446 ssl_close();
447 blob_reset(&ans);
448 return 1;
449
--- 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
+2 -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);
@@ -3307,11 +3308,11 @@
33073308
@ <input type="checkbox" name="pclr" />
33083309
}
33093310
@ Propagate color to descendants</label></div>
33103311
@ <div class='font-size-80'>Be aware that fixed background
33113312
@ colors will not interact well with all available skins.
3312
- @ It is recommended that fossil be allowed to select these
3313
+ @ It is recommended that Fossil be allowed to select these
33133314
@ colors automatically so that it can take the skin's
33143315
@ preferences into account.</div>
33153316
@ </td></tr>
33163317
33173318
@ <tr><th align="right" valign="top">Tags:</th>
33183319
--- 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);
@@ -3307,11 +3308,11 @@
3307 @ <input type="checkbox" name="pclr" />
3308 }
3309 @ Propagate color to descendants</label></div>
3310 @ <div class='font-size-80'>Be aware that fixed background
3311 @ colors will not interact well with all available skins.
3312 @ It is recommended that fossil be allowed to select these
3313 @ colors automatically so that it can take the skin's
3314 @ preferences into account.</div>
3315 @ </td></tr>
3316
3317 @ <tr><th align="right" valign="top">Tags:</th>
3318
--- 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);
@@ -3307,11 +3308,11 @@
3308 @ <input type="checkbox" name="pclr" />
3309 }
3310 @ Propagate color to descendants</label></div>
3311 @ <div class='font-size-80'>Be aware that fixed background
3312 @ colors will not interact well with all available skins.
3313 @ It is recommended that Fossil be allowed to select these
3314 @ colors automatically so that it can take the skin's
3315 @ preferences into account.</div>
3316 @ </td></tr>
3317
3318 @ <tr><th align="right" valign="top">Tags:</th>
3319
+4 -1
--- src/md5.c
+++ src/md5.c
@@ -22,11 +22,14 @@
2222
#include <string.h>
2323
#include <stdio.h>
2424
#include <sqlite3.h>
2525
#include "md5.h"
2626
27
-#ifdef FOSSIL_ENABLE_SSL
27
+#if 0 /* defined FOSSIL_ENABLE_SSL */
28
+
29
+/* MD5 is deprecated in OpenSSL. So we have to fall back to our own
30
+** implementation */
2831
2932
# include <openssl/md5.h>
3033
# define MD5Context MD5_CTX
3134
# define MD5Init MD5_Init
3235
# define MD5Update MD5_Update
3336
--- src/md5.c
+++ src/md5.c
@@ -22,11 +22,14 @@
22 #include <string.h>
23 #include <stdio.h>
24 #include <sqlite3.h>
25 #include "md5.h"
26
27 #ifdef FOSSIL_ENABLE_SSL
 
 
 
28
29 # include <openssl/md5.h>
30 # define MD5Context MD5_CTX
31 # define MD5Init MD5_Init
32 # define MD5Update MD5_Update
33
--- src/md5.c
+++ src/md5.c
@@ -22,11 +22,14 @@
22 #include <string.h>
23 #include <stdio.h>
24 #include <sqlite3.h>
25 #include "md5.h"
26
27 #if 0 /* defined FOSSIL_ENABLE_SSL */
28
29 /* MD5 is deprecated in OpenSSL. So we have to fall back to our own
30 ** implementation */
31
32 # include <openssl/md5.h>
33 # define MD5Context MD5_CTX
34 # define MD5Init MD5_Init
35 # define MD5Update MD5_Update
36
+47 -37
--- src/merge3.c
+++ src/merge3.c
@@ -116,21 +116,22 @@
116116
static int output_one_side(
117117
Blob *pOut, /* Write to this blob */
118118
Blob *pSrc, /* The edited file that is to be copied to pOut */
119119
int *aC, /* Array of integer triples describing the edit */
120120
int i, /* Index in aC[] of current location in pSrc */
121
- int sz /* Number of lines in unedited source to output */
121
+ int sz, /* Number of lines in unedited source to output */
122
+ int *pLn /* Line number counter */
122123
){
123124
while( sz>0 ){
124125
if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
125126
if( aC[i]>=sz ){
126
- blob_copy_lines(pOut, pSrc, sz);
127
+ blob_copy_lines(pOut, pSrc, sz); *pLn += sz;
127128
aC[i] -= sz;
128129
break;
129130
}
130
- blob_copy_lines(pOut, pSrc, aC[i]);
131
- blob_copy_lines(pOut, pSrc, aC[i+2]);
131
+ blob_copy_lines(pOut, pSrc, aC[i]); *pLn += aC[i];
132
+ blob_copy_lines(pOut, pSrc, aC[i+2]); *pLn += aC[i+2];
132133
sz -= aC[i] + aC[i+1];
133134
i += 3;
134135
}
135136
return i;
136137
}
@@ -138,14 +139,14 @@
138139
/*
139140
** Text of boundary markers for merge conflicts.
140141
*/
141142
static const char *const mergeMarker[] = {
142143
/*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
143
- "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<",
144
- "||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||||||",
145
- "======= MERGED IN content follows ==================================",
146
- ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
144
+ "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<",
145
+ "||||||| COMMON ANCESTOR content follows |||||||||||||||||||||||||",
146
+ "======= MERGED IN content follows ===============================",
147
+ ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
147148
};
148149
149150
/*
150151
** Return true if the input blob contains any CR/LF pairs on the first
151152
** ten lines. This should be enough to detect files that use mainly CR/LF
@@ -175,10 +176,20 @@
175176
if( pBlob->aData[pBlob->nUsed-1]!='\n' ){
176177
if( useCrLf ) blob_append_char(pBlob, '\r');
177178
blob_append_char(pBlob, '\n');
178179
}
179180
}
181
+
182
+/*
183
+** Write out one of the four merge-marks.
184
+*/
185
+void append_merge_mark(Blob *pOut, int iMark, int ln, int useCrLf){
186
+ ensure_line_end(pOut, useCrLf);
187
+ blob_append(pOut, mergeMarker[iMark], -1);
188
+ if( ln>0 ) blob_appendf(pOut, " (line %d)", ln);
189
+ ensure_line_end(pOut, useCrLf);
190
+}
180191
181192
/*
182193
** Do a three-way merge. Initialize pOut to contain the result.
183194
**
184195
** The merge is an edit against pV2. Both pV1 and pV2 have a
@@ -196,10 +207,11 @@
196207
int i1, i2; /* Index into aC1[] and aC2[] */
197208
int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */
198209
int limit1, limit2; /* Sizes of aC1[] and aC2[] */
199210
int nConflict = 0; /* Number of merge conflicts seen so far */
200211
int useCrLf = 0;
212
+ int ln1, ln2, lnPivot; /* Line numbers for all files */
201213
DiffConfig DCfg;
202214
203215
blob_zero(pOut); /* Merge results stored in pOut */
204216
205217
/* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
@@ -259,56 +271,57 @@
259271
** which is written into pOut. i1 and i2 are multiples of 3 which are
260272
** indices into aC1[] and aC2[] to the edit triple currently being
261273
** processed
262274
*/
263275
i1 = i2 = 0;
276
+ ln1 = ln2 = lnPivot = 1;
264277
while( i1<limit1 && i2<limit2 ){
265278
DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
266279
i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
267280
i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
268281
269282
if( aC1[i1]>0 && aC2[i2]>0 ){
270283
/* Output text that is unchanged in both V1 and V2 */
271284
nCpy = min(aC1[i1], aC2[i2]);
272285
DEBUG( printf("COPY %d\n", nCpy); )
273
- blob_copy_lines(pOut, pPivot, nCpy);
274
- blob_copy_lines(0, pV1, nCpy);
275
- blob_copy_lines(0, pV2, nCpy);
286
+ blob_copy_lines(pOut, pPivot, nCpy); lnPivot += nCpy;
287
+ blob_copy_lines(0, pV1, nCpy); ln1 += nCpy;
288
+ blob_copy_lines(0, pV2, nCpy); ln2 += nCpy;
276289
aC1[i1] -= nCpy;
277290
aC2[i2] -= nCpy;
278291
}else
279292
if( aC1[i1] >= aC2[i2+1] && aC1[i1]>0 && aC2[i2+1]+aC2[i2+2]>0 ){
280293
/* Output edits to V2 that occurs within unchanged regions of V1 */
281294
nDel = aC2[i2+1];
282295
nIns = aC2[i2+2];
283296
DEBUG( printf("EDIT -%d+%d left\n", nDel, nIns); )
284
- blob_copy_lines(0, pPivot, nDel);
285
- blob_copy_lines(0, pV1, nDel);
286
- blob_copy_lines(pOut, pV2, nIns);
297
+ blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
298
+ blob_copy_lines(0, pV1, nDel); ln1 += nDel;
299
+ blob_copy_lines(pOut, pV2, nIns); ln2 += nIns;
287300
aC1[i1] -= nDel;
288301
i2 += 3;
289302
}else
290303
if( aC2[i2] >= aC1[i1+1] && aC2[i2]>0 && aC1[i1+1]+aC1[i1+2]>0 ){
291304
/* Output edits to V1 that occur within unchanged regions of V2 */
292305
nDel = aC1[i1+1];
293306
nIns = aC1[i1+2];
294307
DEBUG( printf("EDIT -%d+%d right\n", nDel, nIns); )
295
- blob_copy_lines(0, pPivot, nDel);
296
- blob_copy_lines(0, pV2, nDel);
297
- blob_copy_lines(pOut, pV1, nIns);
308
+ blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
309
+ blob_copy_lines(0, pV2, nDel); ln2 += nDel;
310
+ blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
298311
aC2[i2] -= nDel;
299312
i1 += 3;
300313
}else
301314
if( sameEdit(&aC1[i1], &aC2[i2], pV1, pV2) ){
302315
/* Output edits that are identical in both V1 and V2. */
303316
assert( aC1[i1]==0 );
304317
nDel = aC1[i1+1];
305318
nIns = aC1[i1+2];
306319
DEBUG( printf("EDIT -%d+%d both\n", nDel, nIns); )
307
- blob_copy_lines(0, pPivot, nDel);
308
- blob_copy_lines(pOut, pV1, nIns);
309
- blob_copy_lines(0, pV2, nIns);
320
+ blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
321
+ blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
322
+ blob_copy_lines(0, pV2, nIns); ln2 += nIns;
310323
i1 += 3;
311324
i2 += 3;
312325
}else
313326
{
314327
/* We have found a region where different edits to V1 and V2 overlap.
@@ -319,25 +332,21 @@
319332
nConflict++;
320333
while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
321334
sz++;
322335
}
323336
DEBUG( printf("CONFLICT %d\n", sz); )
324
- ensure_line_end(pOut, useCrLf);
325
- blob_append(pOut, mergeMarker[0], -1);
326
- ensure_line_end(pOut, useCrLf);
327
- i1 = output_one_side(pOut, pV1, aC1, i1, sz);
328
- ensure_line_end(pOut, useCrLf);
329
- blob_append(pOut, mergeMarker[1], -1);
330
- ensure_line_end(pOut, useCrLf);
331
- blob_copy_lines(pOut, pPivot, sz);
332
- ensure_line_end(pOut, useCrLf);
333
- blob_append(pOut, mergeMarker[2], -1);
334
- ensure_line_end(pOut, useCrLf);
335
- i2 = output_one_side(pOut, pV2, aC2, i2, sz);
336
- ensure_line_end(pOut, useCrLf);
337
- blob_append(pOut, mergeMarker[3], -1);
338
- ensure_line_end(pOut, useCrLf);
337
+
338
+ append_merge_mark(pOut, 0, ln1, useCrLf);
339
+ i1 = output_one_side(pOut, pV1, aC1, i1, sz, &ln1);
340
+
341
+ append_merge_mark(pOut, 1, lnPivot, useCrLf);
342
+ blob_copy_lines(pOut, pPivot, sz); lnPivot += sz;
343
+
344
+ append_merge_mark(pOut, 2, ln2, useCrLf);
345
+ i2 = output_one_side(pOut, pV2, aC2, i2, sz, &ln2);
346
+
347
+ append_merge_mark(pOut, 3, -1, useCrLf);
339348
}
340349
341350
/* If we are finished with an edit triple, advance to the next
342351
** triple.
343352
*/
@@ -378,12 +387,13 @@
378387
assert( len==(int)strlen(mergeMarker[2]) );
379388
assert( len==(int)strlen(mergeMarker[3]) );
380389
assert( count(mergeMarker)==4 );
381390
for(i=0; i<n; ){
382391
for(j=0; j<4; j++){
383
- if( (memcmp(&z[i], mergeMarker[j], len)==0)
384
- && (i+1==n || z[i+len]=='\n' || z[i+len]=='\r') ) return 1;
392
+ if( (memcmp(&z[i], mergeMarker[j], len)==0) ){
393
+ return 1;
394
+ }
385395
}
386396
while( i<n && z[i]!='\n' ){ i++; }
387397
while( i<n && (z[i]=='\n' || z[i]=='\r') ){ i++; }
388398
}
389399
return 0;
390400
--- src/merge3.c
+++ src/merge3.c
@@ -116,21 +116,22 @@
116 static int output_one_side(
117 Blob *pOut, /* Write to this blob */
118 Blob *pSrc, /* The edited file that is to be copied to pOut */
119 int *aC, /* Array of integer triples describing the edit */
120 int i, /* Index in aC[] of current location in pSrc */
121 int sz /* Number of lines in unedited source to output */
 
122 ){
123 while( sz>0 ){
124 if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
125 if( aC[i]>=sz ){
126 blob_copy_lines(pOut, pSrc, sz);
127 aC[i] -= sz;
128 break;
129 }
130 blob_copy_lines(pOut, pSrc, aC[i]);
131 blob_copy_lines(pOut, pSrc, aC[i+2]);
132 sz -= aC[i] + aC[i+1];
133 i += 3;
134 }
135 return i;
136 }
@@ -138,14 +139,14 @@
138 /*
139 ** Text of boundary markers for merge conflicts.
140 */
141 static const char *const mergeMarker[] = {
142 /*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
143 "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<<<<",
144 "||||||| COMMON ANCESTOR content follows ||||||||||||||||||||||||||||",
145 "======= MERGED IN content follows ==================================",
146 ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
147 };
148
149 /*
150 ** Return true if the input blob contains any CR/LF pairs on the first
151 ** ten lines. This should be enough to detect files that use mainly CR/LF
@@ -175,10 +176,20 @@
175 if( pBlob->aData[pBlob->nUsed-1]!='\n' ){
176 if( useCrLf ) blob_append_char(pBlob, '\r');
177 blob_append_char(pBlob, '\n');
178 }
179 }
 
 
 
 
 
 
 
 
 
 
180
181 /*
182 ** Do a three-way merge. Initialize pOut to contain the result.
183 **
184 ** The merge is an edit against pV2. Both pV1 and pV2 have a
@@ -196,10 +207,11 @@
196 int i1, i2; /* Index into aC1[] and aC2[] */
197 int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */
198 int limit1, limit2; /* Sizes of aC1[] and aC2[] */
199 int nConflict = 0; /* Number of merge conflicts seen so far */
200 int useCrLf = 0;
 
201 DiffConfig DCfg;
202
203 blob_zero(pOut); /* Merge results stored in pOut */
204
205 /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
@@ -259,56 +271,57 @@
259 ** which is written into pOut. i1 and i2 are multiples of 3 which are
260 ** indices into aC1[] and aC2[] to the edit triple currently being
261 ** processed
262 */
263 i1 = i2 = 0;
 
264 while( i1<limit1 && i2<limit2 ){
265 DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
266 i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
267 i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
268
269 if( aC1[i1]>0 && aC2[i2]>0 ){
270 /* Output text that is unchanged in both V1 and V2 */
271 nCpy = min(aC1[i1], aC2[i2]);
272 DEBUG( printf("COPY %d\n", nCpy); )
273 blob_copy_lines(pOut, pPivot, nCpy);
274 blob_copy_lines(0, pV1, nCpy);
275 blob_copy_lines(0, pV2, nCpy);
276 aC1[i1] -= nCpy;
277 aC2[i2] -= nCpy;
278 }else
279 if( aC1[i1] >= aC2[i2+1] && aC1[i1]>0 && aC2[i2+1]+aC2[i2+2]>0 ){
280 /* Output edits to V2 that occurs within unchanged regions of V1 */
281 nDel = aC2[i2+1];
282 nIns = aC2[i2+2];
283 DEBUG( printf("EDIT -%d+%d left\n", nDel, nIns); )
284 blob_copy_lines(0, pPivot, nDel);
285 blob_copy_lines(0, pV1, nDel);
286 blob_copy_lines(pOut, pV2, nIns);
287 aC1[i1] -= nDel;
288 i2 += 3;
289 }else
290 if( aC2[i2] >= aC1[i1+1] && aC2[i2]>0 && aC1[i1+1]+aC1[i1+2]>0 ){
291 /* Output edits to V1 that occur within unchanged regions of V2 */
292 nDel = aC1[i1+1];
293 nIns = aC1[i1+2];
294 DEBUG( printf("EDIT -%d+%d right\n", nDel, nIns); )
295 blob_copy_lines(0, pPivot, nDel);
296 blob_copy_lines(0, pV2, nDel);
297 blob_copy_lines(pOut, pV1, nIns);
298 aC2[i2] -= nDel;
299 i1 += 3;
300 }else
301 if( sameEdit(&aC1[i1], &aC2[i2], pV1, pV2) ){
302 /* Output edits that are identical in both V1 and V2. */
303 assert( aC1[i1]==0 );
304 nDel = aC1[i1+1];
305 nIns = aC1[i1+2];
306 DEBUG( printf("EDIT -%d+%d both\n", nDel, nIns); )
307 blob_copy_lines(0, pPivot, nDel);
308 blob_copy_lines(pOut, pV1, nIns);
309 blob_copy_lines(0, pV2, nIns);
310 i1 += 3;
311 i2 += 3;
312 }else
313 {
314 /* We have found a region where different edits to V1 and V2 overlap.
@@ -319,25 +332,21 @@
319 nConflict++;
320 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
321 sz++;
322 }
323 DEBUG( printf("CONFLICT %d\n", sz); )
324 ensure_line_end(pOut, useCrLf);
325 blob_append(pOut, mergeMarker[0], -1);
326 ensure_line_end(pOut, useCrLf);
327 i1 = output_one_side(pOut, pV1, aC1, i1, sz);
328 ensure_line_end(pOut, useCrLf);
329 blob_append(pOut, mergeMarker[1], -1);
330 ensure_line_end(pOut, useCrLf);
331 blob_copy_lines(pOut, pPivot, sz);
332 ensure_line_end(pOut, useCrLf);
333 blob_append(pOut, mergeMarker[2], -1);
334 ensure_line_end(pOut, useCrLf);
335 i2 = output_one_side(pOut, pV2, aC2, i2, sz);
336 ensure_line_end(pOut, useCrLf);
337 blob_append(pOut, mergeMarker[3], -1);
338 ensure_line_end(pOut, useCrLf);
339 }
340
341 /* If we are finished with an edit triple, advance to the next
342 ** triple.
343 */
@@ -378,12 +387,13 @@
378 assert( len==(int)strlen(mergeMarker[2]) );
379 assert( len==(int)strlen(mergeMarker[3]) );
380 assert( count(mergeMarker)==4 );
381 for(i=0; i<n; ){
382 for(j=0; j<4; j++){
383 if( (memcmp(&z[i], mergeMarker[j], len)==0)
384 && (i+1==n || z[i+len]=='\n' || z[i+len]=='\r') ) return 1;
 
385 }
386 while( i<n && z[i]!='\n' ){ i++; }
387 while( i<n && (z[i]=='\n' || z[i]=='\r') ){ i++; }
388 }
389 return 0;
390
--- src/merge3.c
+++ src/merge3.c
@@ -116,21 +116,22 @@
116 static int output_one_side(
117 Blob *pOut, /* Write to this blob */
118 Blob *pSrc, /* The edited file that is to be copied to pOut */
119 int *aC, /* Array of integer triples describing the edit */
120 int i, /* Index in aC[] of current location in pSrc */
121 int sz, /* Number of lines in unedited source to output */
122 int *pLn /* Line number counter */
123 ){
124 while( sz>0 ){
125 if( aC[i]==0 && aC[i+1]==0 && aC[i+2]==0 ) break;
126 if( aC[i]>=sz ){
127 blob_copy_lines(pOut, pSrc, sz); *pLn += sz;
128 aC[i] -= sz;
129 break;
130 }
131 blob_copy_lines(pOut, pSrc, aC[i]); *pLn += aC[i];
132 blob_copy_lines(pOut, pSrc, aC[i+2]); *pLn += aC[i+2];
133 sz -= aC[i] + aC[i+1];
134 i += 3;
135 }
136 return i;
137 }
@@ -138,14 +139,14 @@
139 /*
140 ** Text of boundary markers for merge conflicts.
141 */
142 static const char *const mergeMarker[] = {
143 /*123456789 123456789 123456789 123456789 123456789 123456789 123456789*/
144 "<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <<<<<<<<<<<<",
145 "||||||| COMMON ANCESTOR content follows |||||||||||||||||||||||||",
146 "======= MERGED IN content follows ===============================",
147 ">>>>>>> END MERGE CONFLICT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
148 };
149
150 /*
151 ** Return true if the input blob contains any CR/LF pairs on the first
152 ** ten lines. This should be enough to detect files that use mainly CR/LF
@@ -175,10 +176,20 @@
176 if( pBlob->aData[pBlob->nUsed-1]!='\n' ){
177 if( useCrLf ) blob_append_char(pBlob, '\r');
178 blob_append_char(pBlob, '\n');
179 }
180 }
181
182 /*
183 ** Write out one of the four merge-marks.
184 */
185 void append_merge_mark(Blob *pOut, int iMark, int ln, int useCrLf){
186 ensure_line_end(pOut, useCrLf);
187 blob_append(pOut, mergeMarker[iMark], -1);
188 if( ln>0 ) blob_appendf(pOut, " (line %d)", ln);
189 ensure_line_end(pOut, useCrLf);
190 }
191
192 /*
193 ** Do a three-way merge. Initialize pOut to contain the result.
194 **
195 ** The merge is an edit against pV2. Both pV1 and pV2 have a
@@ -196,10 +207,11 @@
207 int i1, i2; /* Index into aC1[] and aC2[] */
208 int nCpy, nDel, nIns; /* Number of lines to copy, delete, or insert */
209 int limit1, limit2; /* Sizes of aC1[] and aC2[] */
210 int nConflict = 0; /* Number of merge conflicts seen so far */
211 int useCrLf = 0;
212 int ln1, ln2, lnPivot; /* Line numbers for all files */
213 DiffConfig DCfg;
214
215 blob_zero(pOut); /* Merge results stored in pOut */
216
217 /* If both pV1 and pV2 start with a UTF-8 byte-order-mark (BOM),
@@ -259,56 +271,57 @@
271 ** which is written into pOut. i1 and i2 are multiples of 3 which are
272 ** indices into aC1[] and aC2[] to the edit triple currently being
273 ** processed
274 */
275 i1 = i2 = 0;
276 ln1 = ln2 = lnPivot = 1;
277 while( i1<limit1 && i2<limit2 ){
278 DEBUG( printf("%d: %2d %2d %2d %d: %2d %2d %2d\n",
279 i1/3, aC1[i1], aC1[i1+1], aC1[i1+2],
280 i2/3, aC2[i2], aC2[i2+1], aC2[i2+2]); )
281
282 if( aC1[i1]>0 && aC2[i2]>0 ){
283 /* Output text that is unchanged in both V1 and V2 */
284 nCpy = min(aC1[i1], aC2[i2]);
285 DEBUG( printf("COPY %d\n", nCpy); )
286 blob_copy_lines(pOut, pPivot, nCpy); lnPivot += nCpy;
287 blob_copy_lines(0, pV1, nCpy); ln1 += nCpy;
288 blob_copy_lines(0, pV2, nCpy); ln2 += nCpy;
289 aC1[i1] -= nCpy;
290 aC2[i2] -= nCpy;
291 }else
292 if( aC1[i1] >= aC2[i2+1] && aC1[i1]>0 && aC2[i2+1]+aC2[i2+2]>0 ){
293 /* Output edits to V2 that occurs within unchanged regions of V1 */
294 nDel = aC2[i2+1];
295 nIns = aC2[i2+2];
296 DEBUG( printf("EDIT -%d+%d left\n", nDel, nIns); )
297 blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
298 blob_copy_lines(0, pV1, nDel); ln1 += nDel;
299 blob_copy_lines(pOut, pV2, nIns); ln2 += nIns;
300 aC1[i1] -= nDel;
301 i2 += 3;
302 }else
303 if( aC2[i2] >= aC1[i1+1] && aC2[i2]>0 && aC1[i1+1]+aC1[i1+2]>0 ){
304 /* Output edits to V1 that occur within unchanged regions of V2 */
305 nDel = aC1[i1+1];
306 nIns = aC1[i1+2];
307 DEBUG( printf("EDIT -%d+%d right\n", nDel, nIns); )
308 blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
309 blob_copy_lines(0, pV2, nDel); ln2 += nDel;
310 blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
311 aC2[i2] -= nDel;
312 i1 += 3;
313 }else
314 if( sameEdit(&aC1[i1], &aC2[i2], pV1, pV2) ){
315 /* Output edits that are identical in both V1 and V2. */
316 assert( aC1[i1]==0 );
317 nDel = aC1[i1+1];
318 nIns = aC1[i1+2];
319 DEBUG( printf("EDIT -%d+%d both\n", nDel, nIns); )
320 blob_copy_lines(0, pPivot, nDel); lnPivot += nDel;
321 blob_copy_lines(pOut, pV1, nIns); ln1 += nIns;
322 blob_copy_lines(0, pV2, nIns); ln2 += nIns;
323 i1 += 3;
324 i2 += 3;
325 }else
326 {
327 /* We have found a region where different edits to V1 and V2 overlap.
@@ -319,25 +332,21 @@
332 nConflict++;
333 while( !ends_at_CPY(&aC1[i1], sz) || !ends_at_CPY(&aC2[i2], sz) ){
334 sz++;
335 }
336 DEBUG( printf("CONFLICT %d\n", sz); )
337
338 append_merge_mark(pOut, 0, ln1, useCrLf);
339 i1 = output_one_side(pOut, pV1, aC1, i1, sz, &ln1);
340
341 append_merge_mark(pOut, 1, lnPivot, useCrLf);
342 blob_copy_lines(pOut, pPivot, sz); lnPivot += sz;
343
344 append_merge_mark(pOut, 2, ln2, useCrLf);
345 i2 = output_one_side(pOut, pV2, aC2, i2, sz, &ln2);
346
347 append_merge_mark(pOut, 3, -1, useCrLf);
 
 
 
 
348 }
349
350 /* If we are finished with an edit triple, advance to the next
351 ** triple.
352 */
@@ -378,12 +387,13 @@
387 assert( len==(int)strlen(mergeMarker[2]) );
388 assert( len==(int)strlen(mergeMarker[3]) );
389 assert( count(mergeMarker)==4 );
390 for(i=0; i<n; ){
391 for(j=0; j<4; j++){
392 if( (memcmp(&z[i], mergeMarker[j], len)==0) ){
393 return 1;
394 }
395 }
396 while( i<n && z[i]!='\n' ){ i++; }
397 while( i<n && (z[i]=='\n' || z[i]=='\r') ){ i++; }
398 }
399 return 0;
400
+1 -1
--- src/piechart.c
+++ src/piechart.c
@@ -156,11 +156,11 @@
156156
if( (pieFlags & PIE_OTHER)!=0 && nTotal>1 ){
157157
db_prepare(&q, "SELECT sum(amt), count(*) FROM piechart WHERE amt<:amt");
158158
db_bind_double(&q, ":amt", rTotal/OTHER_CUTOFF);
159159
if( db_step(&q)==SQLITE_ROW ){
160160
rTooSmall = db_column_double(&q, 0);
161
- nTooSmall = db_column_double(&q, 1);
161
+ nTooSmall = db_column_int(&q, 1);
162162
}
163163
db_finalize(&q);
164164
}
165165
if( nTooSmall>1 ){
166166
db_prepare(&q, "SELECT amt, label FROM piechart WHERE amt>=:limit"
167167
--- src/piechart.c
+++ src/piechart.c
@@ -156,11 +156,11 @@
156 if( (pieFlags & PIE_OTHER)!=0 && nTotal>1 ){
157 db_prepare(&q, "SELECT sum(amt), count(*) FROM piechart WHERE amt<:amt");
158 db_bind_double(&q, ":amt", rTotal/OTHER_CUTOFF);
159 if( db_step(&q)==SQLITE_ROW ){
160 rTooSmall = db_column_double(&q, 0);
161 nTooSmall = db_column_double(&q, 1);
162 }
163 db_finalize(&q);
164 }
165 if( nTooSmall>1 ){
166 db_prepare(&q, "SELECT amt, label FROM piechart WHERE amt>=:limit"
167
--- src/piechart.c
+++ src/piechart.c
@@ -156,11 +156,11 @@
156 if( (pieFlags & PIE_OTHER)!=0 && nTotal>1 ){
157 db_prepare(&q, "SELECT sum(amt), count(*) FROM piechart WHERE amt<:amt");
158 db_bind_double(&q, ":amt", rTotal/OTHER_CUTOFF);
159 if( db_step(&q)==SQLITE_ROW ){
160 rTooSmall = db_column_double(&q, 0);
161 nTooSmall = db_column_int(&q, 1);
162 }
163 db_finalize(&q);
164 }
165 if( nTooSmall>1 ){
166 db_prepare(&q, "SELECT amt, label FROM piechart WHERE amt>=:limit"
167
+1 -1
--- src/pikchr.c
+++ src/pikchr.c
@@ -6272,11 +6272,11 @@
62726272
/*
62736273
** Round a PNum into the nearest integer
62746274
*/
62756275
static int pik_round(PNum v){
62766276
if( isnan(v) ) return 0;
6277
- if( v < -2147483647 ) return -2147483648;
6277
+ if( v < -2147483647 ) return (-2147483647-1);
62786278
if( v >= 2147483647 ) return 2147483647;
62796279
return (int)v;
62806280
}
62816281
62826282
/*
62836283
--- src/pikchr.c
+++ src/pikchr.c
@@ -6272,11 +6272,11 @@
6272 /*
6273 ** Round a PNum into the nearest integer
6274 */
6275 static int pik_round(PNum v){
6276 if( isnan(v) ) return 0;
6277 if( v < -2147483647 ) return -2147483648;
6278 if( v >= 2147483647 ) return 2147483647;
6279 return (int)v;
6280 }
6281
6282 /*
6283
--- src/pikchr.c
+++ src/pikchr.c
@@ -6272,11 +6272,11 @@
6272 /*
6273 ** Round a PNum into the nearest integer
6274 */
6275 static int pik_round(PNum v){
6276 if( isnan(v) ) return 0;
6277 if( v < -2147483647 ) return (-2147483647-1);
6278 if( v >= 2147483647 ) return 2147483647;
6279 return (int)v;
6280 }
6281
6282 /*
6283
+94 -29
--- src/shell.c
+++ src/shell.c
@@ -13662,21 +13662,20 @@
1366213662
}
1366313663
return rc;
1366413664
}
1366513665
1366613666
/*
13667
-** Allocate space and save off current error string.
13667
+** Allocate space and save off string indicating current error.
1366813668
*/
1366913669
static char *save_err_msg(
13670
- sqlite3 *db /* Database to query */
13670
+ sqlite3 *db, /* Database to query */
13671
+ const char *zWhen, /* Qualifier (format) wrapper */
13672
+ int rc /* Error code returned from API */
1367113673
){
13672
- int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
13673
- char *zErrMsg = sqlite3_malloc64(nErrMsg);
13674
- if( zErrMsg ){
13675
- memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
13676
- }
13677
- return zErrMsg;
13674
+ if( zWhen==0 )
13675
+ zWhen = "%s (%d)";
13676
+ return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc);
1367813677
}
1367913678
1368013679
#ifdef __linux__
1368113680
/*
1368213681
** Attempt to display I/O stats on Linux using /proc/PID/io
@@ -14594,11 +14593,11 @@
1459414593
while( zSql[0] && (SQLITE_OK == rc) ){
1459514594
static const char *zStmtSql;
1459614595
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1459714596
if( SQLITE_OK != rc ){
1459814597
if( pzErrMsg ){
14599
- *pzErrMsg = save_err_msg(db);
14598
+ *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)", rc);
1460014599
}
1460114600
}else{
1460214601
if( !pStmt ){
1460314602
/* this happens for a comment or white-space */
1460414603
zSql = zLeftover;
@@ -14708,11 +14707,11 @@
1470814707
if( rc!=SQLITE_NOMEM ) rc = rc2;
1470914708
if( rc==SQLITE_OK ){
1471014709
zSql = zLeftover;
1471114710
while( IsSpace(zSql[0]) ) zSql++;
1471214711
}else if( pzErrMsg ){
14713
- *pzErrMsg = save_err_msg(db);
14712
+ *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc);
1471414713
}
1471514714
1471614715
/* clear saved stmt handle */
1471714716
if( pArg ){
1471814717
pArg->pStmt = NULL;
@@ -15022,17 +15021,19 @@
1502215021
".archive ... Manage SQL archives",
1502315022
" Each command must have exactly one of the following options:",
1502415023
" -c, --create Create a new archive",
1502515024
" -u, --update Add or update files with changed mtime",
1502615025
" -i, --insert Like -u but always add even if unchanged",
15026
+ " -r, --remove Remove files from archive",
1502715027
" -t, --list List contents of archive",
1502815028
" -x, --extract Extract files from archive",
1502915029
" Optional arguments:",
1503015030
" -v, --verbose Print each filename as it is processed",
1503115031
" -f FILE, --file FILE Use archive FILE (default is current db)",
1503215032
" -a FILE, --append FILE Open FILE using the apndvfs VFS",
1503315033
" -C DIR, --directory DIR Read/extract files from directory DIR",
15034
+ " -g, --glob Use glob matching for names in archive",
1503415035
" -n, --dryrun Show the SQL that would have occurred",
1503515036
" Examples:",
1503615037
" .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
1503715038
" .ar -tf ARCHIVE # List members of ARCHIVE",
1503815039
" .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
@@ -17189,10 +17190,11 @@
1718917190
u8 eCmd; /* An AR_CMD_* value */
1719017191
u8 bVerbose; /* True if --verbose */
1719117192
u8 bZip; /* True if the archive is a ZIP */
1719217193
u8 bDryRun; /* True if --dry-run */
1719317194
u8 bAppend; /* True if --append */
17195
+ u8 bGlob; /* True if --glob */
1719417196
u8 fromCmdLine; /* Run from -A instead of .archive */
1719517197
int nArg; /* Number of command arguments */
1719617198
char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
1719717199
const char *zFile; /* --file argument, or NULL */
1719817200
const char *zDir; /* --directory argument, or NULL */
@@ -17236,25 +17238,28 @@
1723617238
#define AR_CMD_UPDATE 2
1723717239
#define AR_CMD_INSERT 3
1723817240
#define AR_CMD_EXTRACT 4
1723917241
#define AR_CMD_LIST 5
1724017242
#define AR_CMD_HELP 6
17243
+#define AR_CMD_REMOVE 7
1724117244
1724217245
/*
1724317246
** Other (non-command) switches.
1724417247
*/
17245
-#define AR_SWITCH_VERBOSE 7
17246
-#define AR_SWITCH_FILE 8
17247
-#define AR_SWITCH_DIRECTORY 9
17248
-#define AR_SWITCH_APPEND 10
17249
-#define AR_SWITCH_DRYRUN 11
17248
+#define AR_SWITCH_VERBOSE 8
17249
+#define AR_SWITCH_FILE 9
17250
+#define AR_SWITCH_DIRECTORY 10
17251
+#define AR_SWITCH_APPEND 11
17252
+#define AR_SWITCH_DRYRUN 12
17253
+#define AR_SWITCH_GLOB 13
1725017254
1725117255
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
1725217256
switch( eSwitch ){
1725317257
case AR_CMD_CREATE:
1725417258
case AR_CMD_EXTRACT:
1725517259
case AR_CMD_LIST:
17260
+ case AR_CMD_REMOVE:
1725617261
case AR_CMD_UPDATE:
1725717262
case AR_CMD_INSERT:
1725817263
case AR_CMD_HELP:
1725917264
if( pAr->eCmd ){
1726017265
return arErrorMsg(pAr, "multiple command options");
@@ -17262,10 +17267,13 @@
1726217267
pAr->eCmd = eSwitch;
1726317268
break;
1726417269
1726517270
case AR_SWITCH_DRYRUN:
1726617271
pAr->bDryRun = 1;
17272
+ break;
17273
+ case AR_SWITCH_GLOB:
17274
+ pAr->bGlob = 1;
1726717275
break;
1726817276
case AR_SWITCH_VERBOSE:
1726917277
pAr->bVerbose = 1;
1727017278
break;
1727117279
case AR_SWITCH_APPEND:
@@ -17301,17 +17309,19 @@
1730117309
} aSwitch[] = {
1730217310
{ "create", 'c', AR_CMD_CREATE, 0 },
1730317311
{ "extract", 'x', AR_CMD_EXTRACT, 0 },
1730417312
{ "insert", 'i', AR_CMD_INSERT, 0 },
1730517313
{ "list", 't', AR_CMD_LIST, 0 },
17314
+ { "remove", 'r', AR_CMD_REMOVE, 0 },
1730617315
{ "update", 'u', AR_CMD_UPDATE, 0 },
1730717316
{ "help", 'h', AR_CMD_HELP, 0 },
1730817317
{ "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
1730917318
{ "file", 'f', AR_SWITCH_FILE, 1 },
1731017319
{ "append", 'a', AR_SWITCH_APPEND, 1 },
1731117320
{ "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
1731217321
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
17322
+ { "glob", 'g', AR_SWITCH_GLOB, 0 },
1731317323
};
1731417324
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
1731517325
struct ArSwitch *pEnd = &aSwitch[nSwitch];
1731617326
1731717327
if( nArg<=1 ){
@@ -17424,15 +17434,17 @@
1742417434
return SQLITE_OK;
1742517435
}
1742617436
1742717437
/*
1742817438
** This function assumes that all arguments within the ArCommand.azArg[]
17429
-** array refer to archive members, as for the --extract or --list commands.
17430
-** It checks that each of them are present. If any specified file is not
17431
-** present in the archive, an error is printed to stderr and an error
17432
-** code returned. Otherwise, if all specified arguments are present in
17433
-** the archive, SQLITE_OK is returned.
17439
+** array refer to archive members, as for the --extract, --list or --remove
17440
+** commands. It checks that each of them are "present". If any specified
17441
+** file is not present in the archive, an error is printed to stderr and an
17442
+** error code returned. Otherwise, if all specified arguments are present
17443
+** in the archive, SQLITE_OK is returned. Here, "present" means either an
17444
+** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
17445
+** when pAr->bGlob is true.
1743417446
**
1743517447
** This function strips any trailing '/' characters from each argument.
1743617448
** This is consistent with the way the [tar] command seems to work on
1743717449
** Linux.
1743817450
*/
@@ -17439,15 +17451,15 @@
1743917451
static int arCheckEntries(ArCommand *pAr){
1744017452
int rc = SQLITE_OK;
1744117453
if( pAr->nArg ){
1744217454
int i, j;
1744317455
sqlite3_stmt *pTest = 0;
17456
+ const char *zSel = (pAr->bGlob)
17457
+ ? "SELECT name FROM %s WHERE glob($name,name)"
17458
+ : "SELECT name FROM %s WHERE name=$name";
1744417459
17445
- shellPreparePrintf(pAr->db, &rc, &pTest,
17446
- "SELECT name FROM %s WHERE name=$name",
17447
- pAr->zSrcTable
17448
- );
17460
+ shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
1744917461
j = sqlite3_bind_parameter_index(pTest, "$name");
1745017462
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
1745117463
char *z = pAr->azArg[i];
1745217464
int n = strlen30(z);
1745317465
int bOk = 0;
@@ -17471,29 +17483,31 @@
1747117483
/*
1747217484
** Format a WHERE clause that can be used against the "sqlar" table to
1747317485
** identify all archive members that match the command arguments held
1747417486
** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
1747517487
** The caller is responsible for eventually calling sqlite3_free() on
17476
-** any non-NULL (*pzWhere) value.
17488
+** any non-NULL (*pzWhere) value. Here, "match" means strict equality
17489
+** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
1747717490
*/
1747817491
static void arWhereClause(
1747917492
int *pRc,
17480
- ArCommand *pAr,
17493
+ ArCommand *pAr,
1748117494
char **pzWhere /* OUT: New WHERE clause */
1748217495
){
1748317496
char *zWhere = 0;
17497
+ const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
1748417498
if( *pRc==SQLITE_OK ){
1748517499
if( pAr->nArg==0 ){
1748617500
zWhere = sqlite3_mprintf("1");
1748717501
}else{
1748817502
int i;
1748917503
const char *zSep = "";
1749017504
for(i=0; i<pAr->nArg; i++){
1749117505
const char *z = pAr->azArg[i];
1749217506
zWhere = sqlite3_mprintf(
17493
- "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
17494
- zWhere, zSep, z, strlen30(z)+1, z
17507
+ "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
17508
+ zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
1749517509
);
1749617510
if( zWhere==0 ){
1749717511
*pRc = SQLITE_NOMEM;
1749817512
break;
1749917513
}
@@ -17542,10 +17556,51 @@
1754217556
shellFinalize(&rc, pSql);
1754317557
sqlite3_free(zWhere);
1754417558
return rc;
1754517559
}
1754617560
17561
+
17562
+/*
17563
+** Implementation of .ar "Remove" command.
17564
+*/
17565
+static int arRemoveCommand(ArCommand *pAr){
17566
+ int rc = 0;
17567
+ char *zSql = 0;
17568
+ char *zWhere = 0;
17569
+
17570
+ if( pAr->nArg ){
17571
+ /* Verify that args actually exist within the archive before proceeding.
17572
+ ** And formulate a WHERE clause to match them. */
17573
+ rc = arCheckEntries(pAr);
17574
+ arWhereClause(&rc, pAr, &zWhere);
17575
+ }
17576
+ if( rc==SQLITE_OK ){
17577
+ zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
17578
+ pAr->zSrcTable, zWhere);
17579
+ if( pAr->bDryRun ){
17580
+ utf8_printf(pAr->p->out, "%s\n", zSql);
17581
+ }else{
17582
+ char *zErr = 0;
17583
+ rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
17584
+ if( rc==SQLITE_OK ){
17585
+ rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
17586
+ if( rc!=SQLITE_OK ){
17587
+ sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
17588
+ }else{
17589
+ rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
17590
+ }
17591
+ }
17592
+ if( zErr ){
17593
+ utf8_printf(stdout, "ERROR: %s\n", zErr);
17594
+ sqlite3_free(zErr);
17595
+ }
17596
+ }
17597
+ }
17598
+ sqlite3_free(zWhere);
17599
+ sqlite3_free(zSql);
17600
+ return rc;
17601
+}
1754717602
1754817603
/*
1754917604
** Implementation of .ar "eXtract" command.
1755017605
*/
1755117606
static int arExtractCommand(ArCommand *pAr){
@@ -17795,11 +17850,11 @@
1779517850
cmd.bZip = 1;
1779617851
}else if( cmd.zFile ){
1779717852
int flags;
1779817853
if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
1779917854
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
17800
- || cmd.eCmd==AR_CMD_UPDATE ){
17855
+ || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
1780117856
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
1780217857
}else{
1780317858
flags = SQLITE_OPEN_READONLY;
1780417859
}
1780517860
cmd.db = 0;
@@ -17850,10 +17905,14 @@
1785017905
break;
1785117906
1785217907
case AR_CMD_INSERT:
1785317908
rc = arCreateOrUpdateCommand(&cmd, 1, 0);
1785417909
break;
17910
+
17911
+ case AR_CMD_REMOVE:
17912
+ rc = arRemoveCommand(&cmd);
17913
+ break;
1785517914
1785617915
default:
1785717916
assert( cmd.eCmd==AR_CMD_UPDATE );
1785817917
rc = arCreateOrUpdateCommand(&cmd, 1, 1);
1785917918
break;
@@ -19339,10 +19398,15 @@
1933919398
int nSkip = 0; /* Initial lines to skip */
1934019399
int useOutputMode = 1; /* Use output mode to determine separators */
1934119400
1934219401
failIfSafeMode(p, "cannot run .import in safe mode");
1934319402
memset(&sCtx, 0, sizeof(sCtx));
19403
+ sCtx.z = sqlite3_malloc64(120);
19404
+ if( sCtx.z==0 ){
19405
+ import_cleanup(&sCtx);
19406
+ shell_out_of_memory();
19407
+ }
1934419408
if( p->mode==MODE_Ascii ){
1934519409
xRead = ascii_read_one_field;
1934619410
}else{
1934719411
xRead = csv_read_one_field;
1934819412
}
@@ -19448,10 +19512,11 @@
1944819512
sCtx.xCloser = fclose;
1944919513
}
1945019514
if( sCtx.in==0 ){
1945119515
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
1945219516
rc = 1;
19517
+ import_cleanup(&sCtx);
1945319518
goto meta_command_exit;
1945419519
}
1945519520
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
1945619521
char zSep[2];
1945719522
zSep[1] = 0;
1945819523
--- src/shell.c
+++ src/shell.c
@@ -13662,21 +13662,20 @@
13662 }
13663 return rc;
13664 }
13665
13666 /*
13667 ** Allocate space and save off current error string.
13668 */
13669 static char *save_err_msg(
13670 sqlite3 *db /* Database to query */
 
 
13671 ){
13672 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
13673 char *zErrMsg = sqlite3_malloc64(nErrMsg);
13674 if( zErrMsg ){
13675 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
13676 }
13677 return zErrMsg;
13678 }
13679
13680 #ifdef __linux__
13681 /*
13682 ** Attempt to display I/O stats on Linux using /proc/PID/io
@@ -14594,11 +14593,11 @@
14594 while( zSql[0] && (SQLITE_OK == rc) ){
14595 static const char *zStmtSql;
14596 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14597 if( SQLITE_OK != rc ){
14598 if( pzErrMsg ){
14599 *pzErrMsg = save_err_msg(db);
14600 }
14601 }else{
14602 if( !pStmt ){
14603 /* this happens for a comment or white-space */
14604 zSql = zLeftover;
@@ -14708,11 +14707,11 @@
14708 if( rc!=SQLITE_NOMEM ) rc = rc2;
14709 if( rc==SQLITE_OK ){
14710 zSql = zLeftover;
14711 while( IsSpace(zSql[0]) ) zSql++;
14712 }else if( pzErrMsg ){
14713 *pzErrMsg = save_err_msg(db);
14714 }
14715
14716 /* clear saved stmt handle */
14717 if( pArg ){
14718 pArg->pStmt = NULL;
@@ -15022,17 +15021,19 @@
15022 ".archive ... Manage SQL archives",
15023 " Each command must have exactly one of the following options:",
15024 " -c, --create Create a new archive",
15025 " -u, --update Add or update files with changed mtime",
15026 " -i, --insert Like -u but always add even if unchanged",
 
15027 " -t, --list List contents of archive",
15028 " -x, --extract Extract files from archive",
15029 " Optional arguments:",
15030 " -v, --verbose Print each filename as it is processed",
15031 " -f FILE, --file FILE Use archive FILE (default is current db)",
15032 " -a FILE, --append FILE Open FILE using the apndvfs VFS",
15033 " -C DIR, --directory DIR Read/extract files from directory DIR",
 
15034 " -n, --dryrun Show the SQL that would have occurred",
15035 " Examples:",
15036 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
15037 " .ar -tf ARCHIVE # List members of ARCHIVE",
15038 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
@@ -17189,10 +17190,11 @@
17189 u8 eCmd; /* An AR_CMD_* value */
17190 u8 bVerbose; /* True if --verbose */
17191 u8 bZip; /* True if the archive is a ZIP */
17192 u8 bDryRun; /* True if --dry-run */
17193 u8 bAppend; /* True if --append */
 
17194 u8 fromCmdLine; /* Run from -A instead of .archive */
17195 int nArg; /* Number of command arguments */
17196 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
17197 const char *zFile; /* --file argument, or NULL */
17198 const char *zDir; /* --directory argument, or NULL */
@@ -17236,25 +17238,28 @@
17236 #define AR_CMD_UPDATE 2
17237 #define AR_CMD_INSERT 3
17238 #define AR_CMD_EXTRACT 4
17239 #define AR_CMD_LIST 5
17240 #define AR_CMD_HELP 6
 
17241
17242 /*
17243 ** Other (non-command) switches.
17244 */
17245 #define AR_SWITCH_VERBOSE 7
17246 #define AR_SWITCH_FILE 8
17247 #define AR_SWITCH_DIRECTORY 9
17248 #define AR_SWITCH_APPEND 10
17249 #define AR_SWITCH_DRYRUN 11
 
17250
17251 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
17252 switch( eSwitch ){
17253 case AR_CMD_CREATE:
17254 case AR_CMD_EXTRACT:
17255 case AR_CMD_LIST:
 
17256 case AR_CMD_UPDATE:
17257 case AR_CMD_INSERT:
17258 case AR_CMD_HELP:
17259 if( pAr->eCmd ){
17260 return arErrorMsg(pAr, "multiple command options");
@@ -17262,10 +17267,13 @@
17262 pAr->eCmd = eSwitch;
17263 break;
17264
17265 case AR_SWITCH_DRYRUN:
17266 pAr->bDryRun = 1;
 
 
 
17267 break;
17268 case AR_SWITCH_VERBOSE:
17269 pAr->bVerbose = 1;
17270 break;
17271 case AR_SWITCH_APPEND:
@@ -17301,17 +17309,19 @@
17301 } aSwitch[] = {
17302 { "create", 'c', AR_CMD_CREATE, 0 },
17303 { "extract", 'x', AR_CMD_EXTRACT, 0 },
17304 { "insert", 'i', AR_CMD_INSERT, 0 },
17305 { "list", 't', AR_CMD_LIST, 0 },
 
17306 { "update", 'u', AR_CMD_UPDATE, 0 },
17307 { "help", 'h', AR_CMD_HELP, 0 },
17308 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
17309 { "file", 'f', AR_SWITCH_FILE, 1 },
17310 { "append", 'a', AR_SWITCH_APPEND, 1 },
17311 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
17312 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
 
17313 };
17314 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
17315 struct ArSwitch *pEnd = &aSwitch[nSwitch];
17316
17317 if( nArg<=1 ){
@@ -17424,15 +17434,17 @@
17424 return SQLITE_OK;
17425 }
17426
17427 /*
17428 ** This function assumes that all arguments within the ArCommand.azArg[]
17429 ** array refer to archive members, as for the --extract or --list commands.
17430 ** It checks that each of them are present. If any specified file is not
17431 ** present in the archive, an error is printed to stderr and an error
17432 ** code returned. Otherwise, if all specified arguments are present in
17433 ** the archive, SQLITE_OK is returned.
 
 
17434 **
17435 ** This function strips any trailing '/' characters from each argument.
17436 ** This is consistent with the way the [tar] command seems to work on
17437 ** Linux.
17438 */
@@ -17439,15 +17451,15 @@
17439 static int arCheckEntries(ArCommand *pAr){
17440 int rc = SQLITE_OK;
17441 if( pAr->nArg ){
17442 int i, j;
17443 sqlite3_stmt *pTest = 0;
 
 
 
17444
17445 shellPreparePrintf(pAr->db, &rc, &pTest,
17446 "SELECT name FROM %s WHERE name=$name",
17447 pAr->zSrcTable
17448 );
17449 j = sqlite3_bind_parameter_index(pTest, "$name");
17450 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
17451 char *z = pAr->azArg[i];
17452 int n = strlen30(z);
17453 int bOk = 0;
@@ -17471,29 +17483,31 @@
17471 /*
17472 ** Format a WHERE clause that can be used against the "sqlar" table to
17473 ** identify all archive members that match the command arguments held
17474 ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
17475 ** The caller is responsible for eventually calling sqlite3_free() on
17476 ** any non-NULL (*pzWhere) value.
 
17477 */
17478 static void arWhereClause(
17479 int *pRc,
17480 ArCommand *pAr,
17481 char **pzWhere /* OUT: New WHERE clause */
17482 ){
17483 char *zWhere = 0;
 
17484 if( *pRc==SQLITE_OK ){
17485 if( pAr->nArg==0 ){
17486 zWhere = sqlite3_mprintf("1");
17487 }else{
17488 int i;
17489 const char *zSep = "";
17490 for(i=0; i<pAr->nArg; i++){
17491 const char *z = pAr->azArg[i];
17492 zWhere = sqlite3_mprintf(
17493 "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
17494 zWhere, zSep, z, strlen30(z)+1, z
17495 );
17496 if( zWhere==0 ){
17497 *pRc = SQLITE_NOMEM;
17498 break;
17499 }
@@ -17542,10 +17556,51 @@
17542 shellFinalize(&rc, pSql);
17543 sqlite3_free(zWhere);
17544 return rc;
17545 }
17546
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17547
17548 /*
17549 ** Implementation of .ar "eXtract" command.
17550 */
17551 static int arExtractCommand(ArCommand *pAr){
@@ -17795,11 +17850,11 @@
17795 cmd.bZip = 1;
17796 }else if( cmd.zFile ){
17797 int flags;
17798 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
17799 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
17800 || cmd.eCmd==AR_CMD_UPDATE ){
17801 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
17802 }else{
17803 flags = SQLITE_OPEN_READONLY;
17804 }
17805 cmd.db = 0;
@@ -17850,10 +17905,14 @@
17850 break;
17851
17852 case AR_CMD_INSERT:
17853 rc = arCreateOrUpdateCommand(&cmd, 1, 0);
17854 break;
 
 
 
 
17855
17856 default:
17857 assert( cmd.eCmd==AR_CMD_UPDATE );
17858 rc = arCreateOrUpdateCommand(&cmd, 1, 1);
17859 break;
@@ -19339,10 +19398,15 @@
19339 int nSkip = 0; /* Initial lines to skip */
19340 int useOutputMode = 1; /* Use output mode to determine separators */
19341
19342 failIfSafeMode(p, "cannot run .import in safe mode");
19343 memset(&sCtx, 0, sizeof(sCtx));
 
 
 
 
 
19344 if( p->mode==MODE_Ascii ){
19345 xRead = ascii_read_one_field;
19346 }else{
19347 xRead = csv_read_one_field;
19348 }
@@ -19448,10 +19512,11 @@
19448 sCtx.xCloser = fclose;
19449 }
19450 if( sCtx.in==0 ){
19451 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
19452 rc = 1;
 
19453 goto meta_command_exit;
19454 }
19455 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
19456 char zSep[2];
19457 zSep[1] = 0;
19458
--- src/shell.c
+++ src/shell.c
@@ -13662,21 +13662,20 @@
13662 }
13663 return rc;
13664 }
13665
13666 /*
13667 ** Allocate space and save off string indicating current error.
13668 */
13669 static char *save_err_msg(
13670 sqlite3 *db, /* Database to query */
13671 const char *zWhen, /* Qualifier (format) wrapper */
13672 int rc /* Error code returned from API */
13673 ){
13674 if( zWhen==0 )
13675 zWhen = "%s (%d)";
13676 return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc);
 
 
 
13677 }
13678
13679 #ifdef __linux__
13680 /*
13681 ** Attempt to display I/O stats on Linux using /proc/PID/io
@@ -14594,11 +14593,11 @@
14593 while( zSql[0] && (SQLITE_OK == rc) ){
14594 static const char *zStmtSql;
14595 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14596 if( SQLITE_OK != rc ){
14597 if( pzErrMsg ){
14598 *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)", rc);
14599 }
14600 }else{
14601 if( !pStmt ){
14602 /* this happens for a comment or white-space */
14603 zSql = zLeftover;
@@ -14708,11 +14707,11 @@
14707 if( rc!=SQLITE_NOMEM ) rc = rc2;
14708 if( rc==SQLITE_OK ){
14709 zSql = zLeftover;
14710 while( IsSpace(zSql[0]) ) zSql++;
14711 }else if( pzErrMsg ){
14712 *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc);
14713 }
14714
14715 /* clear saved stmt handle */
14716 if( pArg ){
14717 pArg->pStmt = NULL;
@@ -15022,17 +15021,19 @@
15021 ".archive ... Manage SQL archives",
15022 " Each command must have exactly one of the following options:",
15023 " -c, --create Create a new archive",
15024 " -u, --update Add or update files with changed mtime",
15025 " -i, --insert Like -u but always add even if unchanged",
15026 " -r, --remove Remove files from archive",
15027 " -t, --list List contents of archive",
15028 " -x, --extract Extract files from archive",
15029 " Optional arguments:",
15030 " -v, --verbose Print each filename as it is processed",
15031 " -f FILE, --file FILE Use archive FILE (default is current db)",
15032 " -a FILE, --append FILE Open FILE using the apndvfs VFS",
15033 " -C DIR, --directory DIR Read/extract files from directory DIR",
15034 " -g, --glob Use glob matching for names in archive",
15035 " -n, --dryrun Show the SQL that would have occurred",
15036 " Examples:",
15037 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
15038 " .ar -tf ARCHIVE # List members of ARCHIVE",
15039 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
@@ -17189,10 +17190,11 @@
17190 u8 eCmd; /* An AR_CMD_* value */
17191 u8 bVerbose; /* True if --verbose */
17192 u8 bZip; /* True if the archive is a ZIP */
17193 u8 bDryRun; /* True if --dry-run */
17194 u8 bAppend; /* True if --append */
17195 u8 bGlob; /* True if --glob */
17196 u8 fromCmdLine; /* Run from -A instead of .archive */
17197 int nArg; /* Number of command arguments */
17198 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
17199 const char *zFile; /* --file argument, or NULL */
17200 const char *zDir; /* --directory argument, or NULL */
@@ -17236,25 +17238,28 @@
17238 #define AR_CMD_UPDATE 2
17239 #define AR_CMD_INSERT 3
17240 #define AR_CMD_EXTRACT 4
17241 #define AR_CMD_LIST 5
17242 #define AR_CMD_HELP 6
17243 #define AR_CMD_REMOVE 7
17244
17245 /*
17246 ** Other (non-command) switches.
17247 */
17248 #define AR_SWITCH_VERBOSE 8
17249 #define AR_SWITCH_FILE 9
17250 #define AR_SWITCH_DIRECTORY 10
17251 #define AR_SWITCH_APPEND 11
17252 #define AR_SWITCH_DRYRUN 12
17253 #define AR_SWITCH_GLOB 13
17254
17255 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
17256 switch( eSwitch ){
17257 case AR_CMD_CREATE:
17258 case AR_CMD_EXTRACT:
17259 case AR_CMD_LIST:
17260 case AR_CMD_REMOVE:
17261 case AR_CMD_UPDATE:
17262 case AR_CMD_INSERT:
17263 case AR_CMD_HELP:
17264 if( pAr->eCmd ){
17265 return arErrorMsg(pAr, "multiple command options");
@@ -17262,10 +17267,13 @@
17267 pAr->eCmd = eSwitch;
17268 break;
17269
17270 case AR_SWITCH_DRYRUN:
17271 pAr->bDryRun = 1;
17272 break;
17273 case AR_SWITCH_GLOB:
17274 pAr->bGlob = 1;
17275 break;
17276 case AR_SWITCH_VERBOSE:
17277 pAr->bVerbose = 1;
17278 break;
17279 case AR_SWITCH_APPEND:
@@ -17301,17 +17309,19 @@
17309 } aSwitch[] = {
17310 { "create", 'c', AR_CMD_CREATE, 0 },
17311 { "extract", 'x', AR_CMD_EXTRACT, 0 },
17312 { "insert", 'i', AR_CMD_INSERT, 0 },
17313 { "list", 't', AR_CMD_LIST, 0 },
17314 { "remove", 'r', AR_CMD_REMOVE, 0 },
17315 { "update", 'u', AR_CMD_UPDATE, 0 },
17316 { "help", 'h', AR_CMD_HELP, 0 },
17317 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
17318 { "file", 'f', AR_SWITCH_FILE, 1 },
17319 { "append", 'a', AR_SWITCH_APPEND, 1 },
17320 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
17321 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
17322 { "glob", 'g', AR_SWITCH_GLOB, 0 },
17323 };
17324 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
17325 struct ArSwitch *pEnd = &aSwitch[nSwitch];
17326
17327 if( nArg<=1 ){
@@ -17424,15 +17434,17 @@
17434 return SQLITE_OK;
17435 }
17436
17437 /*
17438 ** This function assumes that all arguments within the ArCommand.azArg[]
17439 ** array refer to archive members, as for the --extract, --list or --remove
17440 ** commands. It checks that each of them are "present". If any specified
17441 ** file is not present in the archive, an error is printed to stderr and an
17442 ** error code returned. Otherwise, if all specified arguments are present
17443 ** in the archive, SQLITE_OK is returned. Here, "present" means either an
17444 ** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
17445 ** when pAr->bGlob is true.
17446 **
17447 ** This function strips any trailing '/' characters from each argument.
17448 ** This is consistent with the way the [tar] command seems to work on
17449 ** Linux.
17450 */
@@ -17439,15 +17451,15 @@
17451 static int arCheckEntries(ArCommand *pAr){
17452 int rc = SQLITE_OK;
17453 if( pAr->nArg ){
17454 int i, j;
17455 sqlite3_stmt *pTest = 0;
17456 const char *zSel = (pAr->bGlob)
17457 ? "SELECT name FROM %s WHERE glob($name,name)"
17458 : "SELECT name FROM %s WHERE name=$name";
17459
17460 shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
 
 
 
17461 j = sqlite3_bind_parameter_index(pTest, "$name");
17462 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
17463 char *z = pAr->azArg[i];
17464 int n = strlen30(z);
17465 int bOk = 0;
@@ -17471,29 +17483,31 @@
17483 /*
17484 ** Format a WHERE clause that can be used against the "sqlar" table to
17485 ** identify all archive members that match the command arguments held
17486 ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
17487 ** The caller is responsible for eventually calling sqlite3_free() on
17488 ** any non-NULL (*pzWhere) value. Here, "match" means strict equality
17489 ** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
17490 */
17491 static void arWhereClause(
17492 int *pRc,
17493 ArCommand *pAr,
17494 char **pzWhere /* OUT: New WHERE clause */
17495 ){
17496 char *zWhere = 0;
17497 const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
17498 if( *pRc==SQLITE_OK ){
17499 if( pAr->nArg==0 ){
17500 zWhere = sqlite3_mprintf("1");
17501 }else{
17502 int i;
17503 const char *zSep = "";
17504 for(i=0; i<pAr->nArg; i++){
17505 const char *z = pAr->azArg[i];
17506 zWhere = sqlite3_mprintf(
17507 "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
17508 zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
17509 );
17510 if( zWhere==0 ){
17511 *pRc = SQLITE_NOMEM;
17512 break;
17513 }
@@ -17542,10 +17556,51 @@
17556 shellFinalize(&rc, pSql);
17557 sqlite3_free(zWhere);
17558 return rc;
17559 }
17560
17561
17562 /*
17563 ** Implementation of .ar "Remove" command.
17564 */
17565 static int arRemoveCommand(ArCommand *pAr){
17566 int rc = 0;
17567 char *zSql = 0;
17568 char *zWhere = 0;
17569
17570 if( pAr->nArg ){
17571 /* Verify that args actually exist within the archive before proceeding.
17572 ** And formulate a WHERE clause to match them. */
17573 rc = arCheckEntries(pAr);
17574 arWhereClause(&rc, pAr, &zWhere);
17575 }
17576 if( rc==SQLITE_OK ){
17577 zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
17578 pAr->zSrcTable, zWhere);
17579 if( pAr->bDryRun ){
17580 utf8_printf(pAr->p->out, "%s\n", zSql);
17581 }else{
17582 char *zErr = 0;
17583 rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
17584 if( rc==SQLITE_OK ){
17585 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
17586 if( rc!=SQLITE_OK ){
17587 sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
17588 }else{
17589 rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
17590 }
17591 }
17592 if( zErr ){
17593 utf8_printf(stdout, "ERROR: %s\n", zErr);
17594 sqlite3_free(zErr);
17595 }
17596 }
17597 }
17598 sqlite3_free(zWhere);
17599 sqlite3_free(zSql);
17600 return rc;
17601 }
17602
17603 /*
17604 ** Implementation of .ar "eXtract" command.
17605 */
17606 static int arExtractCommand(ArCommand *pAr){
@@ -17795,11 +17850,11 @@
17850 cmd.bZip = 1;
17851 }else if( cmd.zFile ){
17852 int flags;
17853 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
17854 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
17855 || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
17856 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
17857 }else{
17858 flags = SQLITE_OPEN_READONLY;
17859 }
17860 cmd.db = 0;
@@ -17850,10 +17905,14 @@
17905 break;
17906
17907 case AR_CMD_INSERT:
17908 rc = arCreateOrUpdateCommand(&cmd, 1, 0);
17909 break;
17910
17911 case AR_CMD_REMOVE:
17912 rc = arRemoveCommand(&cmd);
17913 break;
17914
17915 default:
17916 assert( cmd.eCmd==AR_CMD_UPDATE );
17917 rc = arCreateOrUpdateCommand(&cmd, 1, 1);
17918 break;
@@ -19339,10 +19398,15 @@
19398 int nSkip = 0; /* Initial lines to skip */
19399 int useOutputMode = 1; /* Use output mode to determine separators */
19400
19401 failIfSafeMode(p, "cannot run .import in safe mode");
19402 memset(&sCtx, 0, sizeof(sCtx));
19403 sCtx.z = sqlite3_malloc64(120);
19404 if( sCtx.z==0 ){
19405 import_cleanup(&sCtx);
19406 shell_out_of_memory();
19407 }
19408 if( p->mode==MODE_Ascii ){
19409 xRead = ascii_read_one_field;
19410 }else{
19411 xRead = csv_read_one_field;
19412 }
@@ -19448,10 +19512,11 @@
19512 sCtx.xCloser = fclose;
19513 }
19514 if( sCtx.in==0 ){
19515 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
19516 rc = 1;
19517 import_cleanup(&sCtx);
19518 goto meta_command_exit;
19519 }
19520 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
19521 char zSep[2];
19522 zSep[1] = 0;
19523
+743 -266
--- 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-10-22 11:17:29 1a038242dc6c0cab97dd9375acfce62aa1c386debc36aaed388d366b87ddd931"
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
**
@@ -6709,10 +6718,76 @@
67096718
**
67106719
** See also the [sqlite3_update_hook()] interface.
67116720
*/
67126721
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
67136722
SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
6723
+
6724
+/*
6725
+** CAPI3REF: Autovacuum Compaction Amount Callback
6726
+** METHOD: sqlite3
6727
+**
6728
+** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
6729
+** function C that is invoked prior to each autovacuum of the database
6730
+** file. ^The callback is passed a copy of the generic data pointer (P),
6731
+** the schema-name of the attached database that is being autovacuumed,
6732
+** the the size of the database file in pages, the number of free pages,
6733
+** and the number of bytes per page, respectively. The callback should
6734
+** return the number of free pages that should be removed by the
6735
+** autovacuum. ^If the callback returns zero, then no autovacuum happens.
6736
+** ^If the value returned is greater than or equal to the number of
6737
+** free pages, then a complete autovacuum happens.
6738
+**
6739
+** <p>^If there are multiple ATTACH-ed database files that are being
6740
+** modified as part of a transaction commit, then the autovacuum pages
6741
+** callback is invoked separately for each file.
6742
+**
6743
+** <p><b>The callback is not reentrant.</b> The callback function should
6744
+** not attempt to invoke any other SQLite interface. If it does, bad
6745
+** things may happen, including segmentation faults and corrupt database
6746
+** files. The callback function should be a simple function that
6747
+** does some arithmetic on its input parameters and returns a result.
6748
+**
6749
+** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
6750
+** destructor for the P parameter. ^If X is not NULL, then X(P) is
6751
+** invoked whenever the database connection closes or when the callback
6752
+** is overwritten by another invocation of sqlite3_autovacuum_pages().
6753
+**
6754
+** <p>^There is only one autovacuum pages callback per database connection.
6755
+** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
6756
+** previous invocations for that database connection. ^If the callback
6757
+** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
6758
+** then the autovacuum steps callback is cancelled. The return value
6759
+** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
6760
+** be some other error code if something goes wrong. The current
6761
+** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
6762
+** return codes might be added in future releases.
6763
+**
6764
+** <p>If no autovacuum pages callback is specified (the usual case) or
6765
+** a NULL pointer is provided for the callback,
6766
+** then the default behavior is to vacuum all free pages. So, in other
6767
+** words, the default behavior is the same as if the callback function
6768
+** were something like this:
6769
+**
6770
+** <blockquote><pre>
6771
+** &nbsp; unsigned int demonstration_autovac_pages_callback(
6772
+** &nbsp; void *pClientData,
6773
+** &nbsp; const char *zSchema,
6774
+** &nbsp; unsigned int nDbPage,
6775
+** &nbsp; unsigned int nFreePage,
6776
+** &nbsp; unsigned int nBytePerPage
6777
+** &nbsp; ){
6778
+** &nbsp; return nFreePage;
6779
+** &nbsp; }
6780
+** </pre></blockquote>
6781
+*/
6782
+SQLITE_API int sqlite3_autovacuum_pages(
6783
+ sqlite3 *db,
6784
+ unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
6785
+ void*,
6786
+ void(*)(void*)
6787
+);
6788
+
67146789
67156790
/*
67166791
** CAPI3REF: Data Change Notification Callbacks
67176792
** METHOD: sqlite3
67186793
**
@@ -14078,15 +14153,29 @@
1407814153
int nBusy; /* Incremented with each busy call */
1407914154
};
1408014155
1408114156
/*
1408214157
** Name of table that holds the database schema.
14158
+**
14159
+** The PREFERRED names are used whereever possible. But LEGACY is also
14160
+** used for backwards compatibility.
14161
+**
14162
+** 1. Queries can use either the PREFERRED or the LEGACY names
14163
+** 2. The sqlite3_set_authorizer() callback uses the LEGACY name
14164
+** 3. The PRAGMA table_list statement uses the PREFERRED name
14165
+**
14166
+** The LEGACY names are stored in the internal symbol hash table
14167
+** in support of (2). Names are translated using sqlite3PreferredTableName()
14168
+** for (3). The sqlite3FindTable() function takes care of translating
14169
+** names for (1).
14170
+**
14171
+** Note that "sqlite_temp_schema" can also be called "temp.sqlite_schema".
1408314172
*/
14084
-#define DFLT_SCHEMA_TABLE "sqlite_master"
14085
-#define DFLT_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14086
-#define ALT_SCHEMA_TABLE "sqlite_schema"
14087
-#define ALT_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
14173
+#define LEGACY_SCHEMA_TABLE "sqlite_master"
14174
+#define LEGACY_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14175
+#define PREFERRED_SCHEMA_TABLE "sqlite_schema"
14176
+#define PREFERRED_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
1408814177
1408914178
1409014179
/*
1409114180
** The root-page of the schema table.
1409214181
*/
@@ -14094,11 +14183,11 @@
1409414183
1409514184
/*
1409614185
** The name of the schema table. The name is different for TEMP.
1409714186
*/
1409814187
#define SCHEMA_TABLE(x) \
14099
- ((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE)
14188
+ ((!OMIT_TEMPDB)&&(x==1)?LEGACY_TEMP_SCHEMA_TABLE:LEGACY_SCHEMA_TABLE)
1410014189
1410114190
/*
1410214191
** A convenience macro that returns the number of elements in
1410314192
** an array.
1410414193
*/
@@ -16437,10 +16526,13 @@
1643716526
int (*xCommitCallback)(void*); /* Invoked at every commit. */
1643816527
void *pRollbackArg; /* Argument to xRollbackCallback() */
1643916528
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
1644016529
void *pUpdateArg;
1644116530
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
16531
+ void *pAutovacPagesArg; /* Client argument to autovac_pages */
16532
+ void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
16533
+ unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
1644216534
Parse *pParse; /* Current parse */
1644316535
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
1644416536
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
1644516537
void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
1644616538
void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
@@ -16566,10 +16658,11 @@
1656616658
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
1656716659
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
1656816660
#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
1656916661
/* DELETE, or UPDATE and return */
1657016662
/* the count using a callback. */
16663
+#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
1657116664
1657216665
/* Flags used only if debugging */
1657316666
#ifdef SQLITE_DEBUG
1657416667
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
1657516668
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -18694,12 +18787,14 @@
1869418787
} InitData;
1869518788
1869618789
/*
1869718790
** Allowed values for mInitFlags
1869818791
*/
18792
+#define INITFLAG_AlterMask 0x0003 /* Types of ALTER */
1869918793
#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
1870018794
#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
18795
+#define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */
1870118796
1870218797
/* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
1870318798
** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
1870418799
** parameters are for temporary use during development, to help find
1870518800
** optimial values for parameters in the query planner. The should not
@@ -18816,12 +18911,12 @@
1881618911
union { /* Extra data for callback */
1881718912
NameContext *pNC; /* Naming context */
1881818913
int n; /* A counter */
1881918914
int iCur; /* A cursor number */
1882018915
SrcList *pSrcList; /* FROM clause */
18821
- struct SrcCount *pSrcCount; /* Counting column references */
1882218916
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
18917
+ struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */
1882318918
int *aiCol; /* array of column indexes */
1882418919
struct IdxCover *pIdxCover; /* Check for index coverage */
1882518920
struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
1882618921
ExprList *pGroupBy; /* GROUP BY clause */
1882718922
Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19458,10 +19553,11 @@
1945819553
SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
1945919554
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
1946019555
#define LOCATE_VIEW 0x01
1946119556
#define LOCATE_NOERR 0x02
1946219557
SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
19558
+SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*);
1946319559
SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
1946419560
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
1946519561
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
1946619562
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
1946719563
SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
@@ -19474,11 +19570,11 @@
1947419570
SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
1947519571
SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
1947619572
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
1947719573
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
1947819574
SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19479
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
19575
+SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*);
1948019576
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
1948119577
#ifndef SQLITE_UNTESTABLE
1948219578
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
1948319579
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
1948419580
#endif
@@ -19916,13 +20012,15 @@
1991620012
#endif
1991720013
SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
1991820014
#ifndef SQLITE_OMIT_VIRTUALTABLE
1991920015
SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
1992020016
SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
20017
+SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*);
1992120018
#else
1992220019
# define sqlite3ShadowTableName(A,B) 0
1992320020
# define sqlite3IsShadowTableOf(A,B,C) 0
20021
+# define sqlite3MarkAllShadowTablesOf(A,B)
1992420022
#endif
1992520023
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
1992620024
SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
1992720025
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
1992820026
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -22105,11 +22203,15 @@
2210522203
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
2210622204
#endif
2210722205
SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
2210822206
SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
2210922207
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
22208
+#ifndef SQLITE_OMIT_INCRBLOB
2211022209
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
22210
+#else
22211
+SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int);
22212
+#endif
2211122213
#ifdef SQLITE_DEBUG
2211222214
SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
2211322215
#endif
2211422216
SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
2211522217
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
@@ -24126,16 +24228,19 @@
2412624228
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
2412724229
if( pFile ){
2412824230
rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
2412924231
if( rc!=SQLITE_OK ){
2413024232
sqlite3_free(pFile);
24233
+ *ppFile = 0;
2413124234
}else{
2413224235
*ppFile = pFile;
2413324236
}
2413424237
}else{
24238
+ *ppFile = 0;
2413524239
rc = SQLITE_NOMEM_BKPT;
2413624240
}
24241
+ assert( *ppFile!=0 || rc!=SQLITE_OK );
2413724242
return rc;
2413824243
}
2413924244
SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
2414024245
assert( pFile );
2414124246
sqlite3OsClose(pFile);
@@ -38079,11 +38184,13 @@
3807938184
}
3808038185
}
3808138186
3808238187
/* Forward declaration */
3808338188
static int unixGetTempname(int nBuf, char *zBuf);
38084
-static int unixFcntlExternalReader(unixFile*, int*);
38189
+#ifndef SQLITE_OMIT_WAL
38190
+ static int unixFcntlExternalReader(unixFile*, int*);
38191
+#endif
3808538192
3808638193
/*
3808738194
** Information and control of an open file handle.
3808838195
*/
3808938196
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -38198,11 +38305,16 @@
3819838305
return proxyFileControl(id,op,pArg);
3819938306
}
3820038307
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
3820138308
3820238309
case SQLITE_FCNTL_EXTERNAL_READER: {
38310
+#ifndef SQLITE_OMIT_WAL
3820338311
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
38312
+#else
38313
+ *(int*)pArg = 0;
38314
+ return SQLITE_OK;
38315
+#endif
3820438316
}
3820538317
}
3820638318
return SQLITE_NOTFOUND;
3820738319
}
3820838320
@@ -40252,10 +40364,15 @@
4025240364
if( randomnessPid!=osGetpid(0) ){
4025340365
randomnessPid = osGetpid(0);
4025440366
sqlite3_randomness(0,0);
4025540367
}
4025640368
memset(p, 0, sizeof(unixFile));
40369
+
40370
+#ifdef SQLITE_ASSERT_NO_FILES
40371
+ /* Applications that never read or write a persistent disk files */
40372
+ assert( zName==0 );
40373
+#endif
4025740374
4025840375
if( eType==SQLITE_OPEN_MAIN_DB ){
4025940376
UnixUnusedFd *pUnused;
4026040377
pUnused = findReusableFd(zName, flags);
4026140378
if( pUnused ){
@@ -48664,11 +48781,11 @@
4866448781
/*
4866548782
** Try to enlarge the memory allocation to hold at least sz bytes
4866648783
*/
4866748784
static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
4866848785
unsigned char *pNew;
48669
- if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
48786
+ if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){
4867048787
return SQLITE_FULL;
4867148788
}
4867248789
if( newSz>p->szMax ){
4867348790
return SQLITE_FULL;
4867448791
}
@@ -48723,12 +48840,13 @@
4872348840
*/
4872448841
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
4872548842
MemStore *p = ((MemFile*)pFile)->pStore;
4872648843
int rc = SQLITE_OK;
4872748844
memdbEnter(p);
48728
- if( NEVER(size>p->sz) ){
48729
- rc = SQLITE_FULL;
48845
+ if( size>p->sz ){
48846
+ /* This can only happen with a corrupt wal mode db */
48847
+ rc = SQLITE_CORRUPT;
4873048848
}else{
4873148849
p->sz = size;
4873248850
}
4873348851
memdbLeave(p);
4873448852
return rc;
@@ -48863,11 +48981,11 @@
4886348981
int iAmt,
4886448982
void **pp
4886548983
){
4886648984
MemStore *p = ((MemFile*)pFile)->pStore;
4886748985
memdbEnter(p);
48868
- if( iOfst+iAmt>p->sz ){
48986
+ if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){
4886948987
*pp = 0;
4887048988
}else{
4887148989
p->nMmap++;
4887248990
*pp = (void*)(p->aData + iOfst);
4887348991
}
@@ -48897,13 +49015,12 @@
4889749015
int *pOutFlags
4889849016
){
4889949017
MemFile *pFile = (MemFile*)pFd;
4890049018
MemStore *p = 0;
4890149019
int szName;
48902
- if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
48903
- return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
48904
- }
49020
+ UNUSED_PARAMETER(pVfs);
49021
+
4890549022
memset(pFile, 0, sizeof(*pFile));
4890649023
szName = sqlite3Strlen30(zName);
4890749024
if( szName>1 && zName[0]=='/' ){
4890849025
int i;
4890949026
#ifndef SQLITE_MUTEX_OMIT
@@ -48959,12 +49076,13 @@
4895949076
memset(p, 0, sizeof(*p));
4896049077
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
4896149078
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
4896249079
}
4896349080
pFile->pStore = p;
48964
- assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
48965
- *pOutFlags = flags | SQLITE_OPEN_MEMORY;
49081
+ if( pOutFlags!=0 ){
49082
+ *pOutFlags = flags | SQLITE_OPEN_MEMORY;
49083
+ }
4896649084
pFd->pMethods = &memdb_io_methods;
4896749085
memdbLeave(p);
4896849086
return SQLITE_OK;
4896949087
}
4897049088
@@ -53155,10 +53273,11 @@
5315553273
u8 walSyncFlags; /* See description above */
5315653274
u8 tempFile; /* zFilename is a temporary or immutable file */
5315753275
u8 noLock; /* Do not lock (except in WAL mode) */
5315853276
u8 readOnly; /* True for a read-only database */
5315953277
u8 memDb; /* True to inhibit all file I/O */
53278
+ u8 memVfs; /* VFS-implemented memory database */
5316053279
5316153280
/**************************************************************************
5316253281
** The following block contains those class members that change during
5316353282
** routine operation. Class members not in this block are either fixed
5316453283
** when the pager is first created or else only change when there is a
@@ -57397,11 +57516,11 @@
5739757516
if( zFilename && zFilename[0] ){
5739857517
int fout = 0; /* VFS flags returned by xOpen() */
5739957518
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
5740057519
assert( !memDb );
5740157520
#ifndef SQLITE_OMIT_DESERIALIZE
57402
- memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
57521
+ pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
5740357522
#endif
5740457523
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
5740557524
5740657525
/* If the file was successfully opened for read/write access,
5740757526
** choose a default page size in case we have to create the
@@ -59334,11 +59453,11 @@
5933459453
5933559454
/*
5933659455
** Return true if this is an in-memory or temp-file backed pager.
5933759456
*/
5933859457
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
59339
- return pPager->tempFile;
59458
+ return pPager->tempFile || pPager->memVfs;
5934059459
}
5934159460
5934259461
/*
5934359462
** Check that there are at least nSavepoint savepoints open. If there are
5934459463
** currently less than nSavepoints open, then open one or more savepoints
@@ -60859,13 +60978,17 @@
6085960978
** If the wal-index is currently smaller the iPage pages then the size
6086060979
** of the wal-index might be increased, but only if it is safe to do
6086160980
** so. It is safe to enlarge the wal-index if pWal->writeLock is true
6086260981
** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
6086360982
**
60864
-** If this call is successful, *ppPage is set to point to the wal-index
60865
-** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
60866
-** then an SQLite error code is returned and *ppPage is set to 0.
60983
+** Three possible result scenarios:
60984
+**
60985
+** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
60986
+** (2) rc>=SQLITE_ERROR and *ppPage==NULL
60987
+** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0
60988
+**
60989
+** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
6086760990
*/
6086860991
static SQLITE_NOINLINE int walIndexPageRealloc(
6086960992
Wal *pWal, /* The WAL context */
6087060993
int iPage, /* The page we seek */
6087160994
volatile u32 **ppPage /* Write the page pointer here */
@@ -60894,11 +61017,13 @@
6089461017
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
6089561018
}else{
6089661019
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
6089761020
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
6089861021
);
60899
- assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
61022
+ assert( pWal->apWiData[iPage]!=0
61023
+ || rc!=SQLITE_OK
61024
+ || (pWal->writeLock==0 && iPage==0) );
6090061025
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
6090161026
if( rc==SQLITE_OK ){
6090261027
if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
6090361028
}else if( (rc&0xff)==SQLITE_READONLY ){
6090461029
pWal->readOnly |= WAL_SHM_RDONLY;
@@ -61233,12 +61358,12 @@
6123361358
** in the wal-index file. Set pLoc->iZero to one less than the frame
6123461359
** number of the first frame indexed by this hash table. If a
6123561360
** slot in the hash table is set to N, it refers to frame number
6123661361
** (pLoc->iZero+N) in the log.
6123761362
**
61238
-** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
61239
-** first frame indexed by the hash table, frame (pLoc->iZero+1).
61363
+** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the
61364
+** first frame indexed by the hash table, frame (pLoc->iZero).
6124061365
*/
6124161366
static int walHashGet(
6124261367
Wal *pWal, /* WAL handle */
6124361368
int iHash, /* Find the iHash'th table */
6124461369
WalHashLoc *pLoc /* OUT: Hash table location */
@@ -61246,19 +61371,20 @@
6124661371
int rc; /* Return code */
6124761372
6124861373
rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
6124961374
assert( rc==SQLITE_OK || iHash>0 );
6125061375
61251
- if( rc==SQLITE_OK ){
61376
+ if( pLoc->aPgno ){
6125261377
pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
6125361378
if( iHash==0 ){
6125461379
pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
6125561380
pLoc->iZero = 0;
6125661381
}else{
6125761382
pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
6125861383
}
61259
- pLoc->aPgno = &pLoc->aPgno[-1];
61384
+ }else if( NEVER(rc==SQLITE_OK) ){
61385
+ rc = SQLITE_ERROR;
6126061386
}
6126161387
return rc;
6126261388
}
6126361389
6126461390
/*
@@ -61336,25 +61462,26 @@
6133661462
}
6133761463
6133861464
/* Zero the entries in the aPgno array that correspond to frames with
6133961465
** frame numbers greater than pWal->hdr.mxFrame.
6134061466
*/
61341
- nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
61342
- memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
61467
+ nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]);
61468
+ assert( nByte>=0 );
61469
+ memset((void *)&sLoc.aPgno[iLimit], 0, nByte);
6134361470
6134461471
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
6134561472
/* Verify that the every entry in the mapping region is still reachable
6134661473
** via the hash table even after the cleanup.
6134761474
*/
6134861475
if( iLimit ){
6134961476
int j; /* Loop counter */
6135061477
int iKey; /* Hash key */
61351
- for(j=1; j<=iLimit; j++){
61478
+ for(j=0; j<iLimit; j++){
6135261479
for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
61353
- if( sLoc.aHash[iKey]==j ) break;
61480
+ if( sLoc.aHash[iKey]==j+1 ) break;
6135461481
}
61355
- assert( sLoc.aHash[iKey]==j );
61482
+ assert( sLoc.aHash[iKey]==j+1 );
6135661483
}
6135761484
}
6135861485
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
6135961486
}
6136061487
@@ -61382,32 +61509,32 @@
6138261509
6138361510
/* If this is the first entry to be added to this hash-table, zero the
6138461511
** entire hash table and aPgno[] array before proceeding.
6138561512
*/
6138661513
if( idx==1 ){
61387
- int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
61388
- - (u8 *)&sLoc.aPgno[1]);
61389
- memset((void*)&sLoc.aPgno[1], 0, nByte);
61514
+ int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno);
61515
+ assert( nByte>=0 );
61516
+ memset((void*)sLoc.aPgno, 0, nByte);
6139061517
}
6139161518
6139261519
/* If the entry in aPgno[] is already set, then the previous writer
6139361520
** must have exited unexpectedly in the middle of a transaction (after
6139461521
** writing one or more dirty pages to the WAL to free up memory).
6139561522
** Remove the remnants of that writers uncommitted transaction from
6139661523
** the hash-table before writing any new entries.
6139761524
*/
61398
- if( sLoc.aPgno[idx] ){
61525
+ if( sLoc.aPgno[idx-1] ){
6139961526
walCleanupHash(pWal);
61400
- assert( !sLoc.aPgno[idx] );
61527
+ assert( !sLoc.aPgno[idx-1] );
6140161528
}
6140261529
6140361530
/* Write the aPgno[] array entry and the hash-table slot. */
6140461531
nCollide = idx;
6140561532
for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
6140661533
if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
6140761534
}
61408
- sLoc.aPgno[idx] = iPage;
61535
+ sLoc.aPgno[idx-1] = iPage;
6140961536
AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
6141061537
6141161538
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
6141261539
/* Verify that the number of entries in the hash table exactly equals
6141361540
** the number of entries in the mapping region.
@@ -61424,22 +61551,21 @@
6142461551
** thing to check, so only do this occasionally - not on every
6142561552
** iteration.
6142661553
*/
6142761554
if( (idx&0x3ff)==0 ){
6142861555
int i; /* Loop counter */
61429
- for(i=1; i<=idx; i++){
61556
+ for(i=0; i<idx; i++){
6143061557
for(iKey=walHash(sLoc.aPgno[i]);
6143161558
sLoc.aHash[iKey];
6143261559
iKey=walNextHash(iKey)){
61433
- if( sLoc.aHash[iKey]==i ) break;
61560
+ if( sLoc.aHash[iKey]==i+1 ) break;
6143461561
}
61435
- assert( sLoc.aHash[iKey]==i );
61562
+ assert( sLoc.aHash[iKey]==i+1 );
6143661563
}
6143761564
}
6143861565
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
6143961566
}
61440
-
6144161567
6144261568
return rc;
6144361569
}
6144461570
6144561571
@@ -61557,11 +61683,12 @@
6155761683
u32 iFrame; /* Index of last frame read */
6155861684
u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
6155961685
u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
6156061686
u32 nHdr, nHdr32;
6156161687
rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
61562
- if( rc ) break;
61688
+ assert( aShare!=0 || rc!=SQLITE_OK );
61689
+ if( aShare==0 ) break;
6156361690
pWal->apWiData[iPg] = aPrivate;
6156461691
6156561692
for(iFrame=iFirst; iFrame<=iLast; iFrame++){
6156661693
i64 iOffset = walFrameOffset(iFrame, szPage);
6156761694
u32 pgno; /* Database page number for frame */
@@ -62054,11 +62181,10 @@
6205462181
if( rc==SQLITE_OK ){
6205562182
int j; /* Counter variable */
6205662183
int nEntry; /* Number of entries in this segment */
6205762184
ht_slot *aIndex; /* Sorted index for this segment */
6205862185
62059
- sLoc.aPgno++;
6206062186
if( (i+1)==nSegment ){
6206162187
nEntry = (int)(iLast - sLoc.iZero);
6206262188
}else{
6206362189
nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
6206462190
}
@@ -63193,11 +63319,12 @@
6319363319
i64 iDbOff; /* Offset of db file entry */
6319463320
i64 iWalOff; /* Offset of wal file entry */
6319563321
6319663322
rc = walHashGet(pWal, walFramePage(i), &sLoc);
6319763323
if( rc!=SQLITE_OK ) break;
63198
- pgno = sLoc.aPgno[i-sLoc.iZero];
63324
+ assert( i - sLoc.iZero - 1 >=0 );
63325
+ pgno = sLoc.aPgno[i-sLoc.iZero-1];
6319963326
iDbOff = (i64)(pgno-1) * szPage;
6320063327
6320163328
if( iDbOff+szPage<=szDb ){
6320263329
iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
6320363330
rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
@@ -63426,11 +63553,11 @@
6342663553
}
6342763554
nCollide = HASHTABLE_NSLOT;
6342863555
iKey = walHash(pgno);
6342963556
while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
6343063557
u32 iFrame = iH + sLoc.iZero;
63431
- if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
63558
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){
6343263559
assert( iFrame>iRead || CORRUPT_DB );
6343363560
iRead = iFrame;
6343463561
}
6343563562
if( (nCollide--)==0 ){
6343663563
return SQLITE_CORRUPT_BKPT;
@@ -66919,11 +67046,11 @@
6691967046
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
6692067047
sz2 = get2byte(&data[iFree2+2]);
6692167048
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
6692267049
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
6692367050
sz += sz2;
66924
- }else if( iFree+sz>usableSize ){
67051
+ }else if( NEVER(iFree+sz>usableSize) ){
6692567052
return SQLITE_CORRUPT_PAGE(pPage);
6692667053
}
6692767054
6692867055
cbrk = top+sz;
6692967056
assert( cbrk+(iFree-top) <= usableSize );
@@ -69370,27 +69497,30 @@
6937069497
}
6937169498
6937269499
/*
6937369500
** This routine is called prior to sqlite3PagerCommit when a transaction
6937469501
** is committed for an auto-vacuum database.
69375
-**
69376
-** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
69377
-** the database file should be truncated to during the commit process.
69378
-** i.e. the database has been reorganized so that only the first *pnTrunc
69379
-** pages are in use.
6938069502
*/
69381
-static int autoVacuumCommit(BtShared *pBt){
69503
+static int autoVacuumCommit(Btree *p){
6938269504
int rc = SQLITE_OK;
69383
- Pager *pPager = pBt->pPager;
69384
- VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
69505
+ Pager *pPager;
69506
+ BtShared *pBt;
69507
+ sqlite3 *db;
69508
+ VVA_ONLY( int nRef );
69509
+
69510
+ assert( p!=0 );
69511
+ pBt = p->pBt;
69512
+ pPager = pBt->pPager;
69513
+ VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); )
6938569514
6938669515
assert( sqlite3_mutex_held(pBt->mutex) );
6938769516
invalidateAllOverflowCache(pBt);
6938869517
assert(pBt->autoVacuum);
6938969518
if( !pBt->incrVacuum ){
6939069519
Pgno nFin; /* Number of pages in database after autovacuuming */
6939169520
Pgno nFree; /* Number of pages on the freelist initially */
69521
+ Pgno nVac; /* Number of pages to vacuum */
6939269522
Pgno iFree; /* The next page to be freed */
6939369523
Pgno nOrig; /* Database size before freeing */
6939469524
6939569525
nOrig = btreePagecount(pBt);
6939669526
if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
@@ -69400,22 +69530,46 @@
6940069530
*/
6940169531
return SQLITE_CORRUPT_BKPT;
6940269532
}
6940369533
6940469534
nFree = get4byte(&pBt->pPage1->aData[36]);
69405
- nFin = finalDbSize(pBt, nOrig, nFree);
69535
+ db = p->db;
69536
+ if( db->xAutovacPages ){
69537
+ int iDb;
69538
+ for(iDb=0; ALWAYS(iDb<db->nDb); iDb++){
69539
+ if( db->aDb[iDb].pBt==p ) break;
69540
+ }
69541
+ nVac = db->xAutovacPages(
69542
+ db->pAutovacPagesArg,
69543
+ db->aDb[iDb].zDbSName,
69544
+ nOrig,
69545
+ nFree,
69546
+ pBt->pageSize
69547
+ );
69548
+ if( nVac>nFree ){
69549
+ nVac = nFree;
69550
+ }
69551
+ if( nVac==0 ){
69552
+ return SQLITE_OK;
69553
+ }
69554
+ }else{
69555
+ nVac = nFree;
69556
+ }
69557
+ nFin = finalDbSize(pBt, nOrig, nVac);
6940669558
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
6940769559
if( nFin<nOrig ){
6940869560
rc = saveAllCursors(pBt, 0, 0);
6940969561
}
6941069562
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
69411
- rc = incrVacuumStep(pBt, nFin, iFree, 1);
69563
+ rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree);
6941269564
}
6941369565
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
6941469566
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
69415
- put4byte(&pBt->pPage1->aData[32], 0);
69416
- put4byte(&pBt->pPage1->aData[36], 0);
69567
+ if( nVac==nFree ){
69568
+ put4byte(&pBt->pPage1->aData[32], 0);
69569
+ put4byte(&pBt->pPage1->aData[36], 0);
69570
+ }
6941769571
put4byte(&pBt->pPage1->aData[28], nFin);
6941869572
pBt->bDoTruncate = 1;
6941969573
pBt->nPage = nFin;
6942069574
}
6942169575
if( rc!=SQLITE_OK ){
@@ -69462,11 +69616,11 @@
6946269616
if( p->inTrans==TRANS_WRITE ){
6946369617
BtShared *pBt = p->pBt;
6946469618
sqlite3BtreeEnter(p);
6946569619
#ifndef SQLITE_OMIT_AUTOVACUUM
6946669620
if( pBt->autoVacuum ){
69467
- rc = autoVacuumCommit(pBt);
69621
+ rc = autoVacuumCommit(p);
6946869622
if( rc!=SQLITE_OK ){
6946969623
sqlite3BtreeLeave(p);
6947069624
return rc;
6947169625
}
6947269626
}
@@ -77424,10 +77578,12 @@
7742477578
nByte = 1;
7742577579
}
7742677580
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
7742777581
return SQLITE_NOMEM_BKPT;
7742877582
}
77583
+ assert( pMem->z!=0 );
77584
+ assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
7742977585
7743077586
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
7743177587
pMem->n += pMem->u.nZero;
7743277588
pMem->flags &= ~(MEM_Zero|MEM_Term);
7743377589
return SQLITE_OK;
@@ -77900,19 +78056,35 @@
7790078056
7790178057
/*
7790278058
** Delete any previous value and set the value to be a BLOB of length
7790378059
** n containing all zeros.
7790478060
*/
78061
+#ifndef SQLITE_OMIT_INCRBLOB
7790578062
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
7790678063
sqlite3VdbeMemRelease(pMem);
7790778064
pMem->flags = MEM_Blob|MEM_Zero;
7790878065
pMem->n = 0;
7790978066
if( n<0 ) n = 0;
7791078067
pMem->u.nZero = n;
7791178068
pMem->enc = SQLITE_UTF8;
7791278069
pMem->z = 0;
7791378070
}
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
7791478086
7791578087
/*
7791678088
** The pMem is known to contain content that needs to be destroyed prior
7791778089
** to a value change. So invoke the destructor, then set the value to
7791878090
** a 64-bit integer.
@@ -82037,13 +82209,19 @@
8203782209
8203882210
/* Lock all btrees used by the statement */
8203982211
sqlite3VdbeEnter(p);
8204082212
8204182213
/* Check for one of the special errors */
82042
- mrc = p->rc & 0xff;
82043
- isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
82044
- || 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
+ }
8204582223
if( isSpecialError ){
8204682224
/* If the query was read-only and the error code is SQLITE_INTERRUPT,
8204782225
** no rollback is necessary. Otherwise, at least a savepoint
8204882226
** transaction must be rolled back to restore the database to a
8204982227
** consistent state.
@@ -82091,10 +82269,13 @@
8209182269
if( NEVER(p->readOnly) ){
8209282270
sqlite3VdbeLeave(p);
8209382271
return SQLITE_ERROR;
8209482272
}
8209582273
rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82274
+ }else if( db->flags & SQLITE_CorruptRdOnly ){
82275
+ rc = SQLITE_CORRUPT;
82276
+ db->flags &= ~SQLITE_CorruptRdOnly;
8209682277
}else{
8209782278
/* The auto-commit flag is true, the vdbe program was successful
8209882279
** or hit an 'OR FAIL' constraint and there are no deferred foreign
8209982280
** key constraints to hold up the transaction. This means a commit
8210082281
** is required. */
@@ -84195,10 +84376,12 @@
8419584376
}else{
8419684377
iKey2 = iKey1;
8419784378
}
8419884379
}
8419984380
84381
+ assert( pCsr!=0 );
84382
+ assert( pCsr->eCurType==CURTYPE_BTREE );
8420084383
assert( pCsr->nField==pTab->nCol
8420184384
|| (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
8420284385
);
8420384386
8420484387
preupdate.v = v;
@@ -84773,12 +84956,16 @@
8477384956
Mem *pOut = pCtx->pOut;
8477484957
assert( sqlite3_mutex_held(pOut->db->mutex) );
8477584958
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
8477684959
return SQLITE_TOOBIG;
8477784960
}
84961
+#ifndef SQLITE_OMIT_INCRBLOB
8477884962
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
8477984963
return SQLITE_OK;
84964
+#else
84965
+ return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84966
+#endif
8478084967
}
8478184968
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
8478284969
pCtx->isError = errCode ? errCode : -1;
8478384970
#ifdef SQLITE_DEBUG
8478484971
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85786,11 +85973,15 @@
8578685973
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
8578785974
int rc;
8578885975
Vdbe *p = (Vdbe *)pStmt;
8578985976
rc = vdbeUnbind(p, i);
8579085977
if( rc==SQLITE_OK ){
85978
+#ifndef SQLITE_OMIT_INCRBLOB
8579185979
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
85980
+#else
85981
+ rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
85982
+#endif
8579285983
sqlite3_mutex_leave(p->db->mutex);
8579385984
}
8579485985
return rc;
8579585986
}
8579685987
SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86074,10 +86265,11 @@
8607486265
/* If the old.* record has not yet been loaded into memory, do so now. */
8607586266
if( p->pUnpacked==0 ){
8607686267
u32 nRec;
8607786268
u8 *aRec;
8607886269
86270
+ assert( p->pCsr->eCurType==CURTYPE_BTREE );
8607986271
nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
8608086272
aRec = sqlite3DbMallocRaw(db, nRec);
8608186273
if( !aRec ) goto preupdate_old_out;
8608286274
rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
8608386275
if( rc==SQLITE_OK ){
@@ -89391,20 +89583,25 @@
8939189583
rc = SQLITE_CORRUPT_BKPT;
8939289584
goto abort_due_to_error;
8939389585
}
8939489586
}
8939589587
89396
-/* Opcode: TypeCheck P1 P2 * P4 *
89588
+/* Opcode: TypeCheck P1 P2 P3 P4 *
8939789589
** Synopsis: typecheck(r[P1@P2])
8939889590
**
8939989591
** Apply affinities to the range of P2 registers beginning with P1.
8940089592
** Take the affinities from the Table object in P4. If any value
8940189593
** cannot be coerced into the correct type, then raise an error.
8940289594
**
8940389595
** This opcode is similar to OP_Affinity except that this opcode
8940489596
** forces the register type to the Table column type. This is used
8940589597
** to implement "strict affinity".
89598
+**
89599
+** GENERATED ALWAYS AS ... STATIC columns are only checked if P3
89600
+** is zero. When P3 is non-zero, no type checking occurs for
89601
+** static generated columns. Virtual columns are computed at query time
89602
+** and so they are never checked.
8940689603
**
8940789604
** Preconditions:
8940889605
**
8940989606
** <ul>
8941089607
** <li> P2 should be the number of non-virtual columns in the
@@ -89424,11 +89621,14 @@
8942489621
assert( pTab->tabFlags & TF_Strict );
8942589622
assert( pTab->nNVCol==pOp->p2 );
8942689623
aCol = pTab->aCol;
8942789624
pIn1 = &aMem[pOp->p1];
8942889625
for(i=0; i<pTab->nCol; i++){
89429
- if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
89626
+ if( aCol[i].colFlags & COLFLAG_GENERATED ){
89627
+ if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
89628
+ if( pOp->p3 ){ pIn1++; continue; }
89629
+ }
8943089630
assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
8943189631
applyAffinity(pIn1, aCol[i].affinity, encoding);
8943289632
if( (pIn1->flags & MEM_Null)==0 ){
8943389633
switch( aCol[i].eCType ){
8943489634
case COLTYPE_BLOB: {
@@ -90148,12 +90348,20 @@
9014890348
assert( p->bIsReader );
9014990349
assert( p->readOnly==0 || pOp->p2==0 );
9015090350
assert( pOp->p2>=0 && pOp->p2<=2 );
9015190351
assert( pOp->p1>=0 && pOp->p1<db->nDb );
9015290352
assert( DbMaskTest(p->btreeMask, pOp->p1) );
90153
- if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
90154
- rc = SQLITE_READONLY;
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
+ }
9015590363
goto abort_due_to_error;
9015690364
}
9015790365
pBt = db->aDb[pOp->p1].pBt;
9015890366
9015990367
if( pBt ){
@@ -90191,11 +90399,12 @@
9019190399
p->nStmtDefCons = db->nDeferredCons;
9019290400
p->nStmtDefImmCons = db->nDeferredImmCons;
9019390401
}
9019490402
}
9019590403
assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
90196
- if( pOp->p5
90404
+ if( rc==SQLITE_OK
90405
+ && pOp->p5
9019790406
&& (iMeta!=pOp->p3
9019890407
|| db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
9019990408
){
9020090409
/*
9020190410
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -92997,11 +93206,11 @@
9299793206
db->mDbFlags |= DBFLAG_SchemaChange;
9299893207
p->expired = 0;
9299993208
}else
9300093209
#endif
9300193210
{
93002
- zSchema = DFLT_SCHEMA_TABLE;
93211
+ zSchema = LEGACY_SCHEMA_TABLE;
9300393212
initData.db = db;
9300493213
initData.iDb = iDb;
9300593214
initData.pzErrMsg = &p->zErrMsg;
9300693215
initData.mInitFlags = 0;
9300793216
initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
@@ -94217,10 +94426,11 @@
9421794426
pQuery = &aMem[pOp->p3];
9421894427
pArgc = &pQuery[1];
9421994428
pCur = p->apCsr[pOp->p1];
9422094429
assert( memIsValid(pQuery) );
9422194430
REGISTER_TRACE(pOp->p3, pQuery);
94431
+ assert( pCur!=0 );
9422294432
assert( pCur->eCurType==CURTYPE_VTAB );
9422394433
pVCur = pCur->uc.pVCur;
9422494434
pVtab = pVCur->pVtab;
9422594435
pModule = pVtab->pModule;
9422694436
@@ -94265,10 +94475,11 @@
9426594475
const sqlite3_module *pModule;
9426694476
Mem *pDest;
9426794477
sqlite3_context sContext;
9426894478
9426994479
VdbeCursor *pCur = p->apCsr[pOp->p1];
94480
+ assert( pCur!=0 );
9427094481
assert( pCur->eCurType==CURTYPE_VTAB );
9427194482
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
9427294483
pDest = &aMem[pOp->p3];
9427394484
memAboutToChange(p, pDest);
9427494485
if( pCur->nullRow ){
@@ -94318,10 +94529,11 @@
9431894529
const sqlite3_module *pModule;
9431994530
int res;
9432094531
VdbeCursor *pCur;
9432194532
9432294533
pCur = p->apCsr[pOp->p1];
94534
+ assert( pCur!=0 );
9432394535
assert( pCur->eCurType==CURTYPE_VTAB );
9432494536
if( pCur->nullRow ){
9432594537
break;
9432694538
}
9432794539
pVtab = pCur->uc.pVCur->pVtab;
@@ -94413,11 +94625,11 @@
9441394625
case OP_VUpdate: {
9441494626
sqlite3_vtab *pVtab;
9441594627
const sqlite3_module *pModule;
9441694628
int nArg;
9441794629
int i;
94418
- sqlite_int64 rowid;
94630
+ sqlite_int64 rowid = 0;
9441994631
Mem **apArg;
9442094632
Mem *pX;
9442194633
9442294634
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
9442394635
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -94860,11 +95072,18 @@
9486095072
rc = SQLITE_CORRUPT_BKPT;
9486195073
}
9486295074
assert( rc );
9486395075
#ifdef SQLITE_DEBUG
9486495076
if( db->flags & SQLITE_VdbeTrace ){
94865
- 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);
9486695085
}
9486795086
#endif
9486895087
if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
9486995088
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
9487095089
}
@@ -94873,10 +95092,13 @@
9487395092
testcase( sqlite3GlobalConfig.xLog!=0 );
9487495093
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
9487595094
(int)(pOp - aOp), p->zSql, p->zErrMsg);
9487695095
sqlite3VdbeHalt(p);
9487795096
if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
95097
+ if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
95098
+ db->flags |= SQLITE_CorruptRdOnly;
95099
+ }
9487895100
rc = SQLITE_ERROR;
9487995101
if( resetSchemaOnFault>0 ){
9488095102
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
9488195103
}
9488295104
@@ -95004,11 +95226,14 @@
9500495226
}else{
9500595227
rc = sqlite3_step(p->pStmt);
9500695228
}
9500795229
if( rc==SQLITE_ROW ){
9500895230
VdbeCursor *pC = v->apCsr[0];
95009
- 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;
9501095235
testcase( pC->nHdrParsed==p->iCol );
9501195236
testcase( pC->nHdrParsed==p->iCol+1 );
9501295237
if( type<12 ){
9501395238
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
9501495239
type==0?"null": type==7?"real": "integer"
@@ -95349,10 +95574,12 @@
9534995574
** using the incremental-blob API, this works. For the sessions module
9535095575
** anyhow.
9535195576
*/
9535295577
sqlite3_int64 iKey;
9535395578
iKey = sqlite3BtreeIntegerKey(p->pCsr);
95579
+ assert( v->apCsr[0]!=0 );
95580
+ assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
9535495581
sqlite3VdbePreUpdateHook(
9535595582
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
9535695583
);
9535795584
}
9535895585
#endif
@@ -96731,11 +96958,11 @@
9673196958
void *p = 0;
9673296959
int chunksize = 4*1024;
9673396960
sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
9673496961
sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
9673596962
sqlite3OsFetch(pFd, 0, (int)nByte, &p);
96736
- sqlite3OsUnfetch(pFd, 0, p);
96963
+ if( p ) sqlite3OsUnfetch(pFd, 0, p);
9673796964
}
9673896965
}
9673996966
#else
9674096967
# define vdbeSorterExtendFile(x,y,z)
9674196968
#endif
@@ -97449,10 +97676,11 @@
9744997676
pTask->file2.iEof += pIncr->mxSz;
9745097677
}else{
9745197678
vdbeMergeEngineFree(pMerger);
9745297679
rc = SQLITE_NOMEM_BKPT;
9745397680
}
97681
+ assert( *ppOut!=0 || rc!=SQLITE_OK );
9745497682
return rc;
9745597683
}
9745697684
9745797685
#if SQLITE_MAX_WORKER_THREADS>0
9745897686
/*
@@ -100427,19 +100655,22 @@
100427100655
sqlite3WindowLink(pSel, pWin);
100428100656
pNC->ncFlags |= NC_HasWin;
100429100657
}else
100430100658
#endif /* SQLITE_OMIT_WINDOWFUNC */
100431100659
{
100432
- NameContext *pNC2 = pNC;
100660
+ NameContext *pNC2; /* For looping up thru outer contexts */
100433100661
pExpr->op = TK_AGG_FUNCTION;
100434100662
pExpr->op2 = 0;
100435100663
#ifndef SQLITE_OMIT_WINDOWFUNC
100436100664
if( ExprHasProperty(pExpr, EP_WinFunc) ){
100437100665
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100438100666
}
100439100667
#endif
100440
- while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
100668
+ pNC2 = pNC;
100669
+ while( pNC2
100670
+ && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
100671
+ ){
100441100672
pExpr->op2++;
100442100673
pNC2 = pNC2->pNext;
100443100674
}
100444100675
assert( pDef!=0 || IN_RENAME_OBJECT );
100445100676
if( pNC2 && pDef ){
@@ -101405,12 +101636,12 @@
101405101636
101406101637
/*
101407101638
** Return the affinity character for a single column of a table.
101408101639
*/
101409101640
SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101410
- assert( iCol<pTab->nCol );
101411
- 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;
101412101643
}
101413101644
101414101645
/*
101415101646
** Return the 'affinity' of the expression pExpr if any.
101416101647
**
@@ -103131,11 +103362,11 @@
103131103362
}
103132103363
103133103364
return pRet;
103134103365
}
103135103366
#else
103136
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
103367
+SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
103137103368
assert( p==0 );
103138103369
return 0;
103139103370
}
103140103371
#endif
103141103372
@@ -104186,11 +104417,12 @@
104186104417
Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104187104418
Expr *pRhs = pEList->a[i].pExpr;
104188104419
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104189104420
int j;
104190104421
104191
- assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
104422
+ assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104423
+ || pParse->nErr || db->mallocFailed );
104192104424
for(j=0; j<nExpr; j++){
104193104425
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104194104426
assert( pIdx->azColl[j] );
104195104427
if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104196104428
continue;
@@ -107262,93 +107494,128 @@
107262107494
sqlite3WalkExpr(&w, pExpr);
107263107495
return !w.eCode;
107264107496
}
107265107497
107266107498
107267
-/*
107268
-** An instance of the following structure is used by the tree walker
107269
-** to count references to table columns in the arguments of an
107270
-** aggregate function, in order to implement the
107271
-** sqlite3FunctionThisSrc() routine.
107499
+/* Structure used to pass information throught the Walker in order to
107500
+** implement sqlite3ReferencesSrcList().
107272107501
*/
107273
-struct SrcCount {
107274
- SrcList *pSrc; /* One particular FROM clause in a nested query */
107275
- int iSrcInner; /* Smallest cursor number in this context */
107276
- int nThis; /* Number of references to columns in pSrcList */
107277
- 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 */
107278107507
};
107279107508
107280107509
/*
107281
-** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
107282
-** SELECT with a FROM clause encountered during this iteration, set
107283
-** SrcCount.iSrcInner to the cursor number of the leftmost object in
107284
-** 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.
107285107516
*/
107286
-static int selectSrcCount(Walker *pWalker, Select *pSel){
107287
- struct SrcCount *p = pWalker->u.pSrcCount;
107288
- if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
107289
- 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;
107290107533
}
107291107534
return WRC_Continue;
107292107535
}
107293
-
107294
-/*
107295
-** Count the number of references to columns.
107296
-*/
107297
-static int exprSrcCount(Walker *pWalker, Expr *pExpr){
107298
- /* There was once a NEVER() on the second term on the grounds that
107299
- ** sqlite3FunctionUsesThisSrc() was always called before
107300
- ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
107301
- ** been converted into TK_AGG_COLUMN. But this is no longer true due
107302
- ** to window functions - sqlite3WindowRewrite() may now indirectly call
107303
- ** FunctionUsesThisSrc() when creating a new sub-select. */
107304
- if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
107305
- int i;
107306
- struct SrcCount *p = pWalker->u.pSrcCount;
107307
- 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;
107308107560
int nSrc = pSrc ? pSrc->nSrc : 0;
107309107561
for(i=0; i<nSrc; i++){
107310
- if( pExpr->iTable==pSrc->a[i].iCursor ) break;
107311
- }
107312
- if( i<nSrc ){
107313
- p->nThis++;
107314
- }else if( pExpr->iTable<p->iSrcInner ){
107315
- /* In a well-formed parse tree (no name resolution errors),
107316
- ** TK_COLUMN nodes with smaller Expr.iTable values are in an
107317
- ** outer context. Those are the only ones to count as "other" */
107318
- 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;
107319107570
}
107320107571
}
107321107572
return WRC_Continue;
107322107573
}
107323107574
107324107575
/*
107325
-** Determine if any of the arguments to the pExpr Function reference
107326
-** pSrcList. Return true if they do. Also return true if the function
107327
-** has no arguments or has only constant arguments. Return false if pExpr
107328
-** 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.
107329107589
*/
107330
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
107590
+SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
107331107591
Walker w;
107332
- struct SrcCount cnt;
107333
- assert( pExpr->op==TK_AGG_FUNCTION );
107592
+ struct RefSrcList x;
107334107593
memset(&w, 0, sizeof(w));
107335
- w.xExprCallback = exprSrcCount;
107336
- w.xSelectCallback = selectSrcCount;
107337
- w.u.pSrcCount = &cnt;
107338
- cnt.pSrc = pSrcList;
107339
- cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
107340
- cnt.nThis = 0;
107341
- 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 );
107342107602
assert( ExprUseXList(pExpr) );
107343107603
sqlite3WalkExprList(&w, pExpr->x.pList);
107344107604
#ifndef SQLITE_OMIT_WINDOWFUNC
107345107605
if( ExprHasProperty(pExpr, EP_WinFunc) ){
107346107606
sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107347107607
}
107348107608
#endif
107349
- 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
+ }
107350107617
}
107351107618
107352107619
/*
107353107620
** This is a Walker expression node callback.
107354107621
**
@@ -107758,11 +108025,11 @@
107758108025
int bNoDQS /* Do not allow DQS in the schema */
107759108026
){
107760108027
pParse->colNamesSet = 1;
107761108028
sqlite3NestedParse(pParse,
107762108029
"SELECT 1 "
107763
- "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
108030
+ "FROM \"%w\"." LEGACY_SCHEMA_TABLE " "
107764108031
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107765108032
" AND sql NOT LIKE 'create virtual%%'"
107766108033
" AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
107767108034
zDb,
107768108035
zDb, bTemp, zWhen, bNoDQS
@@ -107769,11 +108036,11 @@
107769108036
);
107770108037
107771108038
if( bTemp==0 ){
107772108039
sqlite3NestedParse(pParse,
107773108040
"SELECT 1 "
107774
- "FROM temp." DFLT_SCHEMA_TABLE " "
108041
+ "FROM temp." LEGACY_SCHEMA_TABLE " "
107775108042
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107776108043
" AND sql NOT LIKE 'create virtual%%'"
107777108044
" AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
107778108045
zDb, zWhen, bNoDQS
107779108046
);
@@ -107787,18 +108054,18 @@
107787108054
** not true, similarly update all SQL statements in the sqlite_schema table
107788108055
** of the temp db.
107789108056
*/
107790108057
static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
107791108058
sqlite3NestedParse(pParse,
107792
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE
108059
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE
107793108060
" SET sql = sqlite_rename_quotefix(%Q, sql)"
107794108061
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107795108062
" AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
107796108063
);
107797108064
if( bTemp==0 ){
107798108065
sqlite3NestedParse(pParse,
107799
- "UPDATE temp." DFLT_SCHEMA_TABLE
108066
+ "UPDATE temp." LEGACY_SCHEMA_TABLE
107800108067
" SET sql = sqlite_rename_quotefix('temp', sql)"
107801108068
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107802108069
" AND sql NOT LIKE 'create virtual%%'"
107803108070
);
107804108071
}
@@ -107912,21 +108179,21 @@
107912108179
nTabName = sqlite3Utf8CharLen(zTabName, -1);
107913108180
107914108181
/* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
107915108182
** the schema to use the new table name. */
107916108183
sqlite3NestedParse(pParse,
107917
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108184
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
107918108185
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
107919108186
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
107920108187
"AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107921108188
, zDb, zDb, zTabName, zName, (iDb==1), zTabName
107922108189
);
107923108190
107924108191
/* Update the tbl_name and name columns of the sqlite_schema table
107925108192
** as required. */
107926108193
sqlite3NestedParse(pParse,
107927
- "UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
108194
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET "
107928108195
"tbl_name = %Q, "
107929108196
"name = CASE "
107930108197
"WHEN type='table' THEN %Q "
107931108198
"WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
107932108199
" AND type='index' THEN "
@@ -108111,11 +108378,11 @@
108111108378
/* substr() operations on characters, but addColOffset is in bytes. So we
108112108379
** have to use printf() to translate between these units: */
108113108380
assert( IsOrdinaryTable(pTab) );
108114108381
assert( IsOrdinaryTable(pNew) );
108115108382
sqlite3NestedParse(pParse,
108116
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108383
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108117108384
"sql = printf('%%.%ds, ',sql) || %Q"
108118108385
" || substr(sql,1+length(printf('%%.%ds',sql))) "
108119108386
"WHERE type = 'table' AND name = %Q",
108120108387
zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,
108121108388
zTab
@@ -108137,11 +108404,11 @@
108137108404
VdbeCoverage(v);
108138108405
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
108139108406
sqlite3ReleaseTempReg(pParse, r1);
108140108407
108141108408
/* Reload the table definition */
108142
- renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
108409
+ renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd);
108143108410
108144108411
/* Verify that constraints are still satisfied */
108145108412
if( pNew->pCheck!=0
108146108413
|| (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
108147108414
){
@@ -108345,21 +108612,21 @@
108345108612
zNew = sqlite3NameFromToken(db, pNew);
108346108613
if( !zNew ) goto exit_rename_column;
108347108614
assert( pNew->n>0 );
108348108615
bQuote = sqlite3Isquote(pNew->z[0]);
108349108616
sqlite3NestedParse(pParse,
108350
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108617
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108351108618
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
108352108619
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
108353108620
" AND (type != 'index' OR tbl_name = %Q)",
108354108621
zDb,
108355108622
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
108356108623
pTab->zName
108357108624
);
108358108625
108359108626
sqlite3NestedParse(pParse,
108360
- "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
108627
+ "UPDATE temp." LEGACY_SCHEMA_TABLE " SET "
108361108628
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
108362108629
"WHERE type IN ('trigger', 'view')",
108363108630
zDb, pTab->zName, iCol, zNew, bQuote
108364108631
);
108365108632
@@ -109030,10 +109297,13 @@
109030109297
}else{
109031109298
p->pTab->nTabRef++;
109032109299
rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
109033109300
}
109034109301
}
109302
+ }
109303
+ if( rc==SQLITE_OK && db->mallocFailed ){
109304
+ rc = SQLITE_NOMEM;
109035109305
}
109036109306
sNC.pSrcList = pSrc;
109037109307
if( rc==SQLITE_OK && pStep->pWhere ){
109038109308
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
109039109309
}
@@ -109833,11 +110103,11 @@
109833110103
assert( iDb>=0 );
109834110104
zDb = db->aDb[iDb].zDbSName;
109835110105
renameTestSchema(pParse, zDb, iDb==1, "", 0);
109836110106
renameFixQuotes(pParse, zDb, iDb==1);
109837110107
sqlite3NestedParse(pParse,
109838
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
110108
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
109839110109
"sql = sqlite_drop_column(%d, sql, %d) "
109840110110
"WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
109841110111
, zDb, iDb, iCol, pTab->zName
109842110112
);
109843110113
@@ -113122,21 +113392,21 @@
113122113392
}
113123113393
}
113124113394
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113125113395
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113126113396
if( i==1 ){
113127
- if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0
113128
- || sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0
113129
- || sqlite3StrICmp(zName+7, &DFLT_SCHEMA_TABLE[7])==0
113397
+ if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0
113398
+ || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0
113399
+ || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0
113130113400
){
113131113401
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113132
- DFLT_TEMP_SCHEMA_TABLE);
113402
+ LEGACY_TEMP_SCHEMA_TABLE);
113133113403
}
113134113404
}else{
113135
- if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
113405
+ if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113136113406
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
113137
- DFLT_SCHEMA_TABLE);
113407
+ LEGACY_SCHEMA_TABLE);
113138113408
}
113139113409
}
113140113410
}
113141113411
}else{
113142113412
/* Match against TEMP first */
@@ -113150,15 +113420,15 @@
113150113420
assert( sqlite3SchemaMutexHeld(db, i, 0) );
113151113421
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113152113422
if( p ) break;
113153113423
}
113154113424
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113155
- if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
113156
- p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE);
113157
- }else if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 ){
113425
+ if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113426
+ p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE);
113427
+ }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
113158113428
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113159
- DFLT_TEMP_SCHEMA_TABLE);
113429
+ LEGACY_TEMP_SCHEMA_TABLE);
113160113430
}
113161113431
}
113162113432
}
113163113433
return p;
113164113434
}
@@ -113249,10 +113519,26 @@
113249113519
}else{
113250113520
zDb = p->zDatabase;
113251113521
}
113252113522
return sqlite3LocateTable(pParse, flags, p->zName, zDb);
113253113523
}
113524
+
113525
+/*
113526
+** Return the preferred table name for system tables. Translate legacy
113527
+** names into the new preferred names, as appropriate.
113528
+*/
113529
+SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){
113530
+ if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113531
+ if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){
113532
+ return PREFERRED_SCHEMA_TABLE;
113533
+ }
113534
+ if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){
113535
+ return PREFERRED_TEMP_SCHEMA_TABLE;
113536
+ }
113537
+ }
113538
+ return zName;
113539
+}
113254113540
113255113541
/*
113256113542
** Locate the in-memory structure that describes
113257113543
** a particular index given the name of that index
113258113544
** and the name of the database that contains the index.
@@ -113648,11 +113934,11 @@
113648113934
** Open the sqlite_schema table stored in database number iDb for
113649113935
** writing. The table is opened using cursor 0.
113650113936
*/
113651113937
SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){
113652113938
Vdbe *v = sqlite3GetVdbe(p);
113653
- sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
113939
+ sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE);
113654113940
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
113655113941
if( p->nTab==0 ){
113656113942
p->nTab = 1;
113657113943
}
113658113944
}
@@ -115227,10 +115513,45 @@
115227115513
if( pMod->pModule->xShadowName==0 ) return 0;
115228115514
return pMod->pModule->xShadowName(zName+nName+1);
115229115515
}
115230115516
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115231115517
115518
+#ifndef SQLITE_OMIT_VIRTUALTABLE
115519
+/*
115520
+** Table pTab is a virtual table. If it the virtual table implementation
115521
+** exists and has an xShadowName method, then loop over all other ordinary
115522
+** tables within the same schema looking for shadow tables of pTab, and mark
115523
+** any shadow tables seen using the TF_Shadow flag.
115524
+*/
115525
+SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){
115526
+ int nName; /* Length of pTab->zName */
115527
+ Module *pMod; /* Module for the virtual table */
115528
+ HashElem *k; /* For looping through the symbol table */
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);
115540
+ assert( pOther->zName!=0 );
115541
+ if( !IsOrdinaryTable(pOther) ) continue;
115542
+ if( pOther->tabFlags & TF_Shadow ) continue;
115543
+ if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0
115544
+ && pOther->zName[nName]=='_'
115545
+ && pMod->pModule->xShadowName(pOther->zName+nName+1)
115546
+ ){
115547
+ pOther->tabFlags |= TF_Shadow;
115548
+ }
115549
+ }
115550
+}
115551
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115552
+
115232115553
#ifndef SQLITE_OMIT_VIRTUALTABLE
115233115554
/*
115234115555
** Return true if zName is a shadow table name in the current database
115235115556
** connection.
115236115557
**
@@ -115555,11 +115876,11 @@
115555115876
/* A slot for the record has already been allocated in the
115556115877
** schema table. We just need to update that slot with all
115557115878
** the information we've collected.
115558115879
*/
115559115880
sqlite3NestedParse(pParse,
115560
- "UPDATE %Q." DFLT_SCHEMA_TABLE
115881
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE
115561115882
" SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
115562115883
" WHERE rowid=#%d",
115563115884
db->aDb[iDb].zDbSName,
115564115885
zType,
115565115886
p->zName,
@@ -115741,17 +116062,16 @@
115741116062
#endif
115742116063
115743116064
assert( pTable );
115744116065
115745116066
#ifndef SQLITE_OMIT_VIRTUALTABLE
115746
- db->nSchemaLock++;
115747
- rc = sqlite3VtabCallConnect(pParse, pTable);
115748
- db->nSchemaLock--;
115749
- if( rc ){
115750
- return 1;
116067
+ if( IsVirtual(pTable) ){
116068
+ db->nSchemaLock++;
116069
+ rc = sqlite3VtabCallConnect(pParse, pTable);
116070
+ db->nSchemaLock--;
116071
+ return rc;
115751116072
}
115752
- if( IsVirtual(pTable) ) return 0;
115753116073
#endif
115754116074
115755116075
#ifndef SQLITE_OMIT_VIEW
115756116076
/* A positive nCol means the columns names for this view are
115757116077
** already known.
@@ -115935,11 +116255,11 @@
115935116255
** The "#NNN" in the SQL is a special constant that means whatever value
115936116256
** is in register NNN. See grammar rules associated with the TK_REGISTER
115937116257
** token for additional information.
115938116258
*/
115939116259
sqlite3NestedParse(pParse,
115940
- "UPDATE %Q." DFLT_SCHEMA_TABLE
116260
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE
115941116261
" SET rootpage=%d WHERE #%d AND rootpage=#%d",
115942116262
pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
115943116263
#endif
115944116264
sqlite3ReleaseTempReg(pParse, r1);
115945116265
}
@@ -116070,11 +116390,11 @@
116070116390
** dropped. Triggers are handled separately because a trigger can be
116071116391
** created in the temp database that refers to a table in another
116072116392
** database.
116073116393
*/
116074116394
sqlite3NestedParse(pParse,
116075
- "DELETE FROM %Q." DFLT_SCHEMA_TABLE
116395
+ "DELETE FROM %Q." LEGACY_SCHEMA_TABLE
116076116396
" WHERE tbl_name=%Q and type!='trigger'",
116077116397
pDb->zDbSName, pTab->zName);
116078116398
if( !isView && !IsVirtual(pTab) ){
116079116399
destroyTable(pParse, pTab);
116080116400
}
@@ -116117,10 +116437,13 @@
116117116437
if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
116118116438
return 1;
116119116439
}
116120116440
if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
116121116441
return 1;
116442
+ }
116443
+ if( pTab->tabFlags & TF_Eponymous ){
116444
+ return 1;
116122116445
}
116123116446
return 0;
116124116447
}
116125116448
116126116449
/*
@@ -117087,11 +117410,11 @@
117087117410
}
117088117411
117089117412
/* Add an entry in sqlite_schema for this index
117090117413
*/
117091117414
sqlite3NestedParse(pParse,
117092
- "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
117415
+ "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
117093117416
db->aDb[iDb].zDbSName,
117094117417
pIndex->zName,
117095117418
pTab->zName,
117096117419
iMem,
117097117420
zStmt
@@ -117273,11 +117596,11 @@
117273117596
/* Generate code to remove the index and from the schema table */
117274117597
v = sqlite3GetVdbe(pParse);
117275117598
if( v ){
117276117599
sqlite3BeginWriteOperation(pParse, 1, iDb);
117277117600
sqlite3NestedParse(pParse,
117278
- "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117601
+ "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117279117602
db->aDb[iDb].zDbSName, pIndex->zName
117280117603
);
117281117604
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
117282117605
sqlite3ChangeCookie(pParse, iDb);
117283117606
destroyRootPage(pParse, pIndex->tnum, iDb);
@@ -123933,28 +124256,34 @@
123933124256
123934124257
/* Before computing generated columns, first go through and make sure
123935124258
** that appropriate affinity has been applied to the regular columns
123936124259
*/
123937124260
sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
123938
- if( (pTab->tabFlags & TF_HasStored)!=0
123939
- && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity
123940
- ){
123941
- /* Change the OP_Affinity argument to '@' (NONE) for all stored
123942
- ** columns. '@' is the no-op affinity and those columns have not
123943
- ** yet been computed. */
123944
- int ii, jj;
123945
- char *zP4 = pOp->p4.z;
123946
- assert( zP4!=0 );
123947
- assert( pOp->p4type==P4_DYNAMIC );
123948
- for(ii=jj=0; zP4[jj]; ii++){
123949
- if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
123950
- continue;
123951
- }
123952
- if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
123953
- zP4[jj] = SQLITE_AFF_NONE;
123954
- }
123955
- jj++;
124261
+ if( (pTab->tabFlags & TF_HasStored)!=0 ){
124262
+ pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
124263
+ if( pOp->opcode==OP_Affinity ){
124264
+ /* Change the OP_Affinity argument to '@' (NONE) for all stored
124265
+ ** columns. '@' is the no-op affinity and those columns have not
124266
+ ** yet been computed. */
124267
+ int ii, jj;
124268
+ char *zP4 = pOp->p4.z;
124269
+ assert( zP4!=0 );
124270
+ assert( pOp->p4type==P4_DYNAMIC );
124271
+ for(ii=jj=0; zP4[jj]; ii++){
124272
+ if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
124273
+ continue;
124274
+ }
124275
+ if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
124276
+ zP4[jj] = SQLITE_AFF_NONE;
124277
+ }
124278
+ jj++;
124279
+ }
124280
+ }else if( pOp->opcode==OP_TypeCheck ){
124281
+ /* If an OP_TypeCheck was generated because the table is STRICT,
124282
+ ** then set the P3 operand to indicate that generated columns should
124283
+ ** not be checked */
124284
+ pOp->p3 = 1;
123956124285
}
123957124286
}
123958124287
123959124288
/* Because there can be multiple generated columns that refer to one another,
123960124289
** this is a two-pass algorithm. On the first pass, mark all generated
@@ -125978,11 +126307,12 @@
125978126307
default: {
125979126308
int nConflictCk; /* Number of opcodes in conflict check logic */
125980126309
125981126310
assert( onError==OE_Replace );
125982126311
nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
125983
- assert( nConflictCk>0 );
126312
+ assert( nConflictCk>0 || db->mallocFailed );
126313
+ testcase( nConflictCk<=0 );
125984126314
testcase( nConflictCk>1 );
125985126315
if( regTrigCnt ){
125986126316
sqlite3MultiWrite(pParse);
125987126317
nReplaceTrig++;
125988126318
}
@@ -126264,12 +126594,13 @@
126264126594
126265126595
assert( op==OP_OpenRead || op==OP_OpenWrite );
126266126596
assert( op==OP_OpenWrite || p5==0 );
126267126597
if( IsVirtual(pTab) ){
126268126598
/* This routine is a no-op for virtual tables. Leave the output
126269
- ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
126270
- ** can detect if they are used by mistake in the caller. */
126599
+ ** variables *piDataCur and *piIdxCur set to illegal cursor numbers
126600
+ ** for improved error detection. */
126601
+ *piDataCur = *piIdxCur = -999;
126271126602
return 0;
126272126603
}
126273126604
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
126274126605
v = pParse->pVdbe;
126275126606
assert( v!=0 );
@@ -127276,10 +127607,14 @@
127276127607
/* Version 3.34.0 and later */
127277127608
int (*txn_state)(sqlite3*,const char*);
127278127609
/* Version 3.36.1 and later */
127279127610
sqlite3_int64 (*changes64)(sqlite3*);
127280127611
sqlite3_int64 (*total_changes64)(sqlite3*);
127612
+ /* Version 3.37.0 and later */
127613
+ int (*autovacuum_pages)(sqlite3*,
127614
+ unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
127615
+ void*, void(*)(void*));
127281127616
};
127282127617
127283127618
/*
127284127619
** This is the function signature used for all extension entry points. It
127285127620
** is also defined in the file "loadext.c".
@@ -127582,10 +127917,15 @@
127582127917
#define sqlite3_create_filename sqlite3_api->create_filename
127583127918
#define sqlite3_free_filename sqlite3_api->free_filename
127584127919
#define sqlite3_database_file_object sqlite3_api->database_file_object
127585127920
/* Version 3.34.0 and later */
127586127921
#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
127587127927
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127588127928
127589127929
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127590127930
/* This case when the file really is being compiled as a loadable
127591127931
** extension */
@@ -128069,10 +128409,12 @@
128069128409
/* Version 3.34.0 and later */
128070128410
sqlite3_txn_state,
128071128411
/* Version 3.36.1 and later */
128072128412
sqlite3_changes64,
128073128413
sqlite3_total_changes64,
128414
+ /* Version 3.37.0 and later */
128415
+ sqlite3_autovacuum_pages,
128074128416
};
128075128417
128076128418
/* True if x is the directory separator character
128077128419
*/
128078128420
#if SQLITE_OS_WIN
@@ -130391,11 +130733,11 @@
130391130733
}else{
130392130734
zType = "table";
130393130735
}
130394130736
sqlite3VdbeMultiLoad(v, 1, "sssiii",
130395130737
db->aDb[ii].zDbSName,
130396
- pTab->zName,
130738
+ sqlite3PreferredTableName(pTab->zName),
130397130739
zType,
130398130740
pTab->nCol,
130399130741
(pTab->tabFlags & TF_WithoutRowid)!=0,
130400130742
(pTab->tabFlags & TF_Strict)!=0
130401130743
);
@@ -130411,11 +130753,11 @@
130411130753
pParse->nMem = 5;
130412130754
sqlite3CodeVerifySchema(pParse, iDb);
130413130755
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
130414130756
Table *pTab = sqliteHashData(i);
130415130757
sqlite3VdbeMultiLoad(v, 1, "ssiii",
130416
- pTab->zName,
130758
+ sqlite3PreferredTableName(pTab->zName),
130417130759
0,
130418130760
pTab->szTabRow,
130419130761
pTab->nRowLogEst,
130420130762
pTab->tabFlags);
130421130763
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -130906,11 +131248,11 @@
130906131248
if( pCol->notNull ){
130907131249
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
130908131250
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
130909131251
pCol->zCnName);
130910131252
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
130911
- if( bStrict ){
131253
+ if( bStrict && pCol->eCType!=COLTYPE_ANY ){
130912131254
sqlite3VdbeGoto(v, doError);
130913131255
}else{
130914131256
integrityCheckResultRow(v);
130915131257
}
130916131258
sqlite3VdbeJumpHere(v, jmp2);
@@ -131867,14 +132209,19 @@
131867132209
sqlite3 *db = pData->db;
131868132210
if( db->mallocFailed ){
131869132211
pData->rc = SQLITE_NOMEM_BKPT;
131870132212
}else if( pData->pzErrMsg[0]!=0 ){
131871132213
/* A error message has already been generated. Do not overwrite it */
131872
- }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){
132214
+ }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
132215
+ static const char *azAlterType[] = {
132216
+ "rename",
132217
+ "drop column",
132218
+ "add column"
132219
+ };
131873132220
*pData->pzErrMsg = sqlite3MPrintf(db,
131874132221
"error in %s %s after %s: %s", azObj[0], azObj[1],
131875
- (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column",
132222
+ azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1],
131876132223
zExtra
131877132224
);
131878132225
pData->rc = SQLITE_ERROR;
131879132226
}else if( db->flags & SQLITE_WriteSchema ){
131880132227
pData->rc = SQLITE_CORRUPT_BKPT;
@@ -135070,10 +135417,13 @@
135070135417
n = sqlite3Strlen30(pCol->zCnName);
135071135418
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
135072135419
if( pCol->zCnName ){
135073135420
memcpy(&pCol->zCnName[n+1], zType, m+1);
135074135421
pCol->colFlags |= COLFLAG_HASTYPE;
135422
+ }else{
135423
+ testcase( pCol->colFlags & COLFLAG_HASTYPE );
135424
+ pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
135075135425
}
135076135426
}
135077135427
if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
135078135428
pColl = sqlite3ExprCollSeq(pParse, p);
135079135429
if( pColl ){
@@ -137809,31 +138159,44 @@
137809138159
**
137810138160
** SELECT count(*) FROM <tbl>
137811138161
**
137812138162
** where table is a database table, not a sub-select or view. If the query
137813138163
** does match this pattern, then a pointer to the Table object representing
137814
-** <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.
137815138171
*/
137816138172
static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
137817138173
Table *pTab;
137818138174
Expr *pExpr;
137819138175
137820138176
assert( !p->pGroupBy );
137821138177
137822
- if( p->pWhere || p->pEList->nExpr!=1
137823
- || 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
137824138183
){
137825138184
return 0;
137826138185
}
137827138186
pTab = p->pSrc->a[0].pTab;
138187
+ assert( pTab!=0 );
138188
+ assert( !IsView(pTab) );
138189
+ if( !IsOrdinaryTable(pTab) ) return 0;
137828138190
pExpr = p->pEList->a[0].pExpr;
137829
- assert( pTab && !IsView(pTab) && pExpr );
137830
-
137831
- if( IsVirtual(pTab) ) return 0;
138191
+ assert( pExpr!=0 );
137832138192
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
137833
- if( NEVER(pAggInfo->nFunc==0) ) return 0;
138193
+ if( pExpr->pAggInfo!=pAggInfo ) return 0;
137834138194
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) );
137835138198
if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
137836138199
137837138200
return pTab;
137838138201
}
137839138202
@@ -140934,11 +141297,11 @@
140934141297
if( v==0 ) goto triggerfinish_cleanup;
140935141298
sqlite3BeginWriteOperation(pParse, 0, iDb);
140936141299
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
140937141300
testcase( z==0 );
140938141301
sqlite3NestedParse(pParse,
140939
- "INSERT INTO %Q." DFLT_SCHEMA_TABLE
141302
+ "INSERT INTO %Q." LEGACY_SCHEMA_TABLE
140940141303
" VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
140941141304
db->aDb[iDb].zDbSName, zName,
140942141305
pTrig->table, z);
140943141306
sqlite3DbFree(db, z);
140944141307
sqlite3ChangeCookie(pParse, iDb);
@@ -141248,11 +141611,11 @@
141248141611
141249141612
/* Generate code to destroy the database record of the trigger.
141250141613
*/
141251141614
if( (v = sqlite3GetVdbe(pParse))!=0 ){
141252141615
sqlite3NestedParse(pParse,
141253
- "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
141616
+ "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
141254141617
db->aDb[iDb].zDbSName, pTrigger->zName
141255141618
);
141256141619
sqlite3ChangeCookie(pParse, iDb);
141257141620
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
141258141621
}
@@ -143901,11 +144264,13 @@
143901144264
rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
143902144265
if( rc!=SQLITE_OK ) goto end_of_vacuum;
143903144266
143904144267
/* Do not attempt to change the page size for a WAL database */
143905144268
if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
143906
- ==PAGER_JOURNALMODE_WAL ){
144269
+ ==PAGER_JOURNALMODE_WAL
144270
+ && pOut==0
144271
+ ){
143907144272
db->nextPagesize = 0;
143908144273
}
143909144274
143910144275
if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
143911144276
|| (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
@@ -144543,11 +144908,11 @@
144543144908
** entry in the sqlite_schema table tht was created for this vtab
144544144909
** by sqlite3StartTable().
144545144910
*/
144546144911
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
144547144912
sqlite3NestedParse(pParse,
144548
- "UPDATE %Q." DFLT_SCHEMA_TABLE " "
144913
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE " "
144549144914
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
144550144915
"WHERE rowid=#%d",
144551144916
db->aDb[iDb].zDbSName,
144552144917
pTab->zName,
144553144918
pTab->zName,
@@ -144563,22 +144928,18 @@
144563144928
sqlite3DbFree(db, zStmt);
144564144929
144565144930
iReg = ++pParse->nMem;
144566144931
sqlite3VdbeLoadString(v, iReg, pTab->zName);
144567144932
sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
144568
- }
144569
-
144570
- /* If we are rereading the sqlite_schema table create the in-memory
144571
- ** record of the table. The xConnect() method is not called until
144572
- ** the first time the virtual table is used in an SQL statement. This
144573
- ** allows a schema that contains virtual tables to be loaded before
144574
- ** the required virtual table implementations are registered. */
144575
- else {
144933
+ }else{
144934
+ /* If we are rereading the sqlite_schema table create the in-memory
144935
+ ** record of the table. */
144576144936
Table *pOld;
144577144937
Schema *pSchema = pTab->pSchema;
144578144938
const char *zName = pTab->zName;
144579
- assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
144939
+ assert( zName!=0 );
144940
+ sqlite3MarkAllShadowTablesOf(db, pTab);
144580144941
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
144581144942
if( pOld ){
144582144943
sqlite3OomFault(db);
144583144944
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
144584144945
return;
@@ -144758,11 +145119,12 @@
144758145119
const char *zMod;
144759145120
Module *pMod;
144760145121
int rc;
144761145122
144762145123
assert( pTab );
144763
- if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
145124
+ assert( IsVirtual(pTab) );
145125
+ if( sqlite3GetVTable(db, pTab) ){
144764145126
return SQLITE_OK;
144765145127
}
144766145128
144767145129
/* Locate the required virtual table module */
144768145130
zMod = pTab->u.vtab.azArg[0];
@@ -144962,11 +145324,14 @@
144962145324
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
144963145325
int rc = SQLITE_OK;
144964145326
Table *pTab;
144965145327
144966145328
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
144967
- 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
+ ){
144968145333
VTable *p;
144969145334
int (*xDestroy)(sqlite3_vtab *);
144970145335
for(p=pTab->u.vtab.p; p; p=p->pNext){
144971145336
assert( p->pVtab );
144972145337
if( p->pVtab->nRef>0 ){
@@ -147900,12 +148265,23 @@
147900148265
147901148266
/* Load the value for the inequality constraint at the end of the
147902148267
** range (if any).
147903148268
*/
147904148269
nConstraint = nEq;
148270
+ assert( pLevel->p2==0 );
147905148271
if( pRangeEnd ){
147906148272
Expr *pRight = pRangeEnd->pExpr->pRight;
148273
+ if( addrSeekScan ){
148274
+ /* For a seek-scan that has a range on the lowest term of the index,
148275
+ ** we have to make the top of the loop be code that sets the end
148276
+ ** condition of the range. Otherwise, the OP_SeekScan might jump
148277
+ ** over that initialization, leaving the range-end value set to the
148278
+ ** range-start value, resulting in a wrong answer.
148279
+ ** See ticket 5981a8c041a3c2f3 (2021-11-02).
148280
+ */
148281
+ pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148282
+ }
147907148283
codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
147908148284
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
147909148285
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
147910148286
&& sqlite3ExprCanBeNull(pRight)
147911148287
){
@@ -147935,11 +148311,11 @@
147935148311
}
147936148312
sqlite3DbFree(db, zStartAff);
147937148313
sqlite3DbFree(db, zEndAff);
147938148314
147939148315
/* Top of the loop body */
147940
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148316
+ if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
147941148317
147942148318
/* Check if the index cursor is past the end of the range. */
147943148319
if( nConstraint ){
147944148320
if( regBignull ){
147945148321
/* Except, skip the end-of-range check while doing the NULL-scan */
@@ -155575,10 +155951,11 @@
155575155951
** program.
155576155952
*/
155577155953
for(ii=0; ii<nTabList; ii++){
155578155954
int addrExplain;
155579155955
int wsFlags;
155956
+ if( pParse->nErr ) goto whereBeginError;
155580155957
pLevel = &pWInfo->a[ii];
155581155958
wsFlags = pLevel->pWLoop->wsFlags;
155582155959
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155583155960
if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155584155961
constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -157028,11 +157405,15 @@
157028157405
}
157029157406
}else{
157030157407
sqlite3SelectDelete(db, pSub);
157031157408
}
157032157409
if( db->mallocFailed ) rc = SQLITE_NOMEM;
157033
- 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);
157034157415
}
157035157416
157036157417
if( rc ){
157037157418
if( pParse->nErr==0 ){
157038157419
assert( pParse->db->mallocFailed );
@@ -160475,13 +160856,13 @@
160475160856
yyStackEntry *yystackEnd; /* Last entry in the stack */
160476160857
#endif
160477160858
};
160478160859
typedef struct yyParser yyParser;
160479160860
160861
+/* #include <assert.h> */
160480160862
#ifndef NDEBUG
160481160863
/* #include <stdio.h> */
160482
-/* #include <assert.h> */
160483160864
static FILE *yyTraceFILE = 0;
160484160865
static char *yyTracePrompt = 0;
160485160866
#endif /* NDEBUG */
160486160867
160487160868
#ifndef NDEBUG
@@ -164226,12 +164607,12 @@
164226164607
assert( yypParser->yytos>=yypParser->yystack );
164227164608
assert( yyact==yypParser->yytos->stateno );
164228164609
yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
164229164610
if( yyact >= YY_MIN_REDUCE ){
164230164611
unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
164231
- assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164232164612
#ifndef NDEBUG
164613
+ assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164233164614
if( yyTraceFILE ){
164234164615
int yysize = yyRuleInfoNRhs[yyruleno];
164235164616
if( yysize ){
164236164617
fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
164237164618
yyTracePrompt,
@@ -167559,10 +167940,13 @@
167559167940
** So it needs to be freed here. Todo: Why not roll the temp schema into
167560167941
** the same sqliteMalloc() as the one that allocates the database
167561167942
** structure?
167562167943
*/
167563167944
sqlite3DbFree(db, db->aDb[1].pSchema);
167945
+ if( db->xAutovacDestr ){
167946
+ db->xAutovacDestr(db->pAutovacPagesArg);
167947
+ }
167564167948
sqlite3_mutex_leave(db->mutex);
167565167949
db->eOpenState = SQLITE_STATE_CLOSED;
167566167950
sqlite3_mutex_free(db->mutex);
167567167951
assert( sqlite3LookasideUsed(db,0)==0 );
167568167952
if( db->lookaside.bMalloced ){
@@ -167613,11 +167997,11 @@
167613167997
sqlite3BtreeLeaveAll(db);
167614167998
167615167999
/* Any deferred constraint violations have now been resolved. */
167616168000
db->nDeferredCons = 0;
167617168001
db->nDeferredImmCons = 0;
167618
- db->flags &= ~(u64)SQLITE_DeferFKs;
168002
+ db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
167619168003
167620168004
/* If one has been configured, invoke the rollback-hook callback */
167621168005
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
167622168006
db->xRollbackCallback(db->pRollbackArg);
167623168007
}
@@ -168459,10 +168843,38 @@
168459168843
db->pPreUpdateArg = pArg;
168460168844
sqlite3_mutex_leave(db->mutex);
168461168845
return pRet;
168462168846
}
168463168847
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
168848
+
168849
+/*
168850
+** Register a function to be invoked prior to each autovacuum that
168851
+** determines the number of pages to vacuum.
168852
+*/
168853
+SQLITE_API int sqlite3_autovacuum_pages(
168854
+ sqlite3 *db, /* Attach the hook to this database */
168855
+ unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
168856
+ void *pArg, /* Argument to the function */
168857
+ void (*xDestructor)(void*) /* Destructor for pArg */
168858
+){
168859
+#ifdef SQLITE_ENABLE_API_ARMOR
168860
+ if( !sqlite3SafetyCheckOk(db) ){
168861
+ if( xDestructor ) xDestructor(pArg);
168862
+ return SQLITE_MISUSE_BKPT;
168863
+ }
168864
+#endif
168865
+ sqlite3_mutex_enter(db->mutex);
168866
+ if( db->xAutovacDestr ){
168867
+ db->xAutovacDestr(db->pAutovacPagesArg);
168868
+ }
168869
+ db->xAutovacPages = xCallback;
168870
+ db->pAutovacPagesArg = pArg;
168871
+ db->xAutovacDestr = xDestructor;
168872
+ sqlite3_mutex_leave(db->mutex);
168873
+ return SQLITE_OK;
168874
+}
168875
+
168464168876
168465168877
#ifndef SQLITE_OMIT_WAL
168466168878
/*
168467168879
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
168468168880
** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
@@ -169313,12 +169725,12 @@
169313169725
**
169314169726
** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
169315169727
** dealt with in the previous code block. Besides these, the only
169316169728
** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
169317169729
** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
169318
- ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
169319
- ** off all other flags.
169730
+ ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
169731
+ ** bits. Silently mask off all other flags.
169320169732
*/
169321169733
flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
169322169734
SQLITE_OPEN_EXCLUSIVE |
169323169735
SQLITE_OPEN_MAIN_DB |
169324169736
SQLITE_OPEN_TEMP_DB |
@@ -169349,11 +169761,11 @@
169349169761
if( isThreadsafe==0 ){
169350169762
sqlite3MutexWarnOnContention(db->mutex);
169351169763
}
169352169764
}
169353169765
sqlite3_mutex_enter(db->mutex);
169354
- db->errMask = 0xff;
169766
+ db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
169355169767
db->nDb = 2;
169356169768
db->eOpenState = SQLITE_STATE_BUSY;
169357169769
db->aDb = db->aDbStatic;
169358169770
db->lookaside.bDisable = 1;
169359169771
db->lookaside.sz = 0;
@@ -169581,12 +169993,12 @@
169581169993
assert( db->mutex!=0 || isThreadsafe==0
169582169994
|| sqlite3GlobalConfig.bFullMutex==0 );
169583169995
sqlite3_mutex_leave(db->mutex);
169584169996
}
169585169997
rc = sqlite3_errcode(db);
169586
- assert( db!=0 || rc==SQLITE_NOMEM );
169587
- if( rc==SQLITE_NOMEM ){
169998
+ assert( db!=0 || (rc&0xff)==SQLITE_NOMEM );
169999
+ if( (rc&0xff)==SQLITE_NOMEM ){
169588170000
sqlite3_close(db);
169589170001
db = 0;
169590170002
}else if( rc!=SQLITE_OK ){
169591170003
db->eOpenState = SQLITE_STATE_SICK;
169592170004
}
@@ -169597,11 +170009,11 @@
169597170009
void *pArg = sqlite3GlobalConfig.pSqllogArg;
169598170010
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
169599170011
}
169600170012
#endif
169601170013
sqlite3_free_filename(zOpen);
169602
- return rc & 0xff;
170014
+ return rc;
169603170015
}
169604170016
169605170017
169606170018
/*
169607170019
** Open a new database handle.
@@ -178147,10 +178559,13 @@
178147178559
while( rc==SQLITE_OK && !pNear->bEof ){
178148178560
fts3EvalNextRow(pCsr, pNear, &rc);
178149178561
if( bEofSave==0 && pNear->iDocid==iDocid ) break;
178150178562
}
178151178563
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
178564
+ if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
178565
+ rc = FTS_CORRUPT_VTAB;
178566
+ }
178152178567
}
178153178568
if( bTreeEof ){
178154178569
while( rc==SQLITE_OK && !pNear->bEof ){
178155178570
fts3EvalNextRow(pCsr, pNear, &rc);
178156178571
}
@@ -189837,17 +190252,17 @@
189837190252
int iEnd = 0;
189838190253
int iCurrent = 0;
189839190254
const char *zDoc;
189840190255
int nDoc;
189841190256
189842
- /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
189843
- ** no way that this operation can fail, so the return code from
189844
- ** 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.
189845190259
*/
189846190260
sCtx.iCol = iCol;
189847190261
sCtx.iTerm = 0;
189848
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190262
+ rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190263
+ if( rc!=SQLITE_OK ) goto offsets_out;
189849190264
189850190265
/* Retreive the text stored in column iCol. If an SQL NULL is stored
189851190266
** in column iCol, jump immediately to the next iteration of the loop.
189852190267
** If an OOM occurs while retrieving the data (this can happen if SQLite
189853190268
** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -190856,11 +191271,11 @@
190856191271
# define ALWAYS(X) (X)
190857191272
# define NEVER(X) (X)
190858191273
# endif
190859191274
# define testcase(X)
190860191275
#endif
190861
-#if defined(NDEBUG)
191276
+#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
190862191277
# define VVA(X)
190863191278
#else
190864191279
# define VVA(X) X
190865191280
#endif
190866191281
@@ -192407,12 +192822,15 @@
192407192822
}else{
192408192823
JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
192409192824
if( pNew==0 ) return 0;
192410192825
pTarget = &pParse->aNode[iTarget];
192411192826
if( pNew!=&pTarget[j+1] ){
192412
- 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 );
192413192830
testcase( pTarget[j+1].eU==1 );
192831
+ testcase( pTarget[j+1].eU==2 );
192414192832
VVA( pTarget[j+1].eU = 5 );
192415192833
pTarget[j+1].u.pPatch = pNew;
192416192834
pTarget[j+1].jnFlags |= JNODE_PATCH;
192417192835
}
192418192836
}
@@ -201403,10 +201821,17 @@
201403201821
** Swap two objects of type TYPE.
201404201822
*/
201405201823
#if !defined(SQLITE_AMALGAMATION)
201406201824
# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
201407201825
#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
+
201408201833
201409201834
/*
201410201835
** The rbu_state table is used to save the state of a partially applied
201411201836
** update so that it can be resumed later. The table consists of integer
201412201837
** keys mapped to values as follows:
@@ -204050,17 +204475,23 @@
204050204475
204051204476
204052204477
/*
204053204478
** Open the database handle and attach the RBU database as "rbu". If an
204054204479
** 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.
204055204484
*/
204056
-static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
204485
+static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
204057204486
assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
204058204487
assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
204488
+ assert( dbMain==0 || rbuIsVacuum(p)==0 );
204059204489
204060204490
/* Open the RBU database */
204061204491
p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
204492
+ p->dbMain = dbMain;
204062204493
204063204494
if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
204064204495
sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
204065204496
if( p->zState==0 ){
204066204497
const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -204422,19 +204853,35 @@
204422204853
p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
204423204854
}
204424204855
204425204856
204426204857
/*
204427
-** 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.
204428204860
*/
204429
-static void rbuLockDatabase(sqlite3rbu *p){
204430
- sqlite3_file *pReal = p->pTargetFd->pReal;
204431
- assert( p->rc==SQLITE_OK );
204432
- p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
204433
- if( p->rc==SQLITE_OK ){
204434
- 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
+ }
204435204871
}
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);
204436204883
}
204437204884
204438204885
#if defined(_WIN32_WCE)
204439204886
static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
204440204887
int nChar;
@@ -204488,22 +204935,28 @@
204488204935
** in WAL mode). So no other connection may be writing the db.
204489204936
**
204490204937
** In order to ensure that there are no database readers, an EXCLUSIVE
204491204938
** lock is obtained here before the *-oal is moved to *-wal.
204492204939
*/
204493
- 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
+
204494204957
if( p->rc==SQLITE_OK ){
204495
- rbuFileSuffix3(zBase, zWal);
204496
- rbuFileSuffix3(zBase, zOal);
204497
-
204498
- /* Re-open the databases. */
204499
- rbuObjIterFinalize(&p->objiter);
204500
- sqlite3_close(p->dbRbu);
204501
- sqlite3_close(p->dbMain);
204502
- p->dbMain = 0;
204503
- p->dbRbu = 0;
204504
-
204505204958
#if defined(_WIN32_WCE)
204506204959
{
204507204960
LPWSTR zWideOal;
204508204961
LPWSTR zWideWal;
204509204962
@@ -204526,15 +204979,23 @@
204526204979
}
204527204980
}
204528204981
#else
204529204982
p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204530204983
#endif
204984
+ }
204531204985
204532
- if( p->rc==SQLITE_OK ){
204533
- rbuOpenDatabase(p, 0);
204534
- rbuSetupCheckpoint(p, 0);
204535
- }
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);
204536204997
}
204537204998
}
204538204999
204539205000
sqlite3_free(zWal);
204540205001
sqlite3_free(zOal);
@@ -205281,13 +205742,13 @@
205281205742
** to be a wal-mode db. But, this may have happened due to an earlier
205282205743
** RBU vacuum operation leaving an old wal file in the directory.
205283205744
** If this is the case, it will have been checkpointed and deleted
205284205745
** when the handle was closed and a second attempt to open the
205285205746
** database may succeed. */
205286
- rbuOpenDatabase(p, &bRetry);
205747
+ rbuOpenDatabase(p, 0, &bRetry);
205287205748
if( bRetry ){
205288
- rbuOpenDatabase(p, 0);
205749
+ rbuOpenDatabase(p, 0, 0);
205289205750
}
205290205751
}
205291205752
205292205753
if( p->rc==SQLITE_OK ){
205293205754
pState = rbuLoadState(p);
@@ -205378,10 +205839,18 @@
205378205839
}
205379205840
}
205380205841
}else if( p->eStage==RBU_STAGE_MOVE ){
205381205842
/* no-op */
205382205843
}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
+ }
205383205852
rbuSetupCheckpoint(p, pState);
205384205853
}else if( p->eStage==RBU_STAGE_DONE ){
205385205854
p->rc = SQLITE_DONE;
205386205855
}else{
205387205856
p->rc = SQLITE_CORRUPT;
@@ -205415,11 +205884,10 @@
205415205884
const char *zTarget,
205416205885
const char *zRbu,
205417205886
const char *zState
205418205887
){
205419205888
if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
205420
- /* TODO: Check that zTarget and zRbu are non-NULL */
205421205889
return openRbuHandle(zTarget, zRbu, zState);
205422205890
}
205423205891
205424205892
/*
205425205893
** Open a handle to begin or resume an RBU VACUUM operation.
@@ -215536,13 +216004,13 @@
215536216004
fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
215537216005
#endif
215538216006
};
215539216007
typedef struct fts5yyParser fts5yyParser;
215540216008
215541
-#ifndef NDEBUG
215542
-/* #include <stdio.h> */
215543216009
/* #include <assert.h> */
216010
+#ifndef NDEBUG
216011
+/* #include <stdio.h> */
215544216012
static FILE *fts5yyTraceFILE = 0;
215545216013
static char *fts5yyTracePrompt = 0;
215546216014
#endif /* NDEBUG */
215547216015
215548216016
#ifndef NDEBUG
@@ -216475,12 +216943,12 @@
216475216943
assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
216476216944
assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
216477216945
fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
216478216946
if( fts5yyact >= fts5YY_MIN_REDUCE ){
216479216947
unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
216480
- assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216481216948
#ifndef NDEBUG
216949
+ assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216482216950
if( fts5yyTraceFILE ){
216483216951
int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
216484216952
if( fts5yysize ){
216485216953
fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
216486216954
fts5yyTracePrompt,
@@ -221608,20 +222076,29 @@
221608222076
Fts5PoslistWriter writer;
221609222077
int bOk; /* True if ok to populate */
221610222078
int bMiss;
221611222079
};
221612222080
222081
+/*
222082
+** Clear the position lists associated with all phrases in the expression
222083
+** passed as the first argument. Argument bLive is true if the expression
222084
+** might be pointing to a real entry, otherwise it has just been reset.
222085
+**
222086
+** At present this function is only used for detail=col and detail=none
222087
+** fts5 tables. This implies that all phrases must be at most 1 token
222088
+** in size, as phrase matches are not supported without detail=full.
222089
+*/
221613222090
static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
221614222091
Fts5PoslistPopulator *pRet;
221615222092
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221616222093
if( pRet ){
221617222094
int i;
221618222095
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221619222096
for(i=0; i<pExpr->nPhrase; i++){
221620222097
Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
221621222098
Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
221622
- assert( pExpr->apExprPhrase[i]->nTerm==1 );
222099
+ assert( pExpr->apExprPhrase[i]->nTerm<=1 );
221623222100
if( bLive &&
221624222101
(pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
221625222102
){
221626222103
pRet[i].bMiss = 1;
221627222104
}else{
@@ -231982,11 +232459,11 @@
231982232459
int nArg, /* Number of args */
231983232460
sqlite3_value **apUnused /* Function arguments */
231984232461
){
231985232462
assert( nArg==0 );
231986232463
UNUSED_PARAM2(nArg, apUnused);
231987
- sqlite3_result_text(pCtx, "fts5: 2021-10-22 11:17:29 1a038242dc6c0cab97dd9375acfce62aa1c386debc36aaed388d366b87ddd931", -1, SQLITE_TRANSIENT);
232464
+ sqlite3_result_text(pCtx, "fts5: 2021-11-15 19:10:13 bd66ab8a1bc3c43a57c7caff5f54545b0feb0177f1f51492f30d308c123c43ba", -1, SQLITE_TRANSIENT);
231988232465
}
231989232466
231990232467
/*
231991232468
** Return true if zName is the extension on one of the shadow tables used
231992232469
** by this module.
231993232470
--- 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-10-22 11:17:29 1a038242dc6c0cab97dd9375acfce62aa1c386debc36aaed388d366b87ddd931"
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 **
@@ -6709,10 +6718,76 @@
6709 **
6710 ** See also the [sqlite3_update_hook()] interface.
6711 */
6712 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
6713 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6714
6715 /*
6716 ** CAPI3REF: Data Change Notification Callbacks
6717 ** METHOD: sqlite3
6718 **
@@ -14078,15 +14153,29 @@
14078 int nBusy; /* Incremented with each busy call */
14079 };
14080
14081 /*
14082 ** Name of table that holds the database schema.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14083 */
14084 #define DFLT_SCHEMA_TABLE "sqlite_master"
14085 #define DFLT_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14086 #define ALT_SCHEMA_TABLE "sqlite_schema"
14087 #define ALT_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
14088
14089
14090 /*
14091 ** The root-page of the schema table.
14092 */
@@ -14094,11 +14183,11 @@
14094
14095 /*
14096 ** The name of the schema table. The name is different for TEMP.
14097 */
14098 #define SCHEMA_TABLE(x) \
14099 ((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE)
14100
14101 /*
14102 ** A convenience macro that returns the number of elements in
14103 ** an array.
14104 */
@@ -16437,10 +16526,13 @@
16437 int (*xCommitCallback)(void*); /* Invoked at every commit. */
16438 void *pRollbackArg; /* Argument to xRollbackCallback() */
16439 void (*xRollbackCallback)(void*); /* Invoked at every commit. */
16440 void *pUpdateArg;
16441 void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
 
 
 
16442 Parse *pParse; /* Current parse */
16443 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
16444 void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
16445 void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
16446 void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
@@ -16566,10 +16658,11 @@
16566 #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
16567 #define SQLITE_EnableView 0x80000000 /* Enable the use of views */
16568 #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
16569 /* DELETE, or UPDATE and return */
16570 /* the count using a callback. */
 
16571
16572 /* Flags used only if debugging */
16573 #ifdef SQLITE_DEBUG
16574 #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
16575 #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -18694,12 +18787,14 @@
18694 } InitData;
18695
18696 /*
18697 ** Allowed values for mInitFlags
18698 */
 
18699 #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
18700 #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
 
18701
18702 /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
18703 ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
18704 ** parameters are for temporary use during development, to help find
18705 ** optimial values for parameters in the query planner. The should not
@@ -18816,12 +18911,12 @@
18816 union { /* Extra data for callback */
18817 NameContext *pNC; /* Naming context */
18818 int n; /* A counter */
18819 int iCur; /* A cursor number */
18820 SrcList *pSrcList; /* FROM clause */
18821 struct SrcCount *pSrcCount; /* Counting column references */
18822 struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
 
18823 int *aiCol; /* array of column indexes */
18824 struct IdxCover *pIdxCover; /* Check for index coverage */
18825 struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
18826 ExprList *pGroupBy; /* GROUP BY clause */
18827 Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19458,10 +19553,11 @@
19458 SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
19459 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
19460 #define LOCATE_VIEW 0x01
19461 #define LOCATE_NOERR 0x02
19462 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
 
19463 SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
19464 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
19465 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
19466 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
19467 SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
@@ -19474,11 +19570,11 @@
19474 SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
19475 SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
19476 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
19477 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
19478 SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19479 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
19480 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
19481 #ifndef SQLITE_UNTESTABLE
19482 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
19483 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
19484 #endif
@@ -19916,13 +20012,15 @@
19916 #endif
19917 SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
19918 #ifndef SQLITE_OMIT_VIRTUALTABLE
19919 SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
19920 SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
 
19921 #else
19922 # define sqlite3ShadowTableName(A,B) 0
19923 # define sqlite3IsShadowTableOf(A,B,C) 0
 
19924 #endif
19925 SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
19926 SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
19927 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
19928 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -22105,11 +22203,15 @@
22105 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
22106 #endif
22107 SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
22108 SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
22109 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
 
22110 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
 
 
 
22111 #ifdef SQLITE_DEBUG
22112 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
22113 #endif
22114 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
22115 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
@@ -24126,16 +24228,19 @@
24126 pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
24127 if( pFile ){
24128 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
24129 if( rc!=SQLITE_OK ){
24130 sqlite3_free(pFile);
 
24131 }else{
24132 *ppFile = pFile;
24133 }
24134 }else{
 
24135 rc = SQLITE_NOMEM_BKPT;
24136 }
 
24137 return rc;
24138 }
24139 SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
24140 assert( pFile );
24141 sqlite3OsClose(pFile);
@@ -38079,11 +38184,13 @@
38079 }
38080 }
38081
38082 /* Forward declaration */
38083 static int unixGetTempname(int nBuf, char *zBuf);
38084 static int unixFcntlExternalReader(unixFile*, int*);
 
 
38085
38086 /*
38087 ** Information and control of an open file handle.
38088 */
38089 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -38198,11 +38305,16 @@
38198 return proxyFileControl(id,op,pArg);
38199 }
38200 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
38201
38202 case SQLITE_FCNTL_EXTERNAL_READER: {
 
38203 return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
 
 
 
 
38204 }
38205 }
38206 return SQLITE_NOTFOUND;
38207 }
38208
@@ -40252,10 +40364,15 @@
40252 if( randomnessPid!=osGetpid(0) ){
40253 randomnessPid = osGetpid(0);
40254 sqlite3_randomness(0,0);
40255 }
40256 memset(p, 0, sizeof(unixFile));
 
 
 
 
 
40257
40258 if( eType==SQLITE_OPEN_MAIN_DB ){
40259 UnixUnusedFd *pUnused;
40260 pUnused = findReusableFd(zName, flags);
40261 if( pUnused ){
@@ -48664,11 +48781,11 @@
48664 /*
48665 ** Try to enlarge the memory allocation to hold at least sz bytes
48666 */
48667 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
48668 unsigned char *pNew;
48669 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
48670 return SQLITE_FULL;
48671 }
48672 if( newSz>p->szMax ){
48673 return SQLITE_FULL;
48674 }
@@ -48723,12 +48840,13 @@
48723 */
48724 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
48725 MemStore *p = ((MemFile*)pFile)->pStore;
48726 int rc = SQLITE_OK;
48727 memdbEnter(p);
48728 if( NEVER(size>p->sz) ){
48729 rc = SQLITE_FULL;
 
48730 }else{
48731 p->sz = size;
48732 }
48733 memdbLeave(p);
48734 return rc;
@@ -48863,11 +48981,11 @@
48863 int iAmt,
48864 void **pp
48865 ){
48866 MemStore *p = ((MemFile*)pFile)->pStore;
48867 memdbEnter(p);
48868 if( iOfst+iAmt>p->sz ){
48869 *pp = 0;
48870 }else{
48871 p->nMmap++;
48872 *pp = (void*)(p->aData + iOfst);
48873 }
@@ -48897,13 +49015,12 @@
48897 int *pOutFlags
48898 ){
48899 MemFile *pFile = (MemFile*)pFd;
48900 MemStore *p = 0;
48901 int szName;
48902 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
48903 return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
48904 }
48905 memset(pFile, 0, sizeof(*pFile));
48906 szName = sqlite3Strlen30(zName);
48907 if( szName>1 && zName[0]=='/' ){
48908 int i;
48909 #ifndef SQLITE_MUTEX_OMIT
@@ -48959,12 +49076,13 @@
48959 memset(p, 0, sizeof(*p));
48960 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
48961 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
48962 }
48963 pFile->pStore = p;
48964 assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
48965 *pOutFlags = flags | SQLITE_OPEN_MEMORY;
 
48966 pFd->pMethods = &memdb_io_methods;
48967 memdbLeave(p);
48968 return SQLITE_OK;
48969 }
48970
@@ -53155,10 +53273,11 @@
53155 u8 walSyncFlags; /* See description above */
53156 u8 tempFile; /* zFilename is a temporary or immutable file */
53157 u8 noLock; /* Do not lock (except in WAL mode) */
53158 u8 readOnly; /* True for a read-only database */
53159 u8 memDb; /* True to inhibit all file I/O */
 
53160
53161 /**************************************************************************
53162 ** The following block contains those class members that change during
53163 ** routine operation. Class members not in this block are either fixed
53164 ** when the pager is first created or else only change when there is a
@@ -57397,11 +57516,11 @@
57397 if( zFilename && zFilename[0] ){
57398 int fout = 0; /* VFS flags returned by xOpen() */
57399 rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
57400 assert( !memDb );
57401 #ifndef SQLITE_OMIT_DESERIALIZE
57402 memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
57403 #endif
57404 readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
57405
57406 /* If the file was successfully opened for read/write access,
57407 ** choose a default page size in case we have to create the
@@ -59334,11 +59453,11 @@
59334
59335 /*
59336 ** Return true if this is an in-memory or temp-file backed pager.
59337 */
59338 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
59339 return pPager->tempFile;
59340 }
59341
59342 /*
59343 ** Check that there are at least nSavepoint savepoints open. If there are
59344 ** currently less than nSavepoints open, then open one or more savepoints
@@ -60859,13 +60978,17 @@
60859 ** If the wal-index is currently smaller the iPage pages then the size
60860 ** of the wal-index might be increased, but only if it is safe to do
60861 ** so. It is safe to enlarge the wal-index if pWal->writeLock is true
60862 ** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
60863 **
60864 ** If this call is successful, *ppPage is set to point to the wal-index
60865 ** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
60866 ** then an SQLite error code is returned and *ppPage is set to 0.
 
 
 
 
60867 */
60868 static SQLITE_NOINLINE int walIndexPageRealloc(
60869 Wal *pWal, /* The WAL context */
60870 int iPage, /* The page we seek */
60871 volatile u32 **ppPage /* Write the page pointer here */
@@ -60894,11 +61017,13 @@
60894 if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
60895 }else{
60896 rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
60897 pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
60898 );
60899 assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
 
 
60900 testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
60901 if( rc==SQLITE_OK ){
60902 if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
60903 }else if( (rc&0xff)==SQLITE_READONLY ){
60904 pWal->readOnly |= WAL_SHM_RDONLY;
@@ -61233,12 +61358,12 @@
61233 ** in the wal-index file. Set pLoc->iZero to one less than the frame
61234 ** number of the first frame indexed by this hash table. If a
61235 ** slot in the hash table is set to N, it refers to frame number
61236 ** (pLoc->iZero+N) in the log.
61237 **
61238 ** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
61239 ** first frame indexed by the hash table, frame (pLoc->iZero+1).
61240 */
61241 static int walHashGet(
61242 Wal *pWal, /* WAL handle */
61243 int iHash, /* Find the iHash'th table */
61244 WalHashLoc *pLoc /* OUT: Hash table location */
@@ -61246,19 +61371,20 @@
61246 int rc; /* Return code */
61247
61248 rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
61249 assert( rc==SQLITE_OK || iHash>0 );
61250
61251 if( rc==SQLITE_OK ){
61252 pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
61253 if( iHash==0 ){
61254 pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
61255 pLoc->iZero = 0;
61256 }else{
61257 pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
61258 }
61259 pLoc->aPgno = &pLoc->aPgno[-1];
 
61260 }
61261 return rc;
61262 }
61263
61264 /*
@@ -61336,25 +61462,26 @@
61336 }
61337
61338 /* Zero the entries in the aPgno array that correspond to frames with
61339 ** frame numbers greater than pWal->hdr.mxFrame.
61340 */
61341 nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
61342 memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
 
61343
61344 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61345 /* Verify that the every entry in the mapping region is still reachable
61346 ** via the hash table even after the cleanup.
61347 */
61348 if( iLimit ){
61349 int j; /* Loop counter */
61350 int iKey; /* Hash key */
61351 for(j=1; j<=iLimit; j++){
61352 for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
61353 if( sLoc.aHash[iKey]==j ) break;
61354 }
61355 assert( sLoc.aHash[iKey]==j );
61356 }
61357 }
61358 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61359 }
61360
@@ -61382,32 +61509,32 @@
61382
61383 /* If this is the first entry to be added to this hash-table, zero the
61384 ** entire hash table and aPgno[] array before proceeding.
61385 */
61386 if( idx==1 ){
61387 int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
61388 - (u8 *)&sLoc.aPgno[1]);
61389 memset((void*)&sLoc.aPgno[1], 0, nByte);
61390 }
61391
61392 /* If the entry in aPgno[] is already set, then the previous writer
61393 ** must have exited unexpectedly in the middle of a transaction (after
61394 ** writing one or more dirty pages to the WAL to free up memory).
61395 ** Remove the remnants of that writers uncommitted transaction from
61396 ** the hash-table before writing any new entries.
61397 */
61398 if( sLoc.aPgno[idx] ){
61399 walCleanupHash(pWal);
61400 assert( !sLoc.aPgno[idx] );
61401 }
61402
61403 /* Write the aPgno[] array entry and the hash-table slot. */
61404 nCollide = idx;
61405 for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61406 if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
61407 }
61408 sLoc.aPgno[idx] = iPage;
61409 AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
61410
61411 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61412 /* Verify that the number of entries in the hash table exactly equals
61413 ** the number of entries in the mapping region.
@@ -61424,22 +61551,21 @@
61424 ** thing to check, so only do this occasionally - not on every
61425 ** iteration.
61426 */
61427 if( (idx&0x3ff)==0 ){
61428 int i; /* Loop counter */
61429 for(i=1; i<=idx; i++){
61430 for(iKey=walHash(sLoc.aPgno[i]);
61431 sLoc.aHash[iKey];
61432 iKey=walNextHash(iKey)){
61433 if( sLoc.aHash[iKey]==i ) break;
61434 }
61435 assert( sLoc.aHash[iKey]==i );
61436 }
61437 }
61438 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61439 }
61440
61441
61442 return rc;
61443 }
61444
61445
@@ -61557,11 +61683,12 @@
61557 u32 iFrame; /* Index of last frame read */
61558 u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
61559 u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
61560 u32 nHdr, nHdr32;
61561 rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
61562 if( rc ) break;
 
61563 pWal->apWiData[iPg] = aPrivate;
61564
61565 for(iFrame=iFirst; iFrame<=iLast; iFrame++){
61566 i64 iOffset = walFrameOffset(iFrame, szPage);
61567 u32 pgno; /* Database page number for frame */
@@ -62054,11 +62181,10 @@
62054 if( rc==SQLITE_OK ){
62055 int j; /* Counter variable */
62056 int nEntry; /* Number of entries in this segment */
62057 ht_slot *aIndex; /* Sorted index for this segment */
62058
62059 sLoc.aPgno++;
62060 if( (i+1)==nSegment ){
62061 nEntry = (int)(iLast - sLoc.iZero);
62062 }else{
62063 nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
62064 }
@@ -63193,11 +63319,12 @@
63193 i64 iDbOff; /* Offset of db file entry */
63194 i64 iWalOff; /* Offset of wal file entry */
63195
63196 rc = walHashGet(pWal, walFramePage(i), &sLoc);
63197 if( rc!=SQLITE_OK ) break;
63198 pgno = sLoc.aPgno[i-sLoc.iZero];
 
63199 iDbOff = (i64)(pgno-1) * szPage;
63200
63201 if( iDbOff+szPage<=szDb ){
63202 iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
63203 rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
@@ -63426,11 +63553,11 @@
63426 }
63427 nCollide = HASHTABLE_NSLOT;
63428 iKey = walHash(pgno);
63429 while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
63430 u32 iFrame = iH + sLoc.iZero;
63431 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
63432 assert( iFrame>iRead || CORRUPT_DB );
63433 iRead = iFrame;
63434 }
63435 if( (nCollide--)==0 ){
63436 return SQLITE_CORRUPT_BKPT;
@@ -66919,11 +67046,11 @@
66919 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
66920 sz2 = get2byte(&data[iFree2+2]);
66921 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
66922 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
66923 sz += sz2;
66924 }else if( iFree+sz>usableSize ){
66925 return SQLITE_CORRUPT_PAGE(pPage);
66926 }
66927
66928 cbrk = top+sz;
66929 assert( cbrk+(iFree-top) <= usableSize );
@@ -69370,27 +69497,30 @@
69370 }
69371
69372 /*
69373 ** This routine is called prior to sqlite3PagerCommit when a transaction
69374 ** is committed for an auto-vacuum database.
69375 **
69376 ** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
69377 ** the database file should be truncated to during the commit process.
69378 ** i.e. the database has been reorganized so that only the first *pnTrunc
69379 ** pages are in use.
69380 */
69381 static int autoVacuumCommit(BtShared *pBt){
69382 int rc = SQLITE_OK;
69383 Pager *pPager = pBt->pPager;
69384 VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
 
 
 
 
 
 
 
69385
69386 assert( sqlite3_mutex_held(pBt->mutex) );
69387 invalidateAllOverflowCache(pBt);
69388 assert(pBt->autoVacuum);
69389 if( !pBt->incrVacuum ){
69390 Pgno nFin; /* Number of pages in database after autovacuuming */
69391 Pgno nFree; /* Number of pages on the freelist initially */
 
69392 Pgno iFree; /* The next page to be freed */
69393 Pgno nOrig; /* Database size before freeing */
69394
69395 nOrig = btreePagecount(pBt);
69396 if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
@@ -69400,22 +69530,46 @@
69400 */
69401 return SQLITE_CORRUPT_BKPT;
69402 }
69403
69404 nFree = get4byte(&pBt->pPage1->aData[36]);
69405 nFin = finalDbSize(pBt, nOrig, nFree);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69406 if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
69407 if( nFin<nOrig ){
69408 rc = saveAllCursors(pBt, 0, 0);
69409 }
69410 for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
69411 rc = incrVacuumStep(pBt, nFin, iFree, 1);
69412 }
69413 if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
69414 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
69415 put4byte(&pBt->pPage1->aData[32], 0);
69416 put4byte(&pBt->pPage1->aData[36], 0);
 
 
69417 put4byte(&pBt->pPage1->aData[28], nFin);
69418 pBt->bDoTruncate = 1;
69419 pBt->nPage = nFin;
69420 }
69421 if( rc!=SQLITE_OK ){
@@ -69462,11 +69616,11 @@
69462 if( p->inTrans==TRANS_WRITE ){
69463 BtShared *pBt = p->pBt;
69464 sqlite3BtreeEnter(p);
69465 #ifndef SQLITE_OMIT_AUTOVACUUM
69466 if( pBt->autoVacuum ){
69467 rc = autoVacuumCommit(pBt);
69468 if( rc!=SQLITE_OK ){
69469 sqlite3BtreeLeave(p);
69470 return rc;
69471 }
69472 }
@@ -77424,10 +77578,12 @@
77424 nByte = 1;
77425 }
77426 if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
77427 return SQLITE_NOMEM_BKPT;
77428 }
 
 
77429
77430 memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
77431 pMem->n += pMem->u.nZero;
77432 pMem->flags &= ~(MEM_Zero|MEM_Term);
77433 return SQLITE_OK;
@@ -77900,19 +78056,35 @@
77900
77901 /*
77902 ** Delete any previous value and set the value to be a BLOB of length
77903 ** n containing all zeros.
77904 */
 
77905 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
77906 sqlite3VdbeMemRelease(pMem);
77907 pMem->flags = MEM_Blob|MEM_Zero;
77908 pMem->n = 0;
77909 if( n<0 ) n = 0;
77910 pMem->u.nZero = n;
77911 pMem->enc = SQLITE_UTF8;
77912 pMem->z = 0;
77913 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77914
77915 /*
77916 ** The pMem is known to contain content that needs to be destroyed prior
77917 ** to a value change. So invoke the destructor, then set the value to
77918 ** a 64-bit integer.
@@ -82037,13 +82209,19 @@
82037
82038 /* Lock all btrees used by the statement */
82039 sqlite3VdbeEnter(p);
82040
82041 /* Check for one of the special errors */
82042 mrc = p->rc & 0xff;
82043 isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
82044 || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
 
 
 
 
 
 
82045 if( isSpecialError ){
82046 /* If the query was read-only and the error code is SQLITE_INTERRUPT,
82047 ** no rollback is necessary. Otherwise, at least a savepoint
82048 ** transaction must be rolled back to restore the database to a
82049 ** consistent state.
@@ -82091,10 +82269,13 @@
82091 if( NEVER(p->readOnly) ){
82092 sqlite3VdbeLeave(p);
82093 return SQLITE_ERROR;
82094 }
82095 rc = SQLITE_CONSTRAINT_FOREIGNKEY;
 
 
 
82096 }else{
82097 /* The auto-commit flag is true, the vdbe program was successful
82098 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
82099 ** key constraints to hold up the transaction. This means a commit
82100 ** is required. */
@@ -84195,10 +84376,12 @@
84195 }else{
84196 iKey2 = iKey1;
84197 }
84198 }
84199
 
 
84200 assert( pCsr->nField==pTab->nCol
84201 || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
84202 );
84203
84204 preupdate.v = v;
@@ -84773,12 +84956,16 @@
84773 Mem *pOut = pCtx->pOut;
84774 assert( sqlite3_mutex_held(pOut->db->mutex) );
84775 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
84776 return SQLITE_TOOBIG;
84777 }
 
84778 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84779 return SQLITE_OK;
 
 
 
84780 }
84781 SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
84782 pCtx->isError = errCode ? errCode : -1;
84783 #ifdef SQLITE_DEBUG
84784 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85786,11 +85973,15 @@
85786 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
85787 int rc;
85788 Vdbe *p = (Vdbe *)pStmt;
85789 rc = vdbeUnbind(p, i);
85790 if( rc==SQLITE_OK ){
 
85791 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
 
 
 
85792 sqlite3_mutex_leave(p->db->mutex);
85793 }
85794 return rc;
85795 }
85796 SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86074,10 +86265,11 @@
86074 /* If the old.* record has not yet been loaded into memory, do so now. */
86075 if( p->pUnpacked==0 ){
86076 u32 nRec;
86077 u8 *aRec;
86078
 
86079 nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
86080 aRec = sqlite3DbMallocRaw(db, nRec);
86081 if( !aRec ) goto preupdate_old_out;
86082 rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
86083 if( rc==SQLITE_OK ){
@@ -89391,20 +89583,25 @@
89391 rc = SQLITE_CORRUPT_BKPT;
89392 goto abort_due_to_error;
89393 }
89394 }
89395
89396 /* Opcode: TypeCheck P1 P2 * P4 *
89397 ** Synopsis: typecheck(r[P1@P2])
89398 **
89399 ** Apply affinities to the range of P2 registers beginning with P1.
89400 ** Take the affinities from the Table object in P4. If any value
89401 ** cannot be coerced into the correct type, then raise an error.
89402 **
89403 ** This opcode is similar to OP_Affinity except that this opcode
89404 ** forces the register type to the Table column type. This is used
89405 ** to implement "strict affinity".
 
 
 
 
 
89406 **
89407 ** Preconditions:
89408 **
89409 ** <ul>
89410 ** <li> P2 should be the number of non-virtual columns in the
@@ -89424,11 +89621,14 @@
89424 assert( pTab->tabFlags & TF_Strict );
89425 assert( pTab->nNVCol==pOp->p2 );
89426 aCol = pTab->aCol;
89427 pIn1 = &aMem[pOp->p1];
89428 for(i=0; i<pTab->nCol; i++){
89429 if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
 
 
 
89430 assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
89431 applyAffinity(pIn1, aCol[i].affinity, encoding);
89432 if( (pIn1->flags & MEM_Null)==0 ){
89433 switch( aCol[i].eCType ){
89434 case COLTYPE_BLOB: {
@@ -90148,12 +90348,20 @@
90148 assert( p->bIsReader );
90149 assert( p->readOnly==0 || pOp->p2==0 );
90150 assert( pOp->p2>=0 && pOp->p2<=2 );
90151 assert( pOp->p1>=0 && pOp->p1<db->nDb );
90152 assert( DbMaskTest(p->btreeMask, pOp->p1) );
90153 if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
90154 rc = SQLITE_READONLY;
 
 
 
 
 
 
 
 
90155 goto abort_due_to_error;
90156 }
90157 pBt = db->aDb[pOp->p1].pBt;
90158
90159 if( pBt ){
@@ -90191,11 +90399,12 @@
90191 p->nStmtDefCons = db->nDeferredCons;
90192 p->nStmtDefImmCons = db->nDeferredImmCons;
90193 }
90194 }
90195 assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
90196 if( pOp->p5
 
90197 && (iMeta!=pOp->p3
90198 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
90199 ){
90200 /*
90201 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -92997,11 +93206,11 @@
92997 db->mDbFlags |= DBFLAG_SchemaChange;
92998 p->expired = 0;
92999 }else
93000 #endif
93001 {
93002 zSchema = DFLT_SCHEMA_TABLE;
93003 initData.db = db;
93004 initData.iDb = iDb;
93005 initData.pzErrMsg = &p->zErrMsg;
93006 initData.mInitFlags = 0;
93007 initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
@@ -94217,10 +94426,11 @@
94217 pQuery = &aMem[pOp->p3];
94218 pArgc = &pQuery[1];
94219 pCur = p->apCsr[pOp->p1];
94220 assert( memIsValid(pQuery) );
94221 REGISTER_TRACE(pOp->p3, pQuery);
 
94222 assert( pCur->eCurType==CURTYPE_VTAB );
94223 pVCur = pCur->uc.pVCur;
94224 pVtab = pVCur->pVtab;
94225 pModule = pVtab->pModule;
94226
@@ -94265,10 +94475,11 @@
94265 const sqlite3_module *pModule;
94266 Mem *pDest;
94267 sqlite3_context sContext;
94268
94269 VdbeCursor *pCur = p->apCsr[pOp->p1];
 
94270 assert( pCur->eCurType==CURTYPE_VTAB );
94271 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
94272 pDest = &aMem[pOp->p3];
94273 memAboutToChange(p, pDest);
94274 if( pCur->nullRow ){
@@ -94318,10 +94529,11 @@
94318 const sqlite3_module *pModule;
94319 int res;
94320 VdbeCursor *pCur;
94321
94322 pCur = p->apCsr[pOp->p1];
 
94323 assert( pCur->eCurType==CURTYPE_VTAB );
94324 if( pCur->nullRow ){
94325 break;
94326 }
94327 pVtab = pCur->uc.pVCur->pVtab;
@@ -94413,11 +94625,11 @@
94413 case OP_VUpdate: {
94414 sqlite3_vtab *pVtab;
94415 const sqlite3_module *pModule;
94416 int nArg;
94417 int i;
94418 sqlite_int64 rowid;
94419 Mem **apArg;
94420 Mem *pX;
94421
94422 assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
94423 || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -94860,11 +95072,18 @@
94860 rc = SQLITE_CORRUPT_BKPT;
94861 }
94862 assert( rc );
94863 #ifdef SQLITE_DEBUG
94864 if( db->flags & SQLITE_VdbeTrace ){
94865 printf("ABORT-due-to-error. rc=%d\n", rc);
 
 
 
 
 
 
 
94866 }
94867 #endif
94868 if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
94869 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
94870 }
@@ -94873,10 +95092,13 @@
94873 testcase( sqlite3GlobalConfig.xLog!=0 );
94874 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
94875 (int)(pOp - aOp), p->zSql, p->zErrMsg);
94876 sqlite3VdbeHalt(p);
94877 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
 
 
 
94878 rc = SQLITE_ERROR;
94879 if( resetSchemaOnFault>0 ){
94880 sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
94881 }
94882
@@ -95004,11 +95226,14 @@
95004 }else{
95005 rc = sqlite3_step(p->pStmt);
95006 }
95007 if( rc==SQLITE_ROW ){
95008 VdbeCursor *pC = v->apCsr[0];
95009 u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
 
 
 
95010 testcase( pC->nHdrParsed==p->iCol );
95011 testcase( pC->nHdrParsed==p->iCol+1 );
95012 if( type<12 ){
95013 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
95014 type==0?"null": type==7?"real": "integer"
@@ -95349,10 +95574,12 @@
95349 ** using the incremental-blob API, this works. For the sessions module
95350 ** anyhow.
95351 */
95352 sqlite3_int64 iKey;
95353 iKey = sqlite3BtreeIntegerKey(p->pCsr);
 
 
95354 sqlite3VdbePreUpdateHook(
95355 v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
95356 );
95357 }
95358 #endif
@@ -96731,11 +96958,11 @@
96731 void *p = 0;
96732 int chunksize = 4*1024;
96733 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
96734 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
96735 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
96736 sqlite3OsUnfetch(pFd, 0, p);
96737 }
96738 }
96739 #else
96740 # define vdbeSorterExtendFile(x,y,z)
96741 #endif
@@ -97449,10 +97676,11 @@
97449 pTask->file2.iEof += pIncr->mxSz;
97450 }else{
97451 vdbeMergeEngineFree(pMerger);
97452 rc = SQLITE_NOMEM_BKPT;
97453 }
 
97454 return rc;
97455 }
97456
97457 #if SQLITE_MAX_WORKER_THREADS>0
97458 /*
@@ -100427,19 +100655,22 @@
100427 sqlite3WindowLink(pSel, pWin);
100428 pNC->ncFlags |= NC_HasWin;
100429 }else
100430 #endif /* SQLITE_OMIT_WINDOWFUNC */
100431 {
100432 NameContext *pNC2 = pNC;
100433 pExpr->op = TK_AGG_FUNCTION;
100434 pExpr->op2 = 0;
100435 #ifndef SQLITE_OMIT_WINDOWFUNC
100436 if( ExprHasProperty(pExpr, EP_WinFunc) ){
100437 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100438 }
100439 #endif
100440 while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
 
 
 
100441 pExpr->op2++;
100442 pNC2 = pNC2->pNext;
100443 }
100444 assert( pDef!=0 || IN_RENAME_OBJECT );
100445 if( pNC2 && pDef ){
@@ -101405,12 +101636,12 @@
101405
101406 /*
101407 ** Return the affinity character for a single column of a table.
101408 */
101409 SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101410 assert( iCol<pTab->nCol );
101411 return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
101412 }
101413
101414 /*
101415 ** Return the 'affinity' of the expression pExpr if any.
101416 **
@@ -103131,11 +103362,11 @@
103131 }
103132
103133 return pRet;
103134 }
103135 #else
103136 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
103137 assert( p==0 );
103138 return 0;
103139 }
103140 #endif
103141
@@ -104186,11 +104417,12 @@
104186 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104187 Expr *pRhs = pEList->a[i].pExpr;
104188 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104189 int j;
104190
104191 assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
 
104192 for(j=0; j<nExpr; j++){
104193 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104194 assert( pIdx->azColl[j] );
104195 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104196 continue;
@@ -107262,93 +107494,128 @@
107262 sqlite3WalkExpr(&w, pExpr);
107263 return !w.eCode;
107264 }
107265
107266
107267 /*
107268 ** An instance of the following structure is used by the tree walker
107269 ** to count references to table columns in the arguments of an
107270 ** aggregate function, in order to implement the
107271 ** sqlite3FunctionThisSrc() routine.
107272 */
107273 struct SrcCount {
107274 SrcList *pSrc; /* One particular FROM clause in a nested query */
107275 int iSrcInner; /* Smallest cursor number in this context */
107276 int nThis; /* Number of references to columns in pSrcList */
107277 int nOther; /* Number of references to columns in other FROM clauses */
107278 };
107279
107280 /*
107281 ** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
107282 ** SELECT with a FROM clause encountered during this iteration, set
107283 ** SrcCount.iSrcInner to the cursor number of the leftmost object in
107284 ** the FROM cause.
 
 
107285 */
107286 static int selectSrcCount(Walker *pWalker, Select *pSel){
107287 struct SrcCount *p = pWalker->u.pSrcCount;
107288 if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
107289 pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
 
 
 
 
 
 
 
 
 
 
 
 
107290 }
107291 return WRC_Continue;
107292 }
107293
107294 /*
107295 ** Count the number of references to columns.
107296 */
107297 static int exprSrcCount(Walker *pWalker, Expr *pExpr){
107298 /* There was once a NEVER() on the second term on the grounds that
107299 ** sqlite3FunctionUsesThisSrc() was always called before
107300 ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
107301 ** been converted into TK_AGG_COLUMN. But this is no longer true due
107302 ** to window functions - sqlite3WindowRewrite() may now indirectly call
107303 ** FunctionUsesThisSrc() when creating a new sub-select. */
107304 if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
107305 int i;
107306 struct SrcCount *p = pWalker->u.pSrcCount;
107307 SrcList *pSrc = p->pSrc;
 
 
 
 
 
 
 
 
 
107308 int nSrc = pSrc ? pSrc->nSrc : 0;
107309 for(i=0; i<nSrc; i++){
107310 if( pExpr->iTable==pSrc->a[i].iCursor ) break;
107311 }
107312 if( i<nSrc ){
107313 p->nThis++;
107314 }else if( pExpr->iTable<p->iSrcInner ){
107315 /* In a well-formed parse tree (no name resolution errors),
107316 ** TK_COLUMN nodes with smaller Expr.iTable values are in an
107317 ** outer context. Those are the only ones to count as "other" */
107318 p->nOther++;
107319 }
107320 }
107321 return WRC_Continue;
107322 }
107323
107324 /*
107325 ** Determine if any of the arguments to the pExpr Function reference
107326 ** pSrcList. Return true if they do. Also return true if the function
107327 ** has no arguments or has only constant arguments. Return false if pExpr
107328 ** references columns but not columns of tables found in pSrcList.
 
 
 
 
 
 
 
 
 
107329 */
107330 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
107331 Walker w;
107332 struct SrcCount cnt;
107333 assert( pExpr->op==TK_AGG_FUNCTION );
107334 memset(&w, 0, sizeof(w));
107335 w.xExprCallback = exprSrcCount;
107336 w.xSelectCallback = selectSrcCount;
107337 w.u.pSrcCount = &cnt;
107338 cnt.pSrc = pSrcList;
107339 cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
107340 cnt.nThis = 0;
107341 cnt.nOther = 0;
 
107342 assert( ExprUseXList(pExpr) );
107343 sqlite3WalkExprList(&w, pExpr->x.pList);
107344 #ifndef SQLITE_OMIT_WINDOWFUNC
107345 if( ExprHasProperty(pExpr, EP_WinFunc) ){
107346 sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107347 }
107348 #endif
107349 return cnt.nThis>0 || cnt.nOther==0;
 
 
 
 
 
 
 
107350 }
107351
107352 /*
107353 ** This is a Walker expression node callback.
107354 **
@@ -107758,11 +108025,11 @@
107758 int bNoDQS /* Do not allow DQS in the schema */
107759 ){
107760 pParse->colNamesSet = 1;
107761 sqlite3NestedParse(pParse,
107762 "SELECT 1 "
107763 "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
107764 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107765 " AND sql NOT LIKE 'create virtual%%'"
107766 " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
107767 zDb,
107768 zDb, bTemp, zWhen, bNoDQS
@@ -107769,11 +108036,11 @@
107769 );
107770
107771 if( bTemp==0 ){
107772 sqlite3NestedParse(pParse,
107773 "SELECT 1 "
107774 "FROM temp." DFLT_SCHEMA_TABLE " "
107775 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107776 " AND sql NOT LIKE 'create virtual%%'"
107777 " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
107778 zDb, zWhen, bNoDQS
107779 );
@@ -107787,18 +108054,18 @@
107787 ** not true, similarly update all SQL statements in the sqlite_schema table
107788 ** of the temp db.
107789 */
107790 static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
107791 sqlite3NestedParse(pParse,
107792 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE
107793 " SET sql = sqlite_rename_quotefix(%Q, sql)"
107794 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107795 " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
107796 );
107797 if( bTemp==0 ){
107798 sqlite3NestedParse(pParse,
107799 "UPDATE temp." DFLT_SCHEMA_TABLE
107800 " SET sql = sqlite_rename_quotefix('temp', sql)"
107801 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107802 " AND sql NOT LIKE 'create virtual%%'"
107803 );
107804 }
@@ -107912,21 +108179,21 @@
107912 nTabName = sqlite3Utf8CharLen(zTabName, -1);
107913
107914 /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
107915 ** the schema to use the new table name. */
107916 sqlite3NestedParse(pParse,
107917 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
107918 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
107919 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
107920 "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107921 , zDb, zDb, zTabName, zName, (iDb==1), zTabName
107922 );
107923
107924 /* Update the tbl_name and name columns of the sqlite_schema table
107925 ** as required. */
107926 sqlite3NestedParse(pParse,
107927 "UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
107928 "tbl_name = %Q, "
107929 "name = CASE "
107930 "WHEN type='table' THEN %Q "
107931 "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
107932 " AND type='index' THEN "
@@ -108111,11 +108378,11 @@
108111 /* substr() operations on characters, but addColOffset is in bytes. So we
108112 ** have to use printf() to translate between these units: */
108113 assert( IsOrdinaryTable(pTab) );
108114 assert( IsOrdinaryTable(pNew) );
108115 sqlite3NestedParse(pParse,
108116 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108117 "sql = printf('%%.%ds, ',sql) || %Q"
108118 " || substr(sql,1+length(printf('%%.%ds',sql))) "
108119 "WHERE type = 'table' AND name = %Q",
108120 zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,
108121 zTab
@@ -108137,11 +108404,11 @@
108137 VdbeCoverage(v);
108138 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
108139 sqlite3ReleaseTempReg(pParse, r1);
108140
108141 /* Reload the table definition */
108142 renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
108143
108144 /* Verify that constraints are still satisfied */
108145 if( pNew->pCheck!=0
108146 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
108147 ){
@@ -108345,21 +108612,21 @@
108345 zNew = sqlite3NameFromToken(db, pNew);
108346 if( !zNew ) goto exit_rename_column;
108347 assert( pNew->n>0 );
108348 bQuote = sqlite3Isquote(pNew->z[0]);
108349 sqlite3NestedParse(pParse,
108350 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108351 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
108352 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
108353 " AND (type != 'index' OR tbl_name = %Q)",
108354 zDb,
108355 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
108356 pTab->zName
108357 );
108358
108359 sqlite3NestedParse(pParse,
108360 "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
108361 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
108362 "WHERE type IN ('trigger', 'view')",
108363 zDb, pTab->zName, iCol, zNew, bQuote
108364 );
108365
@@ -109030,10 +109297,13 @@
109030 }else{
109031 p->pTab->nTabRef++;
109032 rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
109033 }
109034 }
 
 
 
109035 }
109036 sNC.pSrcList = pSrc;
109037 if( rc==SQLITE_OK && pStep->pWhere ){
109038 rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
109039 }
@@ -109833,11 +110103,11 @@
109833 assert( iDb>=0 );
109834 zDb = db->aDb[iDb].zDbSName;
109835 renameTestSchema(pParse, zDb, iDb==1, "", 0);
109836 renameFixQuotes(pParse, zDb, iDb==1);
109837 sqlite3NestedParse(pParse,
109838 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
109839 "sql = sqlite_drop_column(%d, sql, %d) "
109840 "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
109841 , zDb, iDb, iCol, pTab->zName
109842 );
109843
@@ -113122,21 +113392,21 @@
113122 }
113123 }
113124 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113125 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113126 if( i==1 ){
113127 if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0
113128 || sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0
113129 || sqlite3StrICmp(zName+7, &DFLT_SCHEMA_TABLE[7])==0
113130 ){
113131 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113132 DFLT_TEMP_SCHEMA_TABLE);
113133 }
113134 }else{
113135 if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
113136 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
113137 DFLT_SCHEMA_TABLE);
113138 }
113139 }
113140 }
113141 }else{
113142 /* Match against TEMP first */
@@ -113150,15 +113420,15 @@
113150 assert( sqlite3SchemaMutexHeld(db, i, 0) );
113151 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113152 if( p ) break;
113153 }
113154 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113155 if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
113156 p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE);
113157 }else if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 ){
113158 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113159 DFLT_TEMP_SCHEMA_TABLE);
113160 }
113161 }
113162 }
113163 return p;
113164 }
@@ -113249,10 +113519,26 @@
113249 }else{
113250 zDb = p->zDatabase;
113251 }
113252 return sqlite3LocateTable(pParse, flags, p->zName, zDb);
113253 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113254
113255 /*
113256 ** Locate the in-memory structure that describes
113257 ** a particular index given the name of that index
113258 ** and the name of the database that contains the index.
@@ -113648,11 +113934,11 @@
113648 ** Open the sqlite_schema table stored in database number iDb for
113649 ** writing. The table is opened using cursor 0.
113650 */
113651 SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){
113652 Vdbe *v = sqlite3GetVdbe(p);
113653 sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
113654 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
113655 if( p->nTab==0 ){
113656 p->nTab = 1;
113657 }
113658 }
@@ -115227,10 +115513,45 @@
115227 if( pMod->pModule->xShadowName==0 ) return 0;
115228 return pMod->pModule->xShadowName(zName+nName+1);
115229 }
115230 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115232 #ifndef SQLITE_OMIT_VIRTUALTABLE
115233 /*
115234 ** Return true if zName is a shadow table name in the current database
115235 ** connection.
115236 **
@@ -115555,11 +115876,11 @@
115555 /* A slot for the record has already been allocated in the
115556 ** schema table. We just need to update that slot with all
115557 ** the information we've collected.
115558 */
115559 sqlite3NestedParse(pParse,
115560 "UPDATE %Q." DFLT_SCHEMA_TABLE
115561 " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
115562 " WHERE rowid=#%d",
115563 db->aDb[iDb].zDbSName,
115564 zType,
115565 p->zName,
@@ -115741,17 +116062,16 @@
115741 #endif
115742
115743 assert( pTable );
115744
115745 #ifndef SQLITE_OMIT_VIRTUALTABLE
115746 db->nSchemaLock++;
115747 rc = sqlite3VtabCallConnect(pParse, pTable);
115748 db->nSchemaLock--;
115749 if( rc ){
115750 return 1;
115751 }
115752 if( IsVirtual(pTable) ) return 0;
115753 #endif
115754
115755 #ifndef SQLITE_OMIT_VIEW
115756 /* A positive nCol means the columns names for this view are
115757 ** already known.
@@ -115935,11 +116255,11 @@
115935 ** The "#NNN" in the SQL is a special constant that means whatever value
115936 ** is in register NNN. See grammar rules associated with the TK_REGISTER
115937 ** token for additional information.
115938 */
115939 sqlite3NestedParse(pParse,
115940 "UPDATE %Q." DFLT_SCHEMA_TABLE
115941 " SET rootpage=%d WHERE #%d AND rootpage=#%d",
115942 pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
115943 #endif
115944 sqlite3ReleaseTempReg(pParse, r1);
115945 }
@@ -116070,11 +116390,11 @@
116070 ** dropped. Triggers are handled separately because a trigger can be
116071 ** created in the temp database that refers to a table in another
116072 ** database.
116073 */
116074 sqlite3NestedParse(pParse,
116075 "DELETE FROM %Q." DFLT_SCHEMA_TABLE
116076 " WHERE tbl_name=%Q and type!='trigger'",
116077 pDb->zDbSName, pTab->zName);
116078 if( !isView && !IsVirtual(pTab) ){
116079 destroyTable(pParse, pTab);
116080 }
@@ -116117,10 +116437,13 @@
116117 if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
116118 return 1;
116119 }
116120 if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
116121 return 1;
 
 
 
116122 }
116123 return 0;
116124 }
116125
116126 /*
@@ -117087,11 +117410,11 @@
117087 }
117088
117089 /* Add an entry in sqlite_schema for this index
117090 */
117091 sqlite3NestedParse(pParse,
117092 "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
117093 db->aDb[iDb].zDbSName,
117094 pIndex->zName,
117095 pTab->zName,
117096 iMem,
117097 zStmt
@@ -117273,11 +117596,11 @@
117273 /* Generate code to remove the index and from the schema table */
117274 v = sqlite3GetVdbe(pParse);
117275 if( v ){
117276 sqlite3BeginWriteOperation(pParse, 1, iDb);
117277 sqlite3NestedParse(pParse,
117278 "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117279 db->aDb[iDb].zDbSName, pIndex->zName
117280 );
117281 sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
117282 sqlite3ChangeCookie(pParse, iDb);
117283 destroyRootPage(pParse, pIndex->tnum, iDb);
@@ -123933,28 +124256,34 @@
123933
123934 /* Before computing generated columns, first go through and make sure
123935 ** that appropriate affinity has been applied to the regular columns
123936 */
123937 sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
123938 if( (pTab->tabFlags & TF_HasStored)!=0
123939 && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity
123940 ){
123941 /* Change the OP_Affinity argument to '@' (NONE) for all stored
123942 ** columns. '@' is the no-op affinity and those columns have not
123943 ** yet been computed. */
123944 int ii, jj;
123945 char *zP4 = pOp->p4.z;
123946 assert( zP4!=0 );
123947 assert( pOp->p4type==P4_DYNAMIC );
123948 for(ii=jj=0; zP4[jj]; ii++){
123949 if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
123950 continue;
123951 }
123952 if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
123953 zP4[jj] = SQLITE_AFF_NONE;
123954 }
123955 jj++;
 
 
 
 
 
 
123956 }
123957 }
123958
123959 /* Because there can be multiple generated columns that refer to one another,
123960 ** this is a two-pass algorithm. On the first pass, mark all generated
@@ -125978,11 +126307,12 @@
125978 default: {
125979 int nConflictCk; /* Number of opcodes in conflict check logic */
125980
125981 assert( onError==OE_Replace );
125982 nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
125983 assert( nConflictCk>0 );
 
125984 testcase( nConflictCk>1 );
125985 if( regTrigCnt ){
125986 sqlite3MultiWrite(pParse);
125987 nReplaceTrig++;
125988 }
@@ -126264,12 +126594,13 @@
126264
126265 assert( op==OP_OpenRead || op==OP_OpenWrite );
126266 assert( op==OP_OpenWrite || p5==0 );
126267 if( IsVirtual(pTab) ){
126268 /* This routine is a no-op for virtual tables. Leave the output
126269 ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
126270 ** can detect if they are used by mistake in the caller. */
 
126271 return 0;
126272 }
126273 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
126274 v = pParse->pVdbe;
126275 assert( v!=0 );
@@ -127276,10 +127607,14 @@
127276 /* Version 3.34.0 and later */
127277 int (*txn_state)(sqlite3*,const char*);
127278 /* Version 3.36.1 and later */
127279 sqlite3_int64 (*changes64)(sqlite3*);
127280 sqlite3_int64 (*total_changes64)(sqlite3*);
 
 
 
 
127281 };
127282
127283 /*
127284 ** This is the function signature used for all extension entry points. It
127285 ** is also defined in the file "loadext.c".
@@ -127582,10 +127917,15 @@
127582 #define sqlite3_create_filename sqlite3_api->create_filename
127583 #define sqlite3_free_filename sqlite3_api->free_filename
127584 #define sqlite3_database_file_object sqlite3_api->database_file_object
127585 /* Version 3.34.0 and later */
127586 #define sqlite3_txn_state sqlite3_api->txn_state
 
 
 
 
 
127587 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127588
127589 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127590 /* This case when the file really is being compiled as a loadable
127591 ** extension */
@@ -128069,10 +128409,12 @@
128069 /* Version 3.34.0 and later */
128070 sqlite3_txn_state,
128071 /* Version 3.36.1 and later */
128072 sqlite3_changes64,
128073 sqlite3_total_changes64,
 
 
128074 };
128075
128076 /* True if x is the directory separator character
128077 */
128078 #if SQLITE_OS_WIN
@@ -130391,11 +130733,11 @@
130391 }else{
130392 zType = "table";
130393 }
130394 sqlite3VdbeMultiLoad(v, 1, "sssiii",
130395 db->aDb[ii].zDbSName,
130396 pTab->zName,
130397 zType,
130398 pTab->nCol,
130399 (pTab->tabFlags & TF_WithoutRowid)!=0,
130400 (pTab->tabFlags & TF_Strict)!=0
130401 );
@@ -130411,11 +130753,11 @@
130411 pParse->nMem = 5;
130412 sqlite3CodeVerifySchema(pParse, iDb);
130413 for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
130414 Table *pTab = sqliteHashData(i);
130415 sqlite3VdbeMultiLoad(v, 1, "ssiii",
130416 pTab->zName,
130417 0,
130418 pTab->szTabRow,
130419 pTab->nRowLogEst,
130420 pTab->tabFlags);
130421 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -130906,11 +131248,11 @@
130906 if( pCol->notNull ){
130907 jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
130908 zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
130909 pCol->zCnName);
130910 sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
130911 if( bStrict ){
130912 sqlite3VdbeGoto(v, doError);
130913 }else{
130914 integrityCheckResultRow(v);
130915 }
130916 sqlite3VdbeJumpHere(v, jmp2);
@@ -131867,14 +132209,19 @@
131867 sqlite3 *db = pData->db;
131868 if( db->mallocFailed ){
131869 pData->rc = SQLITE_NOMEM_BKPT;
131870 }else if( pData->pzErrMsg[0]!=0 ){
131871 /* A error message has already been generated. Do not overwrite it */
131872 }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){
 
 
 
 
 
131873 *pData->pzErrMsg = sqlite3MPrintf(db,
131874 "error in %s %s after %s: %s", azObj[0], azObj[1],
131875 (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column",
131876 zExtra
131877 );
131878 pData->rc = SQLITE_ERROR;
131879 }else if( db->flags & SQLITE_WriteSchema ){
131880 pData->rc = SQLITE_CORRUPT_BKPT;
@@ -135070,10 +135417,13 @@
135070 n = sqlite3Strlen30(pCol->zCnName);
135071 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
135072 if( pCol->zCnName ){
135073 memcpy(&pCol->zCnName[n+1], zType, m+1);
135074 pCol->colFlags |= COLFLAG_HASTYPE;
 
 
 
135075 }
135076 }
135077 if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
135078 pColl = sqlite3ExprCollSeq(pParse, p);
135079 if( pColl ){
@@ -137809,31 +138159,44 @@
137809 **
137810 ** SELECT count(*) FROM <tbl>
137811 **
137812 ** where table is a database table, not a sub-select or view. If the query
137813 ** does match this pattern, then a pointer to the Table object representing
137814 ** <tbl> is returned. Otherwise, 0 is returned.
 
 
 
 
 
 
137815 */
137816 static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
137817 Table *pTab;
137818 Expr *pExpr;
137819
137820 assert( !p->pGroupBy );
137821
137822 if( p->pWhere || p->pEList->nExpr!=1
137823 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
 
 
 
137824 ){
137825 return 0;
137826 }
137827 pTab = p->pSrc->a[0].pTab;
 
 
 
137828 pExpr = p->pEList->a[0].pExpr;
137829 assert( pTab && !IsView(pTab) && pExpr );
137830
137831 if( IsVirtual(pTab) ) return 0;
137832 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
137833 if( NEVER(pAggInfo->nFunc==0) ) return 0;
137834 if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
 
 
 
137835 if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
137836
137837 return pTab;
137838 }
137839
@@ -140934,11 +141297,11 @@
140934 if( v==0 ) goto triggerfinish_cleanup;
140935 sqlite3BeginWriteOperation(pParse, 0, iDb);
140936 z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
140937 testcase( z==0 );
140938 sqlite3NestedParse(pParse,
140939 "INSERT INTO %Q." DFLT_SCHEMA_TABLE
140940 " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
140941 db->aDb[iDb].zDbSName, zName,
140942 pTrig->table, z);
140943 sqlite3DbFree(db, z);
140944 sqlite3ChangeCookie(pParse, iDb);
@@ -141248,11 +141611,11 @@
141248
141249 /* Generate code to destroy the database record of the trigger.
141250 */
141251 if( (v = sqlite3GetVdbe(pParse))!=0 ){
141252 sqlite3NestedParse(pParse,
141253 "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
141254 db->aDb[iDb].zDbSName, pTrigger->zName
141255 );
141256 sqlite3ChangeCookie(pParse, iDb);
141257 sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
141258 }
@@ -143901,11 +144264,13 @@
143901 rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
143902 if( rc!=SQLITE_OK ) goto end_of_vacuum;
143903
143904 /* Do not attempt to change the page size for a WAL database */
143905 if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
143906 ==PAGER_JOURNALMODE_WAL ){
 
 
143907 db->nextPagesize = 0;
143908 }
143909
143910 if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
143911 || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
@@ -144543,11 +144908,11 @@
144543 ** entry in the sqlite_schema table tht was created for this vtab
144544 ** by sqlite3StartTable().
144545 */
144546 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
144547 sqlite3NestedParse(pParse,
144548 "UPDATE %Q." DFLT_SCHEMA_TABLE " "
144549 "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
144550 "WHERE rowid=#%d",
144551 db->aDb[iDb].zDbSName,
144552 pTab->zName,
144553 pTab->zName,
@@ -144563,22 +144928,18 @@
144563 sqlite3DbFree(db, zStmt);
144564
144565 iReg = ++pParse->nMem;
144566 sqlite3VdbeLoadString(v, iReg, pTab->zName);
144567 sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
144568 }
144569
144570 /* If we are rereading the sqlite_schema table create the in-memory
144571 ** record of the table. The xConnect() method is not called until
144572 ** the first time the virtual table is used in an SQL statement. This
144573 ** allows a schema that contains virtual tables to be loaded before
144574 ** the required virtual table implementations are registered. */
144575 else {
144576 Table *pOld;
144577 Schema *pSchema = pTab->pSchema;
144578 const char *zName = pTab->zName;
144579 assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
 
144580 pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
144581 if( pOld ){
144582 sqlite3OomFault(db);
144583 assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
144584 return;
@@ -144758,11 +145119,12 @@
144758 const char *zMod;
144759 Module *pMod;
144760 int rc;
144761
144762 assert( pTab );
144763 if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
 
144764 return SQLITE_OK;
144765 }
144766
144767 /* Locate the required virtual table module */
144768 zMod = pTab->u.vtab.azArg[0];
@@ -144962,11 +145324,14 @@
144962 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
144963 int rc = SQLITE_OK;
144964 Table *pTab;
144965
144966 pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
144967 if( pTab!=0 && ALWAYS(IsVirtual(pTab)) && ALWAYS(pTab->u.vtab.p!=0) ){
 
 
 
144968 VTable *p;
144969 int (*xDestroy)(sqlite3_vtab *);
144970 for(p=pTab->u.vtab.p; p; p=p->pNext){
144971 assert( p->pVtab );
144972 if( p->pVtab->nRef>0 ){
@@ -147900,12 +148265,23 @@
147900
147901 /* Load the value for the inequality constraint at the end of the
147902 ** range (if any).
147903 */
147904 nConstraint = nEq;
 
147905 if( pRangeEnd ){
147906 Expr *pRight = pRangeEnd->pExpr->pRight;
 
 
 
 
 
 
 
 
 
 
147907 codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
147908 whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
147909 if( (pRangeEnd->wtFlags & TERM_VNULL)==0
147910 && sqlite3ExprCanBeNull(pRight)
147911 ){
@@ -147935,11 +148311,11 @@
147935 }
147936 sqlite3DbFree(db, zStartAff);
147937 sqlite3DbFree(db, zEndAff);
147938
147939 /* Top of the loop body */
147940 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
147941
147942 /* Check if the index cursor is past the end of the range. */
147943 if( nConstraint ){
147944 if( regBignull ){
147945 /* Except, skip the end-of-range check while doing the NULL-scan */
@@ -155575,10 +155951,11 @@
155575 ** program.
155576 */
155577 for(ii=0; ii<nTabList; ii++){
155578 int addrExplain;
155579 int wsFlags;
 
155580 pLevel = &pWInfo->a[ii];
155581 wsFlags = pLevel->pWLoop->wsFlags;
155582 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155583 if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155584 constructAutomaticIndex(pParse, &pWInfo->sWC,
@@ -157028,11 +157405,15 @@
157028 }
157029 }else{
157030 sqlite3SelectDelete(db, pSub);
157031 }
157032 if( db->mallocFailed ) rc = SQLITE_NOMEM;
157033 sqlite3DbFree(db, pTab);
 
 
 
 
157034 }
157035
157036 if( rc ){
157037 if( pParse->nErr==0 ){
157038 assert( pParse->db->mallocFailed );
@@ -160475,13 +160856,13 @@
160475 yyStackEntry *yystackEnd; /* Last entry in the stack */
160476 #endif
160477 };
160478 typedef struct yyParser yyParser;
160479
 
160480 #ifndef NDEBUG
160481 /* #include <stdio.h> */
160482 /* #include <assert.h> */
160483 static FILE *yyTraceFILE = 0;
160484 static char *yyTracePrompt = 0;
160485 #endif /* NDEBUG */
160486
160487 #ifndef NDEBUG
@@ -164226,12 +164607,12 @@
164226 assert( yypParser->yytos>=yypParser->yystack );
164227 assert( yyact==yypParser->yytos->stateno );
164228 yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
164229 if( yyact >= YY_MIN_REDUCE ){
164230 unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
164231 assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
164232 #ifndef NDEBUG
 
164233 if( yyTraceFILE ){
164234 int yysize = yyRuleInfoNRhs[yyruleno];
164235 if( yysize ){
164236 fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
164237 yyTracePrompt,
@@ -167559,10 +167940,13 @@
167559 ** So it needs to be freed here. Todo: Why not roll the temp schema into
167560 ** the same sqliteMalloc() as the one that allocates the database
167561 ** structure?
167562 */
167563 sqlite3DbFree(db, db->aDb[1].pSchema);
 
 
 
167564 sqlite3_mutex_leave(db->mutex);
167565 db->eOpenState = SQLITE_STATE_CLOSED;
167566 sqlite3_mutex_free(db->mutex);
167567 assert( sqlite3LookasideUsed(db,0)==0 );
167568 if( db->lookaside.bMalloced ){
@@ -167613,11 +167997,11 @@
167613 sqlite3BtreeLeaveAll(db);
167614
167615 /* Any deferred constraint violations have now been resolved. */
167616 db->nDeferredCons = 0;
167617 db->nDeferredImmCons = 0;
167618 db->flags &= ~(u64)SQLITE_DeferFKs;
167619
167620 /* If one has been configured, invoke the rollback-hook callback */
167621 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
167622 db->xRollbackCallback(db->pRollbackArg);
167623 }
@@ -168459,10 +168843,38 @@
168459 db->pPreUpdateArg = pArg;
168460 sqlite3_mutex_leave(db->mutex);
168461 return pRet;
168462 }
168463 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168464
168465 #ifndef SQLITE_OMIT_WAL
168466 /*
168467 ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
168468 ** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
@@ -169313,12 +169725,12 @@
169313 **
169314 ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
169315 ** dealt with in the previous code block. Besides these, the only
169316 ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
169317 ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
169318 ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
169319 ** off all other flags.
169320 */
169321 flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
169322 SQLITE_OPEN_EXCLUSIVE |
169323 SQLITE_OPEN_MAIN_DB |
169324 SQLITE_OPEN_TEMP_DB |
@@ -169349,11 +169761,11 @@
169349 if( isThreadsafe==0 ){
169350 sqlite3MutexWarnOnContention(db->mutex);
169351 }
169352 }
169353 sqlite3_mutex_enter(db->mutex);
169354 db->errMask = 0xff;
169355 db->nDb = 2;
169356 db->eOpenState = SQLITE_STATE_BUSY;
169357 db->aDb = db->aDbStatic;
169358 db->lookaside.bDisable = 1;
169359 db->lookaside.sz = 0;
@@ -169581,12 +169993,12 @@
169581 assert( db->mutex!=0 || isThreadsafe==0
169582 || sqlite3GlobalConfig.bFullMutex==0 );
169583 sqlite3_mutex_leave(db->mutex);
169584 }
169585 rc = sqlite3_errcode(db);
169586 assert( db!=0 || rc==SQLITE_NOMEM );
169587 if( rc==SQLITE_NOMEM ){
169588 sqlite3_close(db);
169589 db = 0;
169590 }else if( rc!=SQLITE_OK ){
169591 db->eOpenState = SQLITE_STATE_SICK;
169592 }
@@ -169597,11 +170009,11 @@
169597 void *pArg = sqlite3GlobalConfig.pSqllogArg;
169598 sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
169599 }
169600 #endif
169601 sqlite3_free_filename(zOpen);
169602 return rc & 0xff;
169603 }
169604
169605
169606 /*
169607 ** Open a new database handle.
@@ -178147,10 +178559,13 @@
178147 while( rc==SQLITE_OK && !pNear->bEof ){
178148 fts3EvalNextRow(pCsr, pNear, &rc);
178149 if( bEofSave==0 && pNear->iDocid==iDocid ) break;
178150 }
178151 assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
 
 
 
178152 }
178153 if( bTreeEof ){
178154 while( rc==SQLITE_OK && !pNear->bEof ){
178155 fts3EvalNextRow(pCsr, pNear, &rc);
178156 }
@@ -189837,17 +190252,17 @@
189837 int iEnd = 0;
189838 int iCurrent = 0;
189839 const char *zDoc;
189840 int nDoc;
189841
189842 /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
189843 ** no way that this operation can fail, so the return code from
189844 ** fts3ExprIterate() can be discarded.
189845 */
189846 sCtx.iCol = iCol;
189847 sCtx.iTerm = 0;
189848 (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
 
189849
189850 /* Retreive the text stored in column iCol. If an SQL NULL is stored
189851 ** in column iCol, jump immediately to the next iteration of the loop.
189852 ** If an OOM occurs while retrieving the data (this can happen if SQLite
189853 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -190856,11 +191271,11 @@
190856 # define ALWAYS(X) (X)
190857 # define NEVER(X) (X)
190858 # endif
190859 # define testcase(X)
190860 #endif
190861 #if defined(NDEBUG)
190862 # define VVA(X)
190863 #else
190864 # define VVA(X) X
190865 #endif
190866
@@ -192407,12 +192822,15 @@
192407 }else{
192408 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
192409 if( pNew==0 ) return 0;
192410 pTarget = &pParse->aNode[iTarget];
192411 if( pNew!=&pTarget[j+1] ){
192412 assert( pTarget[j+1].eU==0 || pTarget[j+1].eU==1 );
 
 
192413 testcase( pTarget[j+1].eU==1 );
 
192414 VVA( pTarget[j+1].eU = 5 );
192415 pTarget[j+1].u.pPatch = pNew;
192416 pTarget[j+1].jnFlags |= JNODE_PATCH;
192417 }
192418 }
@@ -201403,10 +201821,17 @@
201403 ** Swap two objects of type TYPE.
201404 */
201405 #if !defined(SQLITE_AMALGAMATION)
201406 # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
201407 #endif
 
 
 
 
 
 
 
201408
201409 /*
201410 ** The rbu_state table is used to save the state of a partially applied
201411 ** update so that it can be resumed later. The table consists of integer
201412 ** keys mapped to values as follows:
@@ -204050,17 +204475,23 @@
204050
204051
204052 /*
204053 ** Open the database handle and attach the RBU database as "rbu". If an
204054 ** error occurs, leave an error code and message in the RBU handle.
 
 
 
 
204055 */
204056 static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
204057 assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
204058 assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
 
204059
204060 /* Open the RBU database */
204061 p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
 
204062
204063 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
204064 sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
204065 if( p->zState==0 ){
204066 const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -204422,19 +204853,35 @@
204422 p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
204423 }
204424
204425
204426 /*
204427 ** Take an EXCLUSIVE lock on the database file.
 
204428 */
204429 static void rbuLockDatabase(sqlite3rbu *p){
204430 sqlite3_file *pReal = p->pTargetFd->pReal;
204431 assert( p->rc==SQLITE_OK );
204432 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
204433 if( p->rc==SQLITE_OK ){
204434 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
 
 
 
 
204435 }
 
 
 
 
 
 
 
 
 
 
 
204436 }
204437
204438 #if defined(_WIN32_WCE)
204439 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
204440 int nChar;
@@ -204488,22 +204935,28 @@
204488 ** in WAL mode). So no other connection may be writing the db.
204489 **
204490 ** In order to ensure that there are no database readers, an EXCLUSIVE
204491 ** lock is obtained here before the *-oal is moved to *-wal.
204492 */
204493 rbuLockDatabase(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204494 if( p->rc==SQLITE_OK ){
204495 rbuFileSuffix3(zBase, zWal);
204496 rbuFileSuffix3(zBase, zOal);
204497
204498 /* Re-open the databases. */
204499 rbuObjIterFinalize(&p->objiter);
204500 sqlite3_close(p->dbRbu);
204501 sqlite3_close(p->dbMain);
204502 p->dbMain = 0;
204503 p->dbRbu = 0;
204504
204505 #if defined(_WIN32_WCE)
204506 {
204507 LPWSTR zWideOal;
204508 LPWSTR zWideWal;
204509
@@ -204526,15 +204979,23 @@
204526 }
204527 }
204528 #else
204529 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204530 #endif
 
204531
204532 if( p->rc==SQLITE_OK ){
204533 rbuOpenDatabase(p, 0);
204534 rbuSetupCheckpoint(p, 0);
204535 }
 
 
 
 
 
 
 
204536 }
204537 }
204538
204539 sqlite3_free(zWal);
204540 sqlite3_free(zOal);
@@ -205281,13 +205742,13 @@
205281 ** to be a wal-mode db. But, this may have happened due to an earlier
205282 ** RBU vacuum operation leaving an old wal file in the directory.
205283 ** If this is the case, it will have been checkpointed and deleted
205284 ** when the handle was closed and a second attempt to open the
205285 ** database may succeed. */
205286 rbuOpenDatabase(p, &bRetry);
205287 if( bRetry ){
205288 rbuOpenDatabase(p, 0);
205289 }
205290 }
205291
205292 if( p->rc==SQLITE_OK ){
205293 pState = rbuLoadState(p);
@@ -205378,10 +205839,18 @@
205378 }
205379 }
205380 }else if( p->eStage==RBU_STAGE_MOVE ){
205381 /* no-op */
205382 }else if( p->eStage==RBU_STAGE_CKPT ){
 
 
 
 
 
 
 
 
205383 rbuSetupCheckpoint(p, pState);
205384 }else if( p->eStage==RBU_STAGE_DONE ){
205385 p->rc = SQLITE_DONE;
205386 }else{
205387 p->rc = SQLITE_CORRUPT;
@@ -205415,11 +205884,10 @@
205415 const char *zTarget,
205416 const char *zRbu,
205417 const char *zState
205418 ){
205419 if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
205420 /* TODO: Check that zTarget and zRbu are non-NULL */
205421 return openRbuHandle(zTarget, zRbu, zState);
205422 }
205423
205424 /*
205425 ** Open a handle to begin or resume an RBU VACUUM operation.
@@ -215536,13 +216004,13 @@
215536 fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
215537 #endif
215538 };
215539 typedef struct fts5yyParser fts5yyParser;
215540
215541 #ifndef NDEBUG
215542 /* #include <stdio.h> */
215543 /* #include <assert.h> */
 
 
215544 static FILE *fts5yyTraceFILE = 0;
215545 static char *fts5yyTracePrompt = 0;
215546 #endif /* NDEBUG */
215547
215548 #ifndef NDEBUG
@@ -216475,12 +216943,12 @@
216475 assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
216476 assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
216477 fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
216478 if( fts5yyact >= fts5YY_MIN_REDUCE ){
216479 unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
216480 assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
216481 #ifndef NDEBUG
 
216482 if( fts5yyTraceFILE ){
216483 int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
216484 if( fts5yysize ){
216485 fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
216486 fts5yyTracePrompt,
@@ -221608,20 +222076,29 @@
221608 Fts5PoslistWriter writer;
221609 int bOk; /* True if ok to populate */
221610 int bMiss;
221611 };
221612
 
 
 
 
 
 
 
 
 
221613 static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
221614 Fts5PoslistPopulator *pRet;
221615 pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221616 if( pRet ){
221617 int i;
221618 memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221619 for(i=0; i<pExpr->nPhrase; i++){
221620 Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
221621 Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
221622 assert( pExpr->apExprPhrase[i]->nTerm==1 );
221623 if( bLive &&
221624 (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
221625 ){
221626 pRet[i].bMiss = 1;
221627 }else{
@@ -231982,11 +232459,11 @@
231982 int nArg, /* Number of args */
231983 sqlite3_value **apUnused /* Function arguments */
231984 ){
231985 assert( nArg==0 );
231986 UNUSED_PARAM2(nArg, apUnused);
231987 sqlite3_result_text(pCtx, "fts5: 2021-10-22 11:17:29 1a038242dc6c0cab97dd9375acfce62aa1c386debc36aaed388d366b87ddd931", -1, SQLITE_TRANSIENT);
231988 }
231989
231990 /*
231991 ** Return true if zName is the extension on one of the shadow tables used
231992 ** by this module.
231993
--- 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 **
@@ -6709,10 +6718,76 @@
6718 **
6719 ** See also the [sqlite3_update_hook()] interface.
6720 */
6721 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
6722 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
6723
6724 /*
6725 ** CAPI3REF: Autovacuum Compaction Amount Callback
6726 ** METHOD: sqlite3
6727 **
6728 ** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
6729 ** function C that is invoked prior to each autovacuum of the database
6730 ** file. ^The callback is passed a copy of the generic data pointer (P),
6731 ** the schema-name of the attached database that is being autovacuumed,
6732 ** the the size of the database file in pages, the number of free pages,
6733 ** and the number of bytes per page, respectively. The callback should
6734 ** return the number of free pages that should be removed by the
6735 ** autovacuum. ^If the callback returns zero, then no autovacuum happens.
6736 ** ^If the value returned is greater than or equal to the number of
6737 ** free pages, then a complete autovacuum happens.
6738 **
6739 ** <p>^If there are multiple ATTACH-ed database files that are being
6740 ** modified as part of a transaction commit, then the autovacuum pages
6741 ** callback is invoked separately for each file.
6742 **
6743 ** <p><b>The callback is not reentrant.</b> The callback function should
6744 ** not attempt to invoke any other SQLite interface. If it does, bad
6745 ** things may happen, including segmentation faults and corrupt database
6746 ** files. The callback function should be a simple function that
6747 ** does some arithmetic on its input parameters and returns a result.
6748 **
6749 ** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
6750 ** destructor for the P parameter. ^If X is not NULL, then X(P) is
6751 ** invoked whenever the database connection closes or when the callback
6752 ** is overwritten by another invocation of sqlite3_autovacuum_pages().
6753 **
6754 ** <p>^There is only one autovacuum pages callback per database connection.
6755 ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
6756 ** previous invocations for that database connection. ^If the callback
6757 ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
6758 ** then the autovacuum steps callback is cancelled. The return value
6759 ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
6760 ** be some other error code if something goes wrong. The current
6761 ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
6762 ** return codes might be added in future releases.
6763 **
6764 ** <p>If no autovacuum pages callback is specified (the usual case) or
6765 ** a NULL pointer is provided for the callback,
6766 ** then the default behavior is to vacuum all free pages. So, in other
6767 ** words, the default behavior is the same as if the callback function
6768 ** were something like this:
6769 **
6770 ** <blockquote><pre>
6771 ** &nbsp; unsigned int demonstration_autovac_pages_callback(
6772 ** &nbsp; void *pClientData,
6773 ** &nbsp; const char *zSchema,
6774 ** &nbsp; unsigned int nDbPage,
6775 ** &nbsp; unsigned int nFreePage,
6776 ** &nbsp; unsigned int nBytePerPage
6777 ** &nbsp; ){
6778 ** &nbsp; return nFreePage;
6779 ** &nbsp; }
6780 ** </pre></blockquote>
6781 */
6782 SQLITE_API int sqlite3_autovacuum_pages(
6783 sqlite3 *db,
6784 unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
6785 void*,
6786 void(*)(void*)
6787 );
6788
6789
6790 /*
6791 ** CAPI3REF: Data Change Notification Callbacks
6792 ** METHOD: sqlite3
6793 **
@@ -14078,15 +14153,29 @@
14153 int nBusy; /* Incremented with each busy call */
14154 };
14155
14156 /*
14157 ** Name of table that holds the database schema.
14158 **
14159 ** The PREFERRED names are used whereever possible. But LEGACY is also
14160 ** used for backwards compatibility.
14161 **
14162 ** 1. Queries can use either the PREFERRED or the LEGACY names
14163 ** 2. The sqlite3_set_authorizer() callback uses the LEGACY name
14164 ** 3. The PRAGMA table_list statement uses the PREFERRED name
14165 **
14166 ** The LEGACY names are stored in the internal symbol hash table
14167 ** in support of (2). Names are translated using sqlite3PreferredTableName()
14168 ** for (3). The sqlite3FindTable() function takes care of translating
14169 ** names for (1).
14170 **
14171 ** Note that "sqlite_temp_schema" can also be called "temp.sqlite_schema".
14172 */
14173 #define LEGACY_SCHEMA_TABLE "sqlite_master"
14174 #define LEGACY_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14175 #define PREFERRED_SCHEMA_TABLE "sqlite_schema"
14176 #define PREFERRED_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
14177
14178
14179 /*
14180 ** The root-page of the schema table.
14181 */
@@ -14094,11 +14183,11 @@
14183
14184 /*
14185 ** The name of the schema table. The name is different for TEMP.
14186 */
14187 #define SCHEMA_TABLE(x) \
14188 ((!OMIT_TEMPDB)&&(x==1)?LEGACY_TEMP_SCHEMA_TABLE:LEGACY_SCHEMA_TABLE)
14189
14190 /*
14191 ** A convenience macro that returns the number of elements in
14192 ** an array.
14193 */
@@ -16437,10 +16526,13 @@
16526 int (*xCommitCallback)(void*); /* Invoked at every commit. */
16527 void *pRollbackArg; /* Argument to xRollbackCallback() */
16528 void (*xRollbackCallback)(void*); /* Invoked at every commit. */
16529 void *pUpdateArg;
16530 void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
16531 void *pAutovacPagesArg; /* Client argument to autovac_pages */
16532 void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
16533 unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
16534 Parse *pParse; /* Current parse */
16535 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
16536 void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
16537 void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
16538 void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
@@ -16566,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 */
@@ -18694,12 +18787,14 @@
18787 } InitData;
18788
18789 /*
18790 ** Allowed values for mInitFlags
18791 */
18792 #define INITFLAG_AlterMask 0x0003 /* Types of ALTER */
18793 #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
18794 #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
18795 #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */
18796
18797 /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
18798 ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
18799 ** parameters are for temporary use during development, to help find
18800 ** optimial values for parameters in the query planner. The should not
@@ -18816,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 */
@@ -19458,10 +19553,11 @@
19553 SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
19554 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
19555 #define LOCATE_VIEW 0x01
19556 #define LOCATE_NOERR 0x02
19557 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
19558 SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*);
19559 SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
19560 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
19561 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
19562 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
19563 SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
@@ -19474,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
@@ -19916,13 +20012,15 @@
20012 #endif
20013 SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
20014 #ifndef SQLITE_OMIT_VIRTUALTABLE
20015 SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
20016 SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
20017 SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*);
20018 #else
20019 # define sqlite3ShadowTableName(A,B) 0
20020 # define sqlite3IsShadowTableOf(A,B,C) 0
20021 # define sqlite3MarkAllShadowTablesOf(A,B)
20022 #endif
20023 SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
20024 SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
20025 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
20026 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -22105,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*);
@@ -24126,16 +24228,19 @@
24228 pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
24229 if( pFile ){
24230 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
24231 if( rc!=SQLITE_OK ){
24232 sqlite3_free(pFile);
24233 *ppFile = 0;
24234 }else{
24235 *ppFile = pFile;
24236 }
24237 }else{
24238 *ppFile = 0;
24239 rc = SQLITE_NOMEM_BKPT;
24240 }
24241 assert( *ppFile!=0 || rc!=SQLITE_OK );
24242 return rc;
24243 }
24244 SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
24245 assert( pFile );
24246 sqlite3OsClose(pFile);
@@ -38079,11 +38184,13 @@
38184 }
38185 }
38186
38187 /* Forward declaration */
38188 static int unixGetTempname(int nBuf, char *zBuf);
38189 #ifndef SQLITE_OMIT_WAL
38190 static int unixFcntlExternalReader(unixFile*, int*);
38191 #endif
38192
38193 /*
38194 ** Information and control of an open file handle.
38195 */
38196 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -38198,11 +38305,16 @@
38305 return proxyFileControl(id,op,pArg);
38306 }
38307 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
38308
38309 case SQLITE_FCNTL_EXTERNAL_READER: {
38310 #ifndef SQLITE_OMIT_WAL
38311 return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
38312 #else
38313 *(int*)pArg = 0;
38314 return SQLITE_OK;
38315 #endif
38316 }
38317 }
38318 return SQLITE_NOTFOUND;
38319 }
38320
@@ -40252,10 +40364,15 @@
40364 if( randomnessPid!=osGetpid(0) ){
40365 randomnessPid = osGetpid(0);
40366 sqlite3_randomness(0,0);
40367 }
40368 memset(p, 0, sizeof(unixFile));
40369
40370 #ifdef SQLITE_ASSERT_NO_FILES
40371 /* Applications that never read or write a persistent disk files */
40372 assert( zName==0 );
40373 #endif
40374
40375 if( eType==SQLITE_OPEN_MAIN_DB ){
40376 UnixUnusedFd *pUnused;
40377 pUnused = findReusableFd(zName, flags);
40378 if( pUnused ){
@@ -48664,11 +48781,11 @@
48781 /*
48782 ** Try to enlarge the memory allocation to hold at least sz bytes
48783 */
48784 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
48785 unsigned char *pNew;
48786 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){
48787 return SQLITE_FULL;
48788 }
48789 if( newSz>p->szMax ){
48790 return SQLITE_FULL;
48791 }
@@ -48723,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;
@@ -48863,11 +48981,11 @@
48981 int iAmt,
48982 void **pp
48983 ){
48984 MemStore *p = ((MemFile*)pFile)->pStore;
48985 memdbEnter(p);
48986 if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){
48987 *pp = 0;
48988 }else{
48989 p->nMmap++;
48990 *pp = (void*)(p->aData + iOfst);
48991 }
@@ -48897,13 +49015,12 @@
49015 int *pOutFlags
49016 ){
49017 MemFile *pFile = (MemFile*)pFd;
49018 MemStore *p = 0;
49019 int szName;
49020 UNUSED_PARAMETER(pVfs);
49021
 
49022 memset(pFile, 0, sizeof(*pFile));
49023 szName = sqlite3Strlen30(zName);
49024 if( szName>1 && zName[0]=='/' ){
49025 int i;
49026 #ifndef SQLITE_MUTEX_OMIT
@@ -48959,12 +49076,13 @@
49076 memset(p, 0, sizeof(*p));
49077 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
49078 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
49079 }
49080 pFile->pStore = p;
49081 if( pOutFlags!=0 ){
49082 *pOutFlags = flags | SQLITE_OPEN_MEMORY;
49083 }
49084 pFd->pMethods = &memdb_io_methods;
49085 memdbLeave(p);
49086 return SQLITE_OK;
49087 }
49088
@@ -53155,10 +53273,11 @@
53273 u8 walSyncFlags; /* See description above */
53274 u8 tempFile; /* zFilename is a temporary or immutable file */
53275 u8 noLock; /* Do not lock (except in WAL mode) */
53276 u8 readOnly; /* True for a read-only database */
53277 u8 memDb; /* True to inhibit all file I/O */
53278 u8 memVfs; /* VFS-implemented memory database */
53279
53280 /**************************************************************************
53281 ** The following block contains those class members that change during
53282 ** routine operation. Class members not in this block are either fixed
53283 ** when the pager is first created or else only change when there is a
@@ -57397,11 +57516,11 @@
57516 if( zFilename && zFilename[0] ){
57517 int fout = 0; /* VFS flags returned by xOpen() */
57518 rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
57519 assert( !memDb );
57520 #ifndef SQLITE_OMIT_DESERIALIZE
57521 pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
57522 #endif
57523 readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
57524
57525 /* If the file was successfully opened for read/write access,
57526 ** choose a default page size in case we have to create the
@@ -59334,11 +59453,11 @@
59453
59454 /*
59455 ** Return true if this is an in-memory or temp-file backed pager.
59456 */
59457 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
59458 return pPager->tempFile || pPager->memVfs;
59459 }
59460
59461 /*
59462 ** Check that there are at least nSavepoint savepoints open. If there are
59463 ** currently less than nSavepoints open, then open one or more savepoints
@@ -60859,13 +60978,17 @@
60978 ** If the wal-index is currently smaller the iPage pages then the size
60979 ** of the wal-index might be increased, but only if it is safe to do
60980 ** so. It is safe to enlarge the wal-index if pWal->writeLock is true
60981 ** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
60982 **
60983 ** Three possible result scenarios:
60984 **
60985 ** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
60986 ** (2) rc>=SQLITE_ERROR and *ppPage==NULL
60987 ** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0
60988 **
60989 ** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
60990 */
60991 static SQLITE_NOINLINE int walIndexPageRealloc(
60992 Wal *pWal, /* The WAL context */
60993 int iPage, /* The page we seek */
60994 volatile u32 **ppPage /* Write the page pointer here */
@@ -60894,11 +61017,13 @@
61017 if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
61018 }else{
61019 rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
61020 pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
61021 );
61022 assert( pWal->apWiData[iPage]!=0
61023 || rc!=SQLITE_OK
61024 || (pWal->writeLock==0 && iPage==0) );
61025 testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
61026 if( rc==SQLITE_OK ){
61027 if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
61028 }else if( (rc&0xff)==SQLITE_READONLY ){
61029 pWal->readOnly |= WAL_SHM_RDONLY;
@@ -61233,12 +61358,12 @@
61358 ** in the wal-index file. Set pLoc->iZero to one less than the frame
61359 ** number of the first frame indexed by this hash table. If a
61360 ** slot in the hash table is set to N, it refers to frame number
61361 ** (pLoc->iZero+N) in the log.
61362 **
61363 ** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the
61364 ** first frame indexed by the hash table, frame (pLoc->iZero).
61365 */
61366 static int walHashGet(
61367 Wal *pWal, /* WAL handle */
61368 int iHash, /* Find the iHash'th table */
61369 WalHashLoc *pLoc /* OUT: Hash table location */
@@ -61246,19 +61371,20 @@
61371 int rc; /* Return code */
61372
61373 rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
61374 assert( rc==SQLITE_OK || iHash>0 );
61375
61376 if( pLoc->aPgno ){
61377 pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
61378 if( iHash==0 ){
61379 pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
61380 pLoc->iZero = 0;
61381 }else{
61382 pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
61383 }
61384 }else if( NEVER(rc==SQLITE_OK) ){
61385 rc = SQLITE_ERROR;
61386 }
61387 return rc;
61388 }
61389
61390 /*
@@ -61336,25 +61462,26 @@
61462 }
61463
61464 /* Zero the entries in the aPgno array that correspond to frames with
61465 ** frame numbers greater than pWal->hdr.mxFrame.
61466 */
61467 nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]);
61468 assert( nByte>=0 );
61469 memset((void *)&sLoc.aPgno[iLimit], 0, nByte);
61470
61471 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61472 /* Verify that the every entry in the mapping region is still reachable
61473 ** via the hash table even after the cleanup.
61474 */
61475 if( iLimit ){
61476 int j; /* Loop counter */
61477 int iKey; /* Hash key */
61478 for(j=0; j<iLimit; j++){
61479 for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
61480 if( sLoc.aHash[iKey]==j+1 ) break;
61481 }
61482 assert( sLoc.aHash[iKey]==j+1 );
61483 }
61484 }
61485 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61486 }
61487
@@ -61382,32 +61509,32 @@
61509
61510 /* If this is the first entry to be added to this hash-table, zero the
61511 ** entire hash table and aPgno[] array before proceeding.
61512 */
61513 if( idx==1 ){
61514 int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno);
61515 assert( nByte>=0 );
61516 memset((void*)sLoc.aPgno, 0, nByte);
61517 }
61518
61519 /* If the entry in aPgno[] is already set, then the previous writer
61520 ** must have exited unexpectedly in the middle of a transaction (after
61521 ** writing one or more dirty pages to the WAL to free up memory).
61522 ** Remove the remnants of that writers uncommitted transaction from
61523 ** the hash-table before writing any new entries.
61524 */
61525 if( sLoc.aPgno[idx-1] ){
61526 walCleanupHash(pWal);
61527 assert( !sLoc.aPgno[idx-1] );
61528 }
61529
61530 /* Write the aPgno[] array entry and the hash-table slot. */
61531 nCollide = idx;
61532 for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61533 if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
61534 }
61535 sLoc.aPgno[idx-1] = iPage;
61536 AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
61537
61538 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61539 /* Verify that the number of entries in the hash table exactly equals
61540 ** the number of entries in the mapping region.
@@ -61424,22 +61551,21 @@
61551 ** thing to check, so only do this occasionally - not on every
61552 ** iteration.
61553 */
61554 if( (idx&0x3ff)==0 ){
61555 int i; /* Loop counter */
61556 for(i=0; i<idx; i++){
61557 for(iKey=walHash(sLoc.aPgno[i]);
61558 sLoc.aHash[iKey];
61559 iKey=walNextHash(iKey)){
61560 if( sLoc.aHash[iKey]==i+1 ) break;
61561 }
61562 assert( sLoc.aHash[iKey]==i+1 );
61563 }
61564 }
61565 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61566 }
 
61567
61568 return rc;
61569 }
61570
61571
@@ -61557,11 +61683,12 @@
61683 u32 iFrame; /* Index of last frame read */
61684 u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
61685 u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
61686 u32 nHdr, nHdr32;
61687 rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
61688 assert( aShare!=0 || rc!=SQLITE_OK );
61689 if( aShare==0 ) break;
61690 pWal->apWiData[iPg] = aPrivate;
61691
61692 for(iFrame=iFirst; iFrame<=iLast; iFrame++){
61693 i64 iOffset = walFrameOffset(iFrame, szPage);
61694 u32 pgno; /* Database page number for frame */
@@ -62054,11 +62181,10 @@
62181 if( rc==SQLITE_OK ){
62182 int j; /* Counter variable */
62183 int nEntry; /* Number of entries in this segment */
62184 ht_slot *aIndex; /* Sorted index for this segment */
62185
 
62186 if( (i+1)==nSegment ){
62187 nEntry = (int)(iLast - sLoc.iZero);
62188 }else{
62189 nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
62190 }
@@ -63193,11 +63319,12 @@
63319 i64 iDbOff; /* Offset of db file entry */
63320 i64 iWalOff; /* Offset of wal file entry */
63321
63322 rc = walHashGet(pWal, walFramePage(i), &sLoc);
63323 if( rc!=SQLITE_OK ) break;
63324 assert( i - sLoc.iZero - 1 >=0 );
63325 pgno = sLoc.aPgno[i-sLoc.iZero-1];
63326 iDbOff = (i64)(pgno-1) * szPage;
63327
63328 if( iDbOff+szPage<=szDb ){
63329 iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
63330 rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
@@ -63426,11 +63553,11 @@
63553 }
63554 nCollide = HASHTABLE_NSLOT;
63555 iKey = walHash(pgno);
63556 while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
63557 u32 iFrame = iH + sLoc.iZero;
63558 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){
63559 assert( iFrame>iRead || CORRUPT_DB );
63560 iRead = iFrame;
63561 }
63562 if( (nCollide--)==0 ){
63563 return SQLITE_CORRUPT_BKPT;
@@ -66919,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 );
@@ -69370,27 +69497,30 @@
69497 }
69498
69499 /*
69500 ** This routine is called prior to sqlite3PagerCommit when a transaction
69501 ** is committed for an auto-vacuum database.
 
 
 
 
 
69502 */
69503 static int autoVacuumCommit(Btree *p){
69504 int rc = SQLITE_OK;
69505 Pager *pPager;
69506 BtShared *pBt;
69507 sqlite3 *db;
69508 VVA_ONLY( int nRef );
69509
69510 assert( p!=0 );
69511 pBt = p->pBt;
69512 pPager = pBt->pPager;
69513 VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); )
69514
69515 assert( sqlite3_mutex_held(pBt->mutex) );
69516 invalidateAllOverflowCache(pBt);
69517 assert(pBt->autoVacuum);
69518 if( !pBt->incrVacuum ){
69519 Pgno nFin; /* Number of pages in database after autovacuuming */
69520 Pgno nFree; /* Number of pages on the freelist initially */
69521 Pgno nVac; /* Number of pages to vacuum */
69522 Pgno iFree; /* The next page to be freed */
69523 Pgno nOrig; /* Database size before freeing */
69524
69525 nOrig = btreePagecount(pBt);
69526 if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
@@ -69400,22 +69530,46 @@
69530 */
69531 return SQLITE_CORRUPT_BKPT;
69532 }
69533
69534 nFree = get4byte(&pBt->pPage1->aData[36]);
69535 db = p->db;
69536 if( db->xAutovacPages ){
69537 int iDb;
69538 for(iDb=0; ALWAYS(iDb<db->nDb); iDb++){
69539 if( db->aDb[iDb].pBt==p ) break;
69540 }
69541 nVac = db->xAutovacPages(
69542 db->pAutovacPagesArg,
69543 db->aDb[iDb].zDbSName,
69544 nOrig,
69545 nFree,
69546 pBt->pageSize
69547 );
69548 if( nVac>nFree ){
69549 nVac = nFree;
69550 }
69551 if( nVac==0 ){
69552 return SQLITE_OK;
69553 }
69554 }else{
69555 nVac = nFree;
69556 }
69557 nFin = finalDbSize(pBt, nOrig, nVac);
69558 if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
69559 if( nFin<nOrig ){
69560 rc = saveAllCursors(pBt, 0, 0);
69561 }
69562 for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
69563 rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree);
69564 }
69565 if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
69566 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
69567 if( nVac==nFree ){
69568 put4byte(&pBt->pPage1->aData[32], 0);
69569 put4byte(&pBt->pPage1->aData[36], 0);
69570 }
69571 put4byte(&pBt->pPage1->aData[28], nFin);
69572 pBt->bDoTruncate = 1;
69573 pBt->nPage = nFin;
69574 }
69575 if( rc!=SQLITE_OK ){
@@ -69462,11 +69616,11 @@
69616 if( p->inTrans==TRANS_WRITE ){
69617 BtShared *pBt = p->pBt;
69618 sqlite3BtreeEnter(p);
69619 #ifndef SQLITE_OMIT_AUTOVACUUM
69620 if( pBt->autoVacuum ){
69621 rc = autoVacuumCommit(p);
69622 if( rc!=SQLITE_OK ){
69623 sqlite3BtreeLeave(p);
69624 return rc;
69625 }
69626 }
@@ -77424,10 +77578,12 @@
77578 nByte = 1;
77579 }
77580 if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
77581 return SQLITE_NOMEM_BKPT;
77582 }
77583 assert( pMem->z!=0 );
77584 assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
77585
77586 memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
77587 pMem->n += pMem->u.nZero;
77588 pMem->flags &= ~(MEM_Zero|MEM_Term);
77589 return SQLITE_OK;
@@ -77900,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.
@@ -82037,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.
@@ -82091,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. */
@@ -84195,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;
@@ -84773,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;
@@ -85786,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){
@@ -86074,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 ){
@@ -89391,20 +89583,25 @@
89583 rc = SQLITE_CORRUPT_BKPT;
89584 goto abort_due_to_error;
89585 }
89586 }
89587
89588 /* Opcode: TypeCheck P1 P2 P3 P4 *
89589 ** Synopsis: typecheck(r[P1@P2])
89590 **
89591 ** Apply affinities to the range of P2 registers beginning with P1.
89592 ** Take the affinities from the Table object in P4. If any value
89593 ** cannot be coerced into the correct type, then raise an error.
89594 **
89595 ** This opcode is similar to OP_Affinity except that this opcode
89596 ** forces the register type to the Table column type. This is used
89597 ** to implement "strict affinity".
89598 **
89599 ** GENERATED ALWAYS AS ... STATIC columns are only checked if P3
89600 ** is zero. When P3 is non-zero, no type checking occurs for
89601 ** static generated columns. Virtual columns are computed at query time
89602 ** and so they are never checked.
89603 **
89604 ** Preconditions:
89605 **
89606 ** <ul>
89607 ** <li> P2 should be the number of non-virtual columns in the
@@ -89424,11 +89621,14 @@
89621 assert( pTab->tabFlags & TF_Strict );
89622 assert( pTab->nNVCol==pOp->p2 );
89623 aCol = pTab->aCol;
89624 pIn1 = &aMem[pOp->p1];
89625 for(i=0; i<pTab->nCol; i++){
89626 if( aCol[i].colFlags & COLFLAG_GENERATED ){
89627 if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
89628 if( pOp->p3 ){ pIn1++; continue; }
89629 }
89630 assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
89631 applyAffinity(pIn1, aCol[i].affinity, encoding);
89632 if( (pIn1->flags & MEM_Null)==0 ){
89633 switch( aCol[i].eCType ){
89634 case COLTYPE_BLOB: {
@@ -90148,12 +90348,20 @@
90348 assert( p->bIsReader );
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 ){
@@ -90191,11 +90399,12 @@
90399 p->nStmtDefCons = db->nDeferredCons;
90400 p->nStmtDefImmCons = db->nDeferredImmCons;
90401 }
90402 }
90403 assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
90404 if( rc==SQLITE_OK
90405 && pOp->p5
90406 && (iMeta!=pOp->p3
90407 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
90408 ){
90409 /*
90410 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -92997,11 +93206,11 @@
93206 db->mDbFlags |= DBFLAG_SchemaChange;
93207 p->expired = 0;
93208 }else
93209 #endif
93210 {
93211 zSchema = LEGACY_SCHEMA_TABLE;
93212 initData.db = db;
93213 initData.iDb = iDb;
93214 initData.pzErrMsg = &p->zErrMsg;
93215 initData.mInitFlags = 0;
93216 initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
@@ -94217,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
@@ -94265,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 ){
@@ -94318,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;
@@ -94413,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
@@ -94860,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 }
@@ -94873,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
@@ -95004,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"
@@ -95349,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
@@ -96731,11 +96958,11 @@
96958 void *p = 0;
96959 int chunksize = 4*1024;
96960 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
96961 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
96962 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
96963 if( p ) sqlite3OsUnfetch(pFd, 0, p);
96964 }
96965 }
96966 #else
96967 # define vdbeSorterExtendFile(x,y,z)
96968 #endif
@@ -97449,10 +97676,11 @@
97676 pTask->file2.iEof += pIncr->mxSz;
97677 }else{
97678 vdbeMergeEngineFree(pMerger);
97679 rc = SQLITE_NOMEM_BKPT;
97680 }
97681 assert( *ppOut!=0 || rc!=SQLITE_OK );
97682 return rc;
97683 }
97684
97685 #if SQLITE_MAX_WORKER_THREADS>0
97686 /*
@@ -100427,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 ){
@@ -101405,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 **
@@ -103131,11 +103362,11 @@
103362 }
103363
103364 return pRet;
103365 }
103366 #else
103367 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
103368 assert( p==0 );
103369 return 0;
103370 }
103371 #endif
103372
@@ -104186,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;
@@ -107262,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 **
@@ -107758,11 +108025,11 @@
108025 int bNoDQS /* Do not allow DQS in the schema */
108026 ){
108027 pParse->colNamesSet = 1;
108028 sqlite3NestedParse(pParse,
108029 "SELECT 1 "
108030 "FROM \"%w\"." LEGACY_SCHEMA_TABLE " "
108031 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108032 " AND sql NOT LIKE 'create virtual%%'"
108033 " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
108034 zDb,
108035 zDb, bTemp, zWhen, bNoDQS
@@ -107769,11 +108036,11 @@
108036 );
108037
108038 if( bTemp==0 ){
108039 sqlite3NestedParse(pParse,
108040 "SELECT 1 "
108041 "FROM temp." LEGACY_SCHEMA_TABLE " "
108042 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108043 " AND sql NOT LIKE 'create virtual%%'"
108044 " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
108045 zDb, zWhen, bNoDQS
108046 );
@@ -107787,18 +108054,18 @@
108054 ** not true, similarly update all SQL statements in the sqlite_schema table
108055 ** of the temp db.
108056 */
108057 static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
108058 sqlite3NestedParse(pParse,
108059 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE
108060 " SET sql = sqlite_rename_quotefix(%Q, sql)"
108061 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108062 " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
108063 );
108064 if( bTemp==0 ){
108065 sqlite3NestedParse(pParse,
108066 "UPDATE temp." LEGACY_SCHEMA_TABLE
108067 " SET sql = sqlite_rename_quotefix('temp', sql)"
108068 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108069 " AND sql NOT LIKE 'create virtual%%'"
108070 );
108071 }
@@ -107912,21 +108179,21 @@
108179 nTabName = sqlite3Utf8CharLen(zTabName, -1);
108180
108181 /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
108182 ** the schema to use the new table name. */
108183 sqlite3NestedParse(pParse,
108184 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108185 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
108186 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
108187 "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108188 , zDb, zDb, zTabName, zName, (iDb==1), zTabName
108189 );
108190
108191 /* Update the tbl_name and name columns of the sqlite_schema table
108192 ** as required. */
108193 sqlite3NestedParse(pParse,
108194 "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET "
108195 "tbl_name = %Q, "
108196 "name = CASE "
108197 "WHEN type='table' THEN %Q "
108198 "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
108199 " AND type='index' THEN "
@@ -108111,11 +108378,11 @@
108378 /* substr() operations on characters, but addColOffset is in bytes. So we
108379 ** have to use printf() to translate between these units: */
108380 assert( IsOrdinaryTable(pTab) );
108381 assert( IsOrdinaryTable(pNew) );
108382 sqlite3NestedParse(pParse,
108383 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108384 "sql = printf('%%.%ds, ',sql) || %Q"
108385 " || substr(sql,1+length(printf('%%.%ds',sql))) "
108386 "WHERE type = 'table' AND name = %Q",
108387 zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,
108388 zTab
@@ -108137,11 +108404,11 @@
108404 VdbeCoverage(v);
108405 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
108406 sqlite3ReleaseTempReg(pParse, r1);
108407
108408 /* Reload the table definition */
108409 renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd);
108410
108411 /* Verify that constraints are still satisfied */
108412 if( pNew->pCheck!=0
108413 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
108414 ){
@@ -108345,21 +108612,21 @@
108612 zNew = sqlite3NameFromToken(db, pNew);
108613 if( !zNew ) goto exit_rename_column;
108614 assert( pNew->n>0 );
108615 bQuote = sqlite3Isquote(pNew->z[0]);
108616 sqlite3NestedParse(pParse,
108617 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108618 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
108619 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
108620 " AND (type != 'index' OR tbl_name = %Q)",
108621 zDb,
108622 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
108623 pTab->zName
108624 );
108625
108626 sqlite3NestedParse(pParse,
108627 "UPDATE temp." LEGACY_SCHEMA_TABLE " SET "
108628 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
108629 "WHERE type IN ('trigger', 'view')",
108630 zDb, pTab->zName, iCol, zNew, bQuote
108631 );
108632
@@ -109030,10 +109297,13 @@
109297 }else{
109298 p->pTab->nTabRef++;
109299 rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
109300 }
109301 }
109302 }
109303 if( rc==SQLITE_OK && db->mallocFailed ){
109304 rc = SQLITE_NOMEM;
109305 }
109306 sNC.pSrcList = pSrc;
109307 if( rc==SQLITE_OK && pStep->pWhere ){
109308 rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
109309 }
@@ -109833,11 +110103,11 @@
110103 assert( iDb>=0 );
110104 zDb = db->aDb[iDb].zDbSName;
110105 renameTestSchema(pParse, zDb, iDb==1, "", 0);
110106 renameFixQuotes(pParse, zDb, iDb==1);
110107 sqlite3NestedParse(pParse,
110108 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
110109 "sql = sqlite_drop_column(%d, sql, %d) "
110110 "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
110111 , zDb, iDb, iCol, pTab->zName
110112 );
110113
@@ -113122,21 +113392,21 @@
113392 }
113393 }
113394 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113395 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113396 if( i==1 ){
113397 if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0
113398 || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0
113399 || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0
113400 ){
113401 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113402 LEGACY_TEMP_SCHEMA_TABLE);
113403 }
113404 }else{
113405 if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113406 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
113407 LEGACY_SCHEMA_TABLE);
113408 }
113409 }
113410 }
113411 }else{
113412 /* Match against TEMP first */
@@ -113150,15 +113420,15 @@
113420 assert( sqlite3SchemaMutexHeld(db, i, 0) );
113421 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113422 if( p ) break;
113423 }
113424 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113425 if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113426 p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE);
113427 }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
113428 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113429 LEGACY_TEMP_SCHEMA_TABLE);
113430 }
113431 }
113432 }
113433 return p;
113434 }
@@ -113249,10 +113519,26 @@
113519 }else{
113520 zDb = p->zDatabase;
113521 }
113522 return sqlite3LocateTable(pParse, flags, p->zName, zDb);
113523 }
113524
113525 /*
113526 ** Return the preferred table name for system tables. Translate legacy
113527 ** names into the new preferred names, as appropriate.
113528 */
113529 SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){
113530 if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113531 if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){
113532 return PREFERRED_SCHEMA_TABLE;
113533 }
113534 if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){
113535 return PREFERRED_TEMP_SCHEMA_TABLE;
113536 }
113537 }
113538 return zName;
113539 }
113540
113541 /*
113542 ** Locate the in-memory structure that describes
113543 ** a particular index given the name of that index
113544 ** and the name of the database that contains the index.
@@ -113648,11 +113934,11 @@
113934 ** Open the sqlite_schema table stored in database number iDb for
113935 ** writing. The table is opened using cursor 0.
113936 */
113937 SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){
113938 Vdbe *v = sqlite3GetVdbe(p);
113939 sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE);
113940 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
113941 if( p->nTab==0 ){
113942 p->nTab = 1;
113943 }
113944 }
@@ -115227,10 +115513,45 @@
115513 if( pMod->pModule->xShadowName==0 ) return 0;
115514 return pMod->pModule->xShadowName(zName+nName+1);
115515 }
115516 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115517
115518 #ifndef SQLITE_OMIT_VIRTUALTABLE
115519 /*
115520 ** Table pTab is a virtual table. If it the virtual table implementation
115521 ** exists and has an xShadowName method, then loop over all other ordinary
115522 ** tables within the same schema looking for shadow tables of pTab, and mark
115523 ** any shadow tables seen using the TF_Shadow flag.
115524 */
115525 SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){
115526 int nName; /* Length of pTab->zName */
115527 Module *pMod; /* Module for the virtual table */
115528 HashElem *k; /* For looping through the symbol table */
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);
115540 assert( pOther->zName!=0 );
115541 if( !IsOrdinaryTable(pOther) ) continue;
115542 if( pOther->tabFlags & TF_Shadow ) continue;
115543 if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0
115544 && pOther->zName[nName]=='_'
115545 && pMod->pModule->xShadowName(pOther->zName+nName+1)
115546 ){
115547 pOther->tabFlags |= TF_Shadow;
115548 }
115549 }
115550 }
115551 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115552
115553 #ifndef SQLITE_OMIT_VIRTUALTABLE
115554 /*
115555 ** Return true if zName is a shadow table name in the current database
115556 ** connection.
115557 **
@@ -115555,11 +115876,11 @@
115876 /* A slot for the record has already been allocated in the
115877 ** schema table. We just need to update that slot with all
115878 ** the information we've collected.
115879 */
115880 sqlite3NestedParse(pParse,
115881 "UPDATE %Q." LEGACY_SCHEMA_TABLE
115882 " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
115883 " WHERE rowid=#%d",
115884 db->aDb[iDb].zDbSName,
115885 zType,
115886 p->zName,
@@ -115741,17 +116062,16 @@
116062 #endif
116063
116064 assert( pTable );
116065
116066 #ifndef SQLITE_OMIT_VIRTUALTABLE
116067 if( IsVirtual(pTable) ){
116068 db->nSchemaLock++;
116069 rc = sqlite3VtabCallConnect(pParse, pTable);
116070 db->nSchemaLock--;
116071 return rc;
116072 }
 
116073 #endif
116074
116075 #ifndef SQLITE_OMIT_VIEW
116076 /* A positive nCol means the columns names for this view are
116077 ** already known.
@@ -115935,11 +116255,11 @@
116255 ** The "#NNN" in the SQL is a special constant that means whatever value
116256 ** is in register NNN. See grammar rules associated with the TK_REGISTER
116257 ** token for additional information.
116258 */
116259 sqlite3NestedParse(pParse,
116260 "UPDATE %Q." LEGACY_SCHEMA_TABLE
116261 " SET rootpage=%d WHERE #%d AND rootpage=#%d",
116262 pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
116263 #endif
116264 sqlite3ReleaseTempReg(pParse, r1);
116265 }
@@ -116070,11 +116390,11 @@
116390 ** dropped. Triggers are handled separately because a trigger can be
116391 ** created in the temp database that refers to a table in another
116392 ** database.
116393 */
116394 sqlite3NestedParse(pParse,
116395 "DELETE FROM %Q." LEGACY_SCHEMA_TABLE
116396 " WHERE tbl_name=%Q and type!='trigger'",
116397 pDb->zDbSName, pTab->zName);
116398 if( !isView && !IsVirtual(pTab) ){
116399 destroyTable(pParse, pTab);
116400 }
@@ -116117,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 /*
@@ -117087,11 +117410,11 @@
117410 }
117411
117412 /* Add an entry in sqlite_schema for this index
117413 */
117414 sqlite3NestedParse(pParse,
117415 "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
117416 db->aDb[iDb].zDbSName,
117417 pIndex->zName,
117418 pTab->zName,
117419 iMem,
117420 zStmt
@@ -117273,11 +117596,11 @@
117596 /* Generate code to remove the index and from the schema table */
117597 v = sqlite3GetVdbe(pParse);
117598 if( v ){
117599 sqlite3BeginWriteOperation(pParse, 1, iDb);
117600 sqlite3NestedParse(pParse,
117601 "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117602 db->aDb[iDb].zDbSName, pIndex->zName
117603 );
117604 sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
117605 sqlite3ChangeCookie(pParse, iDb);
117606 destroyRootPage(pParse, pIndex->tnum, iDb);
@@ -123933,28 +124256,34 @@
124256
124257 /* Before computing generated columns, first go through and make sure
124258 ** that appropriate affinity has been applied to the regular columns
124259 */
124260 sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
124261 if( (pTab->tabFlags & TF_HasStored)!=0 ){
124262 pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
124263 if( pOp->opcode==OP_Affinity ){
124264 /* Change the OP_Affinity argument to '@' (NONE) for all stored
124265 ** columns. '@' is the no-op affinity and those columns have not
124266 ** yet been computed. */
124267 int ii, jj;
124268 char *zP4 = pOp->p4.z;
124269 assert( zP4!=0 );
124270 assert( pOp->p4type==P4_DYNAMIC );
124271 for(ii=jj=0; zP4[jj]; ii++){
124272 if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
124273 continue;
124274 }
124275 if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
124276 zP4[jj] = SQLITE_AFF_NONE;
124277 }
124278 jj++;
124279 }
124280 }else if( pOp->opcode==OP_TypeCheck ){
124281 /* If an OP_TypeCheck was generated because the table is STRICT,
124282 ** then set the P3 operand to indicate that generated columns should
124283 ** not be checked */
124284 pOp->p3 = 1;
124285 }
124286 }
124287
124288 /* Because there can be multiple generated columns that refer to one another,
124289 ** this is a two-pass algorithm. On the first pass, mark all generated
@@ -125978,11 +126307,12 @@
126307 default: {
126308 int nConflictCk; /* Number of opcodes in conflict check logic */
126309
126310 assert( onError==OE_Replace );
126311 nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
126312 assert( nConflictCk>0 || db->mallocFailed );
126313 testcase( nConflictCk<=0 );
126314 testcase( nConflictCk>1 );
126315 if( regTrigCnt ){
126316 sqlite3MultiWrite(pParse);
126317 nReplaceTrig++;
126318 }
@@ -126264,12 +126594,13 @@
126594
126595 assert( op==OP_OpenRead || op==OP_OpenWrite );
126596 assert( op==OP_OpenWrite || p5==0 );
126597 if( IsVirtual(pTab) ){
126598 /* This routine is a no-op for virtual tables. Leave the output
126599 ** variables *piDataCur and *piIdxCur set to illegal cursor numbers
126600 ** for improved error detection. */
126601 *piDataCur = *piIdxCur = -999;
126602 return 0;
126603 }
126604 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
126605 v = pParse->pVdbe;
126606 assert( v!=0 );
@@ -127276,10 +127607,14 @@
127607 /* Version 3.34.0 and later */
127608 int (*txn_state)(sqlite3*,const char*);
127609 /* Version 3.36.1 and later */
127610 sqlite3_int64 (*changes64)(sqlite3*);
127611 sqlite3_int64 (*total_changes64)(sqlite3*);
127612 /* Version 3.37.0 and later */
127613 int (*autovacuum_pages)(sqlite3*,
127614 unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
127615 void*, void(*)(void*));
127616 };
127617
127618 /*
127619 ** This is the function signature used for all extension entry points. It
127620 ** is also defined in the file "loadext.c".
@@ -127582,10 +127917,15 @@
127917 #define sqlite3_create_filename sqlite3_api->create_filename
127918 #define sqlite3_free_filename sqlite3_api->free_filename
127919 #define sqlite3_database_file_object sqlite3_api->database_file_object
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
127931 ** extension */
@@ -128069,10 +128409,12 @@
128409 /* Version 3.34.0 and later */
128410 sqlite3_txn_state,
128411 /* Version 3.36.1 and later */
128412 sqlite3_changes64,
128413 sqlite3_total_changes64,
128414 /* Version 3.37.0 and later */
128415 sqlite3_autovacuum_pages,
128416 };
128417
128418 /* True if x is the directory separator character
128419 */
128420 #if SQLITE_OS_WIN
@@ -130391,11 +130733,11 @@
130733 }else{
130734 zType = "table";
130735 }
130736 sqlite3VdbeMultiLoad(v, 1, "sssiii",
130737 db->aDb[ii].zDbSName,
130738 sqlite3PreferredTableName(pTab->zName),
130739 zType,
130740 pTab->nCol,
130741 (pTab->tabFlags & TF_WithoutRowid)!=0,
130742 (pTab->tabFlags & TF_Strict)!=0
130743 );
@@ -130411,11 +130753,11 @@
130753 pParse->nMem = 5;
130754 sqlite3CodeVerifySchema(pParse, iDb);
130755 for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
130756 Table *pTab = sqliteHashData(i);
130757 sqlite3VdbeMultiLoad(v, 1, "ssiii",
130758 sqlite3PreferredTableName(pTab->zName),
130759 0,
130760 pTab->szTabRow,
130761 pTab->nRowLogEst,
130762 pTab->tabFlags);
130763 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -130906,11 +131248,11 @@
131248 if( pCol->notNull ){
131249 jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
131250 zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
131251 pCol->zCnName);
131252 sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
131253 if( bStrict && pCol->eCType!=COLTYPE_ANY ){
131254 sqlite3VdbeGoto(v, doError);
131255 }else{
131256 integrityCheckResultRow(v);
131257 }
131258 sqlite3VdbeJumpHere(v, jmp2);
@@ -131867,14 +132209,19 @@
132209 sqlite3 *db = pData->db;
132210 if( db->mallocFailed ){
132211 pData->rc = SQLITE_NOMEM_BKPT;
132212 }else if( pData->pzErrMsg[0]!=0 ){
132213 /* A error message has already been generated. Do not overwrite it */
132214 }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
132215 static const char *azAlterType[] = {
132216 "rename",
132217 "drop column",
132218 "add column"
132219 };
132220 *pData->pzErrMsg = sqlite3MPrintf(db,
132221 "error in %s %s after %s: %s", azObj[0], azObj[1],
132222 azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1],
132223 zExtra
132224 );
132225 pData->rc = SQLITE_ERROR;
132226 }else if( db->flags & SQLITE_WriteSchema ){
132227 pData->rc = SQLITE_CORRUPT_BKPT;
@@ -135070,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 ){
@@ -137809,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
@@ -140934,11 +141297,11 @@
141297 if( v==0 ) goto triggerfinish_cleanup;
141298 sqlite3BeginWriteOperation(pParse, 0, iDb);
141299 z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
141300 testcase( z==0 );
141301 sqlite3NestedParse(pParse,
141302 "INSERT INTO %Q." LEGACY_SCHEMA_TABLE
141303 " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
141304 db->aDb[iDb].zDbSName, zName,
141305 pTrig->table, z);
141306 sqlite3DbFree(db, z);
141307 sqlite3ChangeCookie(pParse, iDb);
@@ -141248,11 +141611,11 @@
141611
141612 /* Generate code to destroy the database record of the trigger.
141613 */
141614 if( (v = sqlite3GetVdbe(pParse))!=0 ){
141615 sqlite3NestedParse(pParse,
141616 "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
141617 db->aDb[iDb].zDbSName, pTrigger->zName
141618 );
141619 sqlite3ChangeCookie(pParse, iDb);
141620 sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
141621 }
@@ -143901,11 +144264,13 @@
144264 rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
144265 if( rc!=SQLITE_OK ) goto end_of_vacuum;
144266
144267 /* Do not attempt to change the page size for a WAL database */
144268 if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
144269 ==PAGER_JOURNALMODE_WAL
144270 && pOut==0
144271 ){
144272 db->nextPagesize = 0;
144273 }
144274
144275 if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
144276 || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
@@ -144543,11 +144908,11 @@
144908 ** entry in the sqlite_schema table tht was created for this vtab
144909 ** by sqlite3StartTable().
144910 */
144911 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
144912 sqlite3NestedParse(pParse,
144913 "UPDATE %Q." LEGACY_SCHEMA_TABLE " "
144914 "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
144915 "WHERE rowid=#%d",
144916 db->aDb[iDb].zDbSName,
144917 pTab->zName,
144918 pTab->zName,
@@ -144563,22 +144928,18 @@
144928 sqlite3DbFree(db, zStmt);
144929
144930 iReg = ++pParse->nMem;
144931 sqlite3VdbeLoadString(v, iReg, pTab->zName);
144932 sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
144933 }else{
144934 /* If we are rereading the sqlite_schema table create the in-memory
144935 ** record of the table. */
 
 
 
 
 
144936 Table *pOld;
144937 Schema *pSchema = pTab->pSchema;
144938 const char *zName = pTab->zName;
144939 assert( zName!=0 );
144940 sqlite3MarkAllShadowTablesOf(db, pTab);
144941 pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
144942 if( pOld ){
144943 sqlite3OomFault(db);
144944 assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
144945 return;
@@ -144758,11 +145119,12 @@
145119 const char *zMod;
145120 Module *pMod;
145121 int rc;
145122
145123 assert( pTab );
145124 assert( IsVirtual(pTab) );
145125 if( sqlite3GetVTable(db, pTab) ){
145126 return SQLITE_OK;
145127 }
145128
145129 /* Locate the required virtual table module */
145130 zMod = pTab->u.vtab.azArg[0];
@@ -144962,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 ){
@@ -147900,12 +148265,23 @@
148265
148266 /* Load the value for the inequality constraint at the end of the
148267 ** range (if any).
148268 */
148269 nConstraint = nEq;
148270 assert( pLevel->p2==0 );
148271 if( pRangeEnd ){
148272 Expr *pRight = pRangeEnd->pExpr->pRight;
148273 if( addrSeekScan ){
148274 /* For a seek-scan that has a range on the lowest term of the index,
148275 ** we have to make the top of the loop be code that sets the end
148276 ** condition of the range. Otherwise, the OP_SeekScan might jump
148277 ** over that initialization, leaving the range-end value set to the
148278 ** range-start value, resulting in a wrong answer.
148279 ** See ticket 5981a8c041a3c2f3 (2021-11-02).
148280 */
148281 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148282 }
148283 codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
148284 whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
148285 if( (pRangeEnd->wtFlags & TERM_VNULL)==0
148286 && sqlite3ExprCanBeNull(pRight)
148287 ){
@@ -147935,11 +148311,11 @@
148311 }
148312 sqlite3DbFree(db, zStartAff);
148313 sqlite3DbFree(db, zEndAff);
148314
148315 /* Top of the loop body */
148316 if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148317
148318 /* Check if the index cursor is past the end of the range. */
148319 if( nConstraint ){
148320 if( regBignull ){
148321 /* Except, skip the end-of-range check while doing the NULL-scan */
@@ -155575,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,
@@ -157028,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 );
@@ -160475,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
@@ -164226,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,
@@ -167559,10 +167940,13 @@
167940 ** So it needs to be freed here. Todo: Why not roll the temp schema into
167941 ** the same sqliteMalloc() as the one that allocates the database
167942 ** structure?
167943 */
167944 sqlite3DbFree(db, db->aDb[1].pSchema);
167945 if( db->xAutovacDestr ){
167946 db->xAutovacDestr(db->pAutovacPagesArg);
167947 }
167948 sqlite3_mutex_leave(db->mutex);
167949 db->eOpenState = SQLITE_STATE_CLOSED;
167950 sqlite3_mutex_free(db->mutex);
167951 assert( sqlite3LookasideUsed(db,0)==0 );
167952 if( db->lookaside.bMalloced ){
@@ -167613,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 }
@@ -168459,10 +168843,38 @@
168843 db->pPreUpdateArg = pArg;
168844 sqlite3_mutex_leave(db->mutex);
168845 return pRet;
168846 }
168847 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
168848
168849 /*
168850 ** Register a function to be invoked prior to each autovacuum that
168851 ** determines the number of pages to vacuum.
168852 */
168853 SQLITE_API int sqlite3_autovacuum_pages(
168854 sqlite3 *db, /* Attach the hook to this database */
168855 unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
168856 void *pArg, /* Argument to the function */
168857 void (*xDestructor)(void*) /* Destructor for pArg */
168858 ){
168859 #ifdef SQLITE_ENABLE_API_ARMOR
168860 if( !sqlite3SafetyCheckOk(db) ){
168861 if( xDestructor ) xDestructor(pArg);
168862 return SQLITE_MISUSE_BKPT;
168863 }
168864 #endif
168865 sqlite3_mutex_enter(db->mutex);
168866 if( db->xAutovacDestr ){
168867 db->xAutovacDestr(db->pAutovacPagesArg);
168868 }
168869 db->xAutovacPages = xCallback;
168870 db->pAutovacPagesArg = pArg;
168871 db->xAutovacDestr = xDestructor;
168872 sqlite3_mutex_leave(db->mutex);
168873 return SQLITE_OK;
168874 }
168875
168876
168877 #ifndef SQLITE_OMIT_WAL
168878 /*
168879 ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
168880 ** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
@@ -169313,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 |
@@ -169349,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;
@@ -169581,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 }
@@ -169597,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.
@@ -178147,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 }
@@ -189837,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
@@ -190856,11 +191271,11 @@
191271 # define ALWAYS(X) (X)
191272 # define NEVER(X) (X)
191273 # endif
191274 # define testcase(X)
191275 #endif
191276 #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
191277 # define VVA(X)
191278 #else
191279 # define VVA(X) X
191280 #endif
191281
@@ -192407,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 }
@@ -201403,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:
@@ -204050,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");
@@ -204422,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;
@@ -204488,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
@@ -204526,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);
@@ -205281,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);
@@ -205378,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;
@@ -205415,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.
@@ -215536,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
@@ -216475,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,
@@ -221608,20 +222076,29 @@
222076 Fts5PoslistWriter writer;
222077 int bOk; /* True if ok to populate */
222078 int bMiss;
222079 };
222080
222081 /*
222082 ** Clear the position lists associated with all phrases in the expression
222083 ** passed as the first argument. Argument bLive is true if the expression
222084 ** might be pointing to a real entry, otherwise it has just been reset.
222085 **
222086 ** At present this function is only used for detail=col and detail=none
222087 ** fts5 tables. This implies that all phrases must be at most 1 token
222088 ** in size, as phrase matches are not supported without detail=full.
222089 */
222090 static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
222091 Fts5PoslistPopulator *pRet;
222092 pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
222093 if( pRet ){
222094 int i;
222095 memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
222096 for(i=0; i<pExpr->nPhrase; i++){
222097 Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
222098 Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
222099 assert( pExpr->apExprPhrase[i]->nTerm<=1 );
222100 if( bLive &&
222101 (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
222102 ){
222103 pRet[i].bMiss = 1;
222104 }else{
@@ -231982,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
+76 -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-10-22 11:17:29 1a038242dc6c0cab97dd9375acfce62aa1c386debc36aaed388d366b87ddd931"
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
**
@@ -6403,10 +6412,76 @@
64036412
**
64046413
** See also the [sqlite3_update_hook()] interface.
64056414
*/
64066415
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
64076416
SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
6417
+
6418
+/*
6419
+** CAPI3REF: Autovacuum Compaction Amount Callback
6420
+** METHOD: sqlite3
6421
+**
6422
+** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
6423
+** function C that is invoked prior to each autovacuum of the database
6424
+** file. ^The callback is passed a copy of the generic data pointer (P),
6425
+** the schema-name of the attached database that is being autovacuumed,
6426
+** the the size of the database file in pages, the number of free pages,
6427
+** and the number of bytes per page, respectively. The callback should
6428
+** return the number of free pages that should be removed by the
6429
+** autovacuum. ^If the callback returns zero, then no autovacuum happens.
6430
+** ^If the value returned is greater than or equal to the number of
6431
+** free pages, then a complete autovacuum happens.
6432
+**
6433
+** <p>^If there are multiple ATTACH-ed database files that are being
6434
+** modified as part of a transaction commit, then the autovacuum pages
6435
+** callback is invoked separately for each file.
6436
+**
6437
+** <p><b>The callback is not reentrant.</b> The callback function should
6438
+** not attempt to invoke any other SQLite interface. If it does, bad
6439
+** things may happen, including segmentation faults and corrupt database
6440
+** files. The callback function should be a simple function that
6441
+** does some arithmetic on its input parameters and returns a result.
6442
+**
6443
+** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
6444
+** destructor for the P parameter. ^If X is not NULL, then X(P) is
6445
+** invoked whenever the database connection closes or when the callback
6446
+** is overwritten by another invocation of sqlite3_autovacuum_pages().
6447
+**
6448
+** <p>^There is only one autovacuum pages callback per database connection.
6449
+** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
6450
+** previous invocations for that database connection. ^If the callback
6451
+** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
6452
+** then the autovacuum steps callback is cancelled. The return value
6453
+** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
6454
+** be some other error code if something goes wrong. The current
6455
+** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
6456
+** return codes might be added in future releases.
6457
+**
6458
+** <p>If no autovacuum pages callback is specified (the usual case) or
6459
+** a NULL pointer is provided for the callback,
6460
+** then the default behavior is to vacuum all free pages. So, in other
6461
+** words, the default behavior is the same as if the callback function
6462
+** were something like this:
6463
+**
6464
+** <blockquote><pre>
6465
+** &nbsp; unsigned int demonstration_autovac_pages_callback(
6466
+** &nbsp; void *pClientData,
6467
+** &nbsp; const char *zSchema,
6468
+** &nbsp; unsigned int nDbPage,
6469
+** &nbsp; unsigned int nFreePage,
6470
+** &nbsp; unsigned int nBytePerPage
6471
+** &nbsp; ){
6472
+** &nbsp; return nFreePage;
6473
+** &nbsp; }
6474
+** </pre></blockquote>
6475
+*/
6476
+SQLITE_API int sqlite3_autovacuum_pages(
6477
+ sqlite3 *db,
6478
+ unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
6479
+ void*,
6480
+ void(*)(void*)
6481
+);
6482
+
64086483
64096484
/*
64106485
** CAPI3REF: Data Change Notification Callbacks
64116486
** METHOD: sqlite3
64126487
**
64136488
--- 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-10-22 11:17:29 1a038242dc6c0cab97dd9375acfce62aa1c386debc36aaed388d366b87ddd931"
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 **
@@ -6403,10 +6412,76 @@
6403 **
6404 ** See also the [sqlite3_update_hook()] interface.
6405 */
6406 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
6407 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6408
6409 /*
6410 ** CAPI3REF: Data Change Notification Callbacks
6411 ** METHOD: sqlite3
6412 **
6413
--- 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 **
@@ -6403,10 +6412,76 @@
6412 **
6413 ** See also the [sqlite3_update_hook()] interface.
6414 */
6415 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
6416 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
6417
6418 /*
6419 ** CAPI3REF: Autovacuum Compaction Amount Callback
6420 ** METHOD: sqlite3
6421 **
6422 ** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback
6423 ** function C that is invoked prior to each autovacuum of the database
6424 ** file. ^The callback is passed a copy of the generic data pointer (P),
6425 ** the schema-name of the attached database that is being autovacuumed,
6426 ** the the size of the database file in pages, the number of free pages,
6427 ** and the number of bytes per page, respectively. The callback should
6428 ** return the number of free pages that should be removed by the
6429 ** autovacuum. ^If the callback returns zero, then no autovacuum happens.
6430 ** ^If the value returned is greater than or equal to the number of
6431 ** free pages, then a complete autovacuum happens.
6432 **
6433 ** <p>^If there are multiple ATTACH-ed database files that are being
6434 ** modified as part of a transaction commit, then the autovacuum pages
6435 ** callback is invoked separately for each file.
6436 **
6437 ** <p><b>The callback is not reentrant.</b> The callback function should
6438 ** not attempt to invoke any other SQLite interface. If it does, bad
6439 ** things may happen, including segmentation faults and corrupt database
6440 ** files. The callback function should be a simple function that
6441 ** does some arithmetic on its input parameters and returns a result.
6442 **
6443 ** ^The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional
6444 ** destructor for the P parameter. ^If X is not NULL, then X(P) is
6445 ** invoked whenever the database connection closes or when the callback
6446 ** is overwritten by another invocation of sqlite3_autovacuum_pages().
6447 **
6448 ** <p>^There is only one autovacuum pages callback per database connection.
6449 ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all
6450 ** previous invocations for that database connection. ^If the callback
6451 ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,
6452 ** then the autovacuum steps callback is cancelled. The return value
6453 ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might
6454 ** be some other error code if something goes wrong. The current
6455 ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other
6456 ** return codes might be added in future releases.
6457 **
6458 ** <p>If no autovacuum pages callback is specified (the usual case) or
6459 ** a NULL pointer is provided for the callback,
6460 ** then the default behavior is to vacuum all free pages. So, in other
6461 ** words, the default behavior is the same as if the callback function
6462 ** were something like this:
6463 **
6464 ** <blockquote><pre>
6465 ** &nbsp; unsigned int demonstration_autovac_pages_callback(
6466 ** &nbsp; void *pClientData,
6467 ** &nbsp; const char *zSchema,
6468 ** &nbsp; unsigned int nDbPage,
6469 ** &nbsp; unsigned int nFreePage,
6470 ** &nbsp; unsigned int nBytePerPage
6471 ** &nbsp; ){
6472 ** &nbsp; return nFreePage;
6473 ** &nbsp; }
6474 ** </pre></blockquote>
6475 */
6476 SQLITE_API int sqlite3_autovacuum_pages(
6477 sqlite3 *db,
6478 unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
6479 void*,
6480 void(*)(void*)
6481 );
6482
6483
6484 /*
6485 ** CAPI3REF: Data Change Notification Callbacks
6486 ** METHOD: sqlite3
6487 **
6488
+166 -19
--- src/sync.c
+++ src/sync.c
@@ -18,10 +18,84 @@
1818
** This file contains code used to push, pull, and sync a repository
1919
*/
2020
#include "config.h"
2121
#include "sync.h"
2222
#include <assert.h>
23
+
24
+/*
25
+** Explain what type of sync operation is about to occur
26
+*/
27
+static void sync_explain(unsigned syncFlags){
28
+ if( g.url.isAlias ){
29
+ if( (syncFlags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){
30
+ fossil_print("Sync with %s\n", g.url.canonical);
31
+ }else if( syncFlags & SYNC_PUSH ){
32
+ fossil_print("Push to %s\n", g.url.canonical);
33
+ }else if( syncFlags & SYNC_PULL ){
34
+ fossil_print("Pull from %s\n", g.url.canonical);
35
+ }
36
+ }
37
+}
38
+
39
+
40
+/*
41
+** Call client_sync() one or more times in order to complete a
42
+** sync operation. Usually, client_sync() is called only once, though
43
+** is can be called multiple times if the SYNC_ALLURL flags is set.
44
+*/
45
+static int client_sync_all_urls(
46
+ unsigned syncFlags, /* Mask of SYNC_* flags */
47
+ unsigned configRcvMask, /* Receive these configuration items */
48
+ unsigned configSendMask, /* Send these configuration items */
49
+ const char *zAltPCode /* Alternative project code (usually NULL) */
50
+){
51
+ int nErr;
52
+ int nOther;
53
+ char **azOther;
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"
65
+ " WHERE name glob 'sync-url:*'"
66
+ " AND value<>(SELECT value FROM config WHERE name='last-sync-url')"
67
+ );
68
+ while( db_step(&q)==SQLITE_ROW ){
69
+ const char *zUrl = db_column_text(&q, 0);
70
+ azOther = fossil_realloc(azOther, sizeof(*azOther)*(nOther+1));
71
+ azOther[nOther++] = fossil_strdup(zUrl);
72
+ }
73
+ db_finalize(&q);
74
+ for(i=0; i<nOther; i++){
75
+ int rc;
76
+ url_unparse(&g.url);
77
+ url_parse(azOther[i], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
78
+ sync_explain(syncFlags);
79
+ rc = client_sync(syncFlags, configRcvMask, configSendMask, zAltPCode);
80
+ nErr += rc;
81
+ if( (g.url.flags & URL_REMEMBER_PW)!=0 && rc==0 ){
82
+ char *zKey = mprintf("sync-pw:%s", azOther[i]);
83
+ char *zPw = obscure(g.url.passwd);
84
+ if( zPw && zPw[0] ){
85
+ db_set(zKey/*works-like:""*/, zPw, 0);
86
+ }
87
+ fossil_free(zPw);
88
+ fossil_free(zKey);
89
+ }
90
+ fossil_free(azOther[i]);
91
+ azOther[i] = 0;
92
+ }
93
+ fossil_free(azOther);
94
+ return nErr;
95
+}
96
+
2397
2498
/*
2599
** If the repository is configured for autosyncing, then do an
26100
** autosync. Bits of the "flags" parameter determine details of behavior:
27101
**
@@ -48,27 +122,33 @@
48122
return 0;
49123
}
50124
zAutosync = db_get("autosync", 0);
51125
if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
52126
if( is_false(zAutosync) ) return 0;
53
- if( db_get_boolean("dont-push",0) || fossil_strncmp(zAutosync,"pull",4)==0 ){
127
+ if( db_get_boolean("dont-push",0)
128
+ || sqlite3_strglob("*pull*", zAutosync)==0
129
+ ){
54130
flags &= ~SYNC_CKIN_LOCK;
55131
if( flags & SYNC_PUSH ) return 0;
56132
}
133
+ if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
57134
url_parse(0, URL_REMEMBER);
58135
if( g.url.protocol==0 ) return 0;
59136
if( g.url.user!=0 && g.url.passwd==0 ){
60137
g.url.passwd = unobscure(db_get("last-sync-pw", 0));
61138
g.url.flags |= URL_PROMPT_PW;
62139
url_prompt_for_password();
63140
}
64141
g.zHttpAuth = get_httpauth();
65
- url_remember();
66
- if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
67
- fossil_print("Autosync: %s\n", g.url.canonical);
68
- url_enable_proxy("via proxy: ");
69
- rc = client_sync(flags, configSync, 0, 0);
142
+ if( sqlite3_strglob("*all*", zAutosync)==0 ){
143
+ rc = client_sync_all_urls(flags|SYNC_ALLURL, configSync, 0, 0);
144
+ }else{
145
+ url_remember();
146
+ sync_explain(flags);
147
+ url_enable_proxy("via proxy: ");
148
+ rc = client_sync(flags, configSync, 0, 0);
149
+ }
70150
return rc;
71151
}
72152
73153
/*
74154
** This routine will try a number of times to perform autosync with a
@@ -149,18 +229,25 @@
149229
*pSyncFlags |= SYNC_VERBOSE;
150230
}
151231
if( find_option("no-http-compression",0,0)!=0 ){
152232
*pSyncFlags |= SYNC_NOHTTPCOMPRESS;
153233
}
234
+ if( find_option("all",0,0)!=0 ){
235
+ *pSyncFlags |= SYNC_ALLURL;
236
+ }
154237
url_proxy_options();
155238
clone_ssh_find_options();
156239
if( !uvOnly ) db_find_and_open_repository(0, 0);
157240
db_open_config(0, 1);
158241
if( g.argc==2 ){
159242
if( db_get_boolean("auto-shun",0) ) configSync = CONFIGSET_SHUN;
160243
}else if( g.argc==3 ){
161244
zUrl = g.argv[2];
245
+ if( (*pSyncFlags) & SYNC_ALLURL ){
246
+ fossil_fatal("cannot use both the --all option and specific URL \"%s\"",
247
+ zUrl);
248
+ }
162249
}
163250
if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
164251
&& db_get_boolean("uv-sync",0)
165252
){
166253
*pSyncFlags |= SYNC_UNVERSIONED;
@@ -169,28 +256,19 @@
169256
if( urlFlags & URL_REMEMBER ){
170257
clone_ssh_db_set_options();
171258
}
172259
url_parse(zUrl, urlFlags);
173260
remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
174
- url_remember();
175261
if( g.url.protocol==0 ){
176262
if( urlOptional ) fossil_exit(0);
177263
usage("URL");
178264
}
179265
user_select();
180
- if( g.url.isAlias ){
181
- if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){
182
- fossil_print("Sync with %s\n", g.url.canonical);
183
- }else if( (*pSyncFlags) & SYNC_PUSH ){
184
- fossil_print("Push to %s\n", g.url.canonical);
185
- }else if( (*pSyncFlags) & SYNC_PULL ){
186
- fossil_print("Pull from %s\n", g.url.canonical);
187
- }
188
- }
189266
url_enable_proxy("via proxy: ");
190267
*pConfigFlags |= configSync;
191268
}
269
+
192270
193271
/*
194272
** COMMAND: pull
195273
**
196274
** Usage: %fossil pull ?URL? ?options?
@@ -205,10 +283,11 @@
205283
** pull, remote, or sync command is used. See "fossil help clone" for
206284
** details on the URL formats.
207285
**
208286
** Options:
209287
**
288
+** --all Pull from all remotes, not just the default
210289
** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
211290
** if required by the remote website
212291
** --from-parent-project Pull content from the parent project
213292
** --ipv4 Use only IPv4, not IPv6
214293
** --no-http-compression Do not compress HTTP traffic
@@ -237,11 +316,11 @@
237316
process_sync_args(&configFlags, &syncFlags, 0, urlOmitFlags);
238317
239318
/* We should be done with options.. */
240319
verify_all_options();
241320
242
- client_sync(syncFlags, configFlags, 0, zAltPCode);
321
+ client_sync_all_urls(syncFlags, configFlags, 0, zAltPCode);
243322
}
244323
245324
/*
246325
** COMMAND: push
247326
**
@@ -257,10 +336,11 @@
257336
** pull, remote, or sync command is used. See "fossil help clone" for
258337
** details on the URL formats.
259338
**
260339
** Options:
261340
**
341
+** --all Push to all remotes, not just the default
262342
** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
263343
** if required by the remote website
264344
** --ipv4 Use only IPv4, not IPv6
265345
** --no-http-compression Do not compress HTTP traffic
266346
** --once Do not remember URL for subsequent syncs
@@ -284,11 +364,11 @@
284364
verify_all_options();
285365
286366
if( db_get_boolean("dont-push",0) ){
287367
fossil_fatal("pushing is prohibited: the 'dont-push' option is set");
288368
}
289
- client_sync(syncFlags, 0, 0, 0);
369
+ client_sync_all_urls(syncFlags, 0, 0, 0);
290370
}
291371
292372
293373
/*
294374
** COMMAND: sync
@@ -303,10 +383,11 @@
303383
** pull, remote, or sync command is used. See "fossil help clone" for
304384
** details on the URL formats.
305385
**
306386
** Options:
307387
**
388
+** --all Sync with all remotes, not just the default
308389
** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
309390
** if required by the remote website
310391
** --ipv4 Use only IPv4, not IPv6
311392
** --no-http-compression Do not compress HTTP traffic
312393
** --once Do not remember URL for subsequent syncs
@@ -332,14 +413,14 @@
332413
333414
/* We should be done with options.. */
334415
verify_all_options();
335416
336417
if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH;
337
- client_sync(syncFlags, configFlags, 0, 0);
338418
if( (syncFlags & SYNC_PUSH)==0 ){
339419
fossil_warning("pull only: the 'dont-push' option is set");
340420
}
421
+ client_sync_all_urls(syncFlags, configFlags, 0, 0);
341422
}
342423
343424
/*
344425
** Handle the "fossil unversioned sync" and "fossil unversioned revert"
345426
** commands.
@@ -402,10 +483,16 @@
402483
** "fossil remote NAME" to select a previously-set named URL.
403484
**
404485
** To disable use of the default remote without forgetting its URL,
405486
** say "fossil set autosync 0" instead.
406487
**
488
+** > fossil remote scrub
489
+**
490
+** Forget any saved passwords for remote repositories, but continue
491
+** to remember the URLs themselves. You will be prompted for the
492
+** password the next time it is needed.
493
+**
407494
** > fossil remote REF
408495
**
409496
** Make REF the new default URL, replacing the prior default.
410497
** REF may be a URL or a NAME from a prior "add".
411498
*/
@@ -414,10 +501,31 @@
414501
int nArg;
415502
db_find_and_open_repository(0, 0);
416503
417504
/* We should be done with options.. */
418505
verify_all_options();
506
+
507
+ /* 2021-10-25: A note about data structures.
508
+ **
509
+ ** The remote URLs are stored in the CONFIG table. The URL is stored
510
+ ** separately from the password. The password is obscured using the
511
+ ** obscure() function.
512
+ **
513
+ ** Originally, Fossil only preserved a single remote URL. That URL
514
+ ** is stored in "last-sync-url" and the password in "last-sync-pw". The
515
+ ** ability to have multiple remotes was added later so these names
516
+ ** were retained for backwards compatibility. The other remotes are
517
+ ** stored in "sync-url:NAME" and "sync-pw:NAME" where NAME is the name
518
+ ** of the remote.
519
+ **
520
+ ** The last-sync-url is called "default" for the display list.
521
+ **
522
+ ** The last-sync-url might be duplicated into one of the sync-url:NAME
523
+ ** entries. Thus, when doing a "fossil sync --all" or an autosync with
524
+ ** autosync=all, each sync-url:NAME entry is checked to see if it is the
525
+ ** same as last-sync-url and if it is then that entry is skipped.
526
+ */
419527
420528
if( g.argc==2 ){
421529
/* "fossil remote" with no arguments: Show the last sync URL. */
422530
zUrl = db_get("last-sync-url", 0);
423531
if( zUrl==0 ){
@@ -495,10 +603,49 @@
495603
db_multi_exec("DELETE FROM config WHERE name glob 'sync-url:%q'", zName);
496604
db_multi_exec("DELETE FROM config WHERE name glob 'sync-pw:%q'", zName);
497605
db_protect_pop();
498606
db_commit_transaction();
499607
return;
608
+ }
609
+ if( strncmp(zArg, "scrub", nArg)==0 ){
610
+ if( g.argc!=3 ) usage("scrub");
611
+ db_begin_write();
612
+ db_unprotect(PROTECT_CONFIG);
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;
500647
}
501648
if( sqlite3_strlike("http://%",zArg,0)==0
502649
|| sqlite3_strlike("https://%",zArg,0)==0
503650
|| sqlite3_strlike("ssh:%",zArg,0)==0
504651
|| sqlite3_strlike("file:%",zArg,0)==0
505652
--- src/sync.c
+++ src/sync.c
@@ -18,10 +18,84 @@
18 ** This file contains code used to push, pull, and sync a repository
19 */
20 #include "config.h"
21 #include "sync.h"
22 #include <assert.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
24 /*
25 ** If the repository is configured for autosyncing, then do an
26 ** autosync. Bits of the "flags" parameter determine details of behavior:
27 **
@@ -48,27 +122,33 @@
48 return 0;
49 }
50 zAutosync = db_get("autosync", 0);
51 if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
52 if( is_false(zAutosync) ) return 0;
53 if( db_get_boolean("dont-push",0) || fossil_strncmp(zAutosync,"pull",4)==0 ){
 
 
54 flags &= ~SYNC_CKIN_LOCK;
55 if( flags & SYNC_PUSH ) return 0;
56 }
 
57 url_parse(0, URL_REMEMBER);
58 if( g.url.protocol==0 ) return 0;
59 if( g.url.user!=0 && g.url.passwd==0 ){
60 g.url.passwd = unobscure(db_get("last-sync-pw", 0));
61 g.url.flags |= URL_PROMPT_PW;
62 url_prompt_for_password();
63 }
64 g.zHttpAuth = get_httpauth();
65 url_remember();
66 if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
67 fossil_print("Autosync: %s\n", g.url.canonical);
68 url_enable_proxy("via proxy: ");
69 rc = client_sync(flags, configSync, 0, 0);
 
 
 
70 return rc;
71 }
72
73 /*
74 ** This routine will try a number of times to perform autosync with a
@@ -149,18 +229,25 @@
149 *pSyncFlags |= SYNC_VERBOSE;
150 }
151 if( find_option("no-http-compression",0,0)!=0 ){
152 *pSyncFlags |= SYNC_NOHTTPCOMPRESS;
153 }
 
 
 
154 url_proxy_options();
155 clone_ssh_find_options();
156 if( !uvOnly ) db_find_and_open_repository(0, 0);
157 db_open_config(0, 1);
158 if( g.argc==2 ){
159 if( db_get_boolean("auto-shun",0) ) configSync = CONFIGSET_SHUN;
160 }else if( g.argc==3 ){
161 zUrl = g.argv[2];
 
 
 
 
162 }
163 if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
164 && db_get_boolean("uv-sync",0)
165 ){
166 *pSyncFlags |= SYNC_UNVERSIONED;
@@ -169,28 +256,19 @@
169 if( urlFlags & URL_REMEMBER ){
170 clone_ssh_db_set_options();
171 }
172 url_parse(zUrl, urlFlags);
173 remember_or_get_http_auth(zHttpAuth, urlFlags & URL_REMEMBER, zUrl);
174 url_remember();
175 if( g.url.protocol==0 ){
176 if( urlOptional ) fossil_exit(0);
177 usage("URL");
178 }
179 user_select();
180 if( g.url.isAlias ){
181 if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){
182 fossil_print("Sync with %s\n", g.url.canonical);
183 }else if( (*pSyncFlags) & SYNC_PUSH ){
184 fossil_print("Push to %s\n", g.url.canonical);
185 }else if( (*pSyncFlags) & SYNC_PULL ){
186 fossil_print("Pull from %s\n", g.url.canonical);
187 }
188 }
189 url_enable_proxy("via proxy: ");
190 *pConfigFlags |= configSync;
191 }
 
192
193 /*
194 ** COMMAND: pull
195 **
196 ** Usage: %fossil pull ?URL? ?options?
@@ -205,10 +283,11 @@
205 ** pull, remote, or sync command is used. See "fossil help clone" for
206 ** details on the URL formats.
207 **
208 ** Options:
209 **
 
210 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
211 ** if required by the remote website
212 ** --from-parent-project Pull content from the parent project
213 ** --ipv4 Use only IPv4, not IPv6
214 ** --no-http-compression Do not compress HTTP traffic
@@ -237,11 +316,11 @@
237 process_sync_args(&configFlags, &syncFlags, 0, urlOmitFlags);
238
239 /* We should be done with options.. */
240 verify_all_options();
241
242 client_sync(syncFlags, configFlags, 0, zAltPCode);
243 }
244
245 /*
246 ** COMMAND: push
247 **
@@ -257,10 +336,11 @@
257 ** pull, remote, or sync command is used. See "fossil help clone" for
258 ** details on the URL formats.
259 **
260 ** Options:
261 **
 
262 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
263 ** if required by the remote website
264 ** --ipv4 Use only IPv4, not IPv6
265 ** --no-http-compression Do not compress HTTP traffic
266 ** --once Do not remember URL for subsequent syncs
@@ -284,11 +364,11 @@
284 verify_all_options();
285
286 if( db_get_boolean("dont-push",0) ){
287 fossil_fatal("pushing is prohibited: the 'dont-push' option is set");
288 }
289 client_sync(syncFlags, 0, 0, 0);
290 }
291
292
293 /*
294 ** COMMAND: sync
@@ -303,10 +383,11 @@
303 ** pull, remote, or sync command is used. See "fossil help clone" for
304 ** details on the URL formats.
305 **
306 ** Options:
307 **
 
308 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
309 ** if required by the remote website
310 ** --ipv4 Use only IPv4, not IPv6
311 ** --no-http-compression Do not compress HTTP traffic
312 ** --once Do not remember URL for subsequent syncs
@@ -332,14 +413,14 @@
332
333 /* We should be done with options.. */
334 verify_all_options();
335
336 if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH;
337 client_sync(syncFlags, configFlags, 0, 0);
338 if( (syncFlags & SYNC_PUSH)==0 ){
339 fossil_warning("pull only: the 'dont-push' option is set");
340 }
 
341 }
342
343 /*
344 ** Handle the "fossil unversioned sync" and "fossil unversioned revert"
345 ** commands.
@@ -402,10 +483,16 @@
402 ** "fossil remote NAME" to select a previously-set named URL.
403 **
404 ** To disable use of the default remote without forgetting its URL,
405 ** say "fossil set autosync 0" instead.
406 **
 
 
 
 
 
 
407 ** > fossil remote REF
408 **
409 ** Make REF the new default URL, replacing the prior default.
410 ** REF may be a URL or a NAME from a prior "add".
411 */
@@ -414,10 +501,31 @@
414 int nArg;
415 db_find_and_open_repository(0, 0);
416
417 /* We should be done with options.. */
418 verify_all_options();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
419
420 if( g.argc==2 ){
421 /* "fossil remote" with no arguments: Show the last sync URL. */
422 zUrl = db_get("last-sync-url", 0);
423 if( zUrl==0 ){
@@ -495,10 +603,49 @@
495 db_multi_exec("DELETE FROM config WHERE name glob 'sync-url:%q'", zName);
496 db_multi_exec("DELETE FROM config WHERE name glob 'sync-pw:%q'", zName);
497 db_protect_pop();
498 db_commit_transaction();
499 return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500 }
501 if( sqlite3_strlike("http://%",zArg,0)==0
502 || sqlite3_strlike("https://%",zArg,0)==0
503 || sqlite3_strlike("ssh:%",zArg,0)==0
504 || sqlite3_strlike("file:%",zArg,0)==0
505
--- src/sync.c
+++ src/sync.c
@@ -18,10 +18,84 @@
18 ** This file contains code used to push, pull, and sync a repository
19 */
20 #include "config.h"
21 #include "sync.h"
22 #include <assert.h>
23
24 /*
25 ** Explain what type of sync operation is about to occur
26 */
27 static void sync_explain(unsigned syncFlags){
28 if( g.url.isAlias ){
29 if( (syncFlags & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL) ){
30 fossil_print("Sync with %s\n", g.url.canonical);
31 }else if( syncFlags & SYNC_PUSH ){
32 fossil_print("Push to %s\n", g.url.canonical);
33 }else if( syncFlags & SYNC_PULL ){
34 fossil_print("Pull from %s\n", g.url.canonical);
35 }
36 }
37 }
38
39
40 /*
41 ** Call client_sync() one or more times in order to complete a
42 ** sync operation. Usually, client_sync() is called only once, though
43 ** is can be called multiple times if the SYNC_ALLURL flags is set.
44 */
45 static int client_sync_all_urls(
46 unsigned syncFlags, /* Mask of SYNC_* flags */
47 unsigned configRcvMask, /* Receive these configuration items */
48 unsigned configSendMask, /* Send these configuration items */
49 const char *zAltPCode /* Alternative project code (usually NULL) */
50 ){
51 int nErr;
52 int nOther;
53 char **azOther;
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"
65 " WHERE name glob 'sync-url:*'"
66 " AND value<>(SELECT value FROM config WHERE name='last-sync-url')"
67 );
68 while( db_step(&q)==SQLITE_ROW ){
69 const char *zUrl = db_column_text(&q, 0);
70 azOther = fossil_realloc(azOther, sizeof(*azOther)*(nOther+1));
71 azOther[nOther++] = fossil_strdup(zUrl);
72 }
73 db_finalize(&q);
74 for(i=0; i<nOther; i++){
75 int rc;
76 url_unparse(&g.url);
77 url_parse(azOther[i], URL_PROMPT_PW|URL_ASK_REMEMBER_PW);
78 sync_explain(syncFlags);
79 rc = client_sync(syncFlags, configRcvMask, configSendMask, zAltPCode);
80 nErr += rc;
81 if( (g.url.flags & URL_REMEMBER_PW)!=0 && rc==0 ){
82 char *zKey = mprintf("sync-pw:%s", azOther[i]);
83 char *zPw = obscure(g.url.passwd);
84 if( zPw && zPw[0] ){
85 db_set(zKey/*works-like:""*/, zPw, 0);
86 }
87 fossil_free(zPw);
88 fossil_free(zKey);
89 }
90 fossil_free(azOther[i]);
91 azOther[i] = 0;
92 }
93 fossil_free(azOther);
94 return nErr;
95 }
96
97
98 /*
99 ** If the repository is configured for autosyncing, then do an
100 ** autosync. Bits of the "flags" parameter determine details of behavior:
101 **
@@ -48,27 +122,33 @@
122 return 0;
123 }
124 zAutosync = db_get("autosync", 0);
125 if( zAutosync==0 ) zAutosync = "on"; /* defend against misconfig */
126 if( is_false(zAutosync) ) return 0;
127 if( db_get_boolean("dont-push",0)
128 || sqlite3_strglob("*pull*", zAutosync)==0
129 ){
130 flags &= ~SYNC_CKIN_LOCK;
131 if( flags & SYNC_PUSH ) return 0;
132 }
133 if( find_option("verbose","v",0)!=0 ) flags |= SYNC_VERBOSE;
134 url_parse(0, URL_REMEMBER);
135 if( g.url.protocol==0 ) return 0;
136 if( g.url.user!=0 && g.url.passwd==0 ){
137 g.url.passwd = unobscure(db_get("last-sync-pw", 0));
138 g.url.flags |= URL_PROMPT_PW;
139 url_prompt_for_password();
140 }
141 g.zHttpAuth = get_httpauth();
142 if( sqlite3_strglob("*all*", zAutosync)==0 ){
143 rc = client_sync_all_urls(flags|SYNC_ALLURL, configSync, 0, 0);
144 }else{
145 url_remember();
146 sync_explain(flags);
147 url_enable_proxy("via proxy: ");
148 rc = client_sync(flags, configSync, 0, 0);
149 }
150 return rc;
151 }
152
153 /*
154 ** This routine will try a number of times to perform autosync with a
@@ -149,18 +229,25 @@
229 *pSyncFlags |= SYNC_VERBOSE;
230 }
231 if( find_option("no-http-compression",0,0)!=0 ){
232 *pSyncFlags |= SYNC_NOHTTPCOMPRESS;
233 }
234 if( find_option("all",0,0)!=0 ){
235 *pSyncFlags |= SYNC_ALLURL;
236 }
237 url_proxy_options();
238 clone_ssh_find_options();
239 if( !uvOnly ) db_find_and_open_repository(0, 0);
240 db_open_config(0, 1);
241 if( g.argc==2 ){
242 if( db_get_boolean("auto-shun",0) ) configSync = CONFIGSET_SHUN;
243 }else if( g.argc==3 ){
244 zUrl = g.argv[2];
245 if( (*pSyncFlags) & SYNC_ALLURL ){
246 fossil_fatal("cannot use both the --all option and specific URL \"%s\"",
247 zUrl);
248 }
249 }
250 if( ((*pSyncFlags) & (SYNC_PUSH|SYNC_PULL))==(SYNC_PUSH|SYNC_PULL)
251 && db_get_boolean("uv-sync",0)
252 ){
253 *pSyncFlags |= SYNC_UNVERSIONED;
@@ -169,28 +256,19 @@
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();
 
 
 
 
 
 
 
 
 
266 url_enable_proxy("via proxy: ");
267 *pConfigFlags |= configSync;
268 }
269
270
271 /*
272 ** COMMAND: pull
273 **
274 ** Usage: %fossil pull ?URL? ?options?
@@ -205,10 +283,11 @@
283 ** pull, remote, or sync command is used. See "fossil help clone" for
284 ** details on the URL formats.
285 **
286 ** Options:
287 **
288 ** --all Pull from all remotes, not just the default
289 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
290 ** if required by the remote website
291 ** --from-parent-project Pull content from the parent project
292 ** --ipv4 Use only IPv4, not IPv6
293 ** --no-http-compression Do not compress HTTP traffic
@@ -237,11 +316,11 @@
316 process_sync_args(&configFlags, &syncFlags, 0, urlOmitFlags);
317
318 /* We should be done with options.. */
319 verify_all_options();
320
321 client_sync_all_urls(syncFlags, configFlags, 0, zAltPCode);
322 }
323
324 /*
325 ** COMMAND: push
326 **
@@ -257,10 +336,11 @@
336 ** pull, remote, or sync command is used. See "fossil help clone" for
337 ** details on the URL formats.
338 **
339 ** Options:
340 **
341 ** --all Push to all remotes, not just the default
342 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
343 ** if required by the remote website
344 ** --ipv4 Use only IPv4, not IPv6
345 ** --no-http-compression Do not compress HTTP traffic
346 ** --once Do not remember URL for subsequent syncs
@@ -284,11 +364,11 @@
364 verify_all_options();
365
366 if( db_get_boolean("dont-push",0) ){
367 fossil_fatal("pushing is prohibited: the 'dont-push' option is set");
368 }
369 client_sync_all_urls(syncFlags, 0, 0, 0);
370 }
371
372
373 /*
374 ** COMMAND: sync
@@ -303,10 +383,11 @@
383 ** pull, remote, or sync command is used. See "fossil help clone" for
384 ** details on the URL formats.
385 **
386 ** Options:
387 **
388 ** --all Sync with all remotes, not just the default
389 ** -B|--httpauth USER:PASS Credentials for the simple HTTP auth protocol,
390 ** if required by the remote website
391 ** --ipv4 Use only IPv4, not IPv6
392 ** --no-http-compression Do not compress HTTP traffic
393 ** --once Do not remember URL for subsequent syncs
@@ -332,14 +413,14 @@
413
414 /* We should be done with options.. */
415 verify_all_options();
416
417 if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH;
 
418 if( (syncFlags & SYNC_PUSH)==0 ){
419 fossil_warning("pull only: the 'dont-push' option is set");
420 }
421 client_sync_all_urls(syncFlags, configFlags, 0, 0);
422 }
423
424 /*
425 ** Handle the "fossil unversioned sync" and "fossil unversioned revert"
426 ** commands.
@@ -402,10 +483,16 @@
483 ** "fossil remote NAME" to select a previously-set named URL.
484 **
485 ** To disable use of the default remote without forgetting its URL,
486 ** say "fossil set autosync 0" instead.
487 **
488 ** > fossil remote scrub
489 **
490 ** Forget any saved passwords for remote repositories, but continue
491 ** to remember the URLs themselves. You will be prompted for the
492 ** password the next time it is needed.
493 **
494 ** > fossil remote REF
495 **
496 ** Make REF the new default URL, replacing the prior default.
497 ** REF may be a URL or a NAME from a prior "add".
498 */
@@ -414,10 +501,31 @@
501 int nArg;
502 db_find_and_open_repository(0, 0);
503
504 /* We should be done with options.. */
505 verify_all_options();
506
507 /* 2021-10-25: A note about data structures.
508 **
509 ** The remote URLs are stored in the CONFIG table. The URL is stored
510 ** separately from the password. The password is obscured using the
511 ** obscure() function.
512 **
513 ** Originally, Fossil only preserved a single remote URL. That URL
514 ** is stored in "last-sync-url" and the password in "last-sync-pw". The
515 ** ability to have multiple remotes was added later so these names
516 ** were retained for backwards compatibility. The other remotes are
517 ** stored in "sync-url:NAME" and "sync-pw:NAME" where NAME is the name
518 ** of the remote.
519 **
520 ** The last-sync-url is called "default" for the display list.
521 **
522 ** The last-sync-url might be duplicated into one of the sync-url:NAME
523 ** entries. Thus, when doing a "fossil sync --all" or an autosync with
524 ** autosync=all, each sync-url:NAME entry is checked to see if it is the
525 ** same as last-sync-url and if it is then that entry is skipped.
526 */
527
528 if( g.argc==2 ){
529 /* "fossil remote" with no arguments: Show the last sync URL. */
530 zUrl = db_get("last-sync-url", 0);
531 if( zUrl==0 ){
@@ -495,10 +603,49 @@
603 db_multi_exec("DELETE FROM config WHERE name glob 'sync-url:%q'", zName);
604 db_multi_exec("DELETE FROM config WHERE name glob 'sync-pw:%q'", zName);
605 db_protect_pop();
606 db_commit_transaction();
607 return;
608 }
609 if( strncmp(zArg, "scrub", nArg)==0 ){
610 if( g.argc!=3 ) usage("scrub");
611 db_begin_write();
612 db_unprotect(PROTECT_CONFIG);
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
+27 -22
--- src/url.c
+++ src/url.c
@@ -44,29 +44,29 @@
4444
4545
/*
4646
** The URL related data used with this subsystem.
4747
*/
4848
struct UrlData {
49
- int isFile; /* True if a "file:" url */
50
- int isHttps; /* True if a "https:" url */
51
- int isSsh; /* True if an "ssh:" url */
52
- int isAlias; /* Input URL was an alias */
53
- char *name; /* Hostname for http: or filename for file: */
54
- char *hostname; /* The HOST: parameter on http headers */
49
+ int isFile; /* True if a "file:" url */
50
+ int isHttps; /* True if a "https:" url */
51
+ int isSsh; /* True if an "ssh:" url */
52
+ int isAlias; /* Input URL was an alias */
53
+ char *name; /* Hostname for http: or filename for file: */
54
+ char *hostname; /* The HOST: parameter on http headers */
5555
const char *protocol; /* "http" or "https" or "ssh" or "file" */
56
- int port; /* TCP port number for http: or https: */
57
- int dfltPort; /* The default port for the given protocol */
58
- char *path; /* Pathname for http: */
59
- char *user; /* User id for http: */
60
- char *passwd; /* Password for http: */
61
- char *canonical; /* Canonical representation of the URL */
62
- char *proxyAuth; /* Proxy-Authorizer: string */
63
- char *fossil; /* The fossil query parameter on ssh: */
64
- unsigned flags; /* Boolean flags controlling URL processing */
65
- int useProxy; /* Used to remember that a proxy is in use */
56
+ int port; /* TCP port number for http: or https: */
57
+ int dfltPort; /* The default port for the given protocol */
58
+ char *path; /* Pathname for http: */
59
+ char *user; /* User id for http: */
60
+ char *passwd; /* Password for http: */
61
+ char *canonical; /* Canonical representation of the URL */
62
+ char *proxyAuth; /* Proxy-Authorizer: string */
63
+ char *fossil; /* The fossil query parameter on ssh: */
64
+ unsigned flags; /* Boolean flags controlling URL processing */
65
+ int useProxy; /* Used to remember that a proxy is in use */
6666
char *proxyUrlPath;
67
- int proxyOrigPort; /* Tunneled port number for https through proxy */
67
+ int proxyOrigPort; /* Tunneled port number for https through proxy */
6868
};
6969
#endif /* INTERFACE */
7070
7171
7272
/*
@@ -141,11 +141,11 @@
141141
iStart = 8;
142142
}else if( zUrl[0]=='s' ){
143143
pUrlData->isSsh = 1;
144144
pUrlData->protocol = "ssh";
145145
pUrlData->dfltPort = 22;
146
- pUrlData->fossil = "fossil";
146
+ pUrlData->fossil = fossil_strdup("fossil");
147147
iStart = 6;
148148
}else{
149149
pUrlData->isHttps = 0;
150150
pUrlData->protocol = "http";
151151
pUrlData->dfltPort = 80;
@@ -226,11 +226,11 @@
226226
if( pUrlData->path[i] ){
227227
pUrlData->path[i] = 0;
228228
i++;
229229
}
230230
if( fossil_strcmp(zName,"fossil")==0 ){
231
- pUrlData->fossil = zValue;
231
+ pUrlData->fossil = fossil_strdup(zValue);
232232
dehttpize(pUrlData->fossil);
233233
fossil_free(zExe);
234234
zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil);
235235
cQuerySep = '&';
236236
}
@@ -247,11 +247,15 @@
247247
"%s://%s%T:%d%T%z",
248248
pUrlData->protocol, zLogin, pUrlData->name, pUrlData->port,
249249
pUrlData->path, zExe
250250
);
251251
}
252
- if( pUrlData->isSsh && pUrlData->path[1] ) pUrlData->path++;
252
+ if( pUrlData->isSsh && pUrlData->path[1] ){
253
+ char *zOld = pUrlData->path;
254
+ pUrlData->path = mprintf("%s", zOld+1);
255
+ fossil_free(zOld);
256
+ }
253257
free(zLogin);
254258
}else if( strncmp(zUrl, "file:", 5)==0 ){
255259
pUrlData->isFile = 1;
256260
if( zUrl[5]=='/' && zUrl[6]=='/' ){
257261
i = 7;
@@ -280,11 +284,11 @@
280284
dehttpize(zFile);
281285
file_canonical_name(zFile, &cfile, 0);
282286
free(zFile);
283287
zFile = 0;
284288
pUrlData->protocol = "file";
285
- pUrlData->path = "";
289
+ pUrlData->path = mprintf("");
286290
pUrlData->name = mprintf("%b", &cfile);
287291
pUrlData->canonical = mprintf("file://%T", pUrlData->name);
288292
blob_reset(&cfile);
289293
}else if( pUrlData->user!=0 && pUrlData->passwd==0
290294
&& (urlFlags & URL_PROMPT_PW)!=0 ){
@@ -310,10 +314,11 @@
310314
fossil_free(p->canonical);
311315
fossil_free(p->name);
312316
fossil_free(p->path);
313317
fossil_free(p->user);
314318
fossil_free(p->passwd);
319
+ fossil_free(p->fossil);
315320
memset(p, 0, sizeof(*p));
316321
}
317322
318323
/*
319324
** Parse the given URL, which describes a sync server. Populate variables
@@ -599,11 +604,11 @@
599604
if( isatty(fileno(stdin))
600605
&& (pUrlData->flags & URL_PROMPT_PW)!=0
601606
&& (pUrlData->flags & URL_PROMPTED)==0
602607
){
603608
pUrlData->flags |= URL_PROMPTED;
604
- pUrlData->passwd = prompt_for_user_password(pUrlData->user);
609
+ pUrlData->passwd = prompt_for_user_password(pUrlData->canonical);
605610
if( pUrlData->passwd[0]
606611
&& (pUrlData->flags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0
607612
){
608613
if( save_password_prompt(pUrlData->passwd) ){
609614
pUrlData->flags |= URL_REMEMBER_PW;
610615
--- src/url.c
+++ src/url.c
@@ -44,29 +44,29 @@
44
45 /*
46 ** The URL related data used with this subsystem.
47 */
48 struct UrlData {
49 int isFile; /* True if a "file:" url */
50 int isHttps; /* True if a "https:" url */
51 int isSsh; /* True if an "ssh:" url */
52 int isAlias; /* Input URL was an alias */
53 char *name; /* Hostname for http: or filename for file: */
54 char *hostname; /* The HOST: parameter on http headers */
55 const char *protocol; /* "http" or "https" or "ssh" or "file" */
56 int port; /* TCP port number for http: or https: */
57 int dfltPort; /* The default port for the given protocol */
58 char *path; /* Pathname for http: */
59 char *user; /* User id for http: */
60 char *passwd; /* Password for http: */
61 char *canonical; /* Canonical representation of the URL */
62 char *proxyAuth; /* Proxy-Authorizer: string */
63 char *fossil; /* The fossil query parameter on ssh: */
64 unsigned flags; /* Boolean flags controlling URL processing */
65 int useProxy; /* Used to remember that a proxy is in use */
66 char *proxyUrlPath;
67 int proxyOrigPort; /* Tunneled port number for https through proxy */
68 };
69 #endif /* INTERFACE */
70
71
72 /*
@@ -141,11 +141,11 @@
141 iStart = 8;
142 }else if( zUrl[0]=='s' ){
143 pUrlData->isSsh = 1;
144 pUrlData->protocol = "ssh";
145 pUrlData->dfltPort = 22;
146 pUrlData->fossil = "fossil";
147 iStart = 6;
148 }else{
149 pUrlData->isHttps = 0;
150 pUrlData->protocol = "http";
151 pUrlData->dfltPort = 80;
@@ -226,11 +226,11 @@
226 if( pUrlData->path[i] ){
227 pUrlData->path[i] = 0;
228 i++;
229 }
230 if( fossil_strcmp(zName,"fossil")==0 ){
231 pUrlData->fossil = zValue;
232 dehttpize(pUrlData->fossil);
233 fossil_free(zExe);
234 zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil);
235 cQuerySep = '&';
236 }
@@ -247,11 +247,15 @@
247 "%s://%s%T:%d%T%z",
248 pUrlData->protocol, zLogin, pUrlData->name, pUrlData->port,
249 pUrlData->path, zExe
250 );
251 }
252 if( pUrlData->isSsh && pUrlData->path[1] ) pUrlData->path++;
 
 
 
 
253 free(zLogin);
254 }else if( strncmp(zUrl, "file:", 5)==0 ){
255 pUrlData->isFile = 1;
256 if( zUrl[5]=='/' && zUrl[6]=='/' ){
257 i = 7;
@@ -280,11 +284,11 @@
280 dehttpize(zFile);
281 file_canonical_name(zFile, &cfile, 0);
282 free(zFile);
283 zFile = 0;
284 pUrlData->protocol = "file";
285 pUrlData->path = "";
286 pUrlData->name = mprintf("%b", &cfile);
287 pUrlData->canonical = mprintf("file://%T", pUrlData->name);
288 blob_reset(&cfile);
289 }else if( pUrlData->user!=0 && pUrlData->passwd==0
290 && (urlFlags & URL_PROMPT_PW)!=0 ){
@@ -310,10 +314,11 @@
310 fossil_free(p->canonical);
311 fossil_free(p->name);
312 fossil_free(p->path);
313 fossil_free(p->user);
314 fossil_free(p->passwd);
 
315 memset(p, 0, sizeof(*p));
316 }
317
318 /*
319 ** Parse the given URL, which describes a sync server. Populate variables
@@ -599,11 +604,11 @@
599 if( isatty(fileno(stdin))
600 && (pUrlData->flags & URL_PROMPT_PW)!=0
601 && (pUrlData->flags & URL_PROMPTED)==0
602 ){
603 pUrlData->flags |= URL_PROMPTED;
604 pUrlData->passwd = prompt_for_user_password(pUrlData->user);
605 if( pUrlData->passwd[0]
606 && (pUrlData->flags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0
607 ){
608 if( save_password_prompt(pUrlData->passwd) ){
609 pUrlData->flags |= URL_REMEMBER_PW;
610
--- src/url.c
+++ src/url.c
@@ -44,29 +44,29 @@
44
45 /*
46 ** The URL related data used with this subsystem.
47 */
48 struct UrlData {
49 int isFile; /* True if a "file:" url */
50 int isHttps; /* True if a "https:" url */
51 int isSsh; /* True if an "ssh:" url */
52 int isAlias; /* Input URL was an alias */
53 char *name; /* Hostname for http: or filename for file: */
54 char *hostname; /* The HOST: parameter on http headers */
55 const char *protocol; /* "http" or "https" or "ssh" or "file" */
56 int port; /* TCP port number for http: or https: */
57 int dfltPort; /* The default port for the given protocol */
58 char *path; /* Pathname for http: */
59 char *user; /* User id for http: */
60 char *passwd; /* Password for http: */
61 char *canonical; /* Canonical representation of the URL */
62 char *proxyAuth; /* Proxy-Authorizer: string */
63 char *fossil; /* The fossil query parameter on ssh: */
64 unsigned flags; /* Boolean flags controlling URL processing */
65 int useProxy; /* Used to remember that a proxy is in use */
66 char *proxyUrlPath;
67 int proxyOrigPort; /* Tunneled port number for https through proxy */
68 };
69 #endif /* INTERFACE */
70
71
72 /*
@@ -141,11 +141,11 @@
141 iStart = 8;
142 }else if( zUrl[0]=='s' ){
143 pUrlData->isSsh = 1;
144 pUrlData->protocol = "ssh";
145 pUrlData->dfltPort = 22;
146 pUrlData->fossil = fossil_strdup("fossil");
147 iStart = 6;
148 }else{
149 pUrlData->isHttps = 0;
150 pUrlData->protocol = "http";
151 pUrlData->dfltPort = 80;
@@ -226,11 +226,11 @@
226 if( pUrlData->path[i] ){
227 pUrlData->path[i] = 0;
228 i++;
229 }
230 if( fossil_strcmp(zName,"fossil")==0 ){
231 pUrlData->fossil = fossil_strdup(zValue);
232 dehttpize(pUrlData->fossil);
233 fossil_free(zExe);
234 zExe = mprintf("%cfossil=%T", cQuerySep, pUrlData->fossil);
235 cQuerySep = '&';
236 }
@@ -247,11 +247,15 @@
247 "%s://%s%T:%d%T%z",
248 pUrlData->protocol, zLogin, pUrlData->name, pUrlData->port,
249 pUrlData->path, zExe
250 );
251 }
252 if( pUrlData->isSsh && pUrlData->path[1] ){
253 char *zOld = pUrlData->path;
254 pUrlData->path = mprintf("%s", zOld+1);
255 fossil_free(zOld);
256 }
257 free(zLogin);
258 }else if( strncmp(zUrl, "file:", 5)==0 ){
259 pUrlData->isFile = 1;
260 if( zUrl[5]=='/' && zUrl[6]=='/' ){
261 i = 7;
@@ -280,11 +284,11 @@
284 dehttpize(zFile);
285 file_canonical_name(zFile, &cfile, 0);
286 free(zFile);
287 zFile = 0;
288 pUrlData->protocol = "file";
289 pUrlData->path = mprintf("");
290 pUrlData->name = mprintf("%b", &cfile);
291 pUrlData->canonical = mprintf("file://%T", pUrlData->name);
292 blob_reset(&cfile);
293 }else if( pUrlData->user!=0 && pUrlData->passwd==0
294 && (urlFlags & URL_PROMPT_PW)!=0 ){
@@ -310,10 +314,11 @@
314 fossil_free(p->canonical);
315 fossil_free(p->name);
316 fossil_free(p->path);
317 fossil_free(p->user);
318 fossil_free(p->passwd);
319 fossil_free(p->fossil);
320 memset(p, 0, sizeof(*p));
321 }
322
323 /*
324 ** Parse the given URL, which describes a sync server. Populate variables
@@ -599,11 +604,11 @@
604 if( isatty(fileno(stdin))
605 && (pUrlData->flags & URL_PROMPT_PW)!=0
606 && (pUrlData->flags & URL_PROMPTED)==0
607 ){
608 pUrlData->flags |= URL_PROMPTED;
609 pUrlData->passwd = prompt_for_user_password(pUrlData->canonical);
610 if( pUrlData->passwd[0]
611 && (pUrlData->flags & (URL_REMEMBER|URL_ASK_REMEMBER_PW))!=0
612 ){
613 if( save_password_prompt(pUrlData->passwd) ){
614 pUrlData->flags |= URL_REMEMBER_PW;
615
-4
--- src/user.c
+++ src/user.c
@@ -270,14 +270,10 @@
270270
** Prompt to save Fossil user password
271271
*/
272272
int save_password_prompt(const char *passwd){
273273
Blob x;
274274
char c;
275
- const char *old = db_get("last-sync-pw", 0);
276
- if( (old!=0) && fossil_strcmp(unobscure(old), passwd)==0 ){
277
- return 0;
278
- }
279275
if( fossil_security_level()>=1 ) return 0;
280276
prompt_user("remember password (Y/n)? ", &x);
281277
c = blob_str(&x)[0];
282278
blob_reset(&x);
283279
return ( c!='n' && c!='N' );
284280
--- src/user.c
+++ src/user.c
@@ -270,14 +270,10 @@
270 ** Prompt to save Fossil user password
271 */
272 int save_password_prompt(const char *passwd){
273 Blob x;
274 char c;
275 const char *old = db_get("last-sync-pw", 0);
276 if( (old!=0) && fossil_strcmp(unobscure(old), passwd)==0 ){
277 return 0;
278 }
279 if( fossil_security_level()>=1 ) return 0;
280 prompt_user("remember password (Y/n)? ", &x);
281 c = blob_str(&x)[0];
282 blob_reset(&x);
283 return ( c!='n' && c!='N' );
284
--- src/user.c
+++ src/user.c
@@ -270,14 +270,10 @@
270 ** Prompt to save Fossil user password
271 */
272 int save_password_prompt(const char *passwd){
273 Blob x;
274 char c;
 
 
 
 
275 if( fossil_security_level()>=1 ) return 0;
276 prompt_user("remember password (Y/n)? ", &x);
277 c = blob_str(&x)[0];
278 blob_reset(&x);
279 return ( c!='n' && c!='N' );
280
+1
--- src/xfer.c
+++ src/xfer.c
@@ -1821,10 +1821,11 @@
18211821
#define SYNC_UV_TRACE 0x0400 /* Describe UV activities */
18221822
#define SYNC_UV_DRYRUN 0x0800 /* Do not actually exchange files */
18231823
#define SYNC_IFABLE 0x1000 /* Inability to sync is not fatal */
18241824
#define SYNC_CKIN_LOCK 0x2000 /* Lock the current check-in */
18251825
#define SYNC_NOHTTPCOMPRESS 0x4000 /* Do not compression HTTP messages */
1826
+#define SYNC_ALLURL 0x8000 /* The --all flag - sync to all URLs */
18261827
#endif
18271828
18281829
/*
18291830
** Floating-point absolute value
18301831
*/
18311832
--- src/xfer.c
+++ src/xfer.c
@@ -1821,10 +1821,11 @@
1821 #define SYNC_UV_TRACE 0x0400 /* Describe UV activities */
1822 #define SYNC_UV_DRYRUN 0x0800 /* Do not actually exchange files */
1823 #define SYNC_IFABLE 0x1000 /* Inability to sync is not fatal */
1824 #define SYNC_CKIN_LOCK 0x2000 /* Lock the current check-in */
1825 #define SYNC_NOHTTPCOMPRESS 0x4000 /* Do not compression HTTP messages */
 
1826 #endif
1827
1828 /*
1829 ** Floating-point absolute value
1830 */
1831
--- src/xfer.c
+++ src/xfer.c
@@ -1821,10 +1821,11 @@
1821 #define SYNC_UV_TRACE 0x0400 /* Describe UV activities */
1822 #define SYNC_UV_DRYRUN 0x0800 /* Do not actually exchange files */
1823 #define SYNC_IFABLE 0x1000 /* Inability to sync is not fatal */
1824 #define SYNC_CKIN_LOCK 0x2000 /* Lock the current check-in */
1825 #define SYNC_NOHTTPCOMPRESS 0x4000 /* Do not compression HTTP messages */
1826 #define SYNC_ALLURL 0x8000 /* The --all flag - sync to all URLs */
1827 #endif
1828
1829 /*
1830 ** Floating-point absolute value
1831 */
1832
+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/contribute.wiki
+++ www/contribute.wiki
@@ -27,10 +27,14 @@
2727
2828
Suggested changes or bug fixes can be submitted by creating a patch
2929
against the current source tree:
3030
3131
<tt>fossil diff -i > my-change.patch</tt>
32
+
33
+Alternatively, you can create a binary patch:
34
+
35
+ <tt>fossil patch create my-change.db</tt>
3236
3337
Post patches to
3438
[https://fossil-scm.org/forum | the forum] or email them to
3539
<a href="mailto:[email protected]">[email protected]</a>. Be sure to
3640
describe in detail what the patch does and which version of Fossil
3741
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -27,10 +27,14 @@
27
28 Suggested changes or bug fixes can be submitted by creating a patch
29 against the current source tree:
30
31 <tt>fossil diff -i > my-change.patch</tt>
 
 
 
 
32
33 Post patches to
34 [https://fossil-scm.org/forum | the forum] or email them to
35 <a href="mailto:[email protected]">[email protected]</a>. Be sure to
36 describe in detail what the patch does and which version of Fossil
37
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -27,10 +27,14 @@
27
28 Suggested changes or bug fixes can be submitted by creating a patch
29 against the current source tree:
30
31 <tt>fossil diff -i > my-change.patch</tt>
32
33 Alternatively, you can create a binary patch:
34
35 <tt>fossil patch create my-change.db</tt>
36
37 Post patches to
38 [https://fossil-scm.org/forum | the forum] or email them to
39 <a href="mailto:[email protected]">[email protected]</a>. Be sure to
40 describe in detail what the patch does and which version of Fossil
41
--- www/server/any/cgi.md
+++ www/server/any/cgi.md
@@ -68,6 +68,25 @@
6868
exists.
6969
7070
Additional options available to the CGI script are [documented
7171
separately](../../cgi.wiki).
7272
73
+#### CGI with Apache behind an Nginx proxy
74
+
75
+For the case where the Fossil repositories live on a computer, itself behind
76
+an Internet-facing machine that employs Nginx to reverse proxy HTTP(S) requests
77
+and take care of the TLS part of the connections in a transparent manner for
78
+the downstream web servers, the CGI parameter `HTTPS=on` might not be set.
79
+However, Fossil in CGI mode needs it in order to generate the correct links.
80
+
81
+Apache can be instructed to pass this parameter further to the CGI scripts for
82
+TLS connections with a stanza like
83
+
84
+ SetEnvIf X-Forwarded-Proto "https" HTTPS=on
85
+
86
+in its config file section for CGI, provided that
87
+
88
+ proxy_set_header X-Forwarded-Proto $scheme;
89
+
90
+has been be added in the relevant proxying section of the Nginx config file.
91
+
7392
*[Return to the top-level Fossil server article.](../)*
7493
--- www/server/any/cgi.md
+++ www/server/any/cgi.md
@@ -68,6 +68,25 @@
68 exists.
69
70 Additional options available to the CGI script are [documented
71 separately](../../cgi.wiki).
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73 *[Return to the top-level Fossil server article.](../)*
74
--- www/server/any/cgi.md
+++ www/server/any/cgi.md
@@ -68,6 +68,25 @@
68 exists.
69
70 Additional options available to the CGI script are [documented
71 separately](../../cgi.wiki).
72
73 #### CGI with Apache behind an Nginx proxy
74
75 For the case where the Fossil repositories live on a computer, itself behind
76 an Internet-facing machine that employs Nginx to reverse proxy HTTP(S) requests
77 and take care of the TLS part of the connections in a transparent manner for
78 the downstream web servers, the CGI parameter `HTTPS=on` might not be set.
79 However, Fossil in CGI mode needs it in order to generate the correct links.
80
81 Apache can be instructed to pass this parameter further to the CGI scripts for
82 TLS connections with a stanza like
83
84 SetEnvIf X-Forwarded-Proto "https" HTTPS=on
85
86 in its config file section for CGI, provided that
87
88 proxy_set_header X-Forwarded-Proto $scheme;
89
90 has been be added in the relevant proxying section of the Nginx config file.
91
92 *[Return to the top-level Fossil server article.](../)*
93
--- 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