Fossil SCM

Merged in trunk and resolved numerous code clashes in /chat.

stephan 2021-12-16 04:20 markdown-tagrefs merge
Commit 54dba7479043bdbd47184f6e5950566617834d18e016dd9227b3c7bd53ebea86
64 files changed +1 -1 +1 -1 +11 -1 +40 -11 +40 -11 +14 -4 +2 -2 +74 -9 +23 -2 +30 +30 +10 -5 +8 -3 +287 -118 +287 -118 +3 +62 -9 +3 +1 -1 +5 -4 +1 -1 +31 -21 +2 -2 +4 -1 -4 +47 -37 +1 -1 +1 -1 +1 -1 +4 -12 +194 -81 +1 -1 +3354 -1665 +114 -12 +8 -4 +7 -3 +111 -46 +111 -46 +166 -19 +3 -1 +1 -1 +27 -22 -4 +50 -49 +2 -2 +1 +2 -4 +8 -1 +48 -16 +8 -7 +4 +16 -60 +229 +4 -4 +2 -3 +2 -1 +1 -1 +4 -19 +1 +1 -1 +19 +2 -2 +1 -1 +1 -97
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-2.17
1
+2.18
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 2.17
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 2.18
2
+1 -1
--- auto.def
+++ auto.def
@@ -32,11 +32,11 @@
3232
}
3333
3434
# Update the minimum required SQLite version number here, and also
3535
# in src/main.c near the sqlite3_libversion_number() call. Take care
3636
# that both places agree!
37
-define MINIMUM_SQLITE_VERSION "3.35.0"
37
+define MINIMUM_SQLITE_VERSION "3.37.0"
3838
3939
# This is useful for people wanting Fossil to use an external SQLite library
4040
# to compare the one they have against the minimum required
4141
if {[opt-bool print-minimum-sqlite-version]} {
4242
puts [get-define MINIMUM_SQLITE_VERSION]
4343
--- auto.def
+++ auto.def
@@ -32,11 +32,11 @@
32 }
33
34 # Update the minimum required SQLite version number here, and also
35 # in src/main.c near the sqlite3_libversion_number() call. Take care
36 # that both places agree!
37 define MINIMUM_SQLITE_VERSION "3.35.0"
38
39 # This is useful for people wanting Fossil to use an external SQLite library
40 # to compare the one they have against the minimum required
41 if {[opt-bool print-minimum-sqlite-version]} {
42 puts [get-define MINIMUM_SQLITE_VERSION]
43
--- auto.def
+++ auto.def
@@ -32,11 +32,11 @@
32 }
33
34 # Update the minimum required SQLite version number here, and also
35 # in src/main.c near the sqlite3_libversion_number() call. Take care
36 # that both places agree!
37 define MINIMUM_SQLITE_VERSION "3.37.0"
38
39 # This is useful for people wanting Fossil to use an external SQLite library
40 # to compare the one they have against the minimum required
41 if {[opt-bool print-minimum-sqlite-version]} {
42 puts [get-define MINIMUM_SQLITE_VERSION]
43
+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
+40 -11
--- src/chat.c
+++ src/chat.c
@@ -174,15 +174,23 @@
174174
zInputPlaceholder0 =
175175
mprintf("Type markdown-formatted message for %h.", zProjectName);
176176
style_set_current_feature("chat");
177177
style_header("Chat");
178178
@ <div id='chat-input-area'>
179
- @ <div id='chat-input-line' class='single-line'>
180
- @ <div contenteditable id="chat-input-field" \
179
+ @ <div id='chat-input-line-wrapper' class='compact'>
180
+ @ <input type="text" id="chat-input-field-single" \
181
+ @ data-placeholder0="%h(zInputPlaceholder0)" \
182
+ @ data-placeholder="%h(zInputPlaceholder0)" \
183
+ @ class="chat-input-field"></input>
184
+ @ <textarea id="chat-input-field-multi" \
185
+ @ data-placeholder0="%h(zInputPlaceholder0)" \
186
+ @ data-placeholder="%h(zInputPlaceholder0)" \
187
+ @ class="chat-input-field hidden"></textarea>
188
+ @ <div contenteditable id="chat-input-field-x" \
181189
@ data-placeholder0="%h(zInputPlaceholder0)" \
182190
@ data-placeholder="%h(zInputPlaceholder0)" \
183
- @ class=""></div>
191
+ @ class="chat-input-field hidden"></div>
184192
@ <div id='chat-buttons-wrapper'>
185193
@ <span class='cbutton' id="chat-button-preview" \
186194
@ title="Preview message (Shift-Enter)">&#128065;</span>
187195
@ <span class='cbutton' id="chat-button-attach" \
188196
@ title="Attach file to message">%s(zPaperclip)</span>
@@ -345,17 +353,29 @@
345353
** On success it responds with an empty response: the new message
346354
** should be fetched via /chat-poll. On error, e.g. login expiry,
347355
** it emits a JSON response in the same form as described for
348356
** /chat-poll errors, but as a standalone object instead of a
349357
** list of objects.
358
+**
359
+** Requests to this page should be POST, not GET. POST parameters
360
+** include:
361
+**
362
+** msg The (Markdown) text of the message to be sent
363
+**
364
+** file The content of the file attachment
365
+**
366
+** lmtime ISO-8601 formatted date-time string showing the local time
367
+** of the sender.
368
+**
369
+** At least one of the "msg" or "file" POST parameters must be provided.
350370
*/
351371
void chat_send_webpage(void){
352372
int nByte;
353373
const char *zMsg;
354374
const char *zUserName;
355375
login_check_credentials();
356
- if( !g.perm.Chat ) {
376
+ if( 0==g.perm.Chat ) {
357377
chat_emit_permissions_error(0);
358378
return;
359379
}
360380
chat_create_tables();
361381
zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
@@ -758,11 +778,13 @@
758778
**
759779
** This routine both deletes the identified chat entry and also inserts
760780
** a new entry with the current timestamp and with:
761781
**
762782
** * xmsg = NULL
783
+**
763784
** * file = NULL
785
+**
764786
** * mdel = The msgid of the row that was deleted
765787
**
766788
** This new entry will then be propagated to all listeners so that they
767789
** will know to delete their copies of the message too.
768790
*/
@@ -797,27 +819,34 @@
797819
** URL shows when you run the "fossil remote" command) or to the URL
798820
** specified by the --remote option. If there is no default remote
799821
** Fossil repository and the --remote option is omitted, then this
800822
** command fails with an error.
801823
**
802
-** When there is no SUBCOMMAND (when this command is simply "fossil chat")
803
-** the response is to bring up a web-browser window to the chatroom
804
-** on the default system web-browser. You can accomplish the same by
805
-** typing the appropriate URL into the web-browser yourself. This
806
-** command is merely a convenience for command-line oriented people.
824
+** Subcommands:
825
+**
826
+** > fossil chat
807827
**
808
-** The following subcommands are supported:
828
+** When there is no SUBCOMMAND (when this command is simply "fossil chat")
829
+** the response is to bring up a web-browser window to the chatroom
830
+** on the default system web-browser. You can accomplish the same by
831
+** typing the appropriate URL into the web-browser yourself. This
832
+** command is merely a convenience for command-line oriented people.
809833
**
810834
** > fossil chat send [ARGUMENTS]
811835
**
812836
** This command sends a new message to the chatroom. The message
813837
** to be sent is determined by arguments as follows:
814838
**
815839
** -f|--file FILENAME File to attach to the message
816840
** -m|--message TEXT Text of the chat message
841
+** --remote URL Send to this remote URL
817842
** --unsafe Allow the use of unencrypted http://
818843
**
844
+** > fossil chat url
845
+**
846
+** Show the default URL used to access the chat server.
847
+**
819848
** Additional subcommands may be added in the future.
820849
*/
821850
void chat_command(void){
822851
const char *zUrl = find_option("remote",0,1);
823852
int urlFlags = 0;
@@ -941,11 +970,11 @@
941970
}
942971
fossil_fatal("unable to send the chat message");
943972
}
944973
blob_reset(&down);
945974
}else if( strcmp(g.argv[2],"url")==0 ){
946
- /* Undocumented command. Show the URL to access chat. */
975
+ /* Show the URL to access chat. */
947976
fossil_print("%s/chat\n", zUrl);
948977
}else{
949978
fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
950979
}
951980
}
952981
--- src/chat.c
+++ src/chat.c
@@ -174,15 +174,23 @@
174 zInputPlaceholder0 =
175 mprintf("Type markdown-formatted message for %h.", zProjectName);
176 style_set_current_feature("chat");
177 style_header("Chat");
178 @ <div id='chat-input-area'>
179 @ <div id='chat-input-line' class='single-line'>
180 @ <div contenteditable id="chat-input-field" \
 
 
 
 
 
 
 
 
181 @ data-placeholder0="%h(zInputPlaceholder0)" \
182 @ data-placeholder="%h(zInputPlaceholder0)" \
183 @ class=""></div>
184 @ <div id='chat-buttons-wrapper'>
185 @ <span class='cbutton' id="chat-button-preview" \
186 @ title="Preview message (Shift-Enter)">&#128065;</span>
187 @ <span class='cbutton' id="chat-button-attach" \
188 @ title="Attach file to message">%s(zPaperclip)</span>
@@ -345,17 +353,29 @@
345 ** On success it responds with an empty response: the new message
346 ** should be fetched via /chat-poll. On error, e.g. login expiry,
347 ** it emits a JSON response in the same form as described for
348 ** /chat-poll errors, but as a standalone object instead of a
349 ** list of objects.
 
 
 
 
 
 
 
 
 
 
 
 
350 */
351 void chat_send_webpage(void){
352 int nByte;
353 const char *zMsg;
354 const char *zUserName;
355 login_check_credentials();
356 if( !g.perm.Chat ) {
357 chat_emit_permissions_error(0);
358 return;
359 }
360 chat_create_tables();
361 zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
@@ -758,11 +778,13 @@
758 **
759 ** This routine both deletes the identified chat entry and also inserts
760 ** a new entry with the current timestamp and with:
761 **
762 ** * xmsg = NULL
 
763 ** * file = NULL
 
764 ** * mdel = The msgid of the row that was deleted
765 **
766 ** This new entry will then be propagated to all listeners so that they
767 ** will know to delete their copies of the message too.
768 */
@@ -797,27 +819,34 @@
797 ** URL shows when you run the "fossil remote" command) or to the URL
798 ** specified by the --remote option. If there is no default remote
799 ** Fossil repository and the --remote option is omitted, then this
800 ** command fails with an error.
801 **
802 ** When there is no SUBCOMMAND (when this command is simply "fossil chat")
803 ** the response is to bring up a web-browser window to the chatroom
804 ** on the default system web-browser. You can accomplish the same by
805 ** typing the appropriate URL into the web-browser yourself. This
806 ** command is merely a convenience for command-line oriented people.
807 **
808 ** The following subcommands are supported:
 
 
 
 
809 **
810 ** > fossil chat send [ARGUMENTS]
811 **
812 ** This command sends a new message to the chatroom. The message
813 ** to be sent is determined by arguments as follows:
814 **
815 ** -f|--file FILENAME File to attach to the message
816 ** -m|--message TEXT Text of the chat message
 
817 ** --unsafe Allow the use of unencrypted http://
818 **
 
 
 
 
819 ** Additional subcommands may be added in the future.
820 */
821 void chat_command(void){
822 const char *zUrl = find_option("remote",0,1);
823 int urlFlags = 0;
@@ -941,11 +970,11 @@
941 }
942 fossil_fatal("unable to send the chat message");
943 }
944 blob_reset(&down);
945 }else if( strcmp(g.argv[2],"url")==0 ){
946 /* Undocumented command. Show the URL to access chat. */
947 fossil_print("%s/chat\n", zUrl);
948 }else{
949 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
950 }
951 }
952
--- src/chat.c
+++ src/chat.c
@@ -174,15 +174,23 @@
174 zInputPlaceholder0 =
175 mprintf("Type markdown-formatted message for %h.", zProjectName);
176 style_set_current_feature("chat");
177 style_header("Chat");
178 @ <div id='chat-input-area'>
179 @ <div id='chat-input-line-wrapper' class='compact'>
180 @ <input type="text" id="chat-input-field-single" \
181 @ data-placeholder0="%h(zInputPlaceholder0)" \
182 @ data-placeholder="%h(zInputPlaceholder0)" \
183 @ class="chat-input-field"></input>
184 @ <textarea id="chat-input-field-multi" \
185 @ data-placeholder0="%h(zInputPlaceholder0)" \
186 @ data-placeholder="%h(zInputPlaceholder0)" \
187 @ class="chat-input-field hidden"></textarea>
188 @ <div contenteditable id="chat-input-field-x" \
189 @ data-placeholder0="%h(zInputPlaceholder0)" \
190 @ data-placeholder="%h(zInputPlaceholder0)" \
191 @ class="chat-input-field hidden"></div>
192 @ <div id='chat-buttons-wrapper'>
193 @ <span class='cbutton' id="chat-button-preview" \
194 @ title="Preview message (Shift-Enter)">&#128065;</span>
195 @ <span class='cbutton' id="chat-button-attach" \
196 @ title="Attach file to message">%s(zPaperclip)</span>
@@ -345,17 +353,29 @@
353 ** On success it responds with an empty response: the new message
354 ** should be fetched via /chat-poll. On error, e.g. login expiry,
355 ** it emits a JSON response in the same form as described for
356 ** /chat-poll errors, but as a standalone object instead of a
357 ** list of objects.
358 **
359 ** Requests to this page should be POST, not GET. POST parameters
360 ** include:
361 **
362 ** msg The (Markdown) text of the message to be sent
363 **
364 ** file The content of the file attachment
365 **
366 ** lmtime ISO-8601 formatted date-time string showing the local time
367 ** of the sender.
368 **
369 ** At least one of the "msg" or "file" POST parameters must be provided.
370 */
371 void chat_send_webpage(void){
372 int nByte;
373 const char *zMsg;
374 const char *zUserName;
375 login_check_credentials();
376 if( 0==g.perm.Chat ) {
377 chat_emit_permissions_error(0);
378 return;
379 }
380 chat_create_tables();
381 zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
@@ -758,11 +778,13 @@
778 **
779 ** This routine both deletes the identified chat entry and also inserts
780 ** a new entry with the current timestamp and with:
781 **
782 ** * xmsg = NULL
783 **
784 ** * file = NULL
785 **
786 ** * mdel = The msgid of the row that was deleted
787 **
788 ** This new entry will then be propagated to all listeners so that they
789 ** will know to delete their copies of the message too.
790 */
@@ -797,27 +819,34 @@
819 ** URL shows when you run the "fossil remote" command) or to the URL
820 ** specified by the --remote option. If there is no default remote
821 ** Fossil repository and the --remote option is omitted, then this
822 ** command fails with an error.
823 **
824 ** Subcommands:
825 **
826 ** > fossil chat
 
 
827 **
828 ** When there is no SUBCOMMAND (when this command is simply "fossil chat")
829 ** the response is to bring up a web-browser window to the chatroom
830 ** on the default system web-browser. You can accomplish the same by
831 ** typing the appropriate URL into the web-browser yourself. This
832 ** command is merely a convenience for command-line oriented people.
833 **
834 ** > fossil chat send [ARGUMENTS]
835 **
836 ** This command sends a new message to the chatroom. The message
837 ** to be sent is determined by arguments as follows:
838 **
839 ** -f|--file FILENAME File to attach to the message
840 ** -m|--message TEXT Text of the chat message
841 ** --remote URL Send to this remote URL
842 ** --unsafe Allow the use of unencrypted http://
843 **
844 ** > fossil chat url
845 **
846 ** Show the default URL used to access the chat server.
847 **
848 ** Additional subcommands may be added in the future.
849 */
850 void chat_command(void){
851 const char *zUrl = find_option("remote",0,1);
852 int urlFlags = 0;
@@ -941,11 +970,11 @@
970 }
971 fossil_fatal("unable to send the chat message");
972 }
973 blob_reset(&down);
974 }else if( strcmp(g.argv[2],"url")==0 ){
975 /* Show the URL to access chat. */
976 fossil_print("%s/chat\n", zUrl);
977 }else{
978 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
979 }
980 }
981
+40 -11
--- src/chat.c
+++ src/chat.c
@@ -174,15 +174,23 @@
174174
zInputPlaceholder0 =
175175
mprintf("Type markdown-formatted message for %h.", zProjectName);
176176
style_set_current_feature("chat");
177177
style_header("Chat");
178178
@ <div id='chat-input-area'>
179
- @ <div id='chat-input-line' class='single-line'>
180
- @ <div contenteditable id="chat-input-field" \
179
+ @ <div id='chat-input-line-wrapper' class='compact'>
180
+ @ <input type="text" id="chat-input-field-single" \
181
+ @ data-placeholder0="%h(zInputPlaceholder0)" \
182
+ @ data-placeholder="%h(zInputPlaceholder0)" \
183
+ @ class="chat-input-field"></input>
184
+ @ <textarea id="chat-input-field-multi" \
185
+ @ data-placeholder0="%h(zInputPlaceholder0)" \
186
+ @ data-placeholder="%h(zInputPlaceholder0)" \
187
+ @ class="chat-input-field hidden"></textarea>
188
+ @ <div contenteditable id="chat-input-field-x" \
181189
@ data-placeholder0="%h(zInputPlaceholder0)" \
182190
@ data-placeholder="%h(zInputPlaceholder0)" \
183
- @ class=""></div>
191
+ @ class="chat-input-field hidden"></div>
184192
@ <div id='chat-buttons-wrapper'>
185193
@ <span class='cbutton' id="chat-button-preview" \
186194
@ title="Preview message (Shift-Enter)">&#128065;</span>
187195
@ <span class='cbutton' id="chat-button-attach" \
188196
@ title="Attach file to message">%s(zPaperclip)</span>
@@ -345,17 +353,29 @@
345353
** On success it responds with an empty response: the new message
346354
** should be fetched via /chat-poll. On error, e.g. login expiry,
347355
** it emits a JSON response in the same form as described for
348356
** /chat-poll errors, but as a standalone object instead of a
349357
** list of objects.
358
+**
359
+** Requests to this page should be POST, not GET. POST parameters
360
+** include:
361
+**
362
+** msg The (Markdown) text of the message to be sent
363
+**
364
+** file The content of the file attachment
365
+**
366
+** lmtime ISO-8601 formatted date-time string showing the local time
367
+** of the sender.
368
+**
369
+** At least one of the "msg" or "file" POST parameters must be provided.
350370
*/
351371
void chat_send_webpage(void){
352372
int nByte;
353373
const char *zMsg;
354374
const char *zUserName;
355375
login_check_credentials();
356
- if( !g.perm.Chat ) {
376
+ if( 0==g.perm.Chat ) {
357377
chat_emit_permissions_error(0);
358378
return;
359379
}
360380
chat_create_tables();
361381
zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
@@ -758,11 +778,13 @@
758778
**
759779
** This routine both deletes the identified chat entry and also inserts
760780
** a new entry with the current timestamp and with:
761781
**
762782
** * xmsg = NULL
783
+**
763784
** * file = NULL
785
+**
764786
** * mdel = The msgid of the row that was deleted
765787
**
766788
** This new entry will then be propagated to all listeners so that they
767789
** will know to delete their copies of the message too.
768790
*/
@@ -797,27 +819,34 @@
797819
** URL shows when you run the "fossil remote" command) or to the URL
798820
** specified by the --remote option. If there is no default remote
799821
** Fossil repository and the --remote option is omitted, then this
800822
** command fails with an error.
801823
**
802
-** When there is no SUBCOMMAND (when this command is simply "fossil chat")
803
-** the response is to bring up a web-browser window to the chatroom
804
-** on the default system web-browser. You can accomplish the same by
805
-** typing the appropriate URL into the web-browser yourself. This
806
-** command is merely a convenience for command-line oriented people.
824
+** Subcommands:
825
+**
826
+** > fossil chat
807827
**
808
-** The following subcommands are supported:
828
+** When there is no SUBCOMMAND (when this command is simply "fossil chat")
829
+** the response is to bring up a web-browser window to the chatroom
830
+** on the default system web-browser. You can accomplish the same by
831
+** typing the appropriate URL into the web-browser yourself. This
832
+** command is merely a convenience for command-line oriented people.
809833
**
810834
** > fossil chat send [ARGUMENTS]
811835
**
812836
** This command sends a new message to the chatroom. The message
813837
** to be sent is determined by arguments as follows:
814838
**
815839
** -f|--file FILENAME File to attach to the message
816840
** -m|--message TEXT Text of the chat message
841
+** --remote URL Send to this remote URL
817842
** --unsafe Allow the use of unencrypted http://
818843
**
844
+** > fossil chat url
845
+**
846
+** Show the default URL used to access the chat server.
847
+**
819848
** Additional subcommands may be added in the future.
820849
*/
821850
void chat_command(void){
822851
const char *zUrl = find_option("remote",0,1);
823852
int urlFlags = 0;
@@ -941,11 +970,11 @@
941970
}
942971
fossil_fatal("unable to send the chat message");
943972
}
944973
blob_reset(&down);
945974
}else if( strcmp(g.argv[2],"url")==0 ){
946
- /* Undocumented command. Show the URL to access chat. */
975
+ /* Show the URL to access chat. */
947976
fossil_print("%s/chat\n", zUrl);
948977
}else{
949978
fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
950979
}
951980
}
952981
--- src/chat.c
+++ src/chat.c
@@ -174,15 +174,23 @@
174 zInputPlaceholder0 =
175 mprintf("Type markdown-formatted message for %h.", zProjectName);
176 style_set_current_feature("chat");
177 style_header("Chat");
178 @ <div id='chat-input-area'>
179 @ <div id='chat-input-line' class='single-line'>
180 @ <div contenteditable id="chat-input-field" \
 
 
 
 
 
 
 
 
181 @ data-placeholder0="%h(zInputPlaceholder0)" \
182 @ data-placeholder="%h(zInputPlaceholder0)" \
183 @ class=""></div>
184 @ <div id='chat-buttons-wrapper'>
185 @ <span class='cbutton' id="chat-button-preview" \
186 @ title="Preview message (Shift-Enter)">&#128065;</span>
187 @ <span class='cbutton' id="chat-button-attach" \
188 @ title="Attach file to message">%s(zPaperclip)</span>
@@ -345,17 +353,29 @@
345 ** On success it responds with an empty response: the new message
346 ** should be fetched via /chat-poll. On error, e.g. login expiry,
347 ** it emits a JSON response in the same form as described for
348 ** /chat-poll errors, but as a standalone object instead of a
349 ** list of objects.
 
 
 
 
 
 
 
 
 
 
 
 
350 */
351 void chat_send_webpage(void){
352 int nByte;
353 const char *zMsg;
354 const char *zUserName;
355 login_check_credentials();
356 if( !g.perm.Chat ) {
357 chat_emit_permissions_error(0);
358 return;
359 }
360 chat_create_tables();
361 zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
@@ -758,11 +778,13 @@
758 **
759 ** This routine both deletes the identified chat entry and also inserts
760 ** a new entry with the current timestamp and with:
761 **
762 ** * xmsg = NULL
 
763 ** * file = NULL
 
764 ** * mdel = The msgid of the row that was deleted
765 **
766 ** This new entry will then be propagated to all listeners so that they
767 ** will know to delete their copies of the message too.
768 */
@@ -797,27 +819,34 @@
797 ** URL shows when you run the "fossil remote" command) or to the URL
798 ** specified by the --remote option. If there is no default remote
799 ** Fossil repository and the --remote option is omitted, then this
800 ** command fails with an error.
801 **
802 ** When there is no SUBCOMMAND (when this command is simply "fossil chat")
803 ** the response is to bring up a web-browser window to the chatroom
804 ** on the default system web-browser. You can accomplish the same by
805 ** typing the appropriate URL into the web-browser yourself. This
806 ** command is merely a convenience for command-line oriented people.
807 **
808 ** The following subcommands are supported:
 
 
 
 
809 **
810 ** > fossil chat send [ARGUMENTS]
811 **
812 ** This command sends a new message to the chatroom. The message
813 ** to be sent is determined by arguments as follows:
814 **
815 ** -f|--file FILENAME File to attach to the message
816 ** -m|--message TEXT Text of the chat message
 
817 ** --unsafe Allow the use of unencrypted http://
818 **
 
 
 
 
819 ** Additional subcommands may be added in the future.
820 */
821 void chat_command(void){
822 const char *zUrl = find_option("remote",0,1);
823 int urlFlags = 0;
@@ -941,11 +970,11 @@
941 }
942 fossil_fatal("unable to send the chat message");
943 }
944 blob_reset(&down);
945 }else if( strcmp(g.argv[2],"url")==0 ){
946 /* Undocumented command. Show the URL to access chat. */
947 fossil_print("%s/chat\n", zUrl);
948 }else{
949 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
950 }
951 }
952
--- src/chat.c
+++ src/chat.c
@@ -174,15 +174,23 @@
174 zInputPlaceholder0 =
175 mprintf("Type markdown-formatted message for %h.", zProjectName);
176 style_set_current_feature("chat");
177 style_header("Chat");
178 @ <div id='chat-input-area'>
179 @ <div id='chat-input-line-wrapper' class='compact'>
180 @ <input type="text" id="chat-input-field-single" \
181 @ data-placeholder0="%h(zInputPlaceholder0)" \
182 @ data-placeholder="%h(zInputPlaceholder0)" \
183 @ class="chat-input-field"></input>
184 @ <textarea id="chat-input-field-multi" \
185 @ data-placeholder0="%h(zInputPlaceholder0)" \
186 @ data-placeholder="%h(zInputPlaceholder0)" \
187 @ class="chat-input-field hidden"></textarea>
188 @ <div contenteditable id="chat-input-field-x" \
189 @ data-placeholder0="%h(zInputPlaceholder0)" \
190 @ data-placeholder="%h(zInputPlaceholder0)" \
191 @ class="chat-input-field hidden"></div>
192 @ <div id='chat-buttons-wrapper'>
193 @ <span class='cbutton' id="chat-button-preview" \
194 @ title="Preview message (Shift-Enter)">&#128065;</span>
195 @ <span class='cbutton' id="chat-button-attach" \
196 @ title="Attach file to message">%s(zPaperclip)</span>
@@ -345,17 +353,29 @@
353 ** On success it responds with an empty response: the new message
354 ** should be fetched via /chat-poll. On error, e.g. login expiry,
355 ** it emits a JSON response in the same form as described for
356 ** /chat-poll errors, but as a standalone object instead of a
357 ** list of objects.
358 **
359 ** Requests to this page should be POST, not GET. POST parameters
360 ** include:
361 **
362 ** msg The (Markdown) text of the message to be sent
363 **
364 ** file The content of the file attachment
365 **
366 ** lmtime ISO-8601 formatted date-time string showing the local time
367 ** of the sender.
368 **
369 ** At least one of the "msg" or "file" POST parameters must be provided.
370 */
371 void chat_send_webpage(void){
372 int nByte;
373 const char *zMsg;
374 const char *zUserName;
375 login_check_credentials();
376 if( 0==g.perm.Chat ) {
377 chat_emit_permissions_error(0);
378 return;
379 }
380 chat_create_tables();
381 zUserName = (g.zLogin && g.zLogin[0]) ? g.zLogin : "nobody";
@@ -758,11 +778,13 @@
778 **
779 ** This routine both deletes the identified chat entry and also inserts
780 ** a new entry with the current timestamp and with:
781 **
782 ** * xmsg = NULL
783 **
784 ** * file = NULL
785 **
786 ** * mdel = The msgid of the row that was deleted
787 **
788 ** This new entry will then be propagated to all listeners so that they
789 ** will know to delete their copies of the message too.
790 */
@@ -797,27 +819,34 @@
819 ** URL shows when you run the "fossil remote" command) or to the URL
820 ** specified by the --remote option. If there is no default remote
821 ** Fossil repository and the --remote option is omitted, then this
822 ** command fails with an error.
823 **
824 ** Subcommands:
825 **
826 ** > fossil chat
 
 
827 **
828 ** When there is no SUBCOMMAND (when this command is simply "fossil chat")
829 ** the response is to bring up a web-browser window to the chatroom
830 ** on the default system web-browser. You can accomplish the same by
831 ** typing the appropriate URL into the web-browser yourself. This
832 ** command is merely a convenience for command-line oriented people.
833 **
834 ** > fossil chat send [ARGUMENTS]
835 **
836 ** This command sends a new message to the chatroom. The message
837 ** to be sent is determined by arguments as follows:
838 **
839 ** -f|--file FILENAME File to attach to the message
840 ** -m|--message TEXT Text of the chat message
841 ** --remote URL Send to this remote URL
842 ** --unsafe Allow the use of unencrypted http://
843 **
844 ** > fossil chat url
845 **
846 ** Show the default URL used to access the chat server.
847 **
848 ** Additional subcommands may be added in the future.
849 */
850 void chat_command(void){
851 const char *zUrl = find_option("remote",0,1);
852 int urlFlags = 0;
@@ -941,11 +970,11 @@
970 }
971 fossil_fatal("unable to send the chat message");
972 }
973 blob_reset(&down);
974 }else if( strcmp(g.argv[2],"url")==0 ){
975 /* Show the URL to access chat. */
976 fossil_print("%s/chat\n", zUrl);
977 }else{
978 fossil_fatal("no such subcommand \"%s\". Use --help for help", g.argv[2]);
979 }
980 }
981
+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
+2 -2
--- src/clone.c
+++ src/clone.c
@@ -270,11 +270,11 @@
270270
if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){
271271
fossil_fatal("there are unresolved deltas -"
272272
" the clone is probably incomplete and unusable.");
273273
}
274274
fossil_print("Rebuilding repository meta-data...\n");
275
- rebuild_db(0, 1, 0);
275
+ rebuild_db(1, 0);
276276
if( !noCompress ){
277277
fossil_print("Extra delta compression... "); fflush(stdout);
278278
extra_deltification();
279279
fossil_print("\n");
280280
}
@@ -297,11 +297,11 @@
297297
zRepo, zWorkDir);
298298
blob_init(&cmd, 0, 0);
299299
blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
300300
blob_append(&cmd, " open ", -1);
301301
blob_append_escaped_arg(&cmd, zRepo, 1);
302
- blob_append(&cmd, " --workdir ", -1);
302
+ blob_append(&cmd, " --nosync --workdir ", -1);
303303
blob_append_escaped_arg(&cmd, zWorkDir, 1);
304304
if( allowNested ){
305305
blob_append(&cmd, " --nested", -1);
306306
}
307307
fossil_system(blob_str(&cmd));
308308
--- src/clone.c
+++ src/clone.c
@@ -270,11 +270,11 @@
270 if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){
271 fossil_fatal("there are unresolved deltas -"
272 " the clone is probably incomplete and unusable.");
273 }
274 fossil_print("Rebuilding repository meta-data...\n");
275 rebuild_db(0, 1, 0);
276 if( !noCompress ){
277 fossil_print("Extra delta compression... "); fflush(stdout);
278 extra_deltification();
279 fossil_print("\n");
280 }
@@ -297,11 +297,11 @@
297 zRepo, zWorkDir);
298 blob_init(&cmd, 0, 0);
299 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
300 blob_append(&cmd, " open ", -1);
301 blob_append_escaped_arg(&cmd, zRepo, 1);
302 blob_append(&cmd, " --workdir ", -1);
303 blob_append_escaped_arg(&cmd, zWorkDir, 1);
304 if( allowNested ){
305 blob_append(&cmd, " --nested", -1);
306 }
307 fossil_system(blob_str(&cmd));
308
--- src/clone.c
+++ src/clone.c
@@ -270,11 +270,11 @@
270 if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){
271 fossil_fatal("there are unresolved deltas -"
272 " the clone is probably incomplete and unusable.");
273 }
274 fossil_print("Rebuilding repository meta-data...\n");
275 rebuild_db(1, 0);
276 if( !noCompress ){
277 fossil_print("Extra delta compression... "); fflush(stdout);
278 extra_deltification();
279 fossil_print("\n");
280 }
@@ -297,11 +297,11 @@
297 zRepo, zWorkDir);
298 blob_init(&cmd, 0, 0);
299 blob_append_escaped_arg(&cmd, g.nameOfExe, 1);
300 blob_append(&cmd, " open ", -1);
301 blob_append_escaped_arg(&cmd, zRepo, 1);
302 blob_append(&cmd, " --nosync --workdir ", -1);
303 blob_append_escaped_arg(&cmd, zWorkDir, 1);
304 if( allowNested ){
305 blob_append(&cmd, " --nested", -1);
306 }
307 fossil_system(blob_str(&cmd));
308
+74 -9
--- src/db.c
+++ src/db.c
@@ -1914,16 +1914,16 @@
19141914
int rc;
19151915
if( file_isdir(zHome, ExtFILE)==0 ){
19161916
file_mkdir(zHome, ExtFILE, 0);
19171917
}
19181918
rc = file_access(zHome, W_OK);
1919
- fossil_free(zHome);
19201919
if( rc ){
19211920
if( isOptional ) return 0;
19221921
fossil_fatal("home directory \"%s\" must be writeable", zHome);
19231922
}
19241923
db_init_database(zDbName, zConfigSchema, (char*)0);
1924
+ fossil_free(zHome);
19251925
}
19261926
if( file_access(zDbName, W_OK) ){
19271927
if( isOptional ) return 0;
19281928
fossil_fatal("configuration file %s must be writeable", zDbName);
19291929
}
@@ -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"
@@ -3501,18 +3552,20 @@
35013552
** with the local repository. If you commit this checkout,
35023553
** it will become a new "initial" commit in the repository.
35033554
** -f|--force Continue with the open even if the working directory is
35043555
** not empty.
35053556
** --force-missing Force opening a repository with missing content
3506
-** --keep Only modify the manifest and manifest.uuid files
3557
+** -k|--keep Only modify the manifest and manifest.uuid files
35073558
** --nested Allow opening a repository inside an opened checkout
35083559
** --nosync Do not auto-sync the repository prior to opening
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,21 +3582,23 @@
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;
3537
- keepFlag = find_option("keep",0,0)!=0;
3591
+ keepFlag = find_option("keep","k",0)!=0;
35383592
forceMissingFlag = find_option("force-missing",0,0)!=0;
35393593
allowNested = find_option("nested",0,0)!=0;
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
@@ -1914,16 +1914,16 @@
1914 int rc;
1915 if( file_isdir(zHome, ExtFILE)==0 ){
1916 file_mkdir(zHome, ExtFILE, 0);
1917 }
1918 rc = file_access(zHome, W_OK);
1919 fossil_free(zHome);
1920 if( rc ){
1921 if( isOptional ) return 0;
1922 fossil_fatal("home directory \"%s\" must be writeable", zHome);
1923 }
1924 db_init_database(zDbName, zConfigSchema, (char*)0);
 
1925 }
1926 if( file_access(zDbName, W_OK) ){
1927 if( isOptional ) return 0;
1928 fossil_fatal("configuration file %s must be writeable", zDbName);
1929 }
@@ -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"
@@ -3501,18 +3552,20 @@
3501 ** with the local repository. If you commit this checkout,
3502 ** it will become a new "initial" commit in the repository.
3503 ** -f|--force Continue with the open even if the working directory is
3504 ** not empty.
3505 ** --force-missing Force opening a repository with missing content
3506 ** --keep Only modify the manifest and manifest.uuid files
3507 ** --nested Allow opening a repository inside an opened checkout
3508 ** --nosync Do not auto-sync the repository prior to opening
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,21 +3582,23 @@
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;
3539 allowNested = find_option("nested",0,0)!=0;
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
@@ -1914,16 +1914,16 @@
1914 int rc;
1915 if( file_isdir(zHome, ExtFILE)==0 ){
1916 file_mkdir(zHome, ExtFILE, 0);
1917 }
1918 rc = file_access(zHome, W_OK);
 
1919 if( rc ){
1920 if( isOptional ) return 0;
1921 fossil_fatal("home directory \"%s\" must be writeable", zHome);
1922 }
1923 db_init_database(zDbName, zConfigSchema, (char*)0);
1924 fossil_free(zHome);
1925 }
1926 if( file_access(zDbName, W_OK) ){
1927 if( isOptional ) return 0;
1928 fossil_fatal("configuration file %s must be writeable", zDbName);
1929 }
@@ -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"
@@ -3501,18 +3552,20 @@
3552 ** with the local repository. If you commit this checkout,
3553 ** it will become a new "initial" commit in the repository.
3554 ** -f|--force Continue with the open even if the working directory is
3555 ** not empty.
3556 ** --force-missing Force opening a repository with missing content
3557 ** -k|--keep Only modify the manifest and manifest.uuid files
3558 ** --nested Allow opening a repository inside an opened checkout
3559 ** --nosync Do not auto-sync the repository prior to opening
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,21 +3582,23 @@
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","k",0)!=0;
3592 forceMissingFlag = find_option("force-missing",0,0)!=0;
3593 allowNested = find_option("nested",0,0)!=0;
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
+23 -2
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -551,10 +551,29 @@
551551
blob_reset(&temp1);
552552
blob_reset(&temp2);
553553
blob_reset(&cmd);
554554
}
555555
}
556
+
557
+/*
558
+** Return true if the disk file is identical to the Blob. Return zero
559
+** if the files differ in any way.
560
+*/
561
+static int file_same_as_blob(Blob *blob, const char *zDiskFile){
562
+ Blob file;
563
+ int rc = 0;
564
+ if( blob_size(blob)!=file_size(zDiskFile, ExtFILE) ) return 0;
565
+ blob_zero(&file);
566
+ blob_read_from_file(&file, zDiskFile, ExtFILE);
567
+ if( blob_size(&file)!=blob_size(blob) ){
568
+ rc = 0;
569
+ }else{
570
+ rc = memcmp(blob_buffer(&file), blob_buffer(blob), blob_size(&file))==0;
571
+ }
572
+ blob_reset(&file);
573
+ return rc;
574
+}
556575
557576
/*
558577
** Run a diff between the version zFrom and files on disk. zFrom might
559578
** be NULL which means to simply show the difference between the edited
560579
** files on disk and the check-out on which they are based.
@@ -672,12 +691,14 @@
672691
if( srcid>0 ){
673692
content_get(srcid, &content);
674693
}else{
675694
blob_zero(&content);
676695
}
677
- diff_print_index(zPathname, pCfg, pOut);
678
- diff_file(&content, zFullName, zPathname, pCfg, pOut);
696
+ if( isChnged==0 || !file_same_as_blob(&content, zFullName) ){
697
+ diff_print_index(zPathname, pCfg, pOut);
698
+ diff_file(&content, zFullName, zPathname, pCfg, pOut);
699
+ }
679700
blob_reset(&content);
680701
}
681702
blob_reset(&fname);
682703
}
683704
db_finalize(&q);
684705
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -551,10 +551,29 @@
551 blob_reset(&temp1);
552 blob_reset(&temp2);
553 blob_reset(&cmd);
554 }
555 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
557 /*
558 ** Run a diff between the version zFrom and files on disk. zFrom might
559 ** be NULL which means to simply show the difference between the edited
560 ** files on disk and the check-out on which they are based.
@@ -672,12 +691,14 @@
672 if( srcid>0 ){
673 content_get(srcid, &content);
674 }else{
675 blob_zero(&content);
676 }
677 diff_print_index(zPathname, pCfg, pOut);
678 diff_file(&content, zFullName, zPathname, pCfg, pOut);
 
 
679 blob_reset(&content);
680 }
681 blob_reset(&fname);
682 }
683 db_finalize(&q);
684
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -551,10 +551,29 @@
551 blob_reset(&temp1);
552 blob_reset(&temp2);
553 blob_reset(&cmd);
554 }
555 }
556
557 /*
558 ** Return true if the disk file is identical to the Blob. Return zero
559 ** if the files differ in any way.
560 */
561 static int file_same_as_blob(Blob *blob, const char *zDiskFile){
562 Blob file;
563 int rc = 0;
564 if( blob_size(blob)!=file_size(zDiskFile, ExtFILE) ) return 0;
565 blob_zero(&file);
566 blob_read_from_file(&file, zDiskFile, ExtFILE);
567 if( blob_size(&file)!=blob_size(blob) ){
568 rc = 0;
569 }else{
570 rc = memcmp(blob_buffer(&file), blob_buffer(blob), blob_size(&file))==0;
571 }
572 blob_reset(&file);
573 return rc;
574 }
575
576 /*
577 ** Run a diff between the version zFrom and files on disk. zFrom might
578 ** be NULL which means to simply show the difference between the edited
579 ** files on disk and the check-out on which they are based.
@@ -672,12 +691,14 @@
691 if( srcid>0 ){
692 content_get(srcid, &content);
693 }else{
694 blob_zero(&content);
695 }
696 if( isChnged==0 || !file_same_as_blob(&content, zFullName) ){
697 diff_print_index(zPathname, pCfg, pOut);
698 diff_file(&content, zFullName, zPathname, pCfg, pOut);
699 }
700 blob_reset(&content);
701 }
702 blob_reset(&fname);
703 }
704 db_finalize(&q);
705
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -291,6 +291,36 @@
291291
if(t) t.innerText = title || f.$orig;
292292
return this;
293293
};
294294
F.onPageLoad(()=>F.page.setPageTitle.$orig
295295
= document.querySelector('title').innerText);
296
+ /**
297
+ Returns a function, that, as long as it continues to be invoked,
298
+ will not be triggered. The function will be called after it stops
299
+ being called for N milliseconds. If `immediate` is passed, call
300
+ the callback immediately and hinder future invocations until at
301
+ least the given time has passed.
302
+
303
+ If passed only 1 argument, or passed a falsy 2nd argument,
304
+ the default wait time set in this function's $defaultDelay
305
+ property is used.
306
+
307
+ Source: underscore.js, by way of https://davidwalsh.name/javascript-debounce-function
308
+ */
309
+ F.debounce = function f(func, wait, immediate) {
310
+ var timeout;
311
+ if(!wait) wait = f.$defaultDelay;
312
+ return function() {
313
+ const context = this, args = Array.prototype.slice.call(arguments);
314
+ const later = function() {
315
+ timeout = undefined;
316
+ if(!immediate) func.apply(context, args);
317
+ };
318
+ const callNow = immediate && !timeout;
319
+ clearTimeout(timeout);
320
+ timeout = setTimeout(later, wait);
321
+ if(callNow) func.apply(context, args);
322
+ };
323
+ };
324
+ F.debounce.$defaultDelay = 500 /*arbitrary*/;
325
+
296326
})(window);
297327
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -291,6 +291,36 @@
291 if(t) t.innerText = title || f.$orig;
292 return this;
293 };
294 F.onPageLoad(()=>F.page.setPageTitle.$orig
295 = document.querySelector('title').innerText);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296 })(window);
297
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -291,6 +291,36 @@
291 if(t) t.innerText = title || f.$orig;
292 return this;
293 };
294 F.onPageLoad(()=>F.page.setPageTitle.$orig
295 = document.querySelector('title').innerText);
296 /**
297 Returns a function, that, as long as it continues to be invoked,
298 will not be triggered. The function will be called after it stops
299 being called for N milliseconds. If `immediate` is passed, call
300 the callback immediately and hinder future invocations until at
301 least the given time has passed.
302
303 If passed only 1 argument, or passed a falsy 2nd argument,
304 the default wait time set in this function's $defaultDelay
305 property is used.
306
307 Source: underscore.js, by way of https://davidwalsh.name/javascript-debounce-function
308 */
309 F.debounce = function f(func, wait, immediate) {
310 var timeout;
311 if(!wait) wait = f.$defaultDelay;
312 return function() {
313 const context = this, args = Array.prototype.slice.call(arguments);
314 const later = function() {
315 timeout = undefined;
316 if(!immediate) func.apply(context, args);
317 };
318 const callNow = immediate && !timeout;
319 clearTimeout(timeout);
320 timeout = setTimeout(later, wait);
321 if(callNow) func.apply(context, args);
322 };
323 };
324 F.debounce.$defaultDelay = 500 /*arbitrary*/;
325
326 })(window);
327
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -291,6 +291,36 @@
291291
if(t) t.innerText = title || f.$orig;
292292
return this;
293293
};
294294
F.onPageLoad(()=>F.page.setPageTitle.$orig
295295
= document.querySelector('title').innerText);
296
+ /**
297
+ Returns a function, that, as long as it continues to be invoked,
298
+ will not be triggered. The function will be called after it stops
299
+ being called for N milliseconds. If `immediate` is passed, call
300
+ the callback immediately and hinder future invocations until at
301
+ least the given time has passed.
302
+
303
+ If passed only 1 argument, or passed a falsy 2nd argument,
304
+ the default wait time set in this function's $defaultDelay
305
+ property is used.
306
+
307
+ Source: underscore.js, by way of https://davidwalsh.name/javascript-debounce-function
308
+ */
309
+ F.debounce = function f(func, wait, immediate) {
310
+ var timeout;
311
+ if(!wait) wait = f.$defaultDelay;
312
+ return function() {
313
+ const context = this, args = Array.prototype.slice.call(arguments);
314
+ const later = function() {
315
+ timeout = undefined;
316
+ if(!immediate) func.apply(context, args);
317
+ };
318
+ const callNow = immediate && !timeout;
319
+ clearTimeout(timeout);
320
+ timeout = setTimeout(later, wait);
321
+ if(callNow) func.apply(context, args);
322
+ };
323
+ };
324
+ F.debounce.$defaultDelay = 500 /*arbitrary*/;
325
+
296326
})(window);
297327
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -291,6 +291,36 @@
291 if(t) t.innerText = title || f.$orig;
292 return this;
293 };
294 F.onPageLoad(()=>F.page.setPageTitle.$orig
295 = document.querySelector('title').innerText);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
296 })(window);
297
--- src/fossil.bootstrap.js
+++ src/fossil.bootstrap.js
@@ -291,6 +291,36 @@
291 if(t) t.innerText = title || f.$orig;
292 return this;
293 };
294 F.onPageLoad(()=>F.page.setPageTitle.$orig
295 = document.querySelector('title').innerText);
296 /**
297 Returns a function, that, as long as it continues to be invoked,
298 will not be triggered. The function will be called after it stops
299 being called for N milliseconds. If `immediate` is passed, call
300 the callback immediately and hinder future invocations until at
301 least the given time has passed.
302
303 If passed only 1 argument, or passed a falsy 2nd argument,
304 the default wait time set in this function's $defaultDelay
305 property is used.
306
307 Source: underscore.js, by way of https://davidwalsh.name/javascript-debounce-function
308 */
309 F.debounce = function f(func, wait, immediate) {
310 var timeout;
311 if(!wait) wait = f.$defaultDelay;
312 return function() {
313 const context = this, args = Array.prototype.slice.call(arguments);
314 const later = function() {
315 timeout = undefined;
316 if(!immediate) func.apply(context, args);
317 };
318 const callNow = immediate && !timeout;
319 clearTimeout(timeout);
320 timeout = setTimeout(later, wait);
321 if(callNow) func.apply(context, args);
322 };
323 };
324 F.debounce.$defaultDelay = 500 /*arbitrary*/;
325
326 })(window);
327
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -280,12 +280,13 @@
280280
maybeReplaceButtons: function(){
281281
if(this.pos.next && this.pos.prev
282282
&& (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){
283283
D.clearElement(this.e.btnWrapper);
284284
D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap));
285
- if( this.$fetchQueue && this.$fetchQueue.length>0 ){
286
- this.$fetchQueue = [this.FetchType.FillGap];
285
+ if( this.$fetchQueue && this.$fetchQueue.length>1 ){
286
+ this.$fetchQueue[1] = this.FetchType.FillGap;
287
+ this.$fetchQueue.length = 2;
287288
}
288289
}
289290
return this;
290291
},
291292
@@ -577,12 +578,16 @@
577578
fetchType = this.FetchType.FillGap;
578579
}
579580
}
580581
//console.debug("fetchChunk(",fetchType,")",up);
581582
fOpt.onerror = function(err){
582
- self.msg(true,err.message);
583
- self.$fetchQueue = [];
583
+ if(self.e/*guard against a late-stage onerror() call*/){
584
+ self.msg(true,err.message);
585
+ self.$fetchQueue.length = 0;
586
+ }else{
587
+ Diff.config.chunkFetch.onerror.call(this,err);
588
+ }
584589
};
585590
Diff.fetchArtifactChunk(fOpt);
586591
return this;
587592
}
588593
};
@@ -732,7 +737,7 @@
732737
window.fossil.page.tweakSbsDiffs = function(){
733738
document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
734739
Diff.checkTableWidth();
735740
};
736741
Diff.initTableDiff().checkTableWidth();
737
- window.addEventListener('resize', ()=>Diff.checkTableWidth());
742
+ window.addEventListener('resize', F.debounce(()=>Diff.checkTableWidth()));
738743
}, false);
739744
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -280,12 +280,13 @@
280 maybeReplaceButtons: function(){
281 if(this.pos.next && this.pos.prev
282 && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){
283 D.clearElement(this.e.btnWrapper);
284 D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap));
285 if( this.$fetchQueue && this.$fetchQueue.length>0 ){
286 this.$fetchQueue = [this.FetchType.FillGap];
 
287 }
288 }
289 return this;
290 },
291
@@ -577,12 +578,16 @@
577 fetchType = this.FetchType.FillGap;
578 }
579 }
580 //console.debug("fetchChunk(",fetchType,")",up);
581 fOpt.onerror = function(err){
582 self.msg(true,err.message);
583 self.$fetchQueue = [];
 
 
 
 
584 };
585 Diff.fetchArtifactChunk(fOpt);
586 return this;
587 }
588 };
@@ -732,7 +737,7 @@
732 window.fossil.page.tweakSbsDiffs = function(){
733 document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
734 Diff.checkTableWidth();
735 };
736 Diff.initTableDiff().checkTableWidth();
737 window.addEventListener('resize', ()=>Diff.checkTableWidth());
738 }, false);
739
--- src/fossil.diff.js
+++ src/fossil.diff.js
@@ -280,12 +280,13 @@
280 maybeReplaceButtons: function(){
281 if(this.pos.next && this.pos.prev
282 && (this.pos.endLhs - this.pos.startLhs <= Diff.config.chunkLoadLines)){
283 D.clearElement(this.e.btnWrapper);
284 D.append(this.e.btnWrapper, this.createButton(this.FetchType.FillGap));
285 if( this.$fetchQueue && this.$fetchQueue.length>1 ){
286 this.$fetchQueue[1] = this.FetchType.FillGap;
287 this.$fetchQueue.length = 2;
288 }
289 }
290 return this;
291 },
292
@@ -577,12 +578,16 @@
578 fetchType = this.FetchType.FillGap;
579 }
580 }
581 //console.debug("fetchChunk(",fetchType,")",up);
582 fOpt.onerror = function(err){
583 if(self.e/*guard against a late-stage onerror() call*/){
584 self.msg(true,err.message);
585 self.$fetchQueue.length = 0;
586 }else{
587 Diff.config.chunkFetch.onerror.call(this,err);
588 }
589 };
590 Diff.fetchArtifactChunk(fOpt);
591 return this;
592 }
593 };
@@ -732,7 +737,7 @@
737 window.fossil.page.tweakSbsDiffs = function(){
738 document.querySelectorAll('table.splitdiff').forEach((e)=>Diff.initTableDiff(e));
739 Diff.checkTableWidth();
740 };
741 Diff.initTableDiff().checkTableWidth();
742 window.addEventListener('resize', F.debounce(()=>Diff.checkTableWidth()));
743 }, false);
744
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -27,13 +27,18 @@
2727
"this", noting that this call may have amended the options object
2828
with state other than what the caller provided.
2929
3030
- onerror: callback(Error object) (default = output error message
3131
to console.error() and fossil.error()). Triggered if the request
32
- generates any response other than HTTP 200 or suffers a connection
33
- error or timeout while awaiting a response. In the context of the
34
- callback, the options object is "this".
32
+ generates any response other than HTTP 200, suffers a connection
33
+ error or timeout while awaiting a response, or if the onload()
34
+ handler throws an exception. In the context of the callback, the
35
+ options object is "this". Note that this function is intended to be
36
+ used solely for error reporting, not error recovery. Because
37
+ onerror() may be called if onload() throws, it is up to the caller
38
+ to ensure that their onerror() callback references only state which
39
+ is valid in such a case.
3540
3641
- method: 'POST' | 'GET' (default = 'GET'). CASE SENSITIVE!
3742
3843
- payload: anything acceptable by XHR2.send(ARG) (DOMString,
3944
Document, FormData, Blob, File, ArrayBuffer), or a plain object or
4045
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -27,13 +27,18 @@
27 "this", noting that this call may have amended the options object
28 with state other than what the caller provided.
29
30 - onerror: callback(Error object) (default = output error message
31 to console.error() and fossil.error()). Triggered if the request
32 generates any response other than HTTP 200 or suffers a connection
33 error or timeout while awaiting a response. In the context of the
34 callback, the options object is "this".
 
 
 
 
 
35
36 - method: 'POST' | 'GET' (default = 'GET'). CASE SENSITIVE!
37
38 - payload: anything acceptable by XHR2.send(ARG) (DOMString,
39 Document, FormData, Blob, File, ArrayBuffer), or a plain object or
40
--- src/fossil.fetch.js
+++ src/fossil.fetch.js
@@ -27,13 +27,18 @@
27 "this", noting that this call may have amended the options object
28 with state other than what the caller provided.
29
30 - onerror: callback(Error object) (default = output error message
31 to console.error() and fossil.error()). Triggered if the request
32 generates any response other than HTTP 200, suffers a connection
33 error or timeout while awaiting a response, or if the onload()
34 handler throws an exception. In the context of the callback, the
35 options object is "this". Note that this function is intended to be
36 used solely for error reporting, not error recovery. Because
37 onerror() may be called if onload() throws, it is up to the caller
38 to ensure that their onerror() callback references only state which
39 is valid in such a case.
40
41 - method: 'POST' | 'GET' (default = 'GET'). CASE SENSITIVE!
42
43 - payload: anything acceptable by XHR2.send(ARG) (DOMString,
44 Document, FormData, Blob, File, ArrayBuffer), or a plain object or
45
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -43,10 +43,11 @@
4343
const iso8601ish = function(d){
4444
return d.toISOString()
4545
.replace('T',' ').replace(/\.\d+/,'')
4646
.replace('Z', ' zulu');
4747
};
48
+ const pad2 = (x)=>('0'+x).substr(-2);
4849
/** Returns the local time string of Date object d, defaulting
4950
to the current time. */
5051
const localTimeString = function ff(d){
5152
d || (d = new Date());
5253
return [
@@ -93,11 +94,11 @@
9394
ht = wh;
9495
}else{
9596
elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
9697
ht = wh - extra;
9798
}
98
- f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99
+ f.chat.e.inputX.style.maxHeight = (ht/2)+"px";
99100
/* ^^^^ this is a middle ground between having no size cap
100101
on the input field and having a fixed arbitrary cap. */;
101102
contentArea.style.height =
102103
contentArea.style.maxHeight = [
103104
"calc(", (ht>=100 ? ht : 100), "px",
@@ -109,21 +110,17 @@
109110
if(false){
110111
console.debug("resized.",wh, extra, ht,
111112
window.getComputedStyle(contentArea).maxHeight,
112113
contentArea);
113114
console.debug("Set input max height to: ",
114
- f.chat.e.inputField.style.maxHeight);
115
+ f.chat.e.inputX.style.maxHeight);
115116
}
116117
};
117
- var doit;
118
- window.addEventListener('resize',function(ev){
119
- clearTimeout(doit);
120
- doit = setTimeout(resized, 100);
121
- }, false);
118
+ resized.$disabled = true/*gets deleted when setup is finished*/;
119
+ window.addEventListener('resize', F.debounce(resized, 250), false);
122120
return resized;
123121
})();
124
- ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
125122
fossil.FRK = ForceResizeKludge/*for debugging*/;
126123
const Chat = ForceResizeKludge.chat = (function(){
127124
const cs = {
128125
verboseErrors: false /* if true then certain, mostly extraneous,
129126
error messages may be sent to the console. */,
@@ -130,16 +127,18 @@
130127
e:{/*map of certain DOM elements.*/
131128
messageInjectPoint: E1('#message-inject-point'),
132129
pageTitle: E1('head title'),
133130
loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */,
134131
inputWrapper: E1("#chat-input-area"),
135
- inputLine: E1('#chat-input-line'),
132
+ inputElementWrapper: E1('#chat-input-line-wrapper'),
136133
fileSelectWrapper: E1('#chat-input-file-area'),
137134
viewMessages: E1('#chat-messages-wrapper'),
138135
btnSubmit: E1('#chat-button-submit'),
139136
btnAttach: E1('#chat-button-attach'),
140
- inputField: E1('#chat-input-field'),
137
+ inputX: E1('#chat-input-field-x'),
138
+ input1: E1('#chat-input-field-single'),
139
+ inputM: E1('#chat-input-field-multi'),
141140
inputFile: E1('#chat-input-file'),
142141
contentDiv: E1('div.content'),
143142
viewConfig: E1('#chat-config'),
144143
viewPreview: E1('#chat-preview'),
145144
previewContent: E1('#chat-preview-content'),
@@ -192,23 +191,24 @@
192191
taking into account single- vs multi-line input. The getter returns
193192
a string and the setter returns this object. */
194193
inputValue: function(){
195194
const e = this.inputElement();
196195
if(arguments.length){
197
- e.innerText = arguments[0];
196
+ if(e.isContentEditable) e.innerText = arguments[0];
197
+ else e.value = arguments[0];
198198
return this;
199199
}
200
- return e.innerText;
200
+ return e.isContentEditable ? e.innerText : e.value;
201201
},
202202
/** Asks the current user input field to take focus. Returns this. */
203203
inputFocus: function(){
204204
this.inputElement().focus();
205205
return this;
206206
},
207207
/** Returns the current message input element. */
208208
inputElement: function(){
209
- return this.e.inputField;
209
+ return this.e.inputFields[this.e.inputFields.$currentIndex];
210210
},
211211
/** Enables (if yes is truthy) or disables all elements in
212212
* this.disableDuringAjax. */
213213
enableAjaxComponents: function(yes){
214214
D[yes ? 'enable' : 'disable'](this.disableDuringAjax);
@@ -415,11 +415,11 @@
415415
laid out in a compact form. When off, the edit field and
416416
buttons are larger. */
417417
"edit-compact-mode": true,
418418
/* When on, sets the font-family on messages and the edit
419419
field to monospace. */
420
- "monospace-messages": true,
420
+ "monospace-messages": false,
421421
/* When on, non-chat UI elements (page header/footer) are
422422
hidden */
423423
"chat-only-mode": false,
424424
/* When set to a URI, it is assumed to be an audio file,
425425
which gets played when new messages arrive. When true,
@@ -434,11 +434,17 @@
434434
timestamp of each user's most recent message. */
435435
"active-user-list-timestamps": false,
436436
/* When on, the [audible-alert] is played for one's own
437437
messages, else it is only played for other users'
438438
messages. */
439
- "alert-own-messages": false
439
+ "alert-own-messages": false,
440
+ /* "Experimental mode" input: use a contenteditable field
441
+ for input. This is generally more comfortable to use,
442
+ and more modern, than plain text input fields, but
443
+ the list of browser-specific quirks and bugs is...
444
+ not short. */
445
+ "edit-widget-x": false
440446
}
441447
},
442448
/** Plays a new-message notification sound IF the audible-alert
443449
setting is true, else this is a no-op. Returns this.
444450
*/
@@ -672,16 +678,22 @@
672678
D.addClassBriefly(e, a, 0, cb);
673679
}
674680
return this;
675681
}
676682
};
677
- if(D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){
683
+ cs.e.inputFields = [ cs.e.input1, cs.e.inputM, cs.e.inputX ];
684
+ cs.e.inputFields.$currentIndex = 0;
685
+ cs.e.inputFields.forEach(function(e,ndx){
686
+ if(ndx===cs.e.inputFields.$currentIndex) D.removeClass(e,'hidden');
687
+ else D.addClass(e,'hidden');
688
+ });
689
+ if(D.attr(cs.e.inputX,'contenteditable','plaintext-only').isContentEditable){
678690
cs.$browserHasPlaintextOnly = true;
679691
}else{
680692
/* Only the Chrome family supports contenteditable=plaintext-only */
681693
cs.$browserHasPlaintextOnly = false;
682
- D.attr(cs.e.inputField,'contenteditable','true');
694
+ D.attr(cs.e.inputX,'contenteditable','true');
683695
}
684696
cs.animate.$disabled = true;
685697
F.fetch.beforesend = ()=>cs.ajaxStart();
686698
F.fetch.aftersend = ()=>cs.ajaxEnd();
687699
cs.pageTitleOrig = cs.e.pageTitle.innerText;
@@ -702,18 +714,21 @@
702714
Reports an error in the form of a new message in the chat
703715
feed. All arguments are appended to the message's content area
704716
using fossil.dom.append(), so may be of any type supported by
705717
that function.
706718
*/
707
- cs.reportErrorAsMessage = function(/*msg args*/){
708
- const args = argsToArray(arguments);
719
+ cs.reportErrorAsMessage = function f(/*msg args*/){
720
+ if(undefined === f.$msgid) f.$msgid=0;
721
+ const args = argsToArray(arguments).map(function(v){
722
+ return (v instanceof Error) ? v.message : v;
723
+ });
709724
console.error("chat error:",args);
710725
const d = new Date().toISOString(),
711726
mw = new this.MessageWidget({
712727
isError: true,
713728
xfrom: null,
714
- msgid: -1,
729
+ msgid: "error-"+(++f.$msgid),
715730
mtime: d,
716731
lmtime: d,
717732
xmsg: args
718733
});
719734
this.injectMessageElem(mw.e.body);
@@ -873,10 +888,20 @@
873888
};
874889
document.addEventListener('visibilitychange', function(ev){
875890
cs.pageIsActive = ('visible' === document.visibilityState);
876891
if(cs.pageIsActive){
877892
cs.e.pageTitle.innerText = cs.pageTitleOrig;
893
+ if(document.activeElement!==cs.inputElement()){
894
+ /* An attempt to resolve usability problem reported by Joe
895
+ M. where the Pale Moon browser is giving input focus to
896
+ the Preview button. The down-side of this is that it will
897
+ deselect any text which was previously selected on this
898
+ page. This also, unfortunately, places the focus at the
899
+ start of the element, rather than the last cursor position
900
+ (like a textarea would). */
901
+ setTimeout(()=>cs.inputFocus(), 0);
902
+ }
878903
}
879904
}, true);
880905
cs.setCurrentView(cs.e.viewMessages);
881906
882907
cs.e.activeUserList.addEventListener('click', function f(ev){
@@ -989,10 +1014,19 @@
9891014
})
9901015
elem.querySelectorAll('[data-numtag]').forEach(
9911016
(e)=>e.addEventListener('click', f.$clickNum, false)
9921017
)
9931018
}/*setupHashtags()*/;
1019
+
1020
+ /** Returns the first .message-widget element in DOM element
1021
+ e's lineage. */
1022
+ const findMessageWidgetParent = function(e){
1023
+ while( e && !e.classList.contains('message-widget')){
1024
+ e = e.parentNode;
1025
+ }
1026
+ return e;
1027
+ };
9941028
9951029
/**
9961030
Custom widget type for rendering messages (one message per
9971031
instance). These are modelled after FIELDSET elements but we
9981032
don't use FIELDSET because of cross-browser inconsistencies in
@@ -1016,11 +1050,10 @@
10161050
if(arguments.length){
10171051
this.setMessage(arguments[0]);
10181052
}
10191053
};
10201054
/* Left-zero-pad a number to at least 2 digits */
1021
- const pad2 = (x)=>(''+x).length>1 ? x : '0'+x;
10221055
const dowMap = {
10231056
/* Map of Date.getDay() values to weekday names. */
10241057
0: "Sunday", 1: "Monday", 2: "Tuesday",
10251058
3: "Wednesday", 4: "Thursday", 5: "Friday",
10261059
6: "Saturday"
@@ -1034,10 +1067,11 @@
10341067
d.getHours(),":",
10351068
(d.getMinutes()+100).toString().slice(1,3),
10361069
' ', dowMap[d.getDay()]
10371070
].join('');
10381071
};
1072
+
10391073
cf.prototype = {
10401074
scrollIntoView: function(){
10411075
this.e.content.scrollIntoView();
10421076
},
10431077
setMessage: function(m){
@@ -1068,11 +1102,11 @@
10681102
if(m.isError){
10691103
D.addClass([contentTarget, this.e.tab], 'error');
10701104
}
10711105
D.append(
10721106
this.e.tab,
1073
- D.text('notification @ ',theTime(d))
1107
+ D.append(D.code(), 'notification @ ',theTime(d))
10741108
);
10751109
}
10761110
if( m.xfrom && m.fsize>0 ){
10771111
if( m.fmime
10781112
&& m.fmime.startsWith("image/")
@@ -1105,11 +1139,11 @@
11051139
// hyperlinks, but otherwise it will be markup-free. See the
11061140
// chat_format_to_html() routine in the server for details.
11071141
//
11081142
// Hence, even though innerHTML is normally frowned upon, it is
11091143
// perfectly safe to use in this context.
1110
- if(m.xmsg instanceof Array){
1144
+ if(m.xmsg && 'string' !== typeof m.xmsg){
11111145
// Used by Chat.reportErrorAsMessage()
11121146
D.append(contentTarget, m.xmsg);
11131147
}else{
11141148
contentTarget.innerHTML = m.xmsg;
11151149
contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
@@ -1117,10 +1151,12 @@
11171151
if(F.pikchr){
11181152
F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
11191153
}
11201154
}
11211155
}
1156
+ //console.debug("tab",this.e.tab);
1157
+ //console.debug("this.e.tab.firstElementChild",this.e.tab.firstElementChild);
11221158
this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false);
11231159
/*if(eXFrom){
11241160
eXFrom.addEventListener('click', ()=>this.e.tab.click(), false);
11251161
}*/
11261162
return this;
@@ -1249,14 +1285,11 @@
12491285
this.$eMsg = tgtMsg;
12501286
this.refresh();
12511287
}
12521288
}/*f.popup*/;
12531289
}/*end static init*/
1254
- let theMsg = ev.target;
1255
- while( theMsg && !theMsg.classList.contains('message-widget')){
1256
- theMsg = theMsg.parentNode;
1257
- }
1290
+ const theMsg = findMessageWidgetParent(ev.target);
12581291
if(theMsg) f.popup.show(theMsg);
12591292
}/*_handleLegendClicked()*/
12601293
}/*MessageWidget.prototype*/;
12611294
/** Assumes that e is a MessageWidget element, ensures that
12621295
Chat.e.viewMessages is visible, scrolls the message,
@@ -1283,11 +1316,11 @@
12831316
}
12841317
};
12851318
/** Updates the paste/drop zone with details of the pasted/dropped
12861319
data. The argument must be a Blob or Blob-like object (File) or
12871320
it can be falsy to reset/clear that state.*/
1288
- const updateDropZoneContent = function(blob){
1321
+ const updateDropZoneContent = bxs.updateDropZoneContent = function(blob){
12891322
//console.debug("updateDropZoneContent()",blob);
12901323
const dd = bxs.dropDetails;
12911324
bxs.blob = blob;
12921325
D.clearElement(dd);
12931326
if(!blob){
@@ -1332,11 +1365,11 @@
13321365
/* Acrobatics to keep *some* installations of Firefox
13331366
from pasting formatting into contenteditable fields.
13341367
This also works on Chrome, but chrome has the
13351368
contenteditable=plaintext-only property which does this
13361369
for us. */
1337
- Chat.inputElement().addEventListener(
1370
+ Chat.e.inputX.addEventListener(
13381371
'paste',
13391372
function(ev){
13401373
if (ev.clipboardData && ev.clipboardData.getData) {
13411374
const pastedText = ev.clipboardData.getData('text/plain');
13421375
const selection = window.getSelection();
@@ -1356,30 +1389,60 @@
13561389
ev.dataTransfer.dropEffect = 'none';
13571390
ev.preventDefault();
13581391
ev.stopPropagation();
13591392
return false;
13601393
};
1361
-
13621394
['drop','dragenter','dragleave','dragend'].forEach(
1363
- (k)=>{
1364
- Chat.inputElement().addEventListener(k, noDragDropEvents, false);
1365
- }
1395
+ (k)=>Chat.e.inputX.addEventListener(k, noDragDropEvents, false)
13661396
);
13671397
return bxs;
13681398
})()/*drag/drop/paste*/;
13691399
13701400
const tzOffsetToString = function(off){
13711401
const hours = Math.round(off/60), min = Math.round(off % 30);
13721402
return ''+(hours + (min ? '.5' : ''));
13731403
};
1374
- const pad2 = (x)=>('0'+x).substr(-2);
13751404
const localTime8601 = function(d){
13761405
return [
13771406
d.getYear()+1900, '-', pad2(d.getMonth()+1), '-', pad2(d.getDate()),
13781407
'T', pad2(d.getHours()),':', pad2(d.getMinutes()),':',pad2(d.getSeconds())
13791408
].join('');
13801409
};
1410
+
1411
+ /**
1412
+ Called by Chat.submitMessage() when message sending failed. Injects a fake message
1413
+ containing the content and attachment of the failed message and gives the user buttons
1414
+ to discard it or edit and retry.
1415
+ */
1416
+ const recoverFailedMessage = function(state){
1417
+ const w = D.addClass(D.div(), 'failed-message');
1418
+ D.append(w, D.append(
1419
+ D.span(),"This message was not successfully sent to the server:"
1420
+ ));
1421
+ if(state.msg){
1422
+ const ta = D.textarea();
1423
+ ta.value = state.msg;
1424
+ D.append(w,ta);
1425
+ }
1426
+ if(state.blob){
1427
+ D.append(w,D.append(D.span(),"Attachment: ",(state.blob.name||"unnamed")));
1428
+ //console.debug("blob = ",state.blob);
1429
+ }
1430
+ const buttons = D.addClass(D.div(), 'buttons');
1431
+ D.append(w, buttons);
1432
+ D.append(buttons, D.button("Discard message?", function(){
1433
+ let theMsg = findMessageWidgetParent(w);
1434
+ if(theMsg) Chat.deleteMessageElem(theMsg);
1435
+ }));
1436
+ D.append(buttons, D.button("Edit message and try again?", function(){
1437
+ if(state.msg) Chat.inputValue(ta.value);
1438
+ if(state.blob) BlobXferState.updateDropZoneContent(state.blob);
1439
+ let theMsg = findMessageWidgetParent(w);
1440
+ if(theMsg) Chat.deleteMessageElem(theMsg);
1441
+ }));
1442
+ Chat.reportErrorAsMessage(w);
1443
+ };
13811444
13821445
/**
13831446
Submits the contents of the message input field (if not empty)
13841447
and/or the file attachment field to the server. If both are
13851448
empty, this is a no-op.
@@ -1389,11 +1452,12 @@
13891452
f.spaces = /\s+$/;
13901453
f.markdownContinuation = /\\\s+$/;
13911454
}
13921455
this.setCurrentView(this.e.viewMessages);
13931456
const fd = new FormData();
1394
- var msg = this.inputValue().trim();
1457
+ const fallback = {msg: this.inputValue()};
1458
+ var msg = fallback.msg.trim();
13951459
if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
13961460
/* Cosmetic: trim whitespace from the ends of lines to try to
13971461
keep copy/paste from terminals, especially wide ones, from
13981462
forcing a horizontal scrollbar on all clients. This breaks
13991463
markdown's use of blackslash-space-space for paragraph
@@ -1412,25 +1476,29 @@
14121476
}
14131477
if(msg) fd.set('msg',msg);
14141478
const file = BlobXferState.blob || this.e.inputFile.files[0];
14151479
if(file) fd.set("file", file);
14161480
if( !msg && !file ) return;
1481
+ fallback.blob = file;
14171482
const self = this;
14181483
fd.set("lmtime", localTime8601(new Date()));
14191484
F.fetch("chat-send",{
14201485
payload: fd,
14211486
responseType: 'text',
1422
- onerror:(err)=>this.reportErrorAsMessage(err),
1487
+ onerror:function(err){
1488
+ self.reportErrorAsMessage(err);
1489
+ recoverFailedMessage(fallback);
1490
+ },
14231491
onload:function(txt){
14241492
if(!txt) return/*success response*/;
14251493
try{
14261494
const json = JSON.parse(txt);
14271495
self.newContent({msgs:[json]});
14281496
}catch(e){
14291497
self.reportError(e);
1430
- return;
14311498
}
1499
+ recoverFailedMessage(fallback);
14321500
}
14331501
});
14341502
BlobXferState.clear();
14351503
Chat.inputValue("").inputFocus();
14361504
};
@@ -1494,11 +1562,13 @@
14941562
ev.stopPropagation();
14951563
Chat.submitMessage();
14961564
return false;
14971565
}
14981566
};
1499
- Chat.e.inputField.addEventListener('keydown', inputWidgetKeydown, false);
1567
+ Chat.e.inputFields.forEach(
1568
+ (e)=>e.addEventListener('keydown', inputWidgetKeydown, false)
1569
+ );
15001570
Chat.e.btnSubmit.addEventListener('click',(e)=>{
15011571
e.preventDefault();
15021572
Chat.submitMessage();
15031573
return false;
15041574
});
@@ -1553,76 +1623,110 @@
15531623
Settings options structure: an array of Objects with the
15541624
following properties:
15551625
15561626
label: string for the UI
15571627
1558
- boolValue: string (name of Chat.settings setting) or a
1559
- function which returns true or false. Gets mapped to
1560
- a checkbox.
1628
+ boolValue: string (name of Chat.settings setting) or a function
1629
+ which returns true or false. If it is a string, it gets
1630
+ replaced by a function which returns
1631
+ Chat.settings.getBool(thatString) and the string gets assigned
1632
+ to the persistentSetting property of this object.
15611633
15621634
select: SELECT element (instead of boolValue)
15631635
15641636
callback: optional handler to call after setting is modified.
15651637
It gets passed the setting object: {key:string, value:something}.
1638
+ Its "this" is the options object. If this object has a
1639
+ boolValue string or a persistentSetting property, the argument
1640
+ passed to the callback is a settings object in the form {key:K,
1641
+ value:V}. If this object does not have boolValue string or
1642
+ persistentSetting then the callback is passed an event object
1643
+ in response to the config option's UI widget being activated,
1644
+ normally a 'change' event.
1645
+
1646
+ children: [array of settings objects]. These get listed under
1647
+ this element and indented slightly for visual grouping. Only
1648
+ one level of indention is supported.
1649
+
1650
+ Elements which only have a label and maybe a hint and
1651
+ children can be used as headings.
15661652
1567
- If a setting has a boolValue set, that gets transformed into a
1653
+ If a setting has a boolValue set, that gets rendered as a
15681654
checkbox which toggles the given persistent setting (if
15691655
boolValue is a string) AND listens for changes to that setting
15701656
fired via Chat.settings.set() so that the checkbox can stay in
15711657
sync with external changes to that setting. Various Chat UI
15721658
elements stay in sync with the config UI via those settings
1573
- events.
1659
+ events. The checkbox element gets added to the options object
1660
+ so that the callback() can reference it via this.checkbox.
15741661
*/
15751662
const settingsOps = [{
1576
- label: "Ctrl-enter to Send",
1577
- hint: [
1578
- "When on, only Ctrl-Enter will send messages and Enter adds ",
1579
- "blank lines. ",
1580
- "When off, both Enter and Ctrl-Enter send. ",
1581
- "When the input field has focus, is empty, and preview ",
1582
- "mode is NOT active then Ctrl-Enter toggles this setting."
1583
- ].join(''),
1584
- boolValue: 'edit-ctrl-send'
1585
- },{
1586
- label: "Compact mode",
1587
- hint: [
1588
- "Toggle between a space-saving or more spacious writing area. ",
1589
- "When the input field has focus, is empty, and preview mode ",
1590
- "is NOT active then Shift-Enter toggles this setting."
1591
- ].join(''),
1592
- boolValue: 'edit-compact-mode'
1593
- },{
1594
- label: "Left-align my posts",
1595
- hint: "Default alignment of your own messages is selected "
1596
- +"based window width/height relationship.",
1597
- boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1598
- callback: function f(){
1599
- document.body.classList[
1600
- this.checkbox.checked ? 'remove' : 'add'
1601
- ]('my-messages-right');
1602
- }
1603
- },{
1604
- label: "Monospace message font",
1605
- hint: "Use monospace font for message text?",
1606
- boolValue: 'monospace-messages',
1607
- callback: function(setting){
1608
- document.body.classList[
1609
- setting.value ? 'add' : 'remove'
1610
- ]('monospace-messages');
1611
- }
1612
- },{
1613
- label: "Chat-only mode",
1614
- hint: "Toggle the page between normal fossil view and chat-only view.",
1615
- boolValue: 'chat-only-mode'
1616
- },{
1617
- label: "Show images inline",
1618
- hint: "Whether to show images inline or as a hyperlink.",
1619
- boolValue: 'images-inline'
1620
- },namedOptions.activeUsers,{
1621
- label: "Timestamps in active users list",
1622
- hint: "Whether to show last-message timestamps.",
1623
- boolValue: 'active-user-list-timestamps'
1663
+ label: "Chat Configuration Options",
1664
+ hint: F.storage.isTransient()
1665
+ ? "Local store is unavailable. These settings are transient."
1666
+ : ["Most of these settings are persistent via ",
1667
+ F.storage.storageImplName(), ": ",
1668
+ F.storage.storageHelpDescription()].join('')
1669
+ },{
1670
+ label: "Editing Options...",
1671
+ children:[{
1672
+ label: "Chat-only mode",
1673
+ hint: "Toggle the page between normal fossil view and chat-only view.",
1674
+ boolValue: 'chat-only-mode'
1675
+ },{
1676
+ label: "Ctrl-enter to Send",
1677
+ hint: [
1678
+ "When on, only Ctrl-Enter will send messages and Enter adds ",
1679
+ "blank lines. When off, both Enter and Ctrl-Enter send. ",
1680
+ "When the input field has focus and is empty ",
1681
+ "then Ctrl-Enter toggles this setting."
1682
+ ].join(''),
1683
+ boolValue: 'edit-ctrl-send'
1684
+ },{
1685
+ label: "Compact mode",
1686
+ hint: [
1687
+ "Toggle between a space-saving or more spacious writing area. ",
1688
+ "When the input field has focus, is empty, and preview mode ",
1689
+ "is NOT active then Shift-Enter toggles this setting."].join(''),
1690
+ boolValue: 'edit-compact-mode'
1691
+ },{
1692
+ label: "Use 'contenteditable' editing mode",
1693
+ boolValue: 'edit-widget-x',
1694
+ hint: [
1695
+ "When enabled, chat input uses a so-called 'contenteditable' ",
1696
+ "field. Though generally more comfortable and modern than ",
1697
+ "plain-text input fields, browser-specific quirks and bugs ",
1698
+ "may lead to frustration. Ideal for mobile devices."
1699
+ ].join('')
1700
+ }]
1701
+ },{
1702
+ label: "Appearance Options...",
1703
+ children:[{
1704
+ label: "Left-align my posts",
1705
+ hint: "Default alignment of your own messages is selected "
1706
+ + "based window width/height ratio.",
1707
+ boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1708
+ callback: function f(){
1709
+ document.body.classList[
1710
+ this.checkbox.checked ? 'remove' : 'add'
1711
+ ]('my-messages-right');
1712
+ }
1713
+ },{
1714
+ label: "Monospace message font",
1715
+ hint: "Use monospace font for message and input text.",
1716
+ boolValue: 'monospace-messages',
1717
+ callback: function(setting){
1718
+ document.body.classList[
1719
+ setting.value ? 'add' : 'remove'
1720
+ ]('monospace-messages');
1721
+ }
1722
+ },{
1723
+ label: "Show images inline",
1724
+ hint: "When enabled, attached images are shown inline, "+
1725
+ "else they appear as a download link.",
1726
+ boolValue: 'images-inline'
1727
+ }]
16241728
}];
16251729
16261730
/** Set up selection list of notification sounds. */
16271731
if(1){
16281732
const selectSound = D.select();
@@ -1641,45 +1745,64 @@
16411745
selectSound.selectedIndex = firstSoundIndex;
16421746
}
16431747
}
16441748
Chat.setNewMessageSound(selectSound.value);
16451749
settingsOps.push({
1646
- hint: "Audio alert. How to enable audio playback is browser-specific!",
1647
- select: selectSound,
1648
- callback: function(ev){
1649
- const v = ev.target.value;
1650
- Chat.setNewMessageSound(v);
1651
- F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1652
- if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1653
- }
1750
+ label: "Sound Options...",
1751
+ hint: "How to enable audio playback is browser-specific!",
1752
+ children:[{
1753
+ hint: "Audio alert",
1754
+ select: selectSound,
1755
+ callback: function(ev){
1756
+ const v = ev.target.value;
1757
+ Chat.setNewMessageSound(v);
1758
+ F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1759
+ if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1760
+ }
1761
+ },{
1762
+ label: "Play notification for your own messages",
1763
+ hint: "When enabled, the audio notification will be played for all messages, "+
1764
+ "including your own. When disabled only messages from other users "+
1765
+ "will trigger a notification.",
1766
+ boolValue: 'alert-own-messages'
1767
+ }]
16541768
});
16551769
}/*audio notification config*/
16561770
settingsOps.push({
1657
- label: "Play notification for your own messages.",
1658
- hint: "When enabled, the audio notification will be played for all messages, "+
1659
- "including your own. When disabled only messages from other users "+
1660
- "will trigger a notification.",
1661
- boolValue: 'alert-own-messages'
1771
+ label: "Active User List...",
1772
+ hint: [
1773
+ "/chat cannot track active connections, but it can tell ",
1774
+ "you who has posted recently..."].join(''),
1775
+ children:[
1776
+ namedOptions.activeUsers,{
1777
+ label: "Timestamps in active users list",
1778
+ indent: true,
1779
+ hint: "Show most recent message timestamps in the active user list.",
1780
+ boolValue: 'active-user-list-timestamps'
1781
+ }
1782
+ ]
16621783
});
16631784
/**
16641785
Build UI for config options...
16651786
*/
1666
- settingsOps.forEach(function f(op){
1667
- const line = D.addClass(D.div(), 'menu-entry');
1787
+ settingsOps.forEach(function f(op,indentOrIndex){
1788
+ const menuEntry = D.addClass(D.div(), 'menu-entry');
1789
+ if(true===indentOrIndex) D.addClass(menuEntry, 'child');
16681790
const label = op.label
16691791
? D.append(D.label(),op.label) : undefined;
16701792
const labelWrapper = D.addClass(D.div(), 'label-wrapper');
16711793
var hint;
1672
- const col0 = D.span();
16731794
if(op.hint){
1674
- hint = D.append(D.addClass(D.span(),'hint'),op.hint);
1795
+ hint = D.append(D.addClass(D.label(),'hint'),op.hint);
16751796
}
16761797
if(op.hasOwnProperty('select')){
1677
- D.append(line, col0, labelWrapper);
1798
+ const col0 = D.addClass(D.span(/*empty, but for spacing*/),
1799
+ 'toggle-wrapper');
1800
+ D.append(menuEntry, labelWrapper, col0);
16781801
D.append(labelWrapper, op.select);
16791802
if(hint) D.append(labelWrapper, hint);
1680
- if(label) D.append(col0, label);
1803
+ if(label) D.append(label);
16811804
if(op.callback){
16821805
op.select.addEventListener('change', (ev)=>op.callback(ev), false);
16831806
}
16841807
}else if(op.hasOwnProperty('boolValue')){
16851808
if(undefined === f.$id) f.$id = 0;
@@ -1691,27 +1814,31 @@
16911814
}
16921815
const check = op.checkbox
16931816
= D.attr(D.checkbox(1, op.boolValue()),
16941817
'aria-label', op.label);
16951818
const id = 'cfgopt'+f.$id;
1819
+ const col0 = D.addClass(D.span(), 'toggle-wrapper');
16961820
check.checked = op.boolValue();
16971821
op.checkbox = check;
16981822
D.attr(check, 'id', id);
1699
- D.append(line, col0, labelWrapper);
1823
+ if(hint) D.attr(hint, 'for', id);
1824
+ D.append(menuEntry, labelWrapper, col0);
17001825
D.append(col0, check);
17011826
if(label){
17021827
D.attr(label, 'for', id);
17031828
D.append(labelWrapper, label);
17041829
}
17051830
if(hint) D.append(labelWrapper, hint);
17061831
}else{
1707
- line.addEventListener('click', callback);
1708
- D.append(line, col0, labelWrapper);
1832
+ if(op.callback){
1833
+ menuEntry.addEventListener('click', (ev)=>op.callback(ev));
1834
+ }
1835
+ D.append(menuEntry, labelWrapper);
17091836
if(label) D.append(labelWrapper, label);
17101837
if(hint) D.append(labelWrapper, hint);
17111838
}
1712
- D.append(optionsMenu, line);
1839
+ D.append(optionsMenu, menuEntry);
17131840
if(op.persistentSetting){
17141841
Chat.settings.addListener(
17151842
op.persistentSetting,
17161843
function(setting){
17171844
if(op.checkbox) op.checkbox.checked = !!setting.value;
@@ -1726,10 +1853,14 @@
17261853
}, false);
17271854
}
17281855
}else if(op.callback && op.checkbox){
17291856
op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false);
17301857
}
1858
+ if(op.children){
1859
+ D.addClass(menuEntry, 'parent');
1860
+ op.children.forEach((x)=>f(x,true));
1861
+ }
17311862
});
17321863
})()/*#chat-button-settings setup*/;
17331864
17341865
(function(){
17351866
/* Install default settings... must come after
@@ -1745,20 +1876,58 @@
17451876
Chat.settings.addListener('active-user-list-timestamps',function(s){
17461877
Chat.showActiveUserTimestamps(s.value);
17471878
});
17481879
Chat.settings.addListener('chat-only-mode',function(s){
17491880
Chat.chatOnlyMode(s.value);
1881
+ });
1882
+ Chat.settings.addListener('edit-widget-x',function(s){
1883
+ let eSelected;
1884
+ if(s.value){
1885
+ if(Chat.e.inputX===Chat.inputElement()) return;
1886
+ eSelected = Chat.e.inputX;
1887
+ }else{
1888
+ eSelected = Chat.settings.getBool('edit-compact-mode')
1889
+ ? Chat.e.input1 : Chat.e.inputM;
1890
+ }
1891
+ const v = Chat.inputValue();
1892
+ Chat.inputValue('');
1893
+ Chat.e.inputFields.forEach(function(e,ndx){
1894
+ if(eSelected===e){
1895
+ Chat.e.inputFields.$currentIndex = ndx;
1896
+ D.removeClass(e, 'hidden');
1897
+ }
1898
+ else D.addClass(e,'hidden');
1899
+ });
1900
+ Chat.inputValue(v);
1901
+ eSelected.focus();
17501902
});
17511903
Chat.settings.addListener('edit-compact-mode',function(s){
1752
- Chat.e.inputLine.classList[
1904
+ if(Chat.e.inputX!==Chat.inputElement()){
1905
+ /* Text field/textarea mode: swap them if needed.
1906
+ Compact mode of inputX is toggled via CSS. */
1907
+ const a = s.value
1908
+ ? [Chat.e.input1, Chat.e.inputM, 0]
1909
+ : [Chat.e.inputM, Chat.e.input1, 1];
1910
+ const v = Chat.inputValue();
1911
+ Chat.inputValue('');
1912
+ Chat.e.inputFields.$currentIndex = a[2];
1913
+ Chat.inputValue(v);
1914
+ D.removeClass(a[0], 'hidden');
1915
+ D.addClass(a[1], 'hidden');
1916
+ }
1917
+ Chat.e.inputElementWrapper.classList[
17531918
s.value ? 'add' : 'remove'
17541919
]('compact');
1920
+ Chat.e.inputFields[Chat.e.inputFields.$currentIndex].focus();
17551921
});
17561922
Chat.settings.addListener('edit-ctrl-send',function(s){
17571923
const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1758
- const eInput = Chat.inputElement();
1759
- eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
1924
+ Chat.e.inputFields.forEach((e)=>{
1925
+ const v = e.dataset.placeholder0 + " " +label;
1926
+ if(e.isContentEditable) e.dataset.placeholder = v;
1927
+ else D.attr(e,'placeholder',v);
1928
+ });
17601929
Chat.e.btnSubmit.title = label;
17611930
});
17621931
const valueKludges = {
17631932
/* Convert certain string-format values to other types... */
17641933
"false": false,
@@ -1784,11 +1953,11 @@
17841953
this.inputFocus();
17851954
};
17861955
Chat.e.viewPreview.querySelector('#chat-preview-close').
17871956
addEventListener('click', ()=>Chat.setCurrentView(Chat.e.viewMessages), false);
17881957
let previewPending = false;
1789
- const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputField];
1958
+ const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputFields];
17901959
const submit = function(ev){
17911960
ev.preventDefault();
17921961
ev.stopPropagation();
17931962
if(previewPending) return false;
17941963
const txt = Chat.inputValue();
17951964
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -43,10 +43,11 @@
43 const iso8601ish = function(d){
44 return d.toISOString()
45 .replace('T',' ').replace(/\.\d+/,'')
46 .replace('Z', ' zulu');
47 };
 
48 /** Returns the local time string of Date object d, defaulting
49 to the current time. */
50 const localTimeString = function ff(d){
51 d || (d = new Date());
52 return [
@@ -93,11 +94,11 @@
93 ht = wh;
94 }else{
95 elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
96 ht = wh - extra;
97 }
98 f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99 /* ^^^^ this is a middle ground between having no size cap
100 on the input field and having a fixed arbitrary cap. */;
101 contentArea.style.height =
102 contentArea.style.maxHeight = [
103 "calc(", (ht>=100 ? ht : 100), "px",
@@ -109,21 +110,17 @@
109 if(false){
110 console.debug("resized.",wh, extra, ht,
111 window.getComputedStyle(contentArea).maxHeight,
112 contentArea);
113 console.debug("Set input max height to: ",
114 f.chat.e.inputField.style.maxHeight);
115 }
116 };
117 var doit;
118 window.addEventListener('resize',function(ev){
119 clearTimeout(doit);
120 doit = setTimeout(resized, 100);
121 }, false);
122 return resized;
123 })();
124 ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
125 fossil.FRK = ForceResizeKludge/*for debugging*/;
126 const Chat = ForceResizeKludge.chat = (function(){
127 const cs = {
128 verboseErrors: false /* if true then certain, mostly extraneous,
129 error messages may be sent to the console. */,
@@ -130,16 +127,18 @@
130 e:{/*map of certain DOM elements.*/
131 messageInjectPoint: E1('#message-inject-point'),
132 pageTitle: E1('head title'),
133 loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */,
134 inputWrapper: E1("#chat-input-area"),
135 inputLine: E1('#chat-input-line'),
136 fileSelectWrapper: E1('#chat-input-file-area'),
137 viewMessages: E1('#chat-messages-wrapper'),
138 btnSubmit: E1('#chat-button-submit'),
139 btnAttach: E1('#chat-button-attach'),
140 inputField: E1('#chat-input-field'),
 
 
141 inputFile: E1('#chat-input-file'),
142 contentDiv: E1('div.content'),
143 viewConfig: E1('#chat-config'),
144 viewPreview: E1('#chat-preview'),
145 previewContent: E1('#chat-preview-content'),
@@ -192,23 +191,24 @@
192 taking into account single- vs multi-line input. The getter returns
193 a string and the setter returns this object. */
194 inputValue: function(){
195 const e = this.inputElement();
196 if(arguments.length){
197 e.innerText = arguments[0];
 
198 return this;
199 }
200 return e.innerText;
201 },
202 /** Asks the current user input field to take focus. Returns this. */
203 inputFocus: function(){
204 this.inputElement().focus();
205 return this;
206 },
207 /** Returns the current message input element. */
208 inputElement: function(){
209 return this.e.inputField;
210 },
211 /** Enables (if yes is truthy) or disables all elements in
212 * this.disableDuringAjax. */
213 enableAjaxComponents: function(yes){
214 D[yes ? 'enable' : 'disable'](this.disableDuringAjax);
@@ -415,11 +415,11 @@
415 laid out in a compact form. When off, the edit field and
416 buttons are larger. */
417 "edit-compact-mode": true,
418 /* When on, sets the font-family on messages and the edit
419 field to monospace. */
420 "monospace-messages": true,
421 /* When on, non-chat UI elements (page header/footer) are
422 hidden */
423 "chat-only-mode": false,
424 /* When set to a URI, it is assumed to be an audio file,
425 which gets played when new messages arrive. When true,
@@ -434,11 +434,17 @@
434 timestamp of each user's most recent message. */
435 "active-user-list-timestamps": false,
436 /* When on, the [audible-alert] is played for one's own
437 messages, else it is only played for other users'
438 messages. */
439 "alert-own-messages": false
 
 
 
 
 
 
440 }
441 },
442 /** Plays a new-message notification sound IF the audible-alert
443 setting is true, else this is a no-op. Returns this.
444 */
@@ -672,16 +678,22 @@
672 D.addClassBriefly(e, a, 0, cb);
673 }
674 return this;
675 }
676 };
677 if(D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){
 
 
 
 
 
 
678 cs.$browserHasPlaintextOnly = true;
679 }else{
680 /* Only the Chrome family supports contenteditable=plaintext-only */
681 cs.$browserHasPlaintextOnly = false;
682 D.attr(cs.e.inputField,'contenteditable','true');
683 }
684 cs.animate.$disabled = true;
685 F.fetch.beforesend = ()=>cs.ajaxStart();
686 F.fetch.aftersend = ()=>cs.ajaxEnd();
687 cs.pageTitleOrig = cs.e.pageTitle.innerText;
@@ -702,18 +714,21 @@
702 Reports an error in the form of a new message in the chat
703 feed. All arguments are appended to the message's content area
704 using fossil.dom.append(), so may be of any type supported by
705 that function.
706 */
707 cs.reportErrorAsMessage = function(/*msg args*/){
708 const args = argsToArray(arguments);
 
 
 
709 console.error("chat error:",args);
710 const d = new Date().toISOString(),
711 mw = new this.MessageWidget({
712 isError: true,
713 xfrom: null,
714 msgid: -1,
715 mtime: d,
716 lmtime: d,
717 xmsg: args
718 });
719 this.injectMessageElem(mw.e.body);
@@ -873,10 +888,20 @@
873 };
874 document.addEventListener('visibilitychange', function(ev){
875 cs.pageIsActive = ('visible' === document.visibilityState);
876 if(cs.pageIsActive){
877 cs.e.pageTitle.innerText = cs.pageTitleOrig;
 
 
 
 
 
 
 
 
 
 
878 }
879 }, true);
880 cs.setCurrentView(cs.e.viewMessages);
881
882 cs.e.activeUserList.addEventListener('click', function f(ev){
@@ -989,10 +1014,19 @@
989 })
990 elem.querySelectorAll('[data-numtag]').forEach(
991 (e)=>e.addEventListener('click', f.$clickNum, false)
992 )
993 }/*setupHashtags()*/;
 
 
 
 
 
 
 
 
 
994
995 /**
996 Custom widget type for rendering messages (one message per
997 instance). These are modelled after FIELDSET elements but we
998 don't use FIELDSET because of cross-browser inconsistencies in
@@ -1016,11 +1050,10 @@
1016 if(arguments.length){
1017 this.setMessage(arguments[0]);
1018 }
1019 };
1020 /* Left-zero-pad a number to at least 2 digits */
1021 const pad2 = (x)=>(''+x).length>1 ? x : '0'+x;
1022 const dowMap = {
1023 /* Map of Date.getDay() values to weekday names. */
1024 0: "Sunday", 1: "Monday", 2: "Tuesday",
1025 3: "Wednesday", 4: "Thursday", 5: "Friday",
1026 6: "Saturday"
@@ -1034,10 +1067,11 @@
1034 d.getHours(),":",
1035 (d.getMinutes()+100).toString().slice(1,3),
1036 ' ', dowMap[d.getDay()]
1037 ].join('');
1038 };
 
1039 cf.prototype = {
1040 scrollIntoView: function(){
1041 this.e.content.scrollIntoView();
1042 },
1043 setMessage: function(m){
@@ -1068,11 +1102,11 @@
1068 if(m.isError){
1069 D.addClass([contentTarget, this.e.tab], 'error');
1070 }
1071 D.append(
1072 this.e.tab,
1073 D.text('notification @ ',theTime(d))
1074 );
1075 }
1076 if( m.xfrom && m.fsize>0 ){
1077 if( m.fmime
1078 && m.fmime.startsWith("image/")
@@ -1105,11 +1139,11 @@
1105 // hyperlinks, but otherwise it will be markup-free. See the
1106 // chat_format_to_html() routine in the server for details.
1107 //
1108 // Hence, even though innerHTML is normally frowned upon, it is
1109 // perfectly safe to use in this context.
1110 if(m.xmsg instanceof Array){
1111 // Used by Chat.reportErrorAsMessage()
1112 D.append(contentTarget, m.xmsg);
1113 }else{
1114 contentTarget.innerHTML = m.xmsg;
1115 contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
@@ -1117,10 +1151,12 @@
1117 if(F.pikchr){
1118 F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
1119 }
1120 }
1121 }
 
 
1122 this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false);
1123 /*if(eXFrom){
1124 eXFrom.addEventListener('click', ()=>this.e.tab.click(), false);
1125 }*/
1126 return this;
@@ -1249,14 +1285,11 @@
1249 this.$eMsg = tgtMsg;
1250 this.refresh();
1251 }
1252 }/*f.popup*/;
1253 }/*end static init*/
1254 let theMsg = ev.target;
1255 while( theMsg && !theMsg.classList.contains('message-widget')){
1256 theMsg = theMsg.parentNode;
1257 }
1258 if(theMsg) f.popup.show(theMsg);
1259 }/*_handleLegendClicked()*/
1260 }/*MessageWidget.prototype*/;
1261 /** Assumes that e is a MessageWidget element, ensures that
1262 Chat.e.viewMessages is visible, scrolls the message,
@@ -1283,11 +1316,11 @@
1283 }
1284 };
1285 /** Updates the paste/drop zone with details of the pasted/dropped
1286 data. The argument must be a Blob or Blob-like object (File) or
1287 it can be falsy to reset/clear that state.*/
1288 const updateDropZoneContent = function(blob){
1289 //console.debug("updateDropZoneContent()",blob);
1290 const dd = bxs.dropDetails;
1291 bxs.blob = blob;
1292 D.clearElement(dd);
1293 if(!blob){
@@ -1332,11 +1365,11 @@
1332 /* Acrobatics to keep *some* installations of Firefox
1333 from pasting formatting into contenteditable fields.
1334 This also works on Chrome, but chrome has the
1335 contenteditable=plaintext-only property which does this
1336 for us. */
1337 Chat.inputElement().addEventListener(
1338 'paste',
1339 function(ev){
1340 if (ev.clipboardData && ev.clipboardData.getData) {
1341 const pastedText = ev.clipboardData.getData('text/plain');
1342 const selection = window.getSelection();
@@ -1356,30 +1389,60 @@
1356 ev.dataTransfer.dropEffect = 'none';
1357 ev.preventDefault();
1358 ev.stopPropagation();
1359 return false;
1360 };
1361
1362 ['drop','dragenter','dragleave','dragend'].forEach(
1363 (k)=>{
1364 Chat.inputElement().addEventListener(k, noDragDropEvents, false);
1365 }
1366 );
1367 return bxs;
1368 })()/*drag/drop/paste*/;
1369
1370 const tzOffsetToString = function(off){
1371 const hours = Math.round(off/60), min = Math.round(off % 30);
1372 return ''+(hours + (min ? '.5' : ''));
1373 };
1374 const pad2 = (x)=>('0'+x).substr(-2);
1375 const localTime8601 = function(d){
1376 return [
1377 d.getYear()+1900, '-', pad2(d.getMonth()+1), '-', pad2(d.getDate()),
1378 'T', pad2(d.getHours()),':', pad2(d.getMinutes()),':',pad2(d.getSeconds())
1379 ].join('');
1380 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1381
1382 /**
1383 Submits the contents of the message input field (if not empty)
1384 and/or the file attachment field to the server. If both are
1385 empty, this is a no-op.
@@ -1389,11 +1452,12 @@
1389 f.spaces = /\s+$/;
1390 f.markdownContinuation = /\\\s+$/;
1391 }
1392 this.setCurrentView(this.e.viewMessages);
1393 const fd = new FormData();
1394 var msg = this.inputValue().trim();
 
1395 if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1396 /* Cosmetic: trim whitespace from the ends of lines to try to
1397 keep copy/paste from terminals, especially wide ones, from
1398 forcing a horizontal scrollbar on all clients. This breaks
1399 markdown's use of blackslash-space-space for paragraph
@@ -1412,25 +1476,29 @@
1412 }
1413 if(msg) fd.set('msg',msg);
1414 const file = BlobXferState.blob || this.e.inputFile.files[0];
1415 if(file) fd.set("file", file);
1416 if( !msg && !file ) return;
 
1417 const self = this;
1418 fd.set("lmtime", localTime8601(new Date()));
1419 F.fetch("chat-send",{
1420 payload: fd,
1421 responseType: 'text',
1422 onerror:(err)=>this.reportErrorAsMessage(err),
 
 
 
1423 onload:function(txt){
1424 if(!txt) return/*success response*/;
1425 try{
1426 const json = JSON.parse(txt);
1427 self.newContent({msgs:[json]});
1428 }catch(e){
1429 self.reportError(e);
1430 return;
1431 }
 
1432 }
1433 });
1434 BlobXferState.clear();
1435 Chat.inputValue("").inputFocus();
1436 };
@@ -1494,11 +1562,13 @@
1494 ev.stopPropagation();
1495 Chat.submitMessage();
1496 return false;
1497 }
1498 };
1499 Chat.e.inputField.addEventListener('keydown', inputWidgetKeydown, false);
 
 
1500 Chat.e.btnSubmit.addEventListener('click',(e)=>{
1501 e.preventDefault();
1502 Chat.submitMessage();
1503 return false;
1504 });
@@ -1553,76 +1623,110 @@
1553 Settings options structure: an array of Objects with the
1554 following properties:
1555
1556 label: string for the UI
1557
1558 boolValue: string (name of Chat.settings setting) or a
1559 function which returns true or false. Gets mapped to
1560 a checkbox.
 
 
1561
1562 select: SELECT element (instead of boolValue)
1563
1564 callback: optional handler to call after setting is modified.
1565 It gets passed the setting object: {key:string, value:something}.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1566
1567 If a setting has a boolValue set, that gets transformed into a
1568 checkbox which toggles the given persistent setting (if
1569 boolValue is a string) AND listens for changes to that setting
1570 fired via Chat.settings.set() so that the checkbox can stay in
1571 sync with external changes to that setting. Various Chat UI
1572 elements stay in sync with the config UI via those settings
1573 events.
 
1574 */
1575 const settingsOps = [{
1576 label: "Ctrl-enter to Send",
1577 hint: [
1578 "When on, only Ctrl-Enter will send messages and Enter adds ",
1579 "blank lines. ",
1580 "When off, both Enter and Ctrl-Enter send. ",
1581 "When the input field has focus, is empty, and preview ",
1582 "mode is NOT active then Ctrl-Enter toggles this setting."
1583 ].join(''),
1584 boolValue: 'edit-ctrl-send'
1585 },{
1586 label: "Compact mode",
1587 hint: [
1588 "Toggle between a space-saving or more spacious writing area. ",
1589 "When the input field has focus, is empty, and preview mode ",
1590 "is NOT active then Shift-Enter toggles this setting."
1591 ].join(''),
1592 boolValue: 'edit-compact-mode'
1593 },{
1594 label: "Left-align my posts",
1595 hint: "Default alignment of your own messages is selected "
1596 +"based window width/height relationship.",
1597 boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1598 callback: function f(){
1599 document.body.classList[
1600 this.checkbox.checked ? 'remove' : 'add'
1601 ]('my-messages-right');
1602 }
1603 },{
1604 label: "Monospace message font",
1605 hint: "Use monospace font for message text?",
1606 boolValue: 'monospace-messages',
1607 callback: function(setting){
1608 document.body.classList[
1609 setting.value ? 'add' : 'remove'
1610 ]('monospace-messages');
1611 }
1612 },{
1613 label: "Chat-only mode",
1614 hint: "Toggle the page between normal fossil view and chat-only view.",
1615 boolValue: 'chat-only-mode'
1616 },{
1617 label: "Show images inline",
1618 hint: "Whether to show images inline or as a hyperlink.",
1619 boolValue: 'images-inline'
1620 },namedOptions.activeUsers,{
1621 label: "Timestamps in active users list",
1622 hint: "Whether to show last-message timestamps.",
1623 boolValue: 'active-user-list-timestamps'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1624 }];
1625
1626 /** Set up selection list of notification sounds. */
1627 if(1){
1628 const selectSound = D.select();
@@ -1641,45 +1745,64 @@
1641 selectSound.selectedIndex = firstSoundIndex;
1642 }
1643 }
1644 Chat.setNewMessageSound(selectSound.value);
1645 settingsOps.push({
1646 hint: "Audio alert. How to enable audio playback is browser-specific!",
1647 select: selectSound,
1648 callback: function(ev){
1649 const v = ev.target.value;
1650 Chat.setNewMessageSound(v);
1651 F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1652 if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1653 }
 
 
 
 
 
 
 
 
 
 
1654 });
1655 }/*audio notification config*/
1656 settingsOps.push({
1657 label: "Play notification for your own messages.",
1658 hint: "When enabled, the audio notification will be played for all messages, "+
1659 "including your own. When disabled only messages from other users "+
1660 "will trigger a notification.",
1661 boolValue: 'alert-own-messages'
 
 
 
 
 
 
 
1662 });
1663 /**
1664 Build UI for config options...
1665 */
1666 settingsOps.forEach(function f(op){
1667 const line = D.addClass(D.div(), 'menu-entry');
 
1668 const label = op.label
1669 ? D.append(D.label(),op.label) : undefined;
1670 const labelWrapper = D.addClass(D.div(), 'label-wrapper');
1671 var hint;
1672 const col0 = D.span();
1673 if(op.hint){
1674 hint = D.append(D.addClass(D.span(),'hint'),op.hint);
1675 }
1676 if(op.hasOwnProperty('select')){
1677 D.append(line, col0, labelWrapper);
 
 
1678 D.append(labelWrapper, op.select);
1679 if(hint) D.append(labelWrapper, hint);
1680 if(label) D.append(col0, label);
1681 if(op.callback){
1682 op.select.addEventListener('change', (ev)=>op.callback(ev), false);
1683 }
1684 }else if(op.hasOwnProperty('boolValue')){
1685 if(undefined === f.$id) f.$id = 0;
@@ -1691,27 +1814,31 @@
1691 }
1692 const check = op.checkbox
1693 = D.attr(D.checkbox(1, op.boolValue()),
1694 'aria-label', op.label);
1695 const id = 'cfgopt'+f.$id;
 
1696 check.checked = op.boolValue();
1697 op.checkbox = check;
1698 D.attr(check, 'id', id);
1699 D.append(line, col0, labelWrapper);
 
1700 D.append(col0, check);
1701 if(label){
1702 D.attr(label, 'for', id);
1703 D.append(labelWrapper, label);
1704 }
1705 if(hint) D.append(labelWrapper, hint);
1706 }else{
1707 line.addEventListener('click', callback);
1708 D.append(line, col0, labelWrapper);
 
 
1709 if(label) D.append(labelWrapper, label);
1710 if(hint) D.append(labelWrapper, hint);
1711 }
1712 D.append(optionsMenu, line);
1713 if(op.persistentSetting){
1714 Chat.settings.addListener(
1715 op.persistentSetting,
1716 function(setting){
1717 if(op.checkbox) op.checkbox.checked = !!setting.value;
@@ -1726,10 +1853,14 @@
1726 }, false);
1727 }
1728 }else if(op.callback && op.checkbox){
1729 op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false);
1730 }
 
 
 
 
1731 });
1732 })()/*#chat-button-settings setup*/;
1733
1734 (function(){
1735 /* Install default settings... must come after
@@ -1745,20 +1876,58 @@
1745 Chat.settings.addListener('active-user-list-timestamps',function(s){
1746 Chat.showActiveUserTimestamps(s.value);
1747 });
1748 Chat.settings.addListener('chat-only-mode',function(s){
1749 Chat.chatOnlyMode(s.value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1750 });
1751 Chat.settings.addListener('edit-compact-mode',function(s){
1752 Chat.e.inputLine.classList[
 
 
 
 
 
 
 
 
 
 
 
 
 
1753 s.value ? 'add' : 'remove'
1754 ]('compact');
 
1755 });
1756 Chat.settings.addListener('edit-ctrl-send',function(s){
1757 const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1758 const eInput = Chat.inputElement();
1759 eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
 
 
 
1760 Chat.e.btnSubmit.title = label;
1761 });
1762 const valueKludges = {
1763 /* Convert certain string-format values to other types... */
1764 "false": false,
@@ -1784,11 +1953,11 @@
1784 this.inputFocus();
1785 };
1786 Chat.e.viewPreview.querySelector('#chat-preview-close').
1787 addEventListener('click', ()=>Chat.setCurrentView(Chat.e.viewMessages), false);
1788 let previewPending = false;
1789 const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputField];
1790 const submit = function(ev){
1791 ev.preventDefault();
1792 ev.stopPropagation();
1793 if(previewPending) return false;
1794 const txt = Chat.inputValue();
1795
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -43,10 +43,11 @@
43 const iso8601ish = function(d){
44 return d.toISOString()
45 .replace('T',' ').replace(/\.\d+/,'')
46 .replace('Z', ' zulu');
47 };
48 const pad2 = (x)=>('0'+x).substr(-2);
49 /** Returns the local time string of Date object d, defaulting
50 to the current time. */
51 const localTimeString = function ff(d){
52 d || (d = new Date());
53 return [
@@ -93,11 +94,11 @@
94 ht = wh;
95 }else{
96 elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
97 ht = wh - extra;
98 }
99 f.chat.e.inputX.style.maxHeight = (ht/2)+"px";
100 /* ^^^^ this is a middle ground between having no size cap
101 on the input field and having a fixed arbitrary cap. */;
102 contentArea.style.height =
103 contentArea.style.maxHeight = [
104 "calc(", (ht>=100 ? ht : 100), "px",
@@ -109,21 +110,17 @@
110 if(false){
111 console.debug("resized.",wh, extra, ht,
112 window.getComputedStyle(contentArea).maxHeight,
113 contentArea);
114 console.debug("Set input max height to: ",
115 f.chat.e.inputX.style.maxHeight);
116 }
117 };
118 resized.$disabled = true/*gets deleted when setup is finished*/;
119 window.addEventListener('resize', F.debounce(resized, 250), false);
 
 
 
120 return resized;
121 })();
 
122 fossil.FRK = ForceResizeKludge/*for debugging*/;
123 const Chat = ForceResizeKludge.chat = (function(){
124 const cs = {
125 verboseErrors: false /* if true then certain, mostly extraneous,
126 error messages may be sent to the console. */,
@@ -130,16 +127,18 @@
127 e:{/*map of certain DOM elements.*/
128 messageInjectPoint: E1('#message-inject-point'),
129 pageTitle: E1('head title'),
130 loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */,
131 inputWrapper: E1("#chat-input-area"),
132 inputElementWrapper: E1('#chat-input-line-wrapper'),
133 fileSelectWrapper: E1('#chat-input-file-area'),
134 viewMessages: E1('#chat-messages-wrapper'),
135 btnSubmit: E1('#chat-button-submit'),
136 btnAttach: E1('#chat-button-attach'),
137 inputX: E1('#chat-input-field-x'),
138 input1: E1('#chat-input-field-single'),
139 inputM: E1('#chat-input-field-multi'),
140 inputFile: E1('#chat-input-file'),
141 contentDiv: E1('div.content'),
142 viewConfig: E1('#chat-config'),
143 viewPreview: E1('#chat-preview'),
144 previewContent: E1('#chat-preview-content'),
@@ -192,23 +191,24 @@
191 taking into account single- vs multi-line input. The getter returns
192 a string and the setter returns this object. */
193 inputValue: function(){
194 const e = this.inputElement();
195 if(arguments.length){
196 if(e.isContentEditable) e.innerText = arguments[0];
197 else e.value = arguments[0];
198 return this;
199 }
200 return e.isContentEditable ? e.innerText : e.value;
201 },
202 /** Asks the current user input field to take focus. Returns this. */
203 inputFocus: function(){
204 this.inputElement().focus();
205 return this;
206 },
207 /** Returns the current message input element. */
208 inputElement: function(){
209 return this.e.inputFields[this.e.inputFields.$currentIndex];
210 },
211 /** Enables (if yes is truthy) or disables all elements in
212 * this.disableDuringAjax. */
213 enableAjaxComponents: function(yes){
214 D[yes ? 'enable' : 'disable'](this.disableDuringAjax);
@@ -415,11 +415,11 @@
415 laid out in a compact form. When off, the edit field and
416 buttons are larger. */
417 "edit-compact-mode": true,
418 /* When on, sets the font-family on messages and the edit
419 field to monospace. */
420 "monospace-messages": false,
421 /* When on, non-chat UI elements (page header/footer) are
422 hidden */
423 "chat-only-mode": false,
424 /* When set to a URI, it is assumed to be an audio file,
425 which gets played when new messages arrive. When true,
@@ -434,11 +434,17 @@
434 timestamp of each user's most recent message. */
435 "active-user-list-timestamps": false,
436 /* When on, the [audible-alert] is played for one's own
437 messages, else it is only played for other users'
438 messages. */
439 "alert-own-messages": false,
440 /* "Experimental mode" input: use a contenteditable field
441 for input. This is generally more comfortable to use,
442 and more modern, than plain text input fields, but
443 the list of browser-specific quirks and bugs is...
444 not short. */
445 "edit-widget-x": false
446 }
447 },
448 /** Plays a new-message notification sound IF the audible-alert
449 setting is true, else this is a no-op. Returns this.
450 */
@@ -672,16 +678,22 @@
678 D.addClassBriefly(e, a, 0, cb);
679 }
680 return this;
681 }
682 };
683 cs.e.inputFields = [ cs.e.input1, cs.e.inputM, cs.e.inputX ];
684 cs.e.inputFields.$currentIndex = 0;
685 cs.e.inputFields.forEach(function(e,ndx){
686 if(ndx===cs.e.inputFields.$currentIndex) D.removeClass(e,'hidden');
687 else D.addClass(e,'hidden');
688 });
689 if(D.attr(cs.e.inputX,'contenteditable','plaintext-only').isContentEditable){
690 cs.$browserHasPlaintextOnly = true;
691 }else{
692 /* Only the Chrome family supports contenteditable=plaintext-only */
693 cs.$browserHasPlaintextOnly = false;
694 D.attr(cs.e.inputX,'contenteditable','true');
695 }
696 cs.animate.$disabled = true;
697 F.fetch.beforesend = ()=>cs.ajaxStart();
698 F.fetch.aftersend = ()=>cs.ajaxEnd();
699 cs.pageTitleOrig = cs.e.pageTitle.innerText;
@@ -702,18 +714,21 @@
714 Reports an error in the form of a new message in the chat
715 feed. All arguments are appended to the message's content area
716 using fossil.dom.append(), so may be of any type supported by
717 that function.
718 */
719 cs.reportErrorAsMessage = function f(/*msg args*/){
720 if(undefined === f.$msgid) f.$msgid=0;
721 const args = argsToArray(arguments).map(function(v){
722 return (v instanceof Error) ? v.message : v;
723 });
724 console.error("chat error:",args);
725 const d = new Date().toISOString(),
726 mw = new this.MessageWidget({
727 isError: true,
728 xfrom: null,
729 msgid: "error-"+(++f.$msgid),
730 mtime: d,
731 lmtime: d,
732 xmsg: args
733 });
734 this.injectMessageElem(mw.e.body);
@@ -873,10 +888,20 @@
888 };
889 document.addEventListener('visibilitychange', function(ev){
890 cs.pageIsActive = ('visible' === document.visibilityState);
891 if(cs.pageIsActive){
892 cs.e.pageTitle.innerText = cs.pageTitleOrig;
893 if(document.activeElement!==cs.inputElement()){
894 /* An attempt to resolve usability problem reported by Joe
895 M. where the Pale Moon browser is giving input focus to
896 the Preview button. The down-side of this is that it will
897 deselect any text which was previously selected on this
898 page. This also, unfortunately, places the focus at the
899 start of the element, rather than the last cursor position
900 (like a textarea would). */
901 setTimeout(()=>cs.inputFocus(), 0);
902 }
903 }
904 }, true);
905 cs.setCurrentView(cs.e.viewMessages);
906
907 cs.e.activeUserList.addEventListener('click', function f(ev){
@@ -989,10 +1014,19 @@
1014 })
1015 elem.querySelectorAll('[data-numtag]').forEach(
1016 (e)=>e.addEventListener('click', f.$clickNum, false)
1017 )
1018 }/*setupHashtags()*/;
1019
1020 /** Returns the first .message-widget element in DOM element
1021 e's lineage. */
1022 const findMessageWidgetParent = function(e){
1023 while( e && !e.classList.contains('message-widget')){
1024 e = e.parentNode;
1025 }
1026 return e;
1027 };
1028
1029 /**
1030 Custom widget type for rendering messages (one message per
1031 instance). These are modelled after FIELDSET elements but we
1032 don't use FIELDSET because of cross-browser inconsistencies in
@@ -1016,11 +1050,10 @@
1050 if(arguments.length){
1051 this.setMessage(arguments[0]);
1052 }
1053 };
1054 /* Left-zero-pad a number to at least 2 digits */
 
1055 const dowMap = {
1056 /* Map of Date.getDay() values to weekday names. */
1057 0: "Sunday", 1: "Monday", 2: "Tuesday",
1058 3: "Wednesday", 4: "Thursday", 5: "Friday",
1059 6: "Saturday"
@@ -1034,10 +1067,11 @@
1067 d.getHours(),":",
1068 (d.getMinutes()+100).toString().slice(1,3),
1069 ' ', dowMap[d.getDay()]
1070 ].join('');
1071 };
1072
1073 cf.prototype = {
1074 scrollIntoView: function(){
1075 this.e.content.scrollIntoView();
1076 },
1077 setMessage: function(m){
@@ -1068,11 +1102,11 @@
1102 if(m.isError){
1103 D.addClass([contentTarget, this.e.tab], 'error');
1104 }
1105 D.append(
1106 this.e.tab,
1107 D.append(D.code(), 'notification @ ',theTime(d))
1108 );
1109 }
1110 if( m.xfrom && m.fsize>0 ){
1111 if( m.fmime
1112 && m.fmime.startsWith("image/")
@@ -1105,11 +1139,11 @@
1139 // hyperlinks, but otherwise it will be markup-free. See the
1140 // chat_format_to_html() routine in the server for details.
1141 //
1142 // Hence, even though innerHTML is normally frowned upon, it is
1143 // perfectly safe to use in this context.
1144 if(m.xmsg && 'string' !== typeof m.xmsg){
1145 // Used by Chat.reportErrorAsMessage()
1146 D.append(contentTarget, m.xmsg);
1147 }else{
1148 contentTarget.innerHTML = m.xmsg;
1149 contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
@@ -1117,10 +1151,12 @@
1151 if(F.pikchr){
1152 F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
1153 }
1154 }
1155 }
1156 //console.debug("tab",this.e.tab);
1157 //console.debug("this.e.tab.firstElementChild",this.e.tab.firstElementChild);
1158 this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false);
1159 /*if(eXFrom){
1160 eXFrom.addEventListener('click', ()=>this.e.tab.click(), false);
1161 }*/
1162 return this;
@@ -1249,14 +1285,11 @@
1285 this.$eMsg = tgtMsg;
1286 this.refresh();
1287 }
1288 }/*f.popup*/;
1289 }/*end static init*/
1290 const theMsg = findMessageWidgetParent(ev.target);
 
 
 
1291 if(theMsg) f.popup.show(theMsg);
1292 }/*_handleLegendClicked()*/
1293 }/*MessageWidget.prototype*/;
1294 /** Assumes that e is a MessageWidget element, ensures that
1295 Chat.e.viewMessages is visible, scrolls the message,
@@ -1283,11 +1316,11 @@
1316 }
1317 };
1318 /** Updates the paste/drop zone with details of the pasted/dropped
1319 data. The argument must be a Blob or Blob-like object (File) or
1320 it can be falsy to reset/clear that state.*/
1321 const updateDropZoneContent = bxs.updateDropZoneContent = function(blob){
1322 //console.debug("updateDropZoneContent()",blob);
1323 const dd = bxs.dropDetails;
1324 bxs.blob = blob;
1325 D.clearElement(dd);
1326 if(!blob){
@@ -1332,11 +1365,11 @@
1365 /* Acrobatics to keep *some* installations of Firefox
1366 from pasting formatting into contenteditable fields.
1367 This also works on Chrome, but chrome has the
1368 contenteditable=plaintext-only property which does this
1369 for us. */
1370 Chat.e.inputX.addEventListener(
1371 'paste',
1372 function(ev){
1373 if (ev.clipboardData && ev.clipboardData.getData) {
1374 const pastedText = ev.clipboardData.getData('text/plain');
1375 const selection = window.getSelection();
@@ -1356,30 +1389,60 @@
1389 ev.dataTransfer.dropEffect = 'none';
1390 ev.preventDefault();
1391 ev.stopPropagation();
1392 return false;
1393 };
 
1394 ['drop','dragenter','dragleave','dragend'].forEach(
1395 (k)=>Chat.e.inputX.addEventListener(k, noDragDropEvents, false)
 
 
1396 );
1397 return bxs;
1398 })()/*drag/drop/paste*/;
1399
1400 const tzOffsetToString = function(off){
1401 const hours = Math.round(off/60), min = Math.round(off % 30);
1402 return ''+(hours + (min ? '.5' : ''));
1403 };
 
1404 const localTime8601 = function(d){
1405 return [
1406 d.getYear()+1900, '-', pad2(d.getMonth()+1), '-', pad2(d.getDate()),
1407 'T', pad2(d.getHours()),':', pad2(d.getMinutes()),':',pad2(d.getSeconds())
1408 ].join('');
1409 };
1410
1411 /**
1412 Called by Chat.submitMessage() when message sending failed. Injects a fake message
1413 containing the content and attachment of the failed message and gives the user buttons
1414 to discard it or edit and retry.
1415 */
1416 const recoverFailedMessage = function(state){
1417 const w = D.addClass(D.div(), 'failed-message');
1418 D.append(w, D.append(
1419 D.span(),"This message was not successfully sent to the server:"
1420 ));
1421 if(state.msg){
1422 const ta = D.textarea();
1423 ta.value = state.msg;
1424 D.append(w,ta);
1425 }
1426 if(state.blob){
1427 D.append(w,D.append(D.span(),"Attachment: ",(state.blob.name||"unnamed")));
1428 //console.debug("blob = ",state.blob);
1429 }
1430 const buttons = D.addClass(D.div(), 'buttons');
1431 D.append(w, buttons);
1432 D.append(buttons, D.button("Discard message?", function(){
1433 let theMsg = findMessageWidgetParent(w);
1434 if(theMsg) Chat.deleteMessageElem(theMsg);
1435 }));
1436 D.append(buttons, D.button("Edit message and try again?", function(){
1437 if(state.msg) Chat.inputValue(ta.value);
1438 if(state.blob) BlobXferState.updateDropZoneContent(state.blob);
1439 let theMsg = findMessageWidgetParent(w);
1440 if(theMsg) Chat.deleteMessageElem(theMsg);
1441 }));
1442 Chat.reportErrorAsMessage(w);
1443 };
1444
1445 /**
1446 Submits the contents of the message input field (if not empty)
1447 and/or the file attachment field to the server. If both are
1448 empty, this is a no-op.
@@ -1389,11 +1452,12 @@
1452 f.spaces = /\s+$/;
1453 f.markdownContinuation = /\\\s+$/;
1454 }
1455 this.setCurrentView(this.e.viewMessages);
1456 const fd = new FormData();
1457 const fallback = {msg: this.inputValue()};
1458 var msg = fallback.msg.trim();
1459 if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1460 /* Cosmetic: trim whitespace from the ends of lines to try to
1461 keep copy/paste from terminals, especially wide ones, from
1462 forcing a horizontal scrollbar on all clients. This breaks
1463 markdown's use of blackslash-space-space for paragraph
@@ -1412,25 +1476,29 @@
1476 }
1477 if(msg) fd.set('msg',msg);
1478 const file = BlobXferState.blob || this.e.inputFile.files[0];
1479 if(file) fd.set("file", file);
1480 if( !msg && !file ) return;
1481 fallback.blob = file;
1482 const self = this;
1483 fd.set("lmtime", localTime8601(new Date()));
1484 F.fetch("chat-send",{
1485 payload: fd,
1486 responseType: 'text',
1487 onerror:function(err){
1488 self.reportErrorAsMessage(err);
1489 recoverFailedMessage(fallback);
1490 },
1491 onload:function(txt){
1492 if(!txt) return/*success response*/;
1493 try{
1494 const json = JSON.parse(txt);
1495 self.newContent({msgs:[json]});
1496 }catch(e){
1497 self.reportError(e);
 
1498 }
1499 recoverFailedMessage(fallback);
1500 }
1501 });
1502 BlobXferState.clear();
1503 Chat.inputValue("").inputFocus();
1504 };
@@ -1494,11 +1562,13 @@
1562 ev.stopPropagation();
1563 Chat.submitMessage();
1564 return false;
1565 }
1566 };
1567 Chat.e.inputFields.forEach(
1568 (e)=>e.addEventListener('keydown', inputWidgetKeydown, false)
1569 );
1570 Chat.e.btnSubmit.addEventListener('click',(e)=>{
1571 e.preventDefault();
1572 Chat.submitMessage();
1573 return false;
1574 });
@@ -1553,76 +1623,110 @@
1623 Settings options structure: an array of Objects with the
1624 following properties:
1625
1626 label: string for the UI
1627
1628 boolValue: string (name of Chat.settings setting) or a function
1629 which returns true or false. If it is a string, it gets
1630 replaced by a function which returns
1631 Chat.settings.getBool(thatString) and the string gets assigned
1632 to the persistentSetting property of this object.
1633
1634 select: SELECT element (instead of boolValue)
1635
1636 callback: optional handler to call after setting is modified.
1637 It gets passed the setting object: {key:string, value:something}.
1638 Its "this" is the options object. If this object has a
1639 boolValue string or a persistentSetting property, the argument
1640 passed to the callback is a settings object in the form {key:K,
1641 value:V}. If this object does not have boolValue string or
1642 persistentSetting then the callback is passed an event object
1643 in response to the config option's UI widget being activated,
1644 normally a 'change' event.
1645
1646 children: [array of settings objects]. These get listed under
1647 this element and indented slightly for visual grouping. Only
1648 one level of indention is supported.
1649
1650 Elements which only have a label and maybe a hint and
1651 children can be used as headings.
1652
1653 If a setting has a boolValue set, that gets rendered as a
1654 checkbox which toggles the given persistent setting (if
1655 boolValue is a string) AND listens for changes to that setting
1656 fired via Chat.settings.set() so that the checkbox can stay in
1657 sync with external changes to that setting. Various Chat UI
1658 elements stay in sync with the config UI via those settings
1659 events. The checkbox element gets added to the options object
1660 so that the callback() can reference it via this.checkbox.
1661 */
1662 const settingsOps = [{
1663 label: "Chat Configuration Options",
1664 hint: F.storage.isTransient()
1665 ? "Local store is unavailable. These settings are transient."
1666 : ["Most of these settings are persistent via ",
1667 F.storage.storageImplName(), ": ",
1668 F.storage.storageHelpDescription()].join('')
1669 },{
1670 label: "Editing Options...",
1671 children:[{
1672 label: "Chat-only mode",
1673 hint: "Toggle the page between normal fossil view and chat-only view.",
1674 boolValue: 'chat-only-mode'
1675 },{
1676 label: "Ctrl-enter to Send",
1677 hint: [
1678 "When on, only Ctrl-Enter will send messages and Enter adds ",
1679 "blank lines. When off, both Enter and Ctrl-Enter send. ",
1680 "When the input field has focus and is empty ",
1681 "then Ctrl-Enter toggles this setting."
1682 ].join(''),
1683 boolValue: 'edit-ctrl-send'
1684 },{
1685 label: "Compact mode",
1686 hint: [
1687 "Toggle between a space-saving or more spacious writing area. ",
1688 "When the input field has focus, is empty, and preview mode ",
1689 "is NOT active then Shift-Enter toggles this setting."].join(''),
1690 boolValue: 'edit-compact-mode'
1691 },{
1692 label: "Use 'contenteditable' editing mode",
1693 boolValue: 'edit-widget-x',
1694 hint: [
1695 "When enabled, chat input uses a so-called 'contenteditable' ",
1696 "field. Though generally more comfortable and modern than ",
1697 "plain-text input fields, browser-specific quirks and bugs ",
1698 "may lead to frustration. Ideal for mobile devices."
1699 ].join('')
1700 }]
1701 },{
1702 label: "Appearance Options...",
1703 children:[{
1704 label: "Left-align my posts",
1705 hint: "Default alignment of your own messages is selected "
1706 + "based window width/height ratio.",
1707 boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1708 callback: function f(){
1709 document.body.classList[
1710 this.checkbox.checked ? 'remove' : 'add'
1711 ]('my-messages-right');
1712 }
1713 },{
1714 label: "Monospace message font",
1715 hint: "Use monospace font for message and input text.",
1716 boolValue: 'monospace-messages',
1717 callback: function(setting){
1718 document.body.classList[
1719 setting.value ? 'add' : 'remove'
1720 ]('monospace-messages');
1721 }
1722 },{
1723 label: "Show images inline",
1724 hint: "When enabled, attached images are shown inline, "+
1725 "else they appear as a download link.",
1726 boolValue: 'images-inline'
1727 }]
1728 }];
1729
1730 /** Set up selection list of notification sounds. */
1731 if(1){
1732 const selectSound = D.select();
@@ -1641,45 +1745,64 @@
1745 selectSound.selectedIndex = firstSoundIndex;
1746 }
1747 }
1748 Chat.setNewMessageSound(selectSound.value);
1749 settingsOps.push({
1750 label: "Sound Options...",
1751 hint: "How to enable audio playback is browser-specific!",
1752 children:[{
1753 hint: "Audio alert",
1754 select: selectSound,
1755 callback: function(ev){
1756 const v = ev.target.value;
1757 Chat.setNewMessageSound(v);
1758 F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1759 if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1760 }
1761 },{
1762 label: "Play notification for your own messages",
1763 hint: "When enabled, the audio notification will be played for all messages, "+
1764 "including your own. When disabled only messages from other users "+
1765 "will trigger a notification.",
1766 boolValue: 'alert-own-messages'
1767 }]
1768 });
1769 }/*audio notification config*/
1770 settingsOps.push({
1771 label: "Active User List...",
1772 hint: [
1773 "/chat cannot track active connections, but it can tell ",
1774 "you who has posted recently..."].join(''),
1775 children:[
1776 namedOptions.activeUsers,{
1777 label: "Timestamps in active users list",
1778 indent: true,
1779 hint: "Show most recent message timestamps in the active user list.",
1780 boolValue: 'active-user-list-timestamps'
1781 }
1782 ]
1783 });
1784 /**
1785 Build UI for config options...
1786 */
1787 settingsOps.forEach(function f(op,indentOrIndex){
1788 const menuEntry = D.addClass(D.div(), 'menu-entry');
1789 if(true===indentOrIndex) D.addClass(menuEntry, 'child');
1790 const label = op.label
1791 ? D.append(D.label(),op.label) : undefined;
1792 const labelWrapper = D.addClass(D.div(), 'label-wrapper');
1793 var hint;
 
1794 if(op.hint){
1795 hint = D.append(D.addClass(D.label(),'hint'),op.hint);
1796 }
1797 if(op.hasOwnProperty('select')){
1798 const col0 = D.addClass(D.span(/*empty, but for spacing*/),
1799 'toggle-wrapper');
1800 D.append(menuEntry, labelWrapper, col0);
1801 D.append(labelWrapper, op.select);
1802 if(hint) D.append(labelWrapper, hint);
1803 if(label) D.append(label);
1804 if(op.callback){
1805 op.select.addEventListener('change', (ev)=>op.callback(ev), false);
1806 }
1807 }else if(op.hasOwnProperty('boolValue')){
1808 if(undefined === f.$id) f.$id = 0;
@@ -1691,27 +1814,31 @@
1814 }
1815 const check = op.checkbox
1816 = D.attr(D.checkbox(1, op.boolValue()),
1817 'aria-label', op.label);
1818 const id = 'cfgopt'+f.$id;
1819 const col0 = D.addClass(D.span(), 'toggle-wrapper');
1820 check.checked = op.boolValue();
1821 op.checkbox = check;
1822 D.attr(check, 'id', id);
1823 if(hint) D.attr(hint, 'for', id);
1824 D.append(menuEntry, labelWrapper, col0);
1825 D.append(col0, check);
1826 if(label){
1827 D.attr(label, 'for', id);
1828 D.append(labelWrapper, label);
1829 }
1830 if(hint) D.append(labelWrapper, hint);
1831 }else{
1832 if(op.callback){
1833 menuEntry.addEventListener('click', (ev)=>op.callback(ev));
1834 }
1835 D.append(menuEntry, labelWrapper);
1836 if(label) D.append(labelWrapper, label);
1837 if(hint) D.append(labelWrapper, hint);
1838 }
1839 D.append(optionsMenu, menuEntry);
1840 if(op.persistentSetting){
1841 Chat.settings.addListener(
1842 op.persistentSetting,
1843 function(setting){
1844 if(op.checkbox) op.checkbox.checked = !!setting.value;
@@ -1726,10 +1853,14 @@
1853 }, false);
1854 }
1855 }else if(op.callback && op.checkbox){
1856 op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false);
1857 }
1858 if(op.children){
1859 D.addClass(menuEntry, 'parent');
1860 op.children.forEach((x)=>f(x,true));
1861 }
1862 });
1863 })()/*#chat-button-settings setup*/;
1864
1865 (function(){
1866 /* Install default settings... must come after
@@ -1745,20 +1876,58 @@
1876 Chat.settings.addListener('active-user-list-timestamps',function(s){
1877 Chat.showActiveUserTimestamps(s.value);
1878 });
1879 Chat.settings.addListener('chat-only-mode',function(s){
1880 Chat.chatOnlyMode(s.value);
1881 });
1882 Chat.settings.addListener('edit-widget-x',function(s){
1883 let eSelected;
1884 if(s.value){
1885 if(Chat.e.inputX===Chat.inputElement()) return;
1886 eSelected = Chat.e.inputX;
1887 }else{
1888 eSelected = Chat.settings.getBool('edit-compact-mode')
1889 ? Chat.e.input1 : Chat.e.inputM;
1890 }
1891 const v = Chat.inputValue();
1892 Chat.inputValue('');
1893 Chat.e.inputFields.forEach(function(e,ndx){
1894 if(eSelected===e){
1895 Chat.e.inputFields.$currentIndex = ndx;
1896 D.removeClass(e, 'hidden');
1897 }
1898 else D.addClass(e,'hidden');
1899 });
1900 Chat.inputValue(v);
1901 eSelected.focus();
1902 });
1903 Chat.settings.addListener('edit-compact-mode',function(s){
1904 if(Chat.e.inputX!==Chat.inputElement()){
1905 /* Text field/textarea mode: swap them if needed.
1906 Compact mode of inputX is toggled via CSS. */
1907 const a = s.value
1908 ? [Chat.e.input1, Chat.e.inputM, 0]
1909 : [Chat.e.inputM, Chat.e.input1, 1];
1910 const v = Chat.inputValue();
1911 Chat.inputValue('');
1912 Chat.e.inputFields.$currentIndex = a[2];
1913 Chat.inputValue(v);
1914 D.removeClass(a[0], 'hidden');
1915 D.addClass(a[1], 'hidden');
1916 }
1917 Chat.e.inputElementWrapper.classList[
1918 s.value ? 'add' : 'remove'
1919 ]('compact');
1920 Chat.e.inputFields[Chat.e.inputFields.$currentIndex].focus();
1921 });
1922 Chat.settings.addListener('edit-ctrl-send',function(s){
1923 const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1924 Chat.e.inputFields.forEach((e)=>{
1925 const v = e.dataset.placeholder0 + " " +label;
1926 if(e.isContentEditable) e.dataset.placeholder = v;
1927 else D.attr(e,'placeholder',v);
1928 });
1929 Chat.e.btnSubmit.title = label;
1930 });
1931 const valueKludges = {
1932 /* Convert certain string-format values to other types... */
1933 "false": false,
@@ -1784,11 +1953,11 @@
1953 this.inputFocus();
1954 };
1955 Chat.e.viewPreview.querySelector('#chat-preview-close').
1956 addEventListener('click', ()=>Chat.setCurrentView(Chat.e.viewMessages), false);
1957 let previewPending = false;
1958 const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputFields];
1959 const submit = function(ev){
1960 ev.preventDefault();
1961 ev.stopPropagation();
1962 if(previewPending) return false;
1963 const txt = Chat.inputValue();
1964
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -43,10 +43,11 @@
4343
const iso8601ish = function(d){
4444
return d.toISOString()
4545
.replace('T',' ').replace(/\.\d+/,'')
4646
.replace('Z', ' zulu');
4747
};
48
+ const pad2 = (x)=>('0'+x).substr(-2);
4849
/** Returns the local time string of Date object d, defaulting
4950
to the current time. */
5051
const localTimeString = function ff(d){
5152
d || (d = new Date());
5253
return [
@@ -93,11 +94,11 @@
9394
ht = wh;
9495
}else{
9596
elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
9697
ht = wh - extra;
9798
}
98
- f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99
+ f.chat.e.inputX.style.maxHeight = (ht/2)+"px";
99100
/* ^^^^ this is a middle ground between having no size cap
100101
on the input field and having a fixed arbitrary cap. */;
101102
contentArea.style.height =
102103
contentArea.style.maxHeight = [
103104
"calc(", (ht>=100 ? ht : 100), "px",
@@ -109,21 +110,17 @@
109110
if(false){
110111
console.debug("resized.",wh, extra, ht,
111112
window.getComputedStyle(contentArea).maxHeight,
112113
contentArea);
113114
console.debug("Set input max height to: ",
114
- f.chat.e.inputField.style.maxHeight);
115
+ f.chat.e.inputX.style.maxHeight);
115116
}
116117
};
117
- var doit;
118
- window.addEventListener('resize',function(ev){
119
- clearTimeout(doit);
120
- doit = setTimeout(resized, 100);
121
- }, false);
118
+ resized.$disabled = true/*gets deleted when setup is finished*/;
119
+ window.addEventListener('resize', F.debounce(resized, 250), false);
122120
return resized;
123121
})();
124
- ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
125122
fossil.FRK = ForceResizeKludge/*for debugging*/;
126123
const Chat = ForceResizeKludge.chat = (function(){
127124
const cs = {
128125
verboseErrors: false /* if true then certain, mostly extraneous,
129126
error messages may be sent to the console. */,
@@ -130,16 +127,18 @@
130127
e:{/*map of certain DOM elements.*/
131128
messageInjectPoint: E1('#message-inject-point'),
132129
pageTitle: E1('head title'),
133130
loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */,
134131
inputWrapper: E1("#chat-input-area"),
135
- inputLine: E1('#chat-input-line'),
132
+ inputElementWrapper: E1('#chat-input-line-wrapper'),
136133
fileSelectWrapper: E1('#chat-input-file-area'),
137134
viewMessages: E1('#chat-messages-wrapper'),
138135
btnSubmit: E1('#chat-button-submit'),
139136
btnAttach: E1('#chat-button-attach'),
140
- inputField: E1('#chat-input-field'),
137
+ inputX: E1('#chat-input-field-x'),
138
+ input1: E1('#chat-input-field-single'),
139
+ inputM: E1('#chat-input-field-multi'),
141140
inputFile: E1('#chat-input-file'),
142141
contentDiv: E1('div.content'),
143142
viewConfig: E1('#chat-config'),
144143
viewPreview: E1('#chat-preview'),
145144
previewContent: E1('#chat-preview-content'),
@@ -192,23 +191,24 @@
192191
taking into account single- vs multi-line input. The getter returns
193192
a string and the setter returns this object. */
194193
inputValue: function(){
195194
const e = this.inputElement();
196195
if(arguments.length){
197
- e.innerText = arguments[0];
196
+ if(e.isContentEditable) e.innerText = arguments[0];
197
+ else e.value = arguments[0];
198198
return this;
199199
}
200
- return e.innerText;
200
+ return e.isContentEditable ? e.innerText : e.value;
201201
},
202202
/** Asks the current user input field to take focus. Returns this. */
203203
inputFocus: function(){
204204
this.inputElement().focus();
205205
return this;
206206
},
207207
/** Returns the current message input element. */
208208
inputElement: function(){
209
- return this.e.inputField;
209
+ return this.e.inputFields[this.e.inputFields.$currentIndex];
210210
},
211211
/** Enables (if yes is truthy) or disables all elements in
212212
* this.disableDuringAjax. */
213213
enableAjaxComponents: function(yes){
214214
D[yes ? 'enable' : 'disable'](this.disableDuringAjax);
@@ -415,11 +415,11 @@
415415
laid out in a compact form. When off, the edit field and
416416
buttons are larger. */
417417
"edit-compact-mode": true,
418418
/* When on, sets the font-family on messages and the edit
419419
field to monospace. */
420
- "monospace-messages": true,
420
+ "monospace-messages": false,
421421
/* When on, non-chat UI elements (page header/footer) are
422422
hidden */
423423
"chat-only-mode": false,
424424
/* When set to a URI, it is assumed to be an audio file,
425425
which gets played when new messages arrive. When true,
@@ -434,11 +434,17 @@
434434
timestamp of each user's most recent message. */
435435
"active-user-list-timestamps": false,
436436
/* When on, the [audible-alert] is played for one's own
437437
messages, else it is only played for other users'
438438
messages. */
439
- "alert-own-messages": false
439
+ "alert-own-messages": false,
440
+ /* "Experimental mode" input: use a contenteditable field
441
+ for input. This is generally more comfortable to use,
442
+ and more modern, than plain text input fields, but
443
+ the list of browser-specific quirks and bugs is...
444
+ not short. */
445
+ "edit-widget-x": false
440446
}
441447
},
442448
/** Plays a new-message notification sound IF the audible-alert
443449
setting is true, else this is a no-op. Returns this.
444450
*/
@@ -672,16 +678,22 @@
672678
D.addClassBriefly(e, a, 0, cb);
673679
}
674680
return this;
675681
}
676682
};
677
- if(D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){
683
+ cs.e.inputFields = [ cs.e.input1, cs.e.inputM, cs.e.inputX ];
684
+ cs.e.inputFields.$currentIndex = 0;
685
+ cs.e.inputFields.forEach(function(e,ndx){
686
+ if(ndx===cs.e.inputFields.$currentIndex) D.removeClass(e,'hidden');
687
+ else D.addClass(e,'hidden');
688
+ });
689
+ if(D.attr(cs.e.inputX,'contenteditable','plaintext-only').isContentEditable){
678690
cs.$browserHasPlaintextOnly = true;
679691
}else{
680692
/* Only the Chrome family supports contenteditable=plaintext-only */
681693
cs.$browserHasPlaintextOnly = false;
682
- D.attr(cs.e.inputField,'contenteditable','true');
694
+ D.attr(cs.e.inputX,'contenteditable','true');
683695
}
684696
cs.animate.$disabled = true;
685697
F.fetch.beforesend = ()=>cs.ajaxStart();
686698
F.fetch.aftersend = ()=>cs.ajaxEnd();
687699
cs.pageTitleOrig = cs.e.pageTitle.innerText;
@@ -702,18 +714,21 @@
702714
Reports an error in the form of a new message in the chat
703715
feed. All arguments are appended to the message's content area
704716
using fossil.dom.append(), so may be of any type supported by
705717
that function.
706718
*/
707
- cs.reportErrorAsMessage = function(/*msg args*/){
708
- const args = argsToArray(arguments);
719
+ cs.reportErrorAsMessage = function f(/*msg args*/){
720
+ if(undefined === f.$msgid) f.$msgid=0;
721
+ const args = argsToArray(arguments).map(function(v){
722
+ return (v instanceof Error) ? v.message : v;
723
+ });
709724
console.error("chat error:",args);
710725
const d = new Date().toISOString(),
711726
mw = new this.MessageWidget({
712727
isError: true,
713728
xfrom: null,
714
- msgid: -1,
729
+ msgid: "error-"+(++f.$msgid),
715730
mtime: d,
716731
lmtime: d,
717732
xmsg: args
718733
});
719734
this.injectMessageElem(mw.e.body);
@@ -873,10 +888,20 @@
873888
};
874889
document.addEventListener('visibilitychange', function(ev){
875890
cs.pageIsActive = ('visible' === document.visibilityState);
876891
if(cs.pageIsActive){
877892
cs.e.pageTitle.innerText = cs.pageTitleOrig;
893
+ if(document.activeElement!==cs.inputElement()){
894
+ /* An attempt to resolve usability problem reported by Joe
895
+ M. where the Pale Moon browser is giving input focus to
896
+ the Preview button. The down-side of this is that it will
897
+ deselect any text which was previously selected on this
898
+ page. This also, unfortunately, places the focus at the
899
+ start of the element, rather than the last cursor position
900
+ (like a textarea would). */
901
+ setTimeout(()=>cs.inputFocus(), 0);
902
+ }
878903
}
879904
}, true);
880905
cs.setCurrentView(cs.e.viewMessages);
881906
882907
cs.e.activeUserList.addEventListener('click', function f(ev){
@@ -989,10 +1014,19 @@
9891014
})
9901015
elem.querySelectorAll('[data-numtag]').forEach(
9911016
(e)=>e.addEventListener('click', f.$clickNum, false)
9921017
)
9931018
}/*setupHashtags()*/;
1019
+
1020
+ /** Returns the first .message-widget element in DOM element
1021
+ e's lineage. */
1022
+ const findMessageWidgetParent = function(e){
1023
+ while( e && !e.classList.contains('message-widget')){
1024
+ e = e.parentNode;
1025
+ }
1026
+ return e;
1027
+ };
9941028
9951029
/**
9961030
Custom widget type for rendering messages (one message per
9971031
instance). These are modelled after FIELDSET elements but we
9981032
don't use FIELDSET because of cross-browser inconsistencies in
@@ -1016,11 +1050,10 @@
10161050
if(arguments.length){
10171051
this.setMessage(arguments[0]);
10181052
}
10191053
};
10201054
/* Left-zero-pad a number to at least 2 digits */
1021
- const pad2 = (x)=>(''+x).length>1 ? x : '0'+x;
10221055
const dowMap = {
10231056
/* Map of Date.getDay() values to weekday names. */
10241057
0: "Sunday", 1: "Monday", 2: "Tuesday",
10251058
3: "Wednesday", 4: "Thursday", 5: "Friday",
10261059
6: "Saturday"
@@ -1034,10 +1067,11 @@
10341067
d.getHours(),":",
10351068
(d.getMinutes()+100).toString().slice(1,3),
10361069
' ', dowMap[d.getDay()]
10371070
].join('');
10381071
};
1072
+
10391073
cf.prototype = {
10401074
scrollIntoView: function(){
10411075
this.e.content.scrollIntoView();
10421076
},
10431077
setMessage: function(m){
@@ -1068,11 +1102,11 @@
10681102
if(m.isError){
10691103
D.addClass([contentTarget, this.e.tab], 'error');
10701104
}
10711105
D.append(
10721106
this.e.tab,
1073
- D.text('notification @ ',theTime(d))
1107
+ D.append(D.code(), 'notification @ ',theTime(d))
10741108
);
10751109
}
10761110
if( m.xfrom && m.fsize>0 ){
10771111
if( m.fmime
10781112
&& m.fmime.startsWith("image/")
@@ -1105,11 +1139,11 @@
11051139
// hyperlinks, but otherwise it will be markup-free. See the
11061140
// chat_format_to_html() routine in the server for details.
11071141
//
11081142
// Hence, even though innerHTML is normally frowned upon, it is
11091143
// perfectly safe to use in this context.
1110
- if(m.xmsg instanceof Array){
1144
+ if(m.xmsg && 'string' !== typeof m.xmsg){
11111145
// Used by Chat.reportErrorAsMessage()
11121146
D.append(contentTarget, m.xmsg);
11131147
}else{
11141148
contentTarget.innerHTML = m.xmsg;
11151149
contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
@@ -1117,10 +1151,12 @@
11171151
if(F.pikchr){
11181152
F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
11191153
}
11201154
}
11211155
}
1156
+ //console.debug("tab",this.e.tab);
1157
+ //console.debug("this.e.tab.firstElementChild",this.e.tab.firstElementChild);
11221158
this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false);
11231159
/*if(eXFrom){
11241160
eXFrom.addEventListener('click', ()=>this.e.tab.click(), false);
11251161
}*/
11261162
return this;
@@ -1249,14 +1285,11 @@
12491285
this.$eMsg = tgtMsg;
12501286
this.refresh();
12511287
}
12521288
}/*f.popup*/;
12531289
}/*end static init*/
1254
- let theMsg = ev.target;
1255
- while( theMsg && !theMsg.classList.contains('message-widget')){
1256
- theMsg = theMsg.parentNode;
1257
- }
1290
+ const theMsg = findMessageWidgetParent(ev.target);
12581291
if(theMsg) f.popup.show(theMsg);
12591292
}/*_handleLegendClicked()*/
12601293
}/*MessageWidget.prototype*/;
12611294
/** Assumes that e is a MessageWidget element, ensures that
12621295
Chat.e.viewMessages is visible, scrolls the message,
@@ -1283,11 +1316,11 @@
12831316
}
12841317
};
12851318
/** Updates the paste/drop zone with details of the pasted/dropped
12861319
data. The argument must be a Blob or Blob-like object (File) or
12871320
it can be falsy to reset/clear that state.*/
1288
- const updateDropZoneContent = function(blob){
1321
+ const updateDropZoneContent = bxs.updateDropZoneContent = function(blob){
12891322
//console.debug("updateDropZoneContent()",blob);
12901323
const dd = bxs.dropDetails;
12911324
bxs.blob = blob;
12921325
D.clearElement(dd);
12931326
if(!blob){
@@ -1332,11 +1365,11 @@
13321365
/* Acrobatics to keep *some* installations of Firefox
13331366
from pasting formatting into contenteditable fields.
13341367
This also works on Chrome, but chrome has the
13351368
contenteditable=plaintext-only property which does this
13361369
for us. */
1337
- Chat.inputElement().addEventListener(
1370
+ Chat.e.inputX.addEventListener(
13381371
'paste',
13391372
function(ev){
13401373
if (ev.clipboardData && ev.clipboardData.getData) {
13411374
const pastedText = ev.clipboardData.getData('text/plain');
13421375
const selection = window.getSelection();
@@ -1356,30 +1389,60 @@
13561389
ev.dataTransfer.dropEffect = 'none';
13571390
ev.preventDefault();
13581391
ev.stopPropagation();
13591392
return false;
13601393
};
1361
-
13621394
['drop','dragenter','dragleave','dragend'].forEach(
1363
- (k)=>{
1364
- Chat.inputElement().addEventListener(k, noDragDropEvents, false);
1365
- }
1395
+ (k)=>Chat.e.inputX.addEventListener(k, noDragDropEvents, false)
13661396
);
13671397
return bxs;
13681398
})()/*drag/drop/paste*/;
13691399
13701400
const tzOffsetToString = function(off){
13711401
const hours = Math.round(off/60), min = Math.round(off % 30);
13721402
return ''+(hours + (min ? '.5' : ''));
13731403
};
1374
- const pad2 = (x)=>('0'+x).substr(-2);
13751404
const localTime8601 = function(d){
13761405
return [
13771406
d.getYear()+1900, '-', pad2(d.getMonth()+1), '-', pad2(d.getDate()),
13781407
'T', pad2(d.getHours()),':', pad2(d.getMinutes()),':',pad2(d.getSeconds())
13791408
].join('');
13801409
};
1410
+
1411
+ /**
1412
+ Called by Chat.submitMessage() when message sending failed. Injects a fake message
1413
+ containing the content and attachment of the failed message and gives the user buttons
1414
+ to discard it or edit and retry.
1415
+ */
1416
+ const recoverFailedMessage = function(state){
1417
+ const w = D.addClass(D.div(), 'failed-message');
1418
+ D.append(w, D.append(
1419
+ D.span(),"This message was not successfully sent to the server:"
1420
+ ));
1421
+ if(state.msg){
1422
+ const ta = D.textarea();
1423
+ ta.value = state.msg;
1424
+ D.append(w,ta);
1425
+ }
1426
+ if(state.blob){
1427
+ D.append(w,D.append(D.span(),"Attachment: ",(state.blob.name||"unnamed")));
1428
+ //console.debug("blob = ",state.blob);
1429
+ }
1430
+ const buttons = D.addClass(D.div(), 'buttons');
1431
+ D.append(w, buttons);
1432
+ D.append(buttons, D.button("Discard message?", function(){
1433
+ let theMsg = findMessageWidgetParent(w);
1434
+ if(theMsg) Chat.deleteMessageElem(theMsg);
1435
+ }));
1436
+ D.append(buttons, D.button("Edit message and try again?", function(){
1437
+ if(state.msg) Chat.inputValue(ta.value);
1438
+ if(state.blob) BlobXferState.updateDropZoneContent(state.blob);
1439
+ let theMsg = findMessageWidgetParent(w);
1440
+ if(theMsg) Chat.deleteMessageElem(theMsg);
1441
+ }));
1442
+ Chat.reportErrorAsMessage(w);
1443
+ };
13811444
13821445
/**
13831446
Submits the contents of the message input field (if not empty)
13841447
and/or the file attachment field to the server. If both are
13851448
empty, this is a no-op.
@@ -1389,11 +1452,12 @@
13891452
f.spaces = /\s+$/;
13901453
f.markdownContinuation = /\\\s+$/;
13911454
}
13921455
this.setCurrentView(this.e.viewMessages);
13931456
const fd = new FormData();
1394
- var msg = this.inputValue().trim();
1457
+ const fallback = {msg: this.inputValue()};
1458
+ var msg = fallback.msg.trim();
13951459
if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
13961460
/* Cosmetic: trim whitespace from the ends of lines to try to
13971461
keep copy/paste from terminals, especially wide ones, from
13981462
forcing a horizontal scrollbar on all clients. This breaks
13991463
markdown's use of blackslash-space-space for paragraph
@@ -1412,25 +1476,29 @@
14121476
}
14131477
if(msg) fd.set('msg',msg);
14141478
const file = BlobXferState.blob || this.e.inputFile.files[0];
14151479
if(file) fd.set("file", file);
14161480
if( !msg && !file ) return;
1481
+ fallback.blob = file;
14171482
const self = this;
14181483
fd.set("lmtime", localTime8601(new Date()));
14191484
F.fetch("chat-send",{
14201485
payload: fd,
14211486
responseType: 'text',
1422
- onerror:(err)=>this.reportErrorAsMessage(err),
1487
+ onerror:function(err){
1488
+ self.reportErrorAsMessage(err);
1489
+ recoverFailedMessage(fallback);
1490
+ },
14231491
onload:function(txt){
14241492
if(!txt) return/*success response*/;
14251493
try{
14261494
const json = JSON.parse(txt);
14271495
self.newContent({msgs:[json]});
14281496
}catch(e){
14291497
self.reportError(e);
1430
- return;
14311498
}
1499
+ recoverFailedMessage(fallback);
14321500
}
14331501
});
14341502
BlobXferState.clear();
14351503
Chat.inputValue("").inputFocus();
14361504
};
@@ -1494,11 +1562,13 @@
14941562
ev.stopPropagation();
14951563
Chat.submitMessage();
14961564
return false;
14971565
}
14981566
};
1499
- Chat.e.inputField.addEventListener('keydown', inputWidgetKeydown, false);
1567
+ Chat.e.inputFields.forEach(
1568
+ (e)=>e.addEventListener('keydown', inputWidgetKeydown, false)
1569
+ );
15001570
Chat.e.btnSubmit.addEventListener('click',(e)=>{
15011571
e.preventDefault();
15021572
Chat.submitMessage();
15031573
return false;
15041574
});
@@ -1553,76 +1623,110 @@
15531623
Settings options structure: an array of Objects with the
15541624
following properties:
15551625
15561626
label: string for the UI
15571627
1558
- boolValue: string (name of Chat.settings setting) or a
1559
- function which returns true or false. Gets mapped to
1560
- a checkbox.
1628
+ boolValue: string (name of Chat.settings setting) or a function
1629
+ which returns true or false. If it is a string, it gets
1630
+ replaced by a function which returns
1631
+ Chat.settings.getBool(thatString) and the string gets assigned
1632
+ to the persistentSetting property of this object.
15611633
15621634
select: SELECT element (instead of boolValue)
15631635
15641636
callback: optional handler to call after setting is modified.
15651637
It gets passed the setting object: {key:string, value:something}.
1638
+ Its "this" is the options object. If this object has a
1639
+ boolValue string or a persistentSetting property, the argument
1640
+ passed to the callback is a settings object in the form {key:K,
1641
+ value:V}. If this object does not have boolValue string or
1642
+ persistentSetting then the callback is passed an event object
1643
+ in response to the config option's UI widget being activated,
1644
+ normally a 'change' event.
1645
+
1646
+ children: [array of settings objects]. These get listed under
1647
+ this element and indented slightly for visual grouping. Only
1648
+ one level of indention is supported.
1649
+
1650
+ Elements which only have a label and maybe a hint and
1651
+ children can be used as headings.
15661652
1567
- If a setting has a boolValue set, that gets transformed into a
1653
+ If a setting has a boolValue set, that gets rendered as a
15681654
checkbox which toggles the given persistent setting (if
15691655
boolValue is a string) AND listens for changes to that setting
15701656
fired via Chat.settings.set() so that the checkbox can stay in
15711657
sync with external changes to that setting. Various Chat UI
15721658
elements stay in sync with the config UI via those settings
1573
- events.
1659
+ events. The checkbox element gets added to the options object
1660
+ so that the callback() can reference it via this.checkbox.
15741661
*/
15751662
const settingsOps = [{
1576
- label: "Ctrl-enter to Send",
1577
- hint: [
1578
- "When on, only Ctrl-Enter will send messages and Enter adds ",
1579
- "blank lines. ",
1580
- "When off, both Enter and Ctrl-Enter send. ",
1581
- "When the input field has focus, is empty, and preview ",
1582
- "mode is NOT active then Ctrl-Enter toggles this setting."
1583
- ].join(''),
1584
- boolValue: 'edit-ctrl-send'
1585
- },{
1586
- label: "Compact mode",
1587
- hint: [
1588
- "Toggle between a space-saving or more spacious writing area. ",
1589
- "When the input field has focus, is empty, and preview mode ",
1590
- "is NOT active then Shift-Enter toggles this setting."
1591
- ].join(''),
1592
- boolValue: 'edit-compact-mode'
1593
- },{
1594
- label: "Left-align my posts",
1595
- hint: "Default alignment of your own messages is selected "
1596
- +"based window width/height relationship.",
1597
- boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1598
- callback: function f(){
1599
- document.body.classList[
1600
- this.checkbox.checked ? 'remove' : 'add'
1601
- ]('my-messages-right');
1602
- }
1603
- },{
1604
- label: "Monospace message font",
1605
- hint: "Use monospace font for message text?",
1606
- boolValue: 'monospace-messages',
1607
- callback: function(setting){
1608
- document.body.classList[
1609
- setting.value ? 'add' : 'remove'
1610
- ]('monospace-messages');
1611
- }
1612
- },{
1613
- label: "Chat-only mode",
1614
- hint: "Toggle the page between normal fossil view and chat-only view.",
1615
- boolValue: 'chat-only-mode'
1616
- },{
1617
- label: "Show images inline",
1618
- hint: "Whether to show images inline or as a hyperlink.",
1619
- boolValue: 'images-inline'
1620
- },namedOptions.activeUsers,{
1621
- label: "Timestamps in active users list",
1622
- hint: "Whether to show last-message timestamps.",
1623
- boolValue: 'active-user-list-timestamps'
1663
+ label: "Chat Configuration Options",
1664
+ hint: F.storage.isTransient()
1665
+ ? "Local store is unavailable. These settings are transient."
1666
+ : ["Most of these settings are persistent via ",
1667
+ F.storage.storageImplName(), ": ",
1668
+ F.storage.storageHelpDescription()].join('')
1669
+ },{
1670
+ label: "Editing Options...",
1671
+ children:[{
1672
+ label: "Chat-only mode",
1673
+ hint: "Toggle the page between normal fossil view and chat-only view.",
1674
+ boolValue: 'chat-only-mode'
1675
+ },{
1676
+ label: "Ctrl-enter to Send",
1677
+ hint: [
1678
+ "When on, only Ctrl-Enter will send messages and Enter adds ",
1679
+ "blank lines. When off, both Enter and Ctrl-Enter send. ",
1680
+ "When the input field has focus and is empty ",
1681
+ "then Ctrl-Enter toggles this setting."
1682
+ ].join(''),
1683
+ boolValue: 'edit-ctrl-send'
1684
+ },{
1685
+ label: "Compact mode",
1686
+ hint: [
1687
+ "Toggle between a space-saving or more spacious writing area. ",
1688
+ "When the input field has focus, is empty, and preview mode ",
1689
+ "is NOT active then Shift-Enter toggles this setting."].join(''),
1690
+ boolValue: 'edit-compact-mode'
1691
+ },{
1692
+ label: "Use 'contenteditable' editing mode",
1693
+ boolValue: 'edit-widget-x',
1694
+ hint: [
1695
+ "When enabled, chat input uses a so-called 'contenteditable' ",
1696
+ "field. Though generally more comfortable and modern than ",
1697
+ "plain-text input fields, browser-specific quirks and bugs ",
1698
+ "may lead to frustration. Ideal for mobile devices."
1699
+ ].join('')
1700
+ }]
1701
+ },{
1702
+ label: "Appearance Options...",
1703
+ children:[{
1704
+ label: "Left-align my posts",
1705
+ hint: "Default alignment of your own messages is selected "
1706
+ + "based window width/height ratio.",
1707
+ boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1708
+ callback: function f(){
1709
+ document.body.classList[
1710
+ this.checkbox.checked ? 'remove' : 'add'
1711
+ ]('my-messages-right');
1712
+ }
1713
+ },{
1714
+ label: "Monospace message font",
1715
+ hint: "Use monospace font for message and input text.",
1716
+ boolValue: 'monospace-messages',
1717
+ callback: function(setting){
1718
+ document.body.classList[
1719
+ setting.value ? 'add' : 'remove'
1720
+ ]('monospace-messages');
1721
+ }
1722
+ },{
1723
+ label: "Show images inline",
1724
+ hint: "When enabled, attached images are shown inline, "+
1725
+ "else they appear as a download link.",
1726
+ boolValue: 'images-inline'
1727
+ }]
16241728
}];
16251729
16261730
/** Set up selection list of notification sounds. */
16271731
if(1){
16281732
const selectSound = D.select();
@@ -1641,45 +1745,64 @@
16411745
selectSound.selectedIndex = firstSoundIndex;
16421746
}
16431747
}
16441748
Chat.setNewMessageSound(selectSound.value);
16451749
settingsOps.push({
1646
- hint: "Audio alert. How to enable audio playback is browser-specific!",
1647
- select: selectSound,
1648
- callback: function(ev){
1649
- const v = ev.target.value;
1650
- Chat.setNewMessageSound(v);
1651
- F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1652
- if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1653
- }
1750
+ label: "Sound Options...",
1751
+ hint: "How to enable audio playback is browser-specific!",
1752
+ children:[{
1753
+ hint: "Audio alert",
1754
+ select: selectSound,
1755
+ callback: function(ev){
1756
+ const v = ev.target.value;
1757
+ Chat.setNewMessageSound(v);
1758
+ F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1759
+ if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1760
+ }
1761
+ },{
1762
+ label: "Play notification for your own messages",
1763
+ hint: "When enabled, the audio notification will be played for all messages, "+
1764
+ "including your own. When disabled only messages from other users "+
1765
+ "will trigger a notification.",
1766
+ boolValue: 'alert-own-messages'
1767
+ }]
16541768
});
16551769
}/*audio notification config*/
16561770
settingsOps.push({
1657
- label: "Play notification for your own messages.",
1658
- hint: "When enabled, the audio notification will be played for all messages, "+
1659
- "including your own. When disabled only messages from other users "+
1660
- "will trigger a notification.",
1661
- boolValue: 'alert-own-messages'
1771
+ label: "Active User List...",
1772
+ hint: [
1773
+ "/chat cannot track active connections, but it can tell ",
1774
+ "you who has posted recently..."].join(''),
1775
+ children:[
1776
+ namedOptions.activeUsers,{
1777
+ label: "Timestamps in active users list",
1778
+ indent: true,
1779
+ hint: "Show most recent message timestamps in the active user list.",
1780
+ boolValue: 'active-user-list-timestamps'
1781
+ }
1782
+ ]
16621783
});
16631784
/**
16641785
Build UI for config options...
16651786
*/
1666
- settingsOps.forEach(function f(op){
1667
- const line = D.addClass(D.div(), 'menu-entry');
1787
+ settingsOps.forEach(function f(op,indentOrIndex){
1788
+ const menuEntry = D.addClass(D.div(), 'menu-entry');
1789
+ if(true===indentOrIndex) D.addClass(menuEntry, 'child');
16681790
const label = op.label
16691791
? D.append(D.label(),op.label) : undefined;
16701792
const labelWrapper = D.addClass(D.div(), 'label-wrapper');
16711793
var hint;
1672
- const col0 = D.span();
16731794
if(op.hint){
1674
- hint = D.append(D.addClass(D.span(),'hint'),op.hint);
1795
+ hint = D.append(D.addClass(D.label(),'hint'),op.hint);
16751796
}
16761797
if(op.hasOwnProperty('select')){
1677
- D.append(line, col0, labelWrapper);
1798
+ const col0 = D.addClass(D.span(/*empty, but for spacing*/),
1799
+ 'toggle-wrapper');
1800
+ D.append(menuEntry, labelWrapper, col0);
16781801
D.append(labelWrapper, op.select);
16791802
if(hint) D.append(labelWrapper, hint);
1680
- if(label) D.append(col0, label);
1803
+ if(label) D.append(label);
16811804
if(op.callback){
16821805
op.select.addEventListener('change', (ev)=>op.callback(ev), false);
16831806
}
16841807
}else if(op.hasOwnProperty('boolValue')){
16851808
if(undefined === f.$id) f.$id = 0;
@@ -1691,27 +1814,31 @@
16911814
}
16921815
const check = op.checkbox
16931816
= D.attr(D.checkbox(1, op.boolValue()),
16941817
'aria-label', op.label);
16951818
const id = 'cfgopt'+f.$id;
1819
+ const col0 = D.addClass(D.span(), 'toggle-wrapper');
16961820
check.checked = op.boolValue();
16971821
op.checkbox = check;
16981822
D.attr(check, 'id', id);
1699
- D.append(line, col0, labelWrapper);
1823
+ if(hint) D.attr(hint, 'for', id);
1824
+ D.append(menuEntry, labelWrapper, col0);
17001825
D.append(col0, check);
17011826
if(label){
17021827
D.attr(label, 'for', id);
17031828
D.append(labelWrapper, label);
17041829
}
17051830
if(hint) D.append(labelWrapper, hint);
17061831
}else{
1707
- line.addEventListener('click', callback);
1708
- D.append(line, col0, labelWrapper);
1832
+ if(op.callback){
1833
+ menuEntry.addEventListener('click', (ev)=>op.callback(ev));
1834
+ }
1835
+ D.append(menuEntry, labelWrapper);
17091836
if(label) D.append(labelWrapper, label);
17101837
if(hint) D.append(labelWrapper, hint);
17111838
}
1712
- D.append(optionsMenu, line);
1839
+ D.append(optionsMenu, menuEntry);
17131840
if(op.persistentSetting){
17141841
Chat.settings.addListener(
17151842
op.persistentSetting,
17161843
function(setting){
17171844
if(op.checkbox) op.checkbox.checked = !!setting.value;
@@ -1726,10 +1853,14 @@
17261853
}, false);
17271854
}
17281855
}else if(op.callback && op.checkbox){
17291856
op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false);
17301857
}
1858
+ if(op.children){
1859
+ D.addClass(menuEntry, 'parent');
1860
+ op.children.forEach((x)=>f(x,true));
1861
+ }
17311862
});
17321863
})()/*#chat-button-settings setup*/;
17331864
17341865
(function(){
17351866
/* Install default settings... must come after
@@ -1745,20 +1876,58 @@
17451876
Chat.settings.addListener('active-user-list-timestamps',function(s){
17461877
Chat.showActiveUserTimestamps(s.value);
17471878
});
17481879
Chat.settings.addListener('chat-only-mode',function(s){
17491880
Chat.chatOnlyMode(s.value);
1881
+ });
1882
+ Chat.settings.addListener('edit-widget-x',function(s){
1883
+ let eSelected;
1884
+ if(s.value){
1885
+ if(Chat.e.inputX===Chat.inputElement()) return;
1886
+ eSelected = Chat.e.inputX;
1887
+ }else{
1888
+ eSelected = Chat.settings.getBool('edit-compact-mode')
1889
+ ? Chat.e.input1 : Chat.e.inputM;
1890
+ }
1891
+ const v = Chat.inputValue();
1892
+ Chat.inputValue('');
1893
+ Chat.e.inputFields.forEach(function(e,ndx){
1894
+ if(eSelected===e){
1895
+ Chat.e.inputFields.$currentIndex = ndx;
1896
+ D.removeClass(e, 'hidden');
1897
+ }
1898
+ else D.addClass(e,'hidden');
1899
+ });
1900
+ Chat.inputValue(v);
1901
+ eSelected.focus();
17501902
});
17511903
Chat.settings.addListener('edit-compact-mode',function(s){
1752
- Chat.e.inputLine.classList[
1904
+ if(Chat.e.inputX!==Chat.inputElement()){
1905
+ /* Text field/textarea mode: swap them if needed.
1906
+ Compact mode of inputX is toggled via CSS. */
1907
+ const a = s.value
1908
+ ? [Chat.e.input1, Chat.e.inputM, 0]
1909
+ : [Chat.e.inputM, Chat.e.input1, 1];
1910
+ const v = Chat.inputValue();
1911
+ Chat.inputValue('');
1912
+ Chat.e.inputFields.$currentIndex = a[2];
1913
+ Chat.inputValue(v);
1914
+ D.removeClass(a[0], 'hidden');
1915
+ D.addClass(a[1], 'hidden');
1916
+ }
1917
+ Chat.e.inputElementWrapper.classList[
17531918
s.value ? 'add' : 'remove'
17541919
]('compact');
1920
+ Chat.e.inputFields[Chat.e.inputFields.$currentIndex].focus();
17551921
});
17561922
Chat.settings.addListener('edit-ctrl-send',function(s){
17571923
const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1758
- const eInput = Chat.inputElement();
1759
- eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
1924
+ Chat.e.inputFields.forEach((e)=>{
1925
+ const v = e.dataset.placeholder0 + " " +label;
1926
+ if(e.isContentEditable) e.dataset.placeholder = v;
1927
+ else D.attr(e,'placeholder',v);
1928
+ });
17601929
Chat.e.btnSubmit.title = label;
17611930
});
17621931
const valueKludges = {
17631932
/* Convert certain string-format values to other types... */
17641933
"false": false,
@@ -1784,11 +1953,11 @@
17841953
this.inputFocus();
17851954
};
17861955
Chat.e.viewPreview.querySelector('#chat-preview-close').
17871956
addEventListener('click', ()=>Chat.setCurrentView(Chat.e.viewMessages), false);
17881957
let previewPending = false;
1789
- const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputField];
1958
+ const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputFields];
17901959
const submit = function(ev){
17911960
ev.preventDefault();
17921961
ev.stopPropagation();
17931962
if(previewPending) return false;
17941963
const txt = Chat.inputValue();
17951964
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -43,10 +43,11 @@
43 const iso8601ish = function(d){
44 return d.toISOString()
45 .replace('T',' ').replace(/\.\d+/,'')
46 .replace('Z', ' zulu');
47 };
 
48 /** Returns the local time string of Date object d, defaulting
49 to the current time. */
50 const localTimeString = function ff(d){
51 d || (d = new Date());
52 return [
@@ -93,11 +94,11 @@
93 ht = wh;
94 }else{
95 elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
96 ht = wh - extra;
97 }
98 f.chat.e.inputField.style.maxHeight = (ht/2)+"px";
99 /* ^^^^ this is a middle ground between having no size cap
100 on the input field and having a fixed arbitrary cap. */;
101 contentArea.style.height =
102 contentArea.style.maxHeight = [
103 "calc(", (ht>=100 ? ht : 100), "px",
@@ -109,21 +110,17 @@
109 if(false){
110 console.debug("resized.",wh, extra, ht,
111 window.getComputedStyle(contentArea).maxHeight,
112 contentArea);
113 console.debug("Set input max height to: ",
114 f.chat.e.inputField.style.maxHeight);
115 }
116 };
117 var doit;
118 window.addEventListener('resize',function(ev){
119 clearTimeout(doit);
120 doit = setTimeout(resized, 100);
121 }, false);
122 return resized;
123 })();
124 ForceResizeKludge.$disabled = true/*gets deleted when setup is finished*/;
125 fossil.FRK = ForceResizeKludge/*for debugging*/;
126 const Chat = ForceResizeKludge.chat = (function(){
127 const cs = {
128 verboseErrors: false /* if true then certain, mostly extraneous,
129 error messages may be sent to the console. */,
@@ -130,16 +127,18 @@
130 e:{/*map of certain DOM elements.*/
131 messageInjectPoint: E1('#message-inject-point'),
132 pageTitle: E1('head title'),
133 loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */,
134 inputWrapper: E1("#chat-input-area"),
135 inputLine: E1('#chat-input-line'),
136 fileSelectWrapper: E1('#chat-input-file-area'),
137 viewMessages: E1('#chat-messages-wrapper'),
138 btnSubmit: E1('#chat-button-submit'),
139 btnAttach: E1('#chat-button-attach'),
140 inputField: E1('#chat-input-field'),
 
 
141 inputFile: E1('#chat-input-file'),
142 contentDiv: E1('div.content'),
143 viewConfig: E1('#chat-config'),
144 viewPreview: E1('#chat-preview'),
145 previewContent: E1('#chat-preview-content'),
@@ -192,23 +191,24 @@
192 taking into account single- vs multi-line input. The getter returns
193 a string and the setter returns this object. */
194 inputValue: function(){
195 const e = this.inputElement();
196 if(arguments.length){
197 e.innerText = arguments[0];
 
198 return this;
199 }
200 return e.innerText;
201 },
202 /** Asks the current user input field to take focus. Returns this. */
203 inputFocus: function(){
204 this.inputElement().focus();
205 return this;
206 },
207 /** Returns the current message input element. */
208 inputElement: function(){
209 return this.e.inputField;
210 },
211 /** Enables (if yes is truthy) or disables all elements in
212 * this.disableDuringAjax. */
213 enableAjaxComponents: function(yes){
214 D[yes ? 'enable' : 'disable'](this.disableDuringAjax);
@@ -415,11 +415,11 @@
415 laid out in a compact form. When off, the edit field and
416 buttons are larger. */
417 "edit-compact-mode": true,
418 /* When on, sets the font-family on messages and the edit
419 field to monospace. */
420 "monospace-messages": true,
421 /* When on, non-chat UI elements (page header/footer) are
422 hidden */
423 "chat-only-mode": false,
424 /* When set to a URI, it is assumed to be an audio file,
425 which gets played when new messages arrive. When true,
@@ -434,11 +434,17 @@
434 timestamp of each user's most recent message. */
435 "active-user-list-timestamps": false,
436 /* When on, the [audible-alert] is played for one's own
437 messages, else it is only played for other users'
438 messages. */
439 "alert-own-messages": false
 
 
 
 
 
 
440 }
441 },
442 /** Plays a new-message notification sound IF the audible-alert
443 setting is true, else this is a no-op. Returns this.
444 */
@@ -672,16 +678,22 @@
672 D.addClassBriefly(e, a, 0, cb);
673 }
674 return this;
675 }
676 };
677 if(D.attr(cs.e.inputField,'contenteditable','plaintext-only').isContentEditable){
 
 
 
 
 
 
678 cs.$browserHasPlaintextOnly = true;
679 }else{
680 /* Only the Chrome family supports contenteditable=plaintext-only */
681 cs.$browserHasPlaintextOnly = false;
682 D.attr(cs.e.inputField,'contenteditable','true');
683 }
684 cs.animate.$disabled = true;
685 F.fetch.beforesend = ()=>cs.ajaxStart();
686 F.fetch.aftersend = ()=>cs.ajaxEnd();
687 cs.pageTitleOrig = cs.e.pageTitle.innerText;
@@ -702,18 +714,21 @@
702 Reports an error in the form of a new message in the chat
703 feed. All arguments are appended to the message's content area
704 using fossil.dom.append(), so may be of any type supported by
705 that function.
706 */
707 cs.reportErrorAsMessage = function(/*msg args*/){
708 const args = argsToArray(arguments);
 
 
 
709 console.error("chat error:",args);
710 const d = new Date().toISOString(),
711 mw = new this.MessageWidget({
712 isError: true,
713 xfrom: null,
714 msgid: -1,
715 mtime: d,
716 lmtime: d,
717 xmsg: args
718 });
719 this.injectMessageElem(mw.e.body);
@@ -873,10 +888,20 @@
873 };
874 document.addEventListener('visibilitychange', function(ev){
875 cs.pageIsActive = ('visible' === document.visibilityState);
876 if(cs.pageIsActive){
877 cs.e.pageTitle.innerText = cs.pageTitleOrig;
 
 
 
 
 
 
 
 
 
 
878 }
879 }, true);
880 cs.setCurrentView(cs.e.viewMessages);
881
882 cs.e.activeUserList.addEventListener('click', function f(ev){
@@ -989,10 +1014,19 @@
989 })
990 elem.querySelectorAll('[data-numtag]').forEach(
991 (e)=>e.addEventListener('click', f.$clickNum, false)
992 )
993 }/*setupHashtags()*/;
 
 
 
 
 
 
 
 
 
994
995 /**
996 Custom widget type for rendering messages (one message per
997 instance). These are modelled after FIELDSET elements but we
998 don't use FIELDSET because of cross-browser inconsistencies in
@@ -1016,11 +1050,10 @@
1016 if(arguments.length){
1017 this.setMessage(arguments[0]);
1018 }
1019 };
1020 /* Left-zero-pad a number to at least 2 digits */
1021 const pad2 = (x)=>(''+x).length>1 ? x : '0'+x;
1022 const dowMap = {
1023 /* Map of Date.getDay() values to weekday names. */
1024 0: "Sunday", 1: "Monday", 2: "Tuesday",
1025 3: "Wednesday", 4: "Thursday", 5: "Friday",
1026 6: "Saturday"
@@ -1034,10 +1067,11 @@
1034 d.getHours(),":",
1035 (d.getMinutes()+100).toString().slice(1,3),
1036 ' ', dowMap[d.getDay()]
1037 ].join('');
1038 };
 
1039 cf.prototype = {
1040 scrollIntoView: function(){
1041 this.e.content.scrollIntoView();
1042 },
1043 setMessage: function(m){
@@ -1068,11 +1102,11 @@
1068 if(m.isError){
1069 D.addClass([contentTarget, this.e.tab], 'error');
1070 }
1071 D.append(
1072 this.e.tab,
1073 D.text('notification @ ',theTime(d))
1074 );
1075 }
1076 if( m.xfrom && m.fsize>0 ){
1077 if( m.fmime
1078 && m.fmime.startsWith("image/")
@@ -1105,11 +1139,11 @@
1105 // hyperlinks, but otherwise it will be markup-free. See the
1106 // chat_format_to_html() routine in the server for details.
1107 //
1108 // Hence, even though innerHTML is normally frowned upon, it is
1109 // perfectly safe to use in this context.
1110 if(m.xmsg instanceof Array){
1111 // Used by Chat.reportErrorAsMessage()
1112 D.append(contentTarget, m.xmsg);
1113 }else{
1114 contentTarget.innerHTML = m.xmsg;
1115 contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
@@ -1117,10 +1151,12 @@
1117 if(F.pikchr){
1118 F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
1119 }
1120 }
1121 }
 
 
1122 this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false);
1123 /*if(eXFrom){
1124 eXFrom.addEventListener('click', ()=>this.e.tab.click(), false);
1125 }*/
1126 return this;
@@ -1249,14 +1285,11 @@
1249 this.$eMsg = tgtMsg;
1250 this.refresh();
1251 }
1252 }/*f.popup*/;
1253 }/*end static init*/
1254 let theMsg = ev.target;
1255 while( theMsg && !theMsg.classList.contains('message-widget')){
1256 theMsg = theMsg.parentNode;
1257 }
1258 if(theMsg) f.popup.show(theMsg);
1259 }/*_handleLegendClicked()*/
1260 }/*MessageWidget.prototype*/;
1261 /** Assumes that e is a MessageWidget element, ensures that
1262 Chat.e.viewMessages is visible, scrolls the message,
@@ -1283,11 +1316,11 @@
1283 }
1284 };
1285 /** Updates the paste/drop zone with details of the pasted/dropped
1286 data. The argument must be a Blob or Blob-like object (File) or
1287 it can be falsy to reset/clear that state.*/
1288 const updateDropZoneContent = function(blob){
1289 //console.debug("updateDropZoneContent()",blob);
1290 const dd = bxs.dropDetails;
1291 bxs.blob = blob;
1292 D.clearElement(dd);
1293 if(!blob){
@@ -1332,11 +1365,11 @@
1332 /* Acrobatics to keep *some* installations of Firefox
1333 from pasting formatting into contenteditable fields.
1334 This also works on Chrome, but chrome has the
1335 contenteditable=plaintext-only property which does this
1336 for us. */
1337 Chat.inputElement().addEventListener(
1338 'paste',
1339 function(ev){
1340 if (ev.clipboardData && ev.clipboardData.getData) {
1341 const pastedText = ev.clipboardData.getData('text/plain');
1342 const selection = window.getSelection();
@@ -1356,30 +1389,60 @@
1356 ev.dataTransfer.dropEffect = 'none';
1357 ev.preventDefault();
1358 ev.stopPropagation();
1359 return false;
1360 };
1361
1362 ['drop','dragenter','dragleave','dragend'].forEach(
1363 (k)=>{
1364 Chat.inputElement().addEventListener(k, noDragDropEvents, false);
1365 }
1366 );
1367 return bxs;
1368 })()/*drag/drop/paste*/;
1369
1370 const tzOffsetToString = function(off){
1371 const hours = Math.round(off/60), min = Math.round(off % 30);
1372 return ''+(hours + (min ? '.5' : ''));
1373 };
1374 const pad2 = (x)=>('0'+x).substr(-2);
1375 const localTime8601 = function(d){
1376 return [
1377 d.getYear()+1900, '-', pad2(d.getMonth()+1), '-', pad2(d.getDate()),
1378 'T', pad2(d.getHours()),':', pad2(d.getMinutes()),':',pad2(d.getSeconds())
1379 ].join('');
1380 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1381
1382 /**
1383 Submits the contents of the message input field (if not empty)
1384 and/or the file attachment field to the server. If both are
1385 empty, this is a no-op.
@@ -1389,11 +1452,12 @@
1389 f.spaces = /\s+$/;
1390 f.markdownContinuation = /\\\s+$/;
1391 }
1392 this.setCurrentView(this.e.viewMessages);
1393 const fd = new FormData();
1394 var msg = this.inputValue().trim();
 
1395 if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1396 /* Cosmetic: trim whitespace from the ends of lines to try to
1397 keep copy/paste from terminals, especially wide ones, from
1398 forcing a horizontal scrollbar on all clients. This breaks
1399 markdown's use of blackslash-space-space for paragraph
@@ -1412,25 +1476,29 @@
1412 }
1413 if(msg) fd.set('msg',msg);
1414 const file = BlobXferState.blob || this.e.inputFile.files[0];
1415 if(file) fd.set("file", file);
1416 if( !msg && !file ) return;
 
1417 const self = this;
1418 fd.set("lmtime", localTime8601(new Date()));
1419 F.fetch("chat-send",{
1420 payload: fd,
1421 responseType: 'text',
1422 onerror:(err)=>this.reportErrorAsMessage(err),
 
 
 
1423 onload:function(txt){
1424 if(!txt) return/*success response*/;
1425 try{
1426 const json = JSON.parse(txt);
1427 self.newContent({msgs:[json]});
1428 }catch(e){
1429 self.reportError(e);
1430 return;
1431 }
 
1432 }
1433 });
1434 BlobXferState.clear();
1435 Chat.inputValue("").inputFocus();
1436 };
@@ -1494,11 +1562,13 @@
1494 ev.stopPropagation();
1495 Chat.submitMessage();
1496 return false;
1497 }
1498 };
1499 Chat.e.inputField.addEventListener('keydown', inputWidgetKeydown, false);
 
 
1500 Chat.e.btnSubmit.addEventListener('click',(e)=>{
1501 e.preventDefault();
1502 Chat.submitMessage();
1503 return false;
1504 });
@@ -1553,76 +1623,110 @@
1553 Settings options structure: an array of Objects with the
1554 following properties:
1555
1556 label: string for the UI
1557
1558 boolValue: string (name of Chat.settings setting) or a
1559 function which returns true or false. Gets mapped to
1560 a checkbox.
 
 
1561
1562 select: SELECT element (instead of boolValue)
1563
1564 callback: optional handler to call after setting is modified.
1565 It gets passed the setting object: {key:string, value:something}.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1566
1567 If a setting has a boolValue set, that gets transformed into a
1568 checkbox which toggles the given persistent setting (if
1569 boolValue is a string) AND listens for changes to that setting
1570 fired via Chat.settings.set() so that the checkbox can stay in
1571 sync with external changes to that setting. Various Chat UI
1572 elements stay in sync with the config UI via those settings
1573 events.
 
1574 */
1575 const settingsOps = [{
1576 label: "Ctrl-enter to Send",
1577 hint: [
1578 "When on, only Ctrl-Enter will send messages and Enter adds ",
1579 "blank lines. ",
1580 "When off, both Enter and Ctrl-Enter send. ",
1581 "When the input field has focus, is empty, and preview ",
1582 "mode is NOT active then Ctrl-Enter toggles this setting."
1583 ].join(''),
1584 boolValue: 'edit-ctrl-send'
1585 },{
1586 label: "Compact mode",
1587 hint: [
1588 "Toggle between a space-saving or more spacious writing area. ",
1589 "When the input field has focus, is empty, and preview mode ",
1590 "is NOT active then Shift-Enter toggles this setting."
1591 ].join(''),
1592 boolValue: 'edit-compact-mode'
1593 },{
1594 label: "Left-align my posts",
1595 hint: "Default alignment of your own messages is selected "
1596 +"based window width/height relationship.",
1597 boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1598 callback: function f(){
1599 document.body.classList[
1600 this.checkbox.checked ? 'remove' : 'add'
1601 ]('my-messages-right');
1602 }
1603 },{
1604 label: "Monospace message font",
1605 hint: "Use monospace font for message text?",
1606 boolValue: 'monospace-messages',
1607 callback: function(setting){
1608 document.body.classList[
1609 setting.value ? 'add' : 'remove'
1610 ]('monospace-messages');
1611 }
1612 },{
1613 label: "Chat-only mode",
1614 hint: "Toggle the page between normal fossil view and chat-only view.",
1615 boolValue: 'chat-only-mode'
1616 },{
1617 label: "Show images inline",
1618 hint: "Whether to show images inline or as a hyperlink.",
1619 boolValue: 'images-inline'
1620 },namedOptions.activeUsers,{
1621 label: "Timestamps in active users list",
1622 hint: "Whether to show last-message timestamps.",
1623 boolValue: 'active-user-list-timestamps'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1624 }];
1625
1626 /** Set up selection list of notification sounds. */
1627 if(1){
1628 const selectSound = D.select();
@@ -1641,45 +1745,64 @@
1641 selectSound.selectedIndex = firstSoundIndex;
1642 }
1643 }
1644 Chat.setNewMessageSound(selectSound.value);
1645 settingsOps.push({
1646 hint: "Audio alert. How to enable audio playback is browser-specific!",
1647 select: selectSound,
1648 callback: function(ev){
1649 const v = ev.target.value;
1650 Chat.setNewMessageSound(v);
1651 F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1652 if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1653 }
 
 
 
 
 
 
 
 
 
 
1654 });
1655 }/*audio notification config*/
1656 settingsOps.push({
1657 label: "Play notification for your own messages.",
1658 hint: "When enabled, the audio notification will be played for all messages, "+
1659 "including your own. When disabled only messages from other users "+
1660 "will trigger a notification.",
1661 boolValue: 'alert-own-messages'
 
 
 
 
 
 
 
1662 });
1663 /**
1664 Build UI for config options...
1665 */
1666 settingsOps.forEach(function f(op){
1667 const line = D.addClass(D.div(), 'menu-entry');
 
1668 const label = op.label
1669 ? D.append(D.label(),op.label) : undefined;
1670 const labelWrapper = D.addClass(D.div(), 'label-wrapper');
1671 var hint;
1672 const col0 = D.span();
1673 if(op.hint){
1674 hint = D.append(D.addClass(D.span(),'hint'),op.hint);
1675 }
1676 if(op.hasOwnProperty('select')){
1677 D.append(line, col0, labelWrapper);
 
 
1678 D.append(labelWrapper, op.select);
1679 if(hint) D.append(labelWrapper, hint);
1680 if(label) D.append(col0, label);
1681 if(op.callback){
1682 op.select.addEventListener('change', (ev)=>op.callback(ev), false);
1683 }
1684 }else if(op.hasOwnProperty('boolValue')){
1685 if(undefined === f.$id) f.$id = 0;
@@ -1691,27 +1814,31 @@
1691 }
1692 const check = op.checkbox
1693 = D.attr(D.checkbox(1, op.boolValue()),
1694 'aria-label', op.label);
1695 const id = 'cfgopt'+f.$id;
 
1696 check.checked = op.boolValue();
1697 op.checkbox = check;
1698 D.attr(check, 'id', id);
1699 D.append(line, col0, labelWrapper);
 
1700 D.append(col0, check);
1701 if(label){
1702 D.attr(label, 'for', id);
1703 D.append(labelWrapper, label);
1704 }
1705 if(hint) D.append(labelWrapper, hint);
1706 }else{
1707 line.addEventListener('click', callback);
1708 D.append(line, col0, labelWrapper);
 
 
1709 if(label) D.append(labelWrapper, label);
1710 if(hint) D.append(labelWrapper, hint);
1711 }
1712 D.append(optionsMenu, line);
1713 if(op.persistentSetting){
1714 Chat.settings.addListener(
1715 op.persistentSetting,
1716 function(setting){
1717 if(op.checkbox) op.checkbox.checked = !!setting.value;
@@ -1726,10 +1853,14 @@
1726 }, false);
1727 }
1728 }else if(op.callback && op.checkbox){
1729 op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false);
1730 }
 
 
 
 
1731 });
1732 })()/*#chat-button-settings setup*/;
1733
1734 (function(){
1735 /* Install default settings... must come after
@@ -1745,20 +1876,58 @@
1745 Chat.settings.addListener('active-user-list-timestamps',function(s){
1746 Chat.showActiveUserTimestamps(s.value);
1747 });
1748 Chat.settings.addListener('chat-only-mode',function(s){
1749 Chat.chatOnlyMode(s.value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1750 });
1751 Chat.settings.addListener('edit-compact-mode',function(s){
1752 Chat.e.inputLine.classList[
 
 
 
 
 
 
 
 
 
 
 
 
 
1753 s.value ? 'add' : 'remove'
1754 ]('compact');
 
1755 });
1756 Chat.settings.addListener('edit-ctrl-send',function(s){
1757 const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1758 const eInput = Chat.inputElement();
1759 eInput.dataset.placeholder = eInput.dataset.placeholder0 + " " +label;
 
 
 
1760 Chat.e.btnSubmit.title = label;
1761 });
1762 const valueKludges = {
1763 /* Convert certain string-format values to other types... */
1764 "false": false,
@@ -1784,11 +1953,11 @@
1784 this.inputFocus();
1785 };
1786 Chat.e.viewPreview.querySelector('#chat-preview-close').
1787 addEventListener('click', ()=>Chat.setCurrentView(Chat.e.viewMessages), false);
1788 let previewPending = false;
1789 const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputField];
1790 const submit = function(ev){
1791 ev.preventDefault();
1792 ev.stopPropagation();
1793 if(previewPending) return false;
1794 const txt = Chat.inputValue();
1795
--- src/fossil.page.chat.js
+++ src/fossil.page.chat.js
@@ -43,10 +43,11 @@
43 const iso8601ish = function(d){
44 return d.toISOString()
45 .replace('T',' ').replace(/\.\d+/,'')
46 .replace('Z', ' zulu');
47 };
48 const pad2 = (x)=>('0'+x).substr(-2);
49 /** Returns the local time string of Date object d, defaulting
50 to the current time. */
51 const localTimeString = function ff(d){
52 d || (d = new Date());
53 return [
@@ -93,11 +94,11 @@
94 ht = wh;
95 }else{
96 elemsToCount.forEach((e)=>e ? extra += D.effectiveHeight(e) : false);
97 ht = wh - extra;
98 }
99 f.chat.e.inputX.style.maxHeight = (ht/2)+"px";
100 /* ^^^^ this is a middle ground between having no size cap
101 on the input field and having a fixed arbitrary cap. */;
102 contentArea.style.height =
103 contentArea.style.maxHeight = [
104 "calc(", (ht>=100 ? ht : 100), "px",
@@ -109,21 +110,17 @@
110 if(false){
111 console.debug("resized.",wh, extra, ht,
112 window.getComputedStyle(contentArea).maxHeight,
113 contentArea);
114 console.debug("Set input max height to: ",
115 f.chat.e.inputX.style.maxHeight);
116 }
117 };
118 resized.$disabled = true/*gets deleted when setup is finished*/;
119 window.addEventListener('resize', F.debounce(resized, 250), false);
 
 
 
120 return resized;
121 })();
 
122 fossil.FRK = ForceResizeKludge/*for debugging*/;
123 const Chat = ForceResizeKludge.chat = (function(){
124 const cs = {
125 verboseErrors: false /* if true then certain, mostly extraneous,
126 error messages may be sent to the console. */,
@@ -130,16 +127,18 @@
127 e:{/*map of certain DOM elements.*/
128 messageInjectPoint: E1('#message-inject-point'),
129 pageTitle: E1('head title'),
130 loadOlderToolbar: undefined /* the load-posts toolbar (dynamically created) */,
131 inputWrapper: E1("#chat-input-area"),
132 inputElementWrapper: E1('#chat-input-line-wrapper'),
133 fileSelectWrapper: E1('#chat-input-file-area'),
134 viewMessages: E1('#chat-messages-wrapper'),
135 btnSubmit: E1('#chat-button-submit'),
136 btnAttach: E1('#chat-button-attach'),
137 inputX: E1('#chat-input-field-x'),
138 input1: E1('#chat-input-field-single'),
139 inputM: E1('#chat-input-field-multi'),
140 inputFile: E1('#chat-input-file'),
141 contentDiv: E1('div.content'),
142 viewConfig: E1('#chat-config'),
143 viewPreview: E1('#chat-preview'),
144 previewContent: E1('#chat-preview-content'),
@@ -192,23 +191,24 @@
191 taking into account single- vs multi-line input. The getter returns
192 a string and the setter returns this object. */
193 inputValue: function(){
194 const e = this.inputElement();
195 if(arguments.length){
196 if(e.isContentEditable) e.innerText = arguments[0];
197 else e.value = arguments[0];
198 return this;
199 }
200 return e.isContentEditable ? e.innerText : e.value;
201 },
202 /** Asks the current user input field to take focus. Returns this. */
203 inputFocus: function(){
204 this.inputElement().focus();
205 return this;
206 },
207 /** Returns the current message input element. */
208 inputElement: function(){
209 return this.e.inputFields[this.e.inputFields.$currentIndex];
210 },
211 /** Enables (if yes is truthy) or disables all elements in
212 * this.disableDuringAjax. */
213 enableAjaxComponents: function(yes){
214 D[yes ? 'enable' : 'disable'](this.disableDuringAjax);
@@ -415,11 +415,11 @@
415 laid out in a compact form. When off, the edit field and
416 buttons are larger. */
417 "edit-compact-mode": true,
418 /* When on, sets the font-family on messages and the edit
419 field to monospace. */
420 "monospace-messages": false,
421 /* When on, non-chat UI elements (page header/footer) are
422 hidden */
423 "chat-only-mode": false,
424 /* When set to a URI, it is assumed to be an audio file,
425 which gets played when new messages arrive. When true,
@@ -434,11 +434,17 @@
434 timestamp of each user's most recent message. */
435 "active-user-list-timestamps": false,
436 /* When on, the [audible-alert] is played for one's own
437 messages, else it is only played for other users'
438 messages. */
439 "alert-own-messages": false,
440 /* "Experimental mode" input: use a contenteditable field
441 for input. This is generally more comfortable to use,
442 and more modern, than plain text input fields, but
443 the list of browser-specific quirks and bugs is...
444 not short. */
445 "edit-widget-x": false
446 }
447 },
448 /** Plays a new-message notification sound IF the audible-alert
449 setting is true, else this is a no-op. Returns this.
450 */
@@ -672,16 +678,22 @@
678 D.addClassBriefly(e, a, 0, cb);
679 }
680 return this;
681 }
682 };
683 cs.e.inputFields = [ cs.e.input1, cs.e.inputM, cs.e.inputX ];
684 cs.e.inputFields.$currentIndex = 0;
685 cs.e.inputFields.forEach(function(e,ndx){
686 if(ndx===cs.e.inputFields.$currentIndex) D.removeClass(e,'hidden');
687 else D.addClass(e,'hidden');
688 });
689 if(D.attr(cs.e.inputX,'contenteditable','plaintext-only').isContentEditable){
690 cs.$browserHasPlaintextOnly = true;
691 }else{
692 /* Only the Chrome family supports contenteditable=plaintext-only */
693 cs.$browserHasPlaintextOnly = false;
694 D.attr(cs.e.inputX,'contenteditable','true');
695 }
696 cs.animate.$disabled = true;
697 F.fetch.beforesend = ()=>cs.ajaxStart();
698 F.fetch.aftersend = ()=>cs.ajaxEnd();
699 cs.pageTitleOrig = cs.e.pageTitle.innerText;
@@ -702,18 +714,21 @@
714 Reports an error in the form of a new message in the chat
715 feed. All arguments are appended to the message's content area
716 using fossil.dom.append(), so may be of any type supported by
717 that function.
718 */
719 cs.reportErrorAsMessage = function f(/*msg args*/){
720 if(undefined === f.$msgid) f.$msgid=0;
721 const args = argsToArray(arguments).map(function(v){
722 return (v instanceof Error) ? v.message : v;
723 });
724 console.error("chat error:",args);
725 const d = new Date().toISOString(),
726 mw = new this.MessageWidget({
727 isError: true,
728 xfrom: null,
729 msgid: "error-"+(++f.$msgid),
730 mtime: d,
731 lmtime: d,
732 xmsg: args
733 });
734 this.injectMessageElem(mw.e.body);
@@ -873,10 +888,20 @@
888 };
889 document.addEventListener('visibilitychange', function(ev){
890 cs.pageIsActive = ('visible' === document.visibilityState);
891 if(cs.pageIsActive){
892 cs.e.pageTitle.innerText = cs.pageTitleOrig;
893 if(document.activeElement!==cs.inputElement()){
894 /* An attempt to resolve usability problem reported by Joe
895 M. where the Pale Moon browser is giving input focus to
896 the Preview button. The down-side of this is that it will
897 deselect any text which was previously selected on this
898 page. This also, unfortunately, places the focus at the
899 start of the element, rather than the last cursor position
900 (like a textarea would). */
901 setTimeout(()=>cs.inputFocus(), 0);
902 }
903 }
904 }, true);
905 cs.setCurrentView(cs.e.viewMessages);
906
907 cs.e.activeUserList.addEventListener('click', function f(ev){
@@ -989,10 +1014,19 @@
1014 })
1015 elem.querySelectorAll('[data-numtag]').forEach(
1016 (e)=>e.addEventListener('click', f.$clickNum, false)
1017 )
1018 }/*setupHashtags()*/;
1019
1020 /** Returns the first .message-widget element in DOM element
1021 e's lineage. */
1022 const findMessageWidgetParent = function(e){
1023 while( e && !e.classList.contains('message-widget')){
1024 e = e.parentNode;
1025 }
1026 return e;
1027 };
1028
1029 /**
1030 Custom widget type for rendering messages (one message per
1031 instance). These are modelled after FIELDSET elements but we
1032 don't use FIELDSET because of cross-browser inconsistencies in
@@ -1016,11 +1050,10 @@
1050 if(arguments.length){
1051 this.setMessage(arguments[0]);
1052 }
1053 };
1054 /* Left-zero-pad a number to at least 2 digits */
 
1055 const dowMap = {
1056 /* Map of Date.getDay() values to weekday names. */
1057 0: "Sunday", 1: "Monday", 2: "Tuesday",
1058 3: "Wednesday", 4: "Thursday", 5: "Friday",
1059 6: "Saturday"
@@ -1034,10 +1067,11 @@
1067 d.getHours(),":",
1068 (d.getMinutes()+100).toString().slice(1,3),
1069 ' ', dowMap[d.getDay()]
1070 ].join('');
1071 };
1072
1073 cf.prototype = {
1074 scrollIntoView: function(){
1075 this.e.content.scrollIntoView();
1076 },
1077 setMessage: function(m){
@@ -1068,11 +1102,11 @@
1102 if(m.isError){
1103 D.addClass([contentTarget, this.e.tab], 'error');
1104 }
1105 D.append(
1106 this.e.tab,
1107 D.append(D.code(), 'notification @ ',theTime(d))
1108 );
1109 }
1110 if( m.xfrom && m.fsize>0 ){
1111 if( m.fmime
1112 && m.fmime.startsWith("image/")
@@ -1105,11 +1139,11 @@
1139 // hyperlinks, but otherwise it will be markup-free. See the
1140 // chat_format_to_html() routine in the server for details.
1141 //
1142 // Hence, even though innerHTML is normally frowned upon, it is
1143 // perfectly safe to use in this context.
1144 if(m.xmsg && 'string' !== typeof m.xmsg){
1145 // Used by Chat.reportErrorAsMessage()
1146 D.append(contentTarget, m.xmsg);
1147 }else{
1148 contentTarget.innerHTML = m.xmsg;
1149 contentTarget.querySelectorAll('a').forEach(addAnchorTargetBlank);
@@ -1117,10 +1151,12 @@
1151 if(F.pikchr){
1152 F.pikchr.addSrcView(contentTarget.querySelectorAll('svg.pikchr'));
1153 }
1154 }
1155 }
1156 //console.debug("tab",this.e.tab);
1157 //console.debug("this.e.tab.firstElementChild",this.e.tab.firstElementChild);
1158 this.e.tab.firstElementChild.addEventListener('click', this._handleLegendClicked, false);
1159 /*if(eXFrom){
1160 eXFrom.addEventListener('click', ()=>this.e.tab.click(), false);
1161 }*/
1162 return this;
@@ -1249,14 +1285,11 @@
1285 this.$eMsg = tgtMsg;
1286 this.refresh();
1287 }
1288 }/*f.popup*/;
1289 }/*end static init*/
1290 const theMsg = findMessageWidgetParent(ev.target);
 
 
 
1291 if(theMsg) f.popup.show(theMsg);
1292 }/*_handleLegendClicked()*/
1293 }/*MessageWidget.prototype*/;
1294 /** Assumes that e is a MessageWidget element, ensures that
1295 Chat.e.viewMessages is visible, scrolls the message,
@@ -1283,11 +1316,11 @@
1316 }
1317 };
1318 /** Updates the paste/drop zone with details of the pasted/dropped
1319 data. The argument must be a Blob or Blob-like object (File) or
1320 it can be falsy to reset/clear that state.*/
1321 const updateDropZoneContent = bxs.updateDropZoneContent = function(blob){
1322 //console.debug("updateDropZoneContent()",blob);
1323 const dd = bxs.dropDetails;
1324 bxs.blob = blob;
1325 D.clearElement(dd);
1326 if(!blob){
@@ -1332,11 +1365,11 @@
1365 /* Acrobatics to keep *some* installations of Firefox
1366 from pasting formatting into contenteditable fields.
1367 This also works on Chrome, but chrome has the
1368 contenteditable=plaintext-only property which does this
1369 for us. */
1370 Chat.e.inputX.addEventListener(
1371 'paste',
1372 function(ev){
1373 if (ev.clipboardData && ev.clipboardData.getData) {
1374 const pastedText = ev.clipboardData.getData('text/plain');
1375 const selection = window.getSelection();
@@ -1356,30 +1389,60 @@
1389 ev.dataTransfer.dropEffect = 'none';
1390 ev.preventDefault();
1391 ev.stopPropagation();
1392 return false;
1393 };
 
1394 ['drop','dragenter','dragleave','dragend'].forEach(
1395 (k)=>Chat.e.inputX.addEventListener(k, noDragDropEvents, false)
 
 
1396 );
1397 return bxs;
1398 })()/*drag/drop/paste*/;
1399
1400 const tzOffsetToString = function(off){
1401 const hours = Math.round(off/60), min = Math.round(off % 30);
1402 return ''+(hours + (min ? '.5' : ''));
1403 };
 
1404 const localTime8601 = function(d){
1405 return [
1406 d.getYear()+1900, '-', pad2(d.getMonth()+1), '-', pad2(d.getDate()),
1407 'T', pad2(d.getHours()),':', pad2(d.getMinutes()),':',pad2(d.getSeconds())
1408 ].join('');
1409 };
1410
1411 /**
1412 Called by Chat.submitMessage() when message sending failed. Injects a fake message
1413 containing the content and attachment of the failed message and gives the user buttons
1414 to discard it or edit and retry.
1415 */
1416 const recoverFailedMessage = function(state){
1417 const w = D.addClass(D.div(), 'failed-message');
1418 D.append(w, D.append(
1419 D.span(),"This message was not successfully sent to the server:"
1420 ));
1421 if(state.msg){
1422 const ta = D.textarea();
1423 ta.value = state.msg;
1424 D.append(w,ta);
1425 }
1426 if(state.blob){
1427 D.append(w,D.append(D.span(),"Attachment: ",(state.blob.name||"unnamed")));
1428 //console.debug("blob = ",state.blob);
1429 }
1430 const buttons = D.addClass(D.div(), 'buttons');
1431 D.append(w, buttons);
1432 D.append(buttons, D.button("Discard message?", function(){
1433 let theMsg = findMessageWidgetParent(w);
1434 if(theMsg) Chat.deleteMessageElem(theMsg);
1435 }));
1436 D.append(buttons, D.button("Edit message and try again?", function(){
1437 if(state.msg) Chat.inputValue(ta.value);
1438 if(state.blob) BlobXferState.updateDropZoneContent(state.blob);
1439 let theMsg = findMessageWidgetParent(w);
1440 if(theMsg) Chat.deleteMessageElem(theMsg);
1441 }));
1442 Chat.reportErrorAsMessage(w);
1443 };
1444
1445 /**
1446 Submits the contents of the message input field (if not empty)
1447 and/or the file attachment field to the server. If both are
1448 empty, this is a no-op.
@@ -1389,11 +1452,12 @@
1452 f.spaces = /\s+$/;
1453 f.markdownContinuation = /\\\s+$/;
1454 }
1455 this.setCurrentView(this.e.viewMessages);
1456 const fd = new FormData();
1457 const fallback = {msg: this.inputValue()};
1458 var msg = fallback.msg.trim();
1459 if(msg && (msg.indexOf('\n')>0 || f.spaces.test(msg))){
1460 /* Cosmetic: trim whitespace from the ends of lines to try to
1461 keep copy/paste from terminals, especially wide ones, from
1462 forcing a horizontal scrollbar on all clients. This breaks
1463 markdown's use of blackslash-space-space for paragraph
@@ -1412,25 +1476,29 @@
1476 }
1477 if(msg) fd.set('msg',msg);
1478 const file = BlobXferState.blob || this.e.inputFile.files[0];
1479 if(file) fd.set("file", file);
1480 if( !msg && !file ) return;
1481 fallback.blob = file;
1482 const self = this;
1483 fd.set("lmtime", localTime8601(new Date()));
1484 F.fetch("chat-send",{
1485 payload: fd,
1486 responseType: 'text',
1487 onerror:function(err){
1488 self.reportErrorAsMessage(err);
1489 recoverFailedMessage(fallback);
1490 },
1491 onload:function(txt){
1492 if(!txt) return/*success response*/;
1493 try{
1494 const json = JSON.parse(txt);
1495 self.newContent({msgs:[json]});
1496 }catch(e){
1497 self.reportError(e);
 
1498 }
1499 recoverFailedMessage(fallback);
1500 }
1501 });
1502 BlobXferState.clear();
1503 Chat.inputValue("").inputFocus();
1504 };
@@ -1494,11 +1562,13 @@
1562 ev.stopPropagation();
1563 Chat.submitMessage();
1564 return false;
1565 }
1566 };
1567 Chat.e.inputFields.forEach(
1568 (e)=>e.addEventListener('keydown', inputWidgetKeydown, false)
1569 );
1570 Chat.e.btnSubmit.addEventListener('click',(e)=>{
1571 e.preventDefault();
1572 Chat.submitMessage();
1573 return false;
1574 });
@@ -1553,76 +1623,110 @@
1623 Settings options structure: an array of Objects with the
1624 following properties:
1625
1626 label: string for the UI
1627
1628 boolValue: string (name of Chat.settings setting) or a function
1629 which returns true or false. If it is a string, it gets
1630 replaced by a function which returns
1631 Chat.settings.getBool(thatString) and the string gets assigned
1632 to the persistentSetting property of this object.
1633
1634 select: SELECT element (instead of boolValue)
1635
1636 callback: optional handler to call after setting is modified.
1637 It gets passed the setting object: {key:string, value:something}.
1638 Its "this" is the options object. If this object has a
1639 boolValue string or a persistentSetting property, the argument
1640 passed to the callback is a settings object in the form {key:K,
1641 value:V}. If this object does not have boolValue string or
1642 persistentSetting then the callback is passed an event object
1643 in response to the config option's UI widget being activated,
1644 normally a 'change' event.
1645
1646 children: [array of settings objects]. These get listed under
1647 this element and indented slightly for visual grouping. Only
1648 one level of indention is supported.
1649
1650 Elements which only have a label and maybe a hint and
1651 children can be used as headings.
1652
1653 If a setting has a boolValue set, that gets rendered as a
1654 checkbox which toggles the given persistent setting (if
1655 boolValue is a string) AND listens for changes to that setting
1656 fired via Chat.settings.set() so that the checkbox can stay in
1657 sync with external changes to that setting. Various Chat UI
1658 elements stay in sync with the config UI via those settings
1659 events. The checkbox element gets added to the options object
1660 so that the callback() can reference it via this.checkbox.
1661 */
1662 const settingsOps = [{
1663 label: "Chat Configuration Options",
1664 hint: F.storage.isTransient()
1665 ? "Local store is unavailable. These settings are transient."
1666 : ["Most of these settings are persistent via ",
1667 F.storage.storageImplName(), ": ",
1668 F.storage.storageHelpDescription()].join('')
1669 },{
1670 label: "Editing Options...",
1671 children:[{
1672 label: "Chat-only mode",
1673 hint: "Toggle the page between normal fossil view and chat-only view.",
1674 boolValue: 'chat-only-mode'
1675 },{
1676 label: "Ctrl-enter to Send",
1677 hint: [
1678 "When on, only Ctrl-Enter will send messages and Enter adds ",
1679 "blank lines. When off, both Enter and Ctrl-Enter send. ",
1680 "When the input field has focus and is empty ",
1681 "then Ctrl-Enter toggles this setting."
1682 ].join(''),
1683 boolValue: 'edit-ctrl-send'
1684 },{
1685 label: "Compact mode",
1686 hint: [
1687 "Toggle between a space-saving or more spacious writing area. ",
1688 "When the input field has focus, is empty, and preview mode ",
1689 "is NOT active then Shift-Enter toggles this setting."].join(''),
1690 boolValue: 'edit-compact-mode'
1691 },{
1692 label: "Use 'contenteditable' editing mode",
1693 boolValue: 'edit-widget-x',
1694 hint: [
1695 "When enabled, chat input uses a so-called 'contenteditable' ",
1696 "field. Though generally more comfortable and modern than ",
1697 "plain-text input fields, browser-specific quirks and bugs ",
1698 "may lead to frustration. Ideal for mobile devices."
1699 ].join('')
1700 }]
1701 },{
1702 label: "Appearance Options...",
1703 children:[{
1704 label: "Left-align my posts",
1705 hint: "Default alignment of your own messages is selected "
1706 + "based window width/height ratio.",
1707 boolValue: ()=>!document.body.classList.contains('my-messages-right'),
1708 callback: function f(){
1709 document.body.classList[
1710 this.checkbox.checked ? 'remove' : 'add'
1711 ]('my-messages-right');
1712 }
1713 },{
1714 label: "Monospace message font",
1715 hint: "Use monospace font for message and input text.",
1716 boolValue: 'monospace-messages',
1717 callback: function(setting){
1718 document.body.classList[
1719 setting.value ? 'add' : 'remove'
1720 ]('monospace-messages');
1721 }
1722 },{
1723 label: "Show images inline",
1724 hint: "When enabled, attached images are shown inline, "+
1725 "else they appear as a download link.",
1726 boolValue: 'images-inline'
1727 }]
1728 }];
1729
1730 /** Set up selection list of notification sounds. */
1731 if(1){
1732 const selectSound = D.select();
@@ -1641,45 +1745,64 @@
1745 selectSound.selectedIndex = firstSoundIndex;
1746 }
1747 }
1748 Chat.setNewMessageSound(selectSound.value);
1749 settingsOps.push({
1750 label: "Sound Options...",
1751 hint: "How to enable audio playback is browser-specific!",
1752 children:[{
1753 hint: "Audio alert",
1754 select: selectSound,
1755 callback: function(ev){
1756 const v = ev.target.value;
1757 Chat.setNewMessageSound(v);
1758 F.toast.message("Audio notifications "+(v ? "enabled" : "disabled")+".");
1759 if(v) setTimeout(()=>Chat.playNewMessageSound(), 0);
1760 }
1761 },{
1762 label: "Play notification for your own messages",
1763 hint: "When enabled, the audio notification will be played for all messages, "+
1764 "including your own. When disabled only messages from other users "+
1765 "will trigger a notification.",
1766 boolValue: 'alert-own-messages'
1767 }]
1768 });
1769 }/*audio notification config*/
1770 settingsOps.push({
1771 label: "Active User List...",
1772 hint: [
1773 "/chat cannot track active connections, but it can tell ",
1774 "you who has posted recently..."].join(''),
1775 children:[
1776 namedOptions.activeUsers,{
1777 label: "Timestamps in active users list",
1778 indent: true,
1779 hint: "Show most recent message timestamps in the active user list.",
1780 boolValue: 'active-user-list-timestamps'
1781 }
1782 ]
1783 });
1784 /**
1785 Build UI for config options...
1786 */
1787 settingsOps.forEach(function f(op,indentOrIndex){
1788 const menuEntry = D.addClass(D.div(), 'menu-entry');
1789 if(true===indentOrIndex) D.addClass(menuEntry, 'child');
1790 const label = op.label
1791 ? D.append(D.label(),op.label) : undefined;
1792 const labelWrapper = D.addClass(D.div(), 'label-wrapper');
1793 var hint;
 
1794 if(op.hint){
1795 hint = D.append(D.addClass(D.label(),'hint'),op.hint);
1796 }
1797 if(op.hasOwnProperty('select')){
1798 const col0 = D.addClass(D.span(/*empty, but for spacing*/),
1799 'toggle-wrapper');
1800 D.append(menuEntry, labelWrapper, col0);
1801 D.append(labelWrapper, op.select);
1802 if(hint) D.append(labelWrapper, hint);
1803 if(label) D.append(label);
1804 if(op.callback){
1805 op.select.addEventListener('change', (ev)=>op.callback(ev), false);
1806 }
1807 }else if(op.hasOwnProperty('boolValue')){
1808 if(undefined === f.$id) f.$id = 0;
@@ -1691,27 +1814,31 @@
1814 }
1815 const check = op.checkbox
1816 = D.attr(D.checkbox(1, op.boolValue()),
1817 'aria-label', op.label);
1818 const id = 'cfgopt'+f.$id;
1819 const col0 = D.addClass(D.span(), 'toggle-wrapper');
1820 check.checked = op.boolValue();
1821 op.checkbox = check;
1822 D.attr(check, 'id', id);
1823 if(hint) D.attr(hint, 'for', id);
1824 D.append(menuEntry, labelWrapper, col0);
1825 D.append(col0, check);
1826 if(label){
1827 D.attr(label, 'for', id);
1828 D.append(labelWrapper, label);
1829 }
1830 if(hint) D.append(labelWrapper, hint);
1831 }else{
1832 if(op.callback){
1833 menuEntry.addEventListener('click', (ev)=>op.callback(ev));
1834 }
1835 D.append(menuEntry, labelWrapper);
1836 if(label) D.append(labelWrapper, label);
1837 if(hint) D.append(labelWrapper, hint);
1838 }
1839 D.append(optionsMenu, menuEntry);
1840 if(op.persistentSetting){
1841 Chat.settings.addListener(
1842 op.persistentSetting,
1843 function(setting){
1844 if(op.checkbox) op.checkbox.checked = !!setting.value;
@@ -1726,10 +1853,14 @@
1853 }, false);
1854 }
1855 }else if(op.callback && op.checkbox){
1856 op.checkbox.addEventListener('change', (ev)=>op.callback(ev), false);
1857 }
1858 if(op.children){
1859 D.addClass(menuEntry, 'parent');
1860 op.children.forEach((x)=>f(x,true));
1861 }
1862 });
1863 })()/*#chat-button-settings setup*/;
1864
1865 (function(){
1866 /* Install default settings... must come after
@@ -1745,20 +1876,58 @@
1876 Chat.settings.addListener('active-user-list-timestamps',function(s){
1877 Chat.showActiveUserTimestamps(s.value);
1878 });
1879 Chat.settings.addListener('chat-only-mode',function(s){
1880 Chat.chatOnlyMode(s.value);
1881 });
1882 Chat.settings.addListener('edit-widget-x',function(s){
1883 let eSelected;
1884 if(s.value){
1885 if(Chat.e.inputX===Chat.inputElement()) return;
1886 eSelected = Chat.e.inputX;
1887 }else{
1888 eSelected = Chat.settings.getBool('edit-compact-mode')
1889 ? Chat.e.input1 : Chat.e.inputM;
1890 }
1891 const v = Chat.inputValue();
1892 Chat.inputValue('');
1893 Chat.e.inputFields.forEach(function(e,ndx){
1894 if(eSelected===e){
1895 Chat.e.inputFields.$currentIndex = ndx;
1896 D.removeClass(e, 'hidden');
1897 }
1898 else D.addClass(e,'hidden');
1899 });
1900 Chat.inputValue(v);
1901 eSelected.focus();
1902 });
1903 Chat.settings.addListener('edit-compact-mode',function(s){
1904 if(Chat.e.inputX!==Chat.inputElement()){
1905 /* Text field/textarea mode: swap them if needed.
1906 Compact mode of inputX is toggled via CSS. */
1907 const a = s.value
1908 ? [Chat.e.input1, Chat.e.inputM, 0]
1909 : [Chat.e.inputM, Chat.e.input1, 1];
1910 const v = Chat.inputValue();
1911 Chat.inputValue('');
1912 Chat.e.inputFields.$currentIndex = a[2];
1913 Chat.inputValue(v);
1914 D.removeClass(a[0], 'hidden');
1915 D.addClass(a[1], 'hidden');
1916 }
1917 Chat.e.inputElementWrapper.classList[
1918 s.value ? 'add' : 'remove'
1919 ]('compact');
1920 Chat.e.inputFields[Chat.e.inputFields.$currentIndex].focus();
1921 });
1922 Chat.settings.addListener('edit-ctrl-send',function(s){
1923 const label = (s.value ? "Ctrl-" : "")+"Enter submits messages.";
1924 Chat.e.inputFields.forEach((e)=>{
1925 const v = e.dataset.placeholder0 + " " +label;
1926 if(e.isContentEditable) e.dataset.placeholder = v;
1927 else D.attr(e,'placeholder',v);
1928 });
1929 Chat.e.btnSubmit.title = label;
1930 });
1931 const valueKludges = {
1932 /* Convert certain string-format values to other types... */
1933 "false": false,
@@ -1784,11 +1953,11 @@
1953 this.inputFocus();
1954 };
1955 Chat.e.viewPreview.querySelector('#chat-preview-close').
1956 addEventListener('click', ()=>Chat.setCurrentView(Chat.e.viewMessages), false);
1957 let previewPending = false;
1958 const elemsToEnable = [btnPreview, Chat.e.btnSubmit, Chat.e.inputFields];
1959 const submit = function(ev){
1960 ev.preventDefault();
1961 ev.stopPropagation();
1962 if(previewPending) return false;
1963 const txt = Chat.inputValue();
1964
--- 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
+62 -9
--- 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,32 +417,39 @@
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"
384
- "accept this cert and continue (y/N)? ",
434
+ "accept this cert and continue (y/N/fingerprint)? ",
385435
pUrlData->name, desclen, desc);
386436
BIO_free(mem);
387437
388438
prompt_user(prompt, &ans);
389439
free(prompt);
390440
cReply = blob_str(&ans)[0];
391
- blob_reset(&ans);
392
- if( cReply!='y' && cReply!='Y' ){
441
+ if( cReply!='y' && cReply!='Y'
442
+ && fossil_stricmp(blob_str(&ans),zHash)!=0
443
+ ){
393444
X509_free(cert);
394445
ssl_set_errmsg("SSL cert declined");
395446
ssl_close();
447
+ blob_reset(&ans);
396448
return 1;
397449
}
450
+ blob_reset(&ans);
398451
ssl_one_time_exception(pUrlData, zHash);
399452
prompt_user("remember this exception (y/N)? ", &ans);
400453
cReply = blob_str(&ans)[0];
401454
if( cReply=='y' || cReply=='Y') {
402455
db_open_config(0,0);
@@ -586,18 +639,16 @@
586639
Blob sql;
587640
char *zSep = "(";
588641
db_begin_transaction();
589642
blob_init(&sql, 0, 0);
590643
if( g.argc==4 && find_option("all",0,0)!=0 ){
591
- db_unprotect(PROTECT_CONFIG);
592644
blob_append_sql(&sql,
593645
"DELETE FROM global_config WHERE name GLOB 'cert:*';\n"
594646
"DELETE FROM global_config WHERE name GLOB 'trusted:*';\n"
595647
"DELETE FROM config WHERE name GLOB 'cert:*';\n"
596648
"DELETE FROM config WHERE name GLOB 'trusted:*';\n"
597649
);
598
- db_protect_pop();
599650
}else{
600651
if( g.argc<4 ){
601652
usage("remove-exception DOMAIN-NAME ...");
602653
}
603654
blob_append_sql(&sql,"DELETE FROM global_config WHERE name IN ");
@@ -614,11 +665,13 @@
614665
zSep/*safe-for-%s*/, g.argv[i], g.argv[i]);
615666
zSep = ",";
616667
}
617668
blob_append_sql(&sql,");");
618669
}
670
+ db_unprotect(PROTECT_CONFIG);
619671
db_exec_sql(blob_str(&sql));
672
+ db_protect_pop();
620673
db_commit_transaction();
621674
blob_reset(&sql);
622675
}else
623676
/*default*/{
624677
fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
625678
--- 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,32 +417,39 @@
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)? ",
385 pUrlData->name, desclen, desc);
386 BIO_free(mem);
387
388 prompt_user(prompt, &ans);
389 free(prompt);
390 cReply = blob_str(&ans)[0];
391 blob_reset(&ans);
392 if( cReply!='y' && cReply!='Y' ){
 
393 X509_free(cert);
394 ssl_set_errmsg("SSL cert declined");
395 ssl_close();
 
396 return 1;
397 }
 
398 ssl_one_time_exception(pUrlData, zHash);
399 prompt_user("remember this exception (y/N)? ", &ans);
400 cReply = blob_str(&ans)[0];
401 if( cReply=='y' || cReply=='Y') {
402 db_open_config(0,0);
@@ -586,18 +639,16 @@
586 Blob sql;
587 char *zSep = "(";
588 db_begin_transaction();
589 blob_init(&sql, 0, 0);
590 if( g.argc==4 && find_option("all",0,0)!=0 ){
591 db_unprotect(PROTECT_CONFIG);
592 blob_append_sql(&sql,
593 "DELETE FROM global_config WHERE name GLOB 'cert:*';\n"
594 "DELETE FROM global_config WHERE name GLOB 'trusted:*';\n"
595 "DELETE FROM config WHERE name GLOB 'cert:*';\n"
596 "DELETE FROM config WHERE name GLOB 'trusted:*';\n"
597 );
598 db_protect_pop();
599 }else{
600 if( g.argc<4 ){
601 usage("remove-exception DOMAIN-NAME ...");
602 }
603 blob_append_sql(&sql,"DELETE FROM global_config WHERE name IN ");
@@ -614,11 +665,13 @@
614 zSep/*safe-for-%s*/, g.argv[i], g.argv[i]);
615 zSep = ",";
616 }
617 blob_append_sql(&sql,");");
618 }
 
619 db_exec_sql(blob_str(&sql));
 
620 db_commit_transaction();
621 blob_reset(&sql);
622 }else
623 /*default*/{
624 fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
625
--- 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,32 +417,39 @@
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);
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 }
450 blob_reset(&ans);
451 ssl_one_time_exception(pUrlData, zHash);
452 prompt_user("remember this exception (y/N)? ", &ans);
453 cReply = blob_str(&ans)[0];
454 if( cReply=='y' || cReply=='Y') {
455 db_open_config(0,0);
@@ -586,18 +639,16 @@
639 Blob sql;
640 char *zSep = "(";
641 db_begin_transaction();
642 blob_init(&sql, 0, 0);
643 if( g.argc==4 && find_option("all",0,0)!=0 ){
 
644 blob_append_sql(&sql,
645 "DELETE FROM global_config WHERE name GLOB 'cert:*';\n"
646 "DELETE FROM global_config WHERE name GLOB 'trusted:*';\n"
647 "DELETE FROM config WHERE name GLOB 'cert:*';\n"
648 "DELETE FROM config WHERE name GLOB 'trusted:*';\n"
649 );
 
650 }else{
651 if( g.argc<4 ){
652 usage("remove-exception DOMAIN-NAME ...");
653 }
654 blob_append_sql(&sql,"DELETE FROM global_config WHERE name IN ");
@@ -614,11 +665,13 @@
665 zSep/*safe-for-%s*/, g.argv[i], g.argv[i]);
666 zSep = ",";
667 }
668 blob_append_sql(&sql,");");
669 }
670 db_unprotect(PROTECT_CONFIG);
671 db_exec_sql(blob_str(&sql));
672 db_protect_pop();
673 db_commit_transaction();
674 blob_reset(&sql);
675 }else
676 /*default*/{
677 fossil_fatal("unknown sub-command \"%s\".\nshould be one of:"
678
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178178
socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179179
rc = 1;
180180
#endif
181181
}else if( pUrlData->isFile ){
182182
sqlite3_uint64 iRandId;
183
+ if( !db_looks_like_a_repository(pUrlData->name) ){
184
+ fossil_fatal("not a fossil repository: \"%s\"", pUrlData->name);
185
+ }
183186
sqlite3_randomness(sizeof(iRandId), &iRandId);
184187
transport.zOutFile = mprintf("%s-%llu-out.http",
185188
g.zRepositoryName, iRandId);
186189
transport.zInFile = mprintf("%s-%llu-in.http",
187190
g.zRepositoryName, iRandId);
188191
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178 socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179 rc = 1;
180 #endif
181 }else if( pUrlData->isFile ){
182 sqlite3_uint64 iRandId;
 
 
 
183 sqlite3_randomness(sizeof(iRandId), &iRandId);
184 transport.zOutFile = mprintf("%s-%llu-out.http",
185 g.zRepositoryName, iRandId);
186 transport.zInFile = mprintf("%s-%llu-in.http",
187 g.zRepositoryName, iRandId);
188
--- src/http_transport.c
+++ src/http_transport.c
@@ -178,10 +178,13 @@
178 socket_set_errmsg("HTTPS: Fossil has been compiled without SSL support");
179 rc = 1;
180 #endif
181 }else if( pUrlData->isFile ){
182 sqlite3_uint64 iRandId;
183 if( !db_looks_like_a_repository(pUrlData->name) ){
184 fossil_fatal("not a fossil repository: \"%s\"", pUrlData->name);
185 }
186 sqlite3_randomness(sizeof(iRandId), &iRandId);
187 transport.zOutFile = mprintf("%s-%llu-out.http",
188 g.zRepositoryName, iRandId);
189 transport.zInFile = mprintf("%s-%llu-in.http",
190 g.zRepositoryName, iRandId);
191
+1 -1
--- src/import.c
+++ src/import.c
@@ -2008,11 +2008,11 @@
20082008
if( omitRebuild ){
20092009
omitVacuum = 1;
20102010
}else{
20112011
db_begin_transaction();
20122012
fossil_print("Rebuilding repository meta-data...\n");
2013
- rebuild_db(0, 1, !incrFlag);
2013
+ rebuild_db(1, !incrFlag);
20142014
verify_cancel();
20152015
db_end_transaction(0);
20162016
}
20172017
if( !omitVacuum ){
20182018
fossil_print("Vacuuming..."); fflush(stdout);
20192019
--- src/import.c
+++ src/import.c
@@ -2008,11 +2008,11 @@
2008 if( omitRebuild ){
2009 omitVacuum = 1;
2010 }else{
2011 db_begin_transaction();
2012 fossil_print("Rebuilding repository meta-data...\n");
2013 rebuild_db(0, 1, !incrFlag);
2014 verify_cancel();
2015 db_end_transaction(0);
2016 }
2017 if( !omitVacuum ){
2018 fossil_print("Vacuuming..."); fflush(stdout);
2019
--- src/import.c
+++ src/import.c
@@ -2008,11 +2008,11 @@
2008 if( omitRebuild ){
2009 omitVacuum = 1;
2010 }else{
2011 db_begin_transaction();
2012 fossil_print("Rebuilding repository meta-data...\n");
2013 rebuild_db(1, !incrFlag);
2014 verify_cancel();
2015 db_end_transaction(0);
2016 }
2017 if( !omitVacuum ){
2018 fossil_print("Vacuuming..."); fflush(stdout);
2019
+5 -4
--- src/info.c
+++ src/info.c
@@ -493,11 +493,11 @@
493493
login_check_credentials();
494494
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
495495
rid = name_to_rid_www("name");
496496
if( rid==0 ){
497497
style_header("Check-in Information Error");
498
- @ No such object: %h(g.argv[2])
498
+ @ No such object: %h(PD("name",""))
499499
style_finish_page();
500500
return;
501501
}
502502
zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
503503
style_header("Tags and Properties");
@@ -627,11 +627,11 @@
627627
style_set_current_feature("vinfo");
628628
zName = P("name");
629629
rid = name_to_rid_www("name");
630630
if( rid==0 ){
631631
style_header("Check-in Information Error");
632
- @ No such object: %h(g.argv[2])
632
+ @ No such object: %h(zName)
633633
style_finish_page();
634634
return;
635635
}
636636
zRe = P("regex");
637637
if( zRe ) re_compile(&pRe, zRe, 0);
@@ -1948,11 +1948,11 @@
19481948
iFrom, iTo);
19491949
return;
19501950
}
19511951
content_get(rid, &content);
19521952
g.isConst = 1;
1953
- cgi_set_content_type("text/json");
1953
+ cgi_set_content_type("application/json");
19541954
ln = 0;
19551955
while( go && ln<iFrom ){
19561956
go = blob_line(&content, &line);
19571957
ln++;
19581958
}
@@ -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
@@ -493,11 +493,11 @@
493 login_check_credentials();
494 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
495 rid = name_to_rid_www("name");
496 if( rid==0 ){
497 style_header("Check-in Information Error");
498 @ No such object: %h(g.argv[2])
499 style_finish_page();
500 return;
501 }
502 zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
503 style_header("Tags and Properties");
@@ -627,11 +627,11 @@
627 style_set_current_feature("vinfo");
628 zName = P("name");
629 rid = name_to_rid_www("name");
630 if( rid==0 ){
631 style_header("Check-in Information Error");
632 @ No such object: %h(g.argv[2])
633 style_finish_page();
634 return;
635 }
636 zRe = P("regex");
637 if( zRe ) re_compile(&pRe, zRe, 0);
@@ -1948,11 +1948,11 @@
1948 iFrom, iTo);
1949 return;
1950 }
1951 content_get(rid, &content);
1952 g.isConst = 1;
1953 cgi_set_content_type("text/json");
1954 ln = 0;
1955 while( go && ln<iFrom ){
1956 go = blob_line(&content, &line);
1957 ln++;
1958 }
@@ -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
@@ -493,11 +493,11 @@
493 login_check_credentials();
494 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
495 rid = name_to_rid_www("name");
496 if( rid==0 ){
497 style_header("Check-in Information Error");
498 @ No such object: %h(PD("name",""))
499 style_finish_page();
500 return;
501 }
502 zHash = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
503 style_header("Tags and Properties");
@@ -627,11 +627,11 @@
627 style_set_current_feature("vinfo");
628 zName = P("name");
629 rid = name_to_rid_www("name");
630 if( rid==0 ){
631 style_header("Check-in Information Error");
632 @ No such object: %h(zName)
633 style_finish_page();
634 return;
635 }
636 zRe = P("regex");
637 if( zRe ) re_compile(&pRe, zRe, 0);
@@ -1948,11 +1948,11 @@
1948 iFrom, iTo);
1949 return;
1950 }
1951 content_get(rid, &content);
1952 g.isConst = 1;
1953 cgi_set_content_type("application/json");
1954 ln = 0;
1955 while( go && ln<iFrom ){
1956 go = blob_line(&content, &line);
1957 ln++;
1958 }
@@ -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
+1 -1
--- src/json.c
+++ src/json.c
@@ -2185,11 +2185,11 @@
21852185
it's sqlite3, so it'll fail gracefully).
21862186
*/
21872187
db_close(1);
21882188
db_open_repository(g.zRepositoryName);
21892189
db_begin_transaction();
2190
- rebuild_db(0, 0, 0);
2190
+ rebuild_db(0, 0);
21912191
db_end_transaction(0);
21922192
return NULL;
21932193
}
21942194
}
21952195
21962196
--- src/json.c
+++ src/json.c
@@ -2185,11 +2185,11 @@
2185 it's sqlite3, so it'll fail gracefully).
2186 */
2187 db_close(1);
2188 db_open_repository(g.zRepositoryName);
2189 db_begin_transaction();
2190 rebuild_db(0, 0, 0);
2191 db_end_transaction(0);
2192 return NULL;
2193 }
2194 }
2195
2196
--- src/json.c
+++ src/json.c
@@ -2185,11 +2185,11 @@
2185 it's sqlite3, so it'll fail gracefully).
2186 */
2187 db_close(1);
2188 db_open_repository(g.zRepositoryName);
2189 db_begin_transaction();
2190 rebuild_db(0, 0);
2191 db_end_transaction(0);
2192 return NULL;
2193 }
2194 }
2195
2196
+31 -21
--- src/login.c
+++ src/login.c
@@ -2116,40 +2116,50 @@
21162116
}
21172117
21182118
/*
21192119
** COMMAND: login-group*
21202120
**
2121
-** Usage: %fossil login-group
2122
-** or: %fossil login-group join REPO [-name NAME]
2123
-** or: %fossil login-group leave
2124
-**
2125
-** With no arguments, this command shows the login-group to which the
2126
-** repository belongs.
2127
-**
2128
-** The "join" command adds this repository to login group to which REPO
2129
-** belongs, or creates a new login group between itself and REPO if REPO
2130
-** does not already belong to a login-group. When creating a new login-
2131
-** group, the name of the new group is determined by the "--name" option.
2132
-**
2133
-** The "leave" command takes the repository out of whatever login group
2134
-** it is currently a part of.
2121
+** Usage: %fossil login-group ?SUBCOMMAND? ?OPTIONS?
2122
+**
2123
+** Run various subcommands to manage login-group related settings of the open
2124
+** repository or of the repository identified by the -R or --repository option.
2125
+**
2126
+** > fossil login-group
2127
+**
2128
+** Show the login-group to which the repository belongs.
2129
+**
2130
+** > fossil login-group join ?--name NAME?
2131
+**
2132
+** Add this repository to login group to which REPO belongs, or creates a
2133
+** new login group between itself and REPO if REPO does not already belong
2134
+** to a login-group. When creating a new login-group, the name of the new
2135
+** group is determined by the "--name" option.
2136
+**
2137
+** > fossil login-group leave
2138
+**
2139
+** Takes the repository out of whatever login group it is currently
2140
+** a part of.
2141
+**
2142
+** Options valid for all subcommands:
2143
+**
2144
+** -R|--repository REPO Run commands on repository REPO
21352145
**
21362146
** About Login Groups:
2137
-**
2138
-** A login-group is a set of repositories that share user credentials.
2147
+**
2148
+** A login-group is a set of repositories that share user credentials.
21392149
** If a user is logged into one member of the group, then that user can
2140
-** access any other group member as long as they have an entry in the
2141
-** USER table of that member. If a user changes their password using
2142
-** web interface, their password is also automatically changed in every
2143
-** other member of the login group.
2150
+** access any other group member as long as they have an entry in the USER
2151
+** table of that member. If a user changes their password using web
2152
+** interface, their password is also automatically changed in every other
2153
+** member of the login group.
21442154
*/
21452155
void login_group_command(void){
21462156
const char *zLGName;
21472157
const char *zCmd;
21482158
int nCmd;
21492159
Stmt q;
2150
- db_find_and_open_repository(0,0);
2160
+ db_find_and_open_repository(0, 0);
21512161
if( g.argc>2 ){
21522162
zCmd = g.argv[2];
21532163
nCmd = (int)strlen(zCmd);
21542164
if( strncmp(zCmd,"join",nCmd)==0 && nCmd>=1 ){
21552165
const char *zNewName = find_option("name",0,1);
21562166
--- src/login.c
+++ src/login.c
@@ -2116,40 +2116,50 @@
2116 }
2117
2118 /*
2119 ** COMMAND: login-group*
2120 **
2121 ** Usage: %fossil login-group
2122 ** or: %fossil login-group join REPO [-name NAME]
2123 ** or: %fossil login-group leave
2124 **
2125 ** With no arguments, this command shows the login-group to which the
2126 ** repository belongs.
2127 **
2128 ** The "join" command adds this repository to login group to which REPO
2129 ** belongs, or creates a new login group between itself and REPO if REPO
2130 ** does not already belong to a login-group. When creating a new login-
2131 ** group, the name of the new group is determined by the "--name" option.
2132 **
2133 ** The "leave" command takes the repository out of whatever login group
2134 ** it is currently a part of.
 
 
 
 
 
 
 
 
 
 
2135 **
2136 ** About Login Groups:
2137 **
2138 ** A login-group is a set of repositories that share user credentials.
2139 ** If a user is logged into one member of the group, then that user can
2140 ** access any other group member as long as they have an entry in the
2141 ** USER table of that member. If a user changes their password using
2142 ** web interface, their password is also automatically changed in every
2143 ** other member of the login group.
2144 */
2145 void login_group_command(void){
2146 const char *zLGName;
2147 const char *zCmd;
2148 int nCmd;
2149 Stmt q;
2150 db_find_and_open_repository(0,0);
2151 if( g.argc>2 ){
2152 zCmd = g.argv[2];
2153 nCmd = (int)strlen(zCmd);
2154 if( strncmp(zCmd,"join",nCmd)==0 && nCmd>=1 ){
2155 const char *zNewName = find_option("name",0,1);
2156
--- src/login.c
+++ src/login.c
@@ -2116,40 +2116,50 @@
2116 }
2117
2118 /*
2119 ** COMMAND: login-group*
2120 **
2121 ** Usage: %fossil login-group ?SUBCOMMAND? ?OPTIONS?
2122 **
2123 ** Run various subcommands to manage login-group related settings of the open
2124 ** repository or of the repository identified by the -R or --repository option.
2125 **
2126 ** > fossil login-group
2127 **
2128 ** Show the login-group to which the repository belongs.
2129 **
2130 ** > fossil login-group join ?--name NAME?
2131 **
2132 ** Add this repository to login group to which REPO belongs, or creates a
2133 ** new login group between itself and REPO if REPO does not already belong
2134 ** to a login-group. When creating a new login-group, the name of the new
2135 ** group is determined by the "--name" option.
2136 **
2137 ** > fossil login-group leave
2138 **
2139 ** Takes the repository out of whatever login group it is currently
2140 ** a part of.
2141 **
2142 ** Options valid for all subcommands:
2143 **
2144 ** -R|--repository REPO Run commands on repository REPO
2145 **
2146 ** About Login Groups:
2147 **
2148 ** A login-group is a set of repositories that share user credentials.
2149 ** If a user is logged into one member of the group, then that user can
2150 ** access any other group member as long as they have an entry in the USER
2151 ** table of that member. If a user changes their password using web
2152 ** interface, their password is also automatically changed in every other
2153 ** member of the login group.
2154 */
2155 void login_group_command(void){
2156 const char *zLGName;
2157 const char *zCmd;
2158 int nCmd;
2159 Stmt q;
2160 db_find_and_open_repository(0, 0);
2161 if( g.argc>2 ){
2162 zCmd = g.argv[2];
2163 nCmd = (int)strlen(zCmd);
2164 if( strncmp(zCmd,"join",nCmd)==0 && nCmd>=1 ){
2165 const char *zNewName = find_option("name",0,1);
2166
+2 -2
--- src/main.c
+++ src/main.c
@@ -698,12 +698,12 @@
698698
fossil_limit_memory(1);
699699
700700
/* When updating the minimum SQLite version, change the number here,
701701
** and also MINIMUM_SQLITE_VERSION value set in ../auto.def. Take
702702
** care that both places agree! */
703
- if( sqlite3_libversion_number()<3035000 ){
704
- fossil_panic("Unsuitable SQLite version %s, must be at least 3.35.0",
703
+ if( sqlite3_libversion_number()<3037000 ){
704
+ fossil_panic("Unsuitable SQLite version %s, must be at least 3.37.0",
705705
sqlite3_libversion());
706706
}
707707
708708
sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
709709
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
710710
--- src/main.c
+++ src/main.c
@@ -698,12 +698,12 @@
698 fossil_limit_memory(1);
699
700 /* When updating the minimum SQLite version, change the number here,
701 ** and also MINIMUM_SQLITE_VERSION value set in ../auto.def. Take
702 ** care that both places agree! */
703 if( sqlite3_libversion_number()<3035000 ){
704 fossil_panic("Unsuitable SQLite version %s, must be at least 3.35.0",
705 sqlite3_libversion());
706 }
707
708 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
709 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
710
--- src/main.c
+++ src/main.c
@@ -698,12 +698,12 @@
698 fossil_limit_memory(1);
699
700 /* When updating the minimum SQLite version, change the number here,
701 ** and also MINIMUM_SQLITE_VERSION value set in ../auto.def. Take
702 ** care that both places agree! */
703 if( sqlite3_libversion_number()<3037000 ){
704 fossil_panic("Unsuitable SQLite version %s, must be at least 3.37.0",
705 sqlite3_libversion());
706 }
707
708 sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
709 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
710
+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
--- src/merge.c
+++ src/merge.c
@@ -307,14 +307,10 @@
307307
**
308308
** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
309309
** and do not try to merge parallel changes. This
310310
** option overrides the "binary-glob" setting.
311311
**
312
-** --case-sensitive BOOL Override the case-sensitive setting. If false,
313
-** files whose names differ only in case are taken
314
-** to be the same file.
315
-**
316312
** --cherrypick Do a cherrypick merge VERSION into the current
317313
** checkout. A cherrypick merge pulls in the changes
318314
** of the single check-in VERSION, rather than all
319315
** changes back to the nearest common ancestor.
320316
**
321317
--- src/merge.c
+++ src/merge.c
@@ -307,14 +307,10 @@
307 **
308 ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
309 ** and do not try to merge parallel changes. This
310 ** option overrides the "binary-glob" setting.
311 **
312 ** --case-sensitive BOOL Override the case-sensitive setting. If false,
313 ** files whose names differ only in case are taken
314 ** to be the same file.
315 **
316 ** --cherrypick Do a cherrypick merge VERSION into the current
317 ** checkout. A cherrypick merge pulls in the changes
318 ** of the single check-in VERSION, rather than all
319 ** changes back to the nearest common ancestor.
320 **
321
--- src/merge.c
+++ src/merge.c
@@ -307,14 +307,10 @@
307 **
308 ** --binary GLOBPATTERN Treat files that match GLOBPATTERN as binary
309 ** and do not try to merge parallel changes. This
310 ** option overrides the "binary-glob" setting.
311 **
 
 
 
 
312 ** --cherrypick Do a cherrypick merge VERSION into the current
313 ** checkout. A cherrypick merge pulls in the changes
314 ** of the single check-in VERSION, rather than all
315 ** changes back to the nearest common ancestor.
316 **
317
+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
+1 -1
--- src/pivot.c
+++ src/pivot.c
@@ -62,11 +62,11 @@
6262
** Set a secondary file. The primary file must be set first. There
6363
** must be at least one secondary but there can be more than one if
6464
** desired.
6565
*/
6666
void pivot_set_secondary(int rid){
67
- /* Insert the primary record */
67
+ /* Insert the secondary record */
6868
db_multi_exec(
6969
"INSERT OR IGNORE INTO aqueue(rid, mtime, pending, src)"
7070
" SELECT %d, mtime, 1, 0 FROM event WHERE objid=%d AND type='ci'",
7171
rid, rid
7272
);
7373
--- src/pivot.c
+++ src/pivot.c
@@ -62,11 +62,11 @@
62 ** Set a secondary file. The primary file must be set first. There
63 ** must be at least one secondary but there can be more than one if
64 ** desired.
65 */
66 void pivot_set_secondary(int rid){
67 /* Insert the primary record */
68 db_multi_exec(
69 "INSERT OR IGNORE INTO aqueue(rid, mtime, pending, src)"
70 " SELECT %d, mtime, 1, 0 FROM event WHERE objid=%d AND type='ci'",
71 rid, rid
72 );
73
--- src/pivot.c
+++ src/pivot.c
@@ -62,11 +62,11 @@
62 ** Set a secondary file. The primary file must be set first. There
63 ** must be at least one secondary but there can be more than one if
64 ** desired.
65 */
66 void pivot_set_secondary(int rid){
67 /* Insert the secondary record */
68 db_multi_exec(
69 "INSERT OR IGNORE INTO aqueue(rid, mtime, pending, src)"
70 " SELECT %d, mtime, 1, 0 FROM event WHERE objid=%d AND type='ci'",
71 rid, rid
72 );
73
+4 -12
--- src/rebuild.c
+++ src/rebuild.c
@@ -368,17 +368,12 @@
368368
** Core function to rebuild the information in the derived tables of a
369369
** fossil repository from the blobs. This function is shared between
370370
** 'rebuild_database' ('rebuild') and 'reconstruct_cmd'
371371
** ('reconstruct'), both of which have to regenerate this information
372372
** from scratch.
373
-**
374
-** If the randomize parameter is true, then the BLOBs are deliberately
375
-** extracted in a random order. This feature is used to test the
376
-** ability of fossil to accept records in any order and still
377
-** construct a sane repository.
378373
*/
379
-int rebuild_db(int randomize, int doOut, int doClustering){
374
+int rebuild_db(int doOut, int doClustering){
380375
Stmt s, q;
381376
int errCnt = 0;
382377
int incrSize;
383378
Blob sql;
384379
@@ -605,18 +600,16 @@
605600
** --index Always add in the full-text search index
606601
** --noverify Skip the verification of changes to the BLOB table
607602
** --noindex Always omit the full-text search index
608603
** --pagesize N Set the database pagesize to N. (512..65536 and power of 2)
609604
** --quiet Only show output if there are errors
610
-** --randomize Scan artifacts in a random order
611605
** --stats Show artifact statistics after rebuilding
612606
** --vacuum Run VACUUM on the database after rebuilding
613607
** --wal Set Write-Ahead-Log journalling mode on the database
614608
*/
615609
void rebuild_database(void){
616610
int forceFlag;
617
- int randomizeFlag;
618611
int errCnt = 0;
619612
int omitVerify;
620613
int doClustering;
621614
const char *zPagesize;
622615
int newPagesize = 0;
@@ -632,11 +625,10 @@
632625
int optIfNeeded;
633626
int compressOnlyFlag;
634627
635628
omitVerify = find_option("noverify",0,0)!=0;
636629
forceFlag = find_option("force","f",0)!=0;
637
- randomizeFlag = find_option("randomize", 0, 0)!=0;
638630
doClustering = find_option("cluster", 0, 0)!=0;
639631
runVacuum = find_option("vacuum",0,0)!=0;
640632
runDeanalyze = find_option("deanalyze",0,0)!=0;
641633
runAnalyze = find_option("analyze",0,0)!=0;
642634
runCompress = find_option("compress",0,0)!=0;
@@ -679,11 +671,11 @@
679671
db_begin_transaction();
680672
db_unprotect(PROTECT_ALL);
681673
if( !compressOnlyFlag ){
682674
search_drop_index();
683675
ttyOutput = 1;
684
- errCnt = rebuild_db(randomizeFlag, 1, doClustering);
676
+ errCnt = rebuild_db(1, doClustering);
685677
reconstruct_private_table();
686678
}
687679
db_multi_exec(
688680
"REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
689681
"REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
@@ -963,11 +955,11 @@
963955
db_end_transaction(0);
964956
db_unprotect(PROTECT_ALL);
965957
db_multi_exec("VACUUM;");
966958
db_protect_pop();
967959
}else{
968
- rebuild_db(0, 1, 0);
960
+ rebuild_db(1, 0);
969961
db_end_transaction(0);
970962
}
971963
}
972964
973965
/*
@@ -1255,11 +1247,11 @@
12551247
12561248
fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]);
12571249
recon_read_dir(g.argv[3]);
12581250
fossil_print("\nBuilding the Fossil repository...\n");
12591251
1260
- rebuild_db(0, 1, 1);
1252
+ rebuild_db(1, 1);
12611253
12621254
/* Backwards compatibility: Mark check-ins with "+private" tags as private. */
12631255
reconstruct_private_table();
12641256
/* Newer method: Import the list of private artifacts to the PRIVATE table. */
12651257
if( fKeepPrivate ){
12661258
--- src/rebuild.c
+++ src/rebuild.c
@@ -368,17 +368,12 @@
368 ** Core function to rebuild the information in the derived tables of a
369 ** fossil repository from the blobs. This function is shared between
370 ** 'rebuild_database' ('rebuild') and 'reconstruct_cmd'
371 ** ('reconstruct'), both of which have to regenerate this information
372 ** from scratch.
373 **
374 ** If the randomize parameter is true, then the BLOBs are deliberately
375 ** extracted in a random order. This feature is used to test the
376 ** ability of fossil to accept records in any order and still
377 ** construct a sane repository.
378 */
379 int rebuild_db(int randomize, int doOut, int doClustering){
380 Stmt s, q;
381 int errCnt = 0;
382 int incrSize;
383 Blob sql;
384
@@ -605,18 +600,16 @@
605 ** --index Always add in the full-text search index
606 ** --noverify Skip the verification of changes to the BLOB table
607 ** --noindex Always omit the full-text search index
608 ** --pagesize N Set the database pagesize to N. (512..65536 and power of 2)
609 ** --quiet Only show output if there are errors
610 ** --randomize Scan artifacts in a random order
611 ** --stats Show artifact statistics after rebuilding
612 ** --vacuum Run VACUUM on the database after rebuilding
613 ** --wal Set Write-Ahead-Log journalling mode on the database
614 */
615 void rebuild_database(void){
616 int forceFlag;
617 int randomizeFlag;
618 int errCnt = 0;
619 int omitVerify;
620 int doClustering;
621 const char *zPagesize;
622 int newPagesize = 0;
@@ -632,11 +625,10 @@
632 int optIfNeeded;
633 int compressOnlyFlag;
634
635 omitVerify = find_option("noverify",0,0)!=0;
636 forceFlag = find_option("force","f",0)!=0;
637 randomizeFlag = find_option("randomize", 0, 0)!=0;
638 doClustering = find_option("cluster", 0, 0)!=0;
639 runVacuum = find_option("vacuum",0,0)!=0;
640 runDeanalyze = find_option("deanalyze",0,0)!=0;
641 runAnalyze = find_option("analyze",0,0)!=0;
642 runCompress = find_option("compress",0,0)!=0;
@@ -679,11 +671,11 @@
679 db_begin_transaction();
680 db_unprotect(PROTECT_ALL);
681 if( !compressOnlyFlag ){
682 search_drop_index();
683 ttyOutput = 1;
684 errCnt = rebuild_db(randomizeFlag, 1, doClustering);
685 reconstruct_private_table();
686 }
687 db_multi_exec(
688 "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
689 "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
@@ -963,11 +955,11 @@
963 db_end_transaction(0);
964 db_unprotect(PROTECT_ALL);
965 db_multi_exec("VACUUM;");
966 db_protect_pop();
967 }else{
968 rebuild_db(0, 1, 0);
969 db_end_transaction(0);
970 }
971 }
972
973 /*
@@ -1255,11 +1247,11 @@
1255
1256 fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]);
1257 recon_read_dir(g.argv[3]);
1258 fossil_print("\nBuilding the Fossil repository...\n");
1259
1260 rebuild_db(0, 1, 1);
1261
1262 /* Backwards compatibility: Mark check-ins with "+private" tags as private. */
1263 reconstruct_private_table();
1264 /* Newer method: Import the list of private artifacts to the PRIVATE table. */
1265 if( fKeepPrivate ){
1266
--- src/rebuild.c
+++ src/rebuild.c
@@ -368,17 +368,12 @@
368 ** Core function to rebuild the information in the derived tables of a
369 ** fossil repository from the blobs. This function is shared between
370 ** 'rebuild_database' ('rebuild') and 'reconstruct_cmd'
371 ** ('reconstruct'), both of which have to regenerate this information
372 ** from scratch.
 
 
 
 
 
373 */
374 int rebuild_db(int doOut, int doClustering){
375 Stmt s, q;
376 int errCnt = 0;
377 int incrSize;
378 Blob sql;
379
@@ -605,18 +600,16 @@
600 ** --index Always add in the full-text search index
601 ** --noverify Skip the verification of changes to the BLOB table
602 ** --noindex Always omit the full-text search index
603 ** --pagesize N Set the database pagesize to N. (512..65536 and power of 2)
604 ** --quiet Only show output if there are errors
 
605 ** --stats Show artifact statistics after rebuilding
606 ** --vacuum Run VACUUM on the database after rebuilding
607 ** --wal Set Write-Ahead-Log journalling mode on the database
608 */
609 void rebuild_database(void){
610 int forceFlag;
 
611 int errCnt = 0;
612 int omitVerify;
613 int doClustering;
614 const char *zPagesize;
615 int newPagesize = 0;
@@ -632,11 +625,10 @@
625 int optIfNeeded;
626 int compressOnlyFlag;
627
628 omitVerify = find_option("noverify",0,0)!=0;
629 forceFlag = find_option("force","f",0)!=0;
 
630 doClustering = find_option("cluster", 0, 0)!=0;
631 runVacuum = find_option("vacuum",0,0)!=0;
632 runDeanalyze = find_option("deanalyze",0,0)!=0;
633 runAnalyze = find_option("analyze",0,0)!=0;
634 runCompress = find_option("compress",0,0)!=0;
@@ -679,11 +671,11 @@
671 db_begin_transaction();
672 db_unprotect(PROTECT_ALL);
673 if( !compressOnlyFlag ){
674 search_drop_index();
675 ttyOutput = 1;
676 errCnt = rebuild_db(1, doClustering);
677 reconstruct_private_table();
678 }
679 db_multi_exec(
680 "REPLACE INTO config(name,value,mtime) VALUES('content-schema',%Q,now());"
681 "REPLACE INTO config(name,value,mtime) VALUES('aux-schema',%Q,now());"
@@ -963,11 +955,11 @@
955 db_end_transaction(0);
956 db_unprotect(PROTECT_ALL);
957 db_multi_exec("VACUUM;");
958 db_protect_pop();
959 }else{
960 rebuild_db(1, 0);
961 db_end_transaction(0);
962 }
963 }
964
965 /*
@@ -1255,11 +1247,11 @@
1247
1248 fossil_print("Reading files from directory \"%s\"...\n", g.argv[3]);
1249 recon_read_dir(g.argv[3]);
1250 fossil_print("\nBuilding the Fossil repository...\n");
1251
1252 rebuild_db(1, 1);
1253
1254 /* Backwards compatibility: Mark check-ins with "+private" tags as private. */
1255 reconstruct_private_table();
1256 /* Newer method: Import the list of private artifacts to the PRIVATE table. */
1257 if( fKeepPrivate ){
1258
+194 -81
--- src/shell.c
+++ src/shell.c
@@ -872,11 +872,11 @@
872872
for(i=0; i<nAppend; i++){
873873
if( zAppend[i]==quote ) len++;
874874
}
875875
}
876876
877
- if( p->n+len>=p->nAlloc ){
877
+ if( p->z==0 || p->n+len>=p->nAlloc ){
878878
p->nAlloc = p->nAlloc*2 + len + 20;
879879
p->z = realloc(p->z, p->nAlloc);
880880
if( p->z==0 ) shell_out_of_memory();
881881
}
882882
@@ -6261,13 +6261,13 @@
62616261
rc = 1;
62626262
goto re_match_end;
62636263
}
62646264
case RE_OP_CC_EXC: {
62656265
if( c==0 ) break;
6266
- /* fall-through */
6266
+ /* fall-through */ goto re_op_cc_inc;
62676267
}
6268
- case RE_OP_CC_INC: {
6268
+ case RE_OP_CC_INC: re_op_cc_inc: {
62696269
int j = 1;
62706270
int n = pRe->aArg[x];
62716271
int hit = 0;
62726272
for(j=1; j>0 && j<n; j++){
62736273
if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
@@ -6794,10 +6794,13 @@
67946794
typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
67956795
typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
67966796
#define MIN(a,b) ((a)<(b) ? (a) : (b))
67976797
67986798
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
6799
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
6800
+#endif
6801
+#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
67996802
# define ALWAYS(X) (1)
68006803
# define NEVER(X) (0)
68016804
#elif !defined(NDEBUG)
68026805
# define ALWAYS(X) ((X)?1:(assert(0),0))
68036806
# define NEVER(X) ((X)?(assert(0),1):0)
@@ -8672,11 +8675,11 @@
86728675
**
86738676
** SELECT zipfile(name,data) ...
86748677
** SELECT zipfile(name,mode,mtime,data) ...
86758678
** SELECT zipfile(name,mode,mtime,data,method) ...
86768679
*/
8677
-void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
8680
+static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
86788681
ZipfileCtx *p; /* Aggregate function context */
86798682
ZipfileEntry e; /* New entry to add to zip archive */
86808683
86818684
sqlite3_value *pName = 0;
86828685
sqlite3_value *pMode = 0;
@@ -8847,11 +8850,11 @@
88478850
}
88488851
88498852
/*
88508853
** xFinalize() callback for zipfile aggregate function.
88518854
*/
8852
-void zipfileFinal(sqlite3_context *pCtx){
8855
+static void zipfileFinal(sqlite3_context *pCtx){
88538856
ZipfileCtx *p;
88548857
ZipfileEOCD eocd;
88558858
sqlite3_int64 nZip;
88568859
u8 *aZip;
88578860
@@ -9253,10 +9256,27 @@
92539256
*/
92549257
/* #include "sqlite3expert.h" */
92559258
#include <assert.h>
92569259
#include <string.h>
92579260
#include <stdio.h>
9261
+
9262
+#if !defined(SQLITE_AMALGAMATION)
9263
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
9264
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
9265
+#endif
9266
+#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
9267
+# define ALWAYS(X) (1)
9268
+# define NEVER(X) (0)
9269
+#elif !defined(NDEBUG)
9270
+# define ALWAYS(X) ((X)?1:(assert(0),0))
9271
+# define NEVER(X) ((X)?(assert(0),1):0)
9272
+#else
9273
+# define ALWAYS(X) (X)
9274
+# define NEVER(X) (X)
9275
+#endif
9276
+#endif /* !defined(SQLITE_AMALGAMATION) */
9277
+
92589278
92599279
#ifndef SQLITE_OMIT_VIRTUALTABLE
92609280
92619281
/* typedef sqlite3_int64 i64; */
92629282
/* typedef sqlite3_uint64 u64; */
@@ -9980,13 +10000,13 @@
998010000
idxFinalize(&rc, p1);
998110001
998210002
if( rc!=SQLITE_OK ){
998310003
sqlite3_free(pNew);
998410004
pNew = 0;
9985
- }else{
10005
+ }else if( ALWAYS(pNew!=0) ){
998610006
pNew->zName = pCsr;
9987
- memcpy(pNew->zName, zTab, nTab+1);
10007
+ if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1);
998810008
}
998910009
999010010
*ppOut = pNew;
999110011
return rc;
999210012
}
@@ -10390,11 +10410,11 @@
1039010410
/*
1039110411
** This function is called after candidate indexes have been created. It
1039210412
** runs all the queries to see which indexes they prefer, and populates
1039310413
** IdxStatement.zIdx and IdxStatement.zEQP with the results.
1039410414
*/
10395
-int idxFindIndexes(
10415
+static int idxFindIndexes(
1039610416
sqlite3expert *p,
1039710417
char **pzErr /* OUT: Error message (sqlite3_malloc) */
1039810418
){
1039910419
IdxStatement *pStmt;
1040010420
sqlite3 *dbm = p->dbm;
@@ -12289,10 +12309,12 @@
1228912309
#define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
1229012310
#define MODE_Json 13 /* Output JSON */
1229112311
#define MODE_Markdown 14 /* Markdown formatting */
1229212312
#define MODE_Table 15 /* MySQL-style table formatting */
1229312313
#define MODE_Box 16 /* Unicode box-drawing characters */
12314
+#define MODE_Count 17 /* Output only a count of the rows of output */
12315
+#define MODE_Off 18 /* No query output shown */
1229412316
1229512317
static const char *modeDescr[] = {
1229612318
"line",
1229712319
"column",
1229812320
"list",
@@ -12307,11 +12329,13 @@
1230712329
"prettyprint",
1230812330
"eqp",
1230912331
"json",
1231012332
"markdown",
1231112333
"table",
12312
- "box"
12334
+ "box",
12335
+ "count",
12336
+ "off"
1231312337
};
1231412338
1231512339
/*
1231612340
** These are the column/row/line separators used by the various
1231712341
** import/export modes.
@@ -12798,21 +12822,18 @@
1279812822
static void output_csv(ShellState *p, const char *z, int bSep){
1279912823
FILE *out = p->out;
1280012824
if( z==0 ){
1280112825
utf8_printf(out,"%s",p->nullValue);
1280212826
}else{
12803
- int i;
12804
- int nSep = strlen30(p->colSeparator);
12827
+ unsigned i;
1280512828
for(i=0; z[i]; i++){
12806
- if( needCsvQuote[((unsigned char*)z)[i]]
12807
- || (z[i]==p->colSeparator[0] &&
12808
- (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
12829
+ if( needCsvQuote[((unsigned char*)z)[i]] ){
1280912830
i = 0;
1281012831
break;
1281112832
}
1281212833
}
12813
- if( i==0 ){
12834
+ if( i==0 || strstr(z, p->colSeparator)!=0 ){
1281412835
char *zQuoted = sqlite3_mprintf("\"%w\"", z);
1281512836
utf8_printf(out, "%s", zQuoted);
1281612837
sqlite3_free(zQuoted);
1281712838
}else{
1281812839
utf8_printf(out, "%s", z);
@@ -13132,10 +13153,14 @@
1313213153
int i;
1313313154
ShellState *p = (ShellState*)pArg;
1313413155
1313513156
if( azArg==0 ) return 0;
1313613157
switch( p->cMode ){
13158
+ case MODE_Count:
13159
+ case MODE_Off: {
13160
+ break;
13161
+ }
1313713162
case MODE_Line: {
1313813163
int w = 5;
1313913164
if( azArg==0 ) break;
1314013165
for(i=0; i<nArg; i++){
1314113166
int len = strlen30(azCol[i] ? azCol[i] : "");
@@ -13642,21 +13667,20 @@
1364213667
}
1364313668
return rc;
1364413669
}
1364513670
1364613671
/*
13647
-** Allocate space and save off current error string.
13672
+** Allocate space and save off string indicating current error.
1364813673
*/
1364913674
static char *save_err_msg(
13650
- sqlite3 *db /* Database to query */
13675
+ sqlite3 *db, /* Database to query */
13676
+ const char *zWhen, /* Qualifier (format) wrapper */
13677
+ int rc /* Error code returned from API */
1365113678
){
13652
- int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
13653
- char *zErrMsg = sqlite3_malloc64(nErrMsg);
13654
- if( zErrMsg ){
13655
- memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
13656
- }
13657
- return zErrMsg;
13679
+ if( zWhen==0 )
13680
+ zWhen = "%s (%d)";
13681
+ return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc);
1365813682
}
1365913683
1366013684
#ifdef __linux__
1366113685
/*
1366213686
** Attempt to display I/O stats on Linux using /proc/PID/io
@@ -13830,17 +13854,24 @@
1383013854
raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
1383113855
iCur);
1383213856
}
1383313857
1383413858
if( pArg->pStmt ){
13859
+ int iHit, iMiss;
1383513860
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
1383613861
bReset);
1383713862
raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
1383813863
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
1383913864
raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
1384013865
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
1384113866
raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
13867
+ iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset);
13868
+ iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset);
13869
+ if( iHit || iMiss ){
13870
+ raw_printf(pArg->out, "Bloom filter bypass taken: %d/%d\n",
13871
+ iHit, iHit+iMiss);
13872
+ }
1384213873
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
1384313874
raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
1384413875
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
1384513876
raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
1384613877
iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
@@ -14343,10 +14374,11 @@
1434314374
static void exec_prepared_stmt(
1434414375
ShellState *pArg, /* Pointer to ShellState */
1434514376
sqlite3_stmt *pStmt /* Statment to run */
1434614377
){
1434714378
int rc;
14379
+ sqlite3_uint64 nRow = 0;
1434814380
1434914381
if( pArg->cMode==MODE_Column
1435014382
|| pArg->cMode==MODE_Table
1435114383
|| pArg->cMode==MODE_Box
1435214384
|| pArg->cMode==MODE_Markdown
@@ -14375,10 +14407,11 @@
1437514407
/* save off ptrs to column names */
1437614408
for(i=0; i<nCol; i++){
1437714409
azCols[i] = (char *)sqlite3_column_name(pStmt, i);
1437814410
}
1437914411
do{
14412
+ nRow++;
1438014413
/* extract the data and data types */
1438114414
for(i=0; i<nCol; i++){
1438214415
aiTypes[i] = x = sqlite3_column_type(pStmt, i);
1438314416
if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
1438414417
azVals[i] = "";
@@ -14402,10 +14435,12 @@
1440214435
}
1440314436
} while( SQLITE_ROW == rc );
1440414437
sqlite3_free(pData);
1440514438
if( pArg->cMode==MODE_Json ){
1440614439
fputs("]\n", pArg->out);
14440
+ }else if( pArg->cMode==MODE_Count ){
14441
+ printf("%llu row%s\n", nRow, nRow!=1 ? "s" : "");
1440714442
}
1440814443
}
1440914444
}
1441014445
}
1441114446
@@ -14574,11 +14609,11 @@
1457414609
while( zSql[0] && (SQLITE_OK == rc) ){
1457514610
static const char *zStmtSql;
1457614611
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
1457714612
if( SQLITE_OK != rc ){
1457814613
if( pzErrMsg ){
14579
- *pzErrMsg = save_err_msg(db);
14614
+ *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)", rc);
1458014615
}
1458114616
}else{
1458214617
if( !pStmt ){
1458314618
/* this happens for a comment or white-space */
1458414619
zSql = zLeftover;
@@ -14688,11 +14723,11 @@
1468814723
if( rc!=SQLITE_NOMEM ) rc = rc2;
1468914724
if( rc==SQLITE_OK ){
1469014725
zSql = zLeftover;
1469114726
while( IsSpace(zSql[0]) ) zSql++;
1469214727
}else if( pzErrMsg ){
14693
- *pzErrMsg = save_err_msg(db);
14728
+ *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc);
1469414729
}
1469514730
1469614731
/* clear saved stmt handle */
1469714732
if( pArg ){
1469814733
pArg->pStmt = NULL;
@@ -15002,17 +15037,19 @@
1500215037
".archive ... Manage SQL archives",
1500315038
" Each command must have exactly one of the following options:",
1500415039
" -c, --create Create a new archive",
1500515040
" -u, --update Add or update files with changed mtime",
1500615041
" -i, --insert Like -u but always add even if unchanged",
15042
+ " -r, --remove Remove files from archive",
1500715043
" -t, --list List contents of archive",
1500815044
" -x, --extract Extract files from archive",
1500915045
" Optional arguments:",
1501015046
" -v, --verbose Print each filename as it is processed",
1501115047
" -f FILE, --file FILE Use archive FILE (default is current db)",
1501215048
" -a FILE, --append FILE Open FILE using the apndvfs VFS",
1501315049
" -C DIR, --directory DIR Read/extract files from directory DIR",
15050
+ " -g, --glob Use glob matching for names in archive",
1501415051
" -n, --dryrun Show the SQL that would have occurred",
1501515052
" Examples:",
1501615053
" .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
1501715054
" .ar -tf ARCHIVE # List members of ARCHIVE",
1501815055
" .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
@@ -17169,10 +17206,11 @@
1716917206
u8 eCmd; /* An AR_CMD_* value */
1717017207
u8 bVerbose; /* True if --verbose */
1717117208
u8 bZip; /* True if the archive is a ZIP */
1717217209
u8 bDryRun; /* True if --dry-run */
1717317210
u8 bAppend; /* True if --append */
17211
+ u8 bGlob; /* True if --glob */
1717417212
u8 fromCmdLine; /* Run from -A instead of .archive */
1717517213
int nArg; /* Number of command arguments */
1717617214
char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
1717717215
const char *zFile; /* --file argument, or NULL */
1717817216
const char *zDir; /* --directory argument, or NULL */
@@ -17216,25 +17254,28 @@
1721617254
#define AR_CMD_UPDATE 2
1721717255
#define AR_CMD_INSERT 3
1721817256
#define AR_CMD_EXTRACT 4
1721917257
#define AR_CMD_LIST 5
1722017258
#define AR_CMD_HELP 6
17259
+#define AR_CMD_REMOVE 7
1722117260
1722217261
/*
1722317262
** Other (non-command) switches.
1722417263
*/
17225
-#define AR_SWITCH_VERBOSE 7
17226
-#define AR_SWITCH_FILE 8
17227
-#define AR_SWITCH_DIRECTORY 9
17228
-#define AR_SWITCH_APPEND 10
17229
-#define AR_SWITCH_DRYRUN 11
17264
+#define AR_SWITCH_VERBOSE 8
17265
+#define AR_SWITCH_FILE 9
17266
+#define AR_SWITCH_DIRECTORY 10
17267
+#define AR_SWITCH_APPEND 11
17268
+#define AR_SWITCH_DRYRUN 12
17269
+#define AR_SWITCH_GLOB 13
1723017270
1723117271
static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
1723217272
switch( eSwitch ){
1723317273
case AR_CMD_CREATE:
1723417274
case AR_CMD_EXTRACT:
1723517275
case AR_CMD_LIST:
17276
+ case AR_CMD_REMOVE:
1723617277
case AR_CMD_UPDATE:
1723717278
case AR_CMD_INSERT:
1723817279
case AR_CMD_HELP:
1723917280
if( pAr->eCmd ){
1724017281
return arErrorMsg(pAr, "multiple command options");
@@ -17242,10 +17283,13 @@
1724217283
pAr->eCmd = eSwitch;
1724317284
break;
1724417285
1724517286
case AR_SWITCH_DRYRUN:
1724617287
pAr->bDryRun = 1;
17288
+ break;
17289
+ case AR_SWITCH_GLOB:
17290
+ pAr->bGlob = 1;
1724717291
break;
1724817292
case AR_SWITCH_VERBOSE:
1724917293
pAr->bVerbose = 1;
1725017294
break;
1725117295
case AR_SWITCH_APPEND:
@@ -17281,17 +17325,19 @@
1728117325
} aSwitch[] = {
1728217326
{ "create", 'c', AR_CMD_CREATE, 0 },
1728317327
{ "extract", 'x', AR_CMD_EXTRACT, 0 },
1728417328
{ "insert", 'i', AR_CMD_INSERT, 0 },
1728517329
{ "list", 't', AR_CMD_LIST, 0 },
17330
+ { "remove", 'r', AR_CMD_REMOVE, 0 },
1728617331
{ "update", 'u', AR_CMD_UPDATE, 0 },
1728717332
{ "help", 'h', AR_CMD_HELP, 0 },
1728817333
{ "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
1728917334
{ "file", 'f', AR_SWITCH_FILE, 1 },
1729017335
{ "append", 'a', AR_SWITCH_APPEND, 1 },
1729117336
{ "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
1729217337
{ "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
17338
+ { "glob", 'g', AR_SWITCH_GLOB, 0 },
1729317339
};
1729417340
int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
1729517341
struct ArSwitch *pEnd = &aSwitch[nSwitch];
1729617342
1729717343
if( nArg<=1 ){
@@ -17404,15 +17450,17 @@
1740417450
return SQLITE_OK;
1740517451
}
1740617452
1740717453
/*
1740817454
** This function assumes that all arguments within the ArCommand.azArg[]
17409
-** array refer to archive members, as for the --extract or --list commands.
17410
-** It checks that each of them are present. If any specified file is not
17411
-** present in the archive, an error is printed to stderr and an error
17412
-** code returned. Otherwise, if all specified arguments are present in
17413
-** the archive, SQLITE_OK is returned.
17455
+** array refer to archive members, as for the --extract, --list or --remove
17456
+** commands. It checks that each of them are "present". If any specified
17457
+** file is not present in the archive, an error is printed to stderr and an
17458
+** error code returned. Otherwise, if all specified arguments are present
17459
+** in the archive, SQLITE_OK is returned. Here, "present" means either an
17460
+** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
17461
+** when pAr->bGlob is true.
1741417462
**
1741517463
** This function strips any trailing '/' characters from each argument.
1741617464
** This is consistent with the way the [tar] command seems to work on
1741717465
** Linux.
1741817466
*/
@@ -17419,15 +17467,15 @@
1741917467
static int arCheckEntries(ArCommand *pAr){
1742017468
int rc = SQLITE_OK;
1742117469
if( pAr->nArg ){
1742217470
int i, j;
1742317471
sqlite3_stmt *pTest = 0;
17472
+ const char *zSel = (pAr->bGlob)
17473
+ ? "SELECT name FROM %s WHERE glob($name,name)"
17474
+ : "SELECT name FROM %s WHERE name=$name";
1742417475
17425
- shellPreparePrintf(pAr->db, &rc, &pTest,
17426
- "SELECT name FROM %s WHERE name=$name",
17427
- pAr->zSrcTable
17428
- );
17476
+ shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
1742917477
j = sqlite3_bind_parameter_index(pTest, "$name");
1743017478
for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
1743117479
char *z = pAr->azArg[i];
1743217480
int n = strlen30(z);
1743317481
int bOk = 0;
@@ -17451,29 +17499,31 @@
1745117499
/*
1745217500
** Format a WHERE clause that can be used against the "sqlar" table to
1745317501
** identify all archive members that match the command arguments held
1745417502
** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
1745517503
** The caller is responsible for eventually calling sqlite3_free() on
17456
-** any non-NULL (*pzWhere) value.
17504
+** any non-NULL (*pzWhere) value. Here, "match" means strict equality
17505
+** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
1745717506
*/
1745817507
static void arWhereClause(
1745917508
int *pRc,
17460
- ArCommand *pAr,
17509
+ ArCommand *pAr,
1746117510
char **pzWhere /* OUT: New WHERE clause */
1746217511
){
1746317512
char *zWhere = 0;
17513
+ const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
1746417514
if( *pRc==SQLITE_OK ){
1746517515
if( pAr->nArg==0 ){
1746617516
zWhere = sqlite3_mprintf("1");
1746717517
}else{
1746817518
int i;
1746917519
const char *zSep = "";
1747017520
for(i=0; i<pAr->nArg; i++){
1747117521
const char *z = pAr->azArg[i];
1747217522
zWhere = sqlite3_mprintf(
17473
- "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
17474
- zWhere, zSep, z, strlen30(z)+1, z
17523
+ "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
17524
+ zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
1747517525
);
1747617526
if( zWhere==0 ){
1747717527
*pRc = SQLITE_NOMEM;
1747817528
break;
1747917529
}
@@ -17522,10 +17572,51 @@
1752217572
shellFinalize(&rc, pSql);
1752317573
sqlite3_free(zWhere);
1752417574
return rc;
1752517575
}
1752617576
17577
+
17578
+/*
17579
+** Implementation of .ar "Remove" command.
17580
+*/
17581
+static int arRemoveCommand(ArCommand *pAr){
17582
+ int rc = 0;
17583
+ char *zSql = 0;
17584
+ char *zWhere = 0;
17585
+
17586
+ if( pAr->nArg ){
17587
+ /* Verify that args actually exist within the archive before proceeding.
17588
+ ** And formulate a WHERE clause to match them. */
17589
+ rc = arCheckEntries(pAr);
17590
+ arWhereClause(&rc, pAr, &zWhere);
17591
+ }
17592
+ if( rc==SQLITE_OK ){
17593
+ zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
17594
+ pAr->zSrcTable, zWhere);
17595
+ if( pAr->bDryRun ){
17596
+ utf8_printf(pAr->p->out, "%s\n", zSql);
17597
+ }else{
17598
+ char *zErr = 0;
17599
+ rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
17600
+ if( rc==SQLITE_OK ){
17601
+ rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
17602
+ if( rc!=SQLITE_OK ){
17603
+ sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
17604
+ }else{
17605
+ rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
17606
+ }
17607
+ }
17608
+ if( zErr ){
17609
+ utf8_printf(stdout, "ERROR: %s\n", zErr);
17610
+ sqlite3_free(zErr);
17611
+ }
17612
+ }
17613
+ }
17614
+ sqlite3_free(zWhere);
17615
+ sqlite3_free(zSql);
17616
+ return rc;
17617
+}
1752717618
1752817619
/*
1752917620
** Implementation of .ar "eXtract" command.
1753017621
*/
1753117622
static int arExtractCommand(ArCommand *pAr){
@@ -17775,11 +17866,11 @@
1777517866
cmd.bZip = 1;
1777617867
}else if( cmd.zFile ){
1777717868
int flags;
1777817869
if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
1777917870
if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
17780
- || cmd.eCmd==AR_CMD_UPDATE ){
17871
+ || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
1778117872
flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
1778217873
}else{
1778317874
flags = SQLITE_OPEN_READONLY;
1778417875
}
1778517876
cmd.db = 0;
@@ -17830,10 +17921,14 @@
1783017921
break;
1783117922
1783217923
case AR_CMD_INSERT:
1783317924
rc = arCreateOrUpdateCommand(&cmd, 1, 0);
1783417925
break;
17926
+
17927
+ case AR_CMD_REMOVE:
17928
+ rc = arRemoveCommand(&cmd);
17929
+ break;
1783517930
1783617931
default:
1783717932
assert( cmd.eCmd==AR_CMD_UPDATE );
1783817933
rc = arCreateOrUpdateCommand(&cmd, 1, 1);
1783917934
break;
@@ -19319,10 +19414,15 @@
1931919414
int nSkip = 0; /* Initial lines to skip */
1932019415
int useOutputMode = 1; /* Use output mode to determine separators */
1932119416
1932219417
failIfSafeMode(p, "cannot run .import in safe mode");
1932319418
memset(&sCtx, 0, sizeof(sCtx));
19419
+ sCtx.z = sqlite3_malloc64(120);
19420
+ if( sCtx.z==0 ){
19421
+ import_cleanup(&sCtx);
19422
+ shell_out_of_memory();
19423
+ }
1932419424
if( p->mode==MODE_Ascii ){
1932519425
xRead = ascii_read_one_field;
1932619426
}else{
1932719427
xRead = csv_read_one_field;
1932819428
}
@@ -19428,10 +19528,11 @@
1942819528
sCtx.xCloser = fclose;
1942919529
}
1943019530
if( sCtx.in==0 ){
1943119531
utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
1943219532
rc = 1;
19533
+ import_cleanup(&sCtx);
1943319534
goto meta_command_exit;
1943419535
}
1943519536
if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
1943619537
char zSep[2];
1943719538
zSep[1] = 0;
@@ -19846,10 +19947,14 @@
1984619947
p->mode = MODE_Markdown;
1984719948
}else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
1984819949
p->mode = MODE_Table;
1984919950
}else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
1985019951
p->mode = MODE_Box;
19952
+ }else if( c2=='c' && strncmp(azArg[1],"count",n2)==0 ){
19953
+ p->mode = MODE_Count;
19954
+ }else if( c2=='o' && strncmp(azArg[1],"off",n2)==0 ){
19955
+ p->mode = MODE_Off;
1985119956
}else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
1985219957
p->mode = MODE_Json;
1985319958
}else if( nArg==1 ){
1985419959
raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
1985519960
}else{
@@ -19915,42 +20020,32 @@
1991520020
1991620021
if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
1991720022
char *zNewFilename = 0; /* Name of the database file to open */
1991820023
int iName = 1; /* Index in azArg[] of the filename */
1991920024
int newFlag = 0; /* True to delete file before opening */
19920
- /* Close the existing database */
19921
- session_close_all(p, -1);
19922
- close_db(p->db);
19923
- p->db = 0;
19924
- p->pAuxDb->zDbFilename = 0;
19925
- sqlite3_free(p->pAuxDb->zFreeOnClose);
19926
- p->pAuxDb->zFreeOnClose = 0;
19927
- p->openMode = SHELL_OPEN_UNSPEC;
19928
- p->openFlags = 0;
19929
- p->szMax = 0;
20025
+ int openMode = SHELL_OPEN_UNSPEC;
20026
+
1993020027
/* Check for command-line arguments */
1993120028
for(iName=1; iName<nArg; iName++){
1993220029
const char *z = azArg[iName];
1993320030
if( optionMatch(z,"new") ){
1993420031
newFlag = 1;
1993520032
#ifdef SQLITE_HAVE_ZLIB
1993620033
}else if( optionMatch(z, "zip") ){
19937
- p->openMode = SHELL_OPEN_ZIPFILE;
20034
+ openMode = SHELL_OPEN_ZIPFILE;
1993820035
#endif
1993920036
}else if( optionMatch(z, "append") ){
19940
- p->openMode = SHELL_OPEN_APPENDVFS;
20037
+ openMode = SHELL_OPEN_APPENDVFS;
1994120038
}else if( optionMatch(z, "readonly") ){
19942
- p->openMode = SHELL_OPEN_READONLY;
20039
+ openMode = SHELL_OPEN_READONLY;
1994320040
}else if( optionMatch(z, "nofollow") ){
1994420041
p->openFlags |= SQLITE_OPEN_NOFOLLOW;
19945
- }else if( optionMatch(z, "excl") ){
19946
- p->openFlags |= SQLITE_OPEN_EXCLUSIVE;
1994720042
#ifndef SQLITE_OMIT_DESERIALIZE
1994820043
}else if( optionMatch(z, "deserialize") ){
19949
- p->openMode = SHELL_OPEN_DESERIALIZE;
20044
+ openMode = SHELL_OPEN_DESERIALIZE;
1995020045
}else if( optionMatch(z, "hexdb") ){
19951
- p->openMode = SHELL_OPEN_HEXDB;
20046
+ openMode = SHELL_OPEN_HEXDB;
1995220047
}else if( optionMatch(z, "maxsize") && iName+1<nArg ){
1995320048
p->szMax = integerValue(azArg[++iName]);
1995420049
#endif /* SQLITE_OMIT_DESERIALIZE */
1995520050
}else if( z[0]=='-' ){
1995620051
utf8_printf(stderr, "unknown option: %s\n", z);
@@ -19962,10 +20057,22 @@
1996220057
goto meta_command_exit;
1996320058
}else{
1996420059
zNewFilename = sqlite3_mprintf("%s", z);
1996520060
}
1996620061
}
20062
+
20063
+ /* Close the existing database */
20064
+ session_close_all(p, -1);
20065
+ close_db(p->db);
20066
+ p->db = 0;
20067
+ p->pAuxDb->zDbFilename = 0;
20068
+ sqlite3_free(p->pAuxDb->zFreeOnClose);
20069
+ p->pAuxDb->zFreeOnClose = 0;
20070
+ p->openMode = openMode;
20071
+ p->openFlags = 0;
20072
+ p->szMax = 0;
20073
+
1996720074
/* If a filename is specified, try to open it first */
1996820075
if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
1996920076
if( newFlag && !p->bSafeMode ) shellDeleteFile(zNewFilename);
1997020077
if( p->bSafeMode
1997120078
&& p->openMode!=SHELL_OPEN_HEXDB
@@ -21180,34 +21287,35 @@
2118021287
#ifndef SQLITE_UNTESTABLE
2118121288
if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
2118221289
static const struct {
2118321290
const char *zCtrlName; /* Name of a test-control option */
2118421291
int ctrlCode; /* Integer code for that option */
21292
+ int unSafe; /* Not valid for --safe mode */
2118521293
const char *zUsage; /* Usage notes */
2118621294
} aCtrl[] = {
21187
- { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
21188
- { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
21189
- /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
21190
- /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
21191
- { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
21192
- { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
21193
- /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
21194
- { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
21195
- { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
21196
- { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
21197
- { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
21198
- { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
21295
+ { "always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
21296
+ { "assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
21297
+ /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
21298
+ /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/
21299
+ { "byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
21300
+ { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
21301
+ /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
21302
+ { "imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
21303
+ { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
21304
+ { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
21305
+ { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
21306
+ { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
2119921307
#ifdef YYCOVERAGE
21200
- { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
21308
+ { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
2120121309
#endif
21202
- { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
21203
- { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
21204
- { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
21205
- { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
21206
- { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" },
21207
- { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, "NMAX" },
21208
- { "tune", SQLITE_TESTCTRL_TUNE, "ID VALUE" },
21310
+ { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
21311
+ { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
21312
+ { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
21313
+ { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
21314
+ { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
21315
+ { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
21316
+ { "tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
2120921317
};
2121021318
int testctrl = -1;
2121121319
int iCtrl = -1;
2121221320
int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
2121321321
int isOk = 0;
@@ -21251,10 +21359,15 @@
2125121359
}
2125221360
}
2125321361
if( testctrl<0 ){
2125421362
utf8_printf(stderr,"Error: unknown test-control: %s\n"
2125521363
"Use \".testctrl --help\" for help\n", zCmd);
21364
+ }else if( aCtrl[iCtrl].unSafe && p->bSafeMode ){
21365
+ utf8_printf(stderr,
21366
+ "line %d: \".testctrl %s\" may not be used in safe mode\n",
21367
+ p->lineno, aCtrl[iCtrl].zCtrlName);
21368
+ exit(1);
2125621369
}else{
2125721370
switch(testctrl){
2125821371
2125921372
/* sqlite3_test_control(int, db, int) */
2126021373
case SQLITE_TESTCTRL_OPTIMIZATIONS:
2126121374
--- src/shell.c
+++ src/shell.c
@@ -872,11 +872,11 @@
872 for(i=0; i<nAppend; i++){
873 if( zAppend[i]==quote ) len++;
874 }
875 }
876
877 if( p->n+len>=p->nAlloc ){
878 p->nAlloc = p->nAlloc*2 + len + 20;
879 p->z = realloc(p->z, p->nAlloc);
880 if( p->z==0 ) shell_out_of_memory();
881 }
882
@@ -6261,13 +6261,13 @@
6261 rc = 1;
6262 goto re_match_end;
6263 }
6264 case RE_OP_CC_EXC: {
6265 if( c==0 ) break;
6266 /* fall-through */
6267 }
6268 case RE_OP_CC_INC: {
6269 int j = 1;
6270 int n = pRe->aArg[x];
6271 int hit = 0;
6272 for(j=1; j>0 && j<n; j++){
6273 if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
@@ -6794,10 +6794,13 @@
6794 typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
6795 typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
6796 #define MIN(a,b) ((a)<(b) ? (a) : (b))
6797
6798 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
 
 
 
6799 # define ALWAYS(X) (1)
6800 # define NEVER(X) (0)
6801 #elif !defined(NDEBUG)
6802 # define ALWAYS(X) ((X)?1:(assert(0),0))
6803 # define NEVER(X) ((X)?(assert(0),1):0)
@@ -8672,11 +8675,11 @@
8672 **
8673 ** SELECT zipfile(name,data) ...
8674 ** SELECT zipfile(name,mode,mtime,data) ...
8675 ** SELECT zipfile(name,mode,mtime,data,method) ...
8676 */
8677 void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
8678 ZipfileCtx *p; /* Aggregate function context */
8679 ZipfileEntry e; /* New entry to add to zip archive */
8680
8681 sqlite3_value *pName = 0;
8682 sqlite3_value *pMode = 0;
@@ -8847,11 +8850,11 @@
8847 }
8848
8849 /*
8850 ** xFinalize() callback for zipfile aggregate function.
8851 */
8852 void zipfileFinal(sqlite3_context *pCtx){
8853 ZipfileCtx *p;
8854 ZipfileEOCD eocd;
8855 sqlite3_int64 nZip;
8856 u8 *aZip;
8857
@@ -9253,10 +9256,27 @@
9253 */
9254 /* #include "sqlite3expert.h" */
9255 #include <assert.h>
9256 #include <string.h>
9257 #include <stdio.h>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9258
9259 #ifndef SQLITE_OMIT_VIRTUALTABLE
9260
9261 /* typedef sqlite3_int64 i64; */
9262 /* typedef sqlite3_uint64 u64; */
@@ -9980,13 +10000,13 @@
9980 idxFinalize(&rc, p1);
9981
9982 if( rc!=SQLITE_OK ){
9983 sqlite3_free(pNew);
9984 pNew = 0;
9985 }else{
9986 pNew->zName = pCsr;
9987 memcpy(pNew->zName, zTab, nTab+1);
9988 }
9989
9990 *ppOut = pNew;
9991 return rc;
9992 }
@@ -10390,11 +10410,11 @@
10390 /*
10391 ** This function is called after candidate indexes have been created. It
10392 ** runs all the queries to see which indexes they prefer, and populates
10393 ** IdxStatement.zIdx and IdxStatement.zEQP with the results.
10394 */
10395 int idxFindIndexes(
10396 sqlite3expert *p,
10397 char **pzErr /* OUT: Error message (sqlite3_malloc) */
10398 ){
10399 IdxStatement *pStmt;
10400 sqlite3 *dbm = p->dbm;
@@ -12289,10 +12309,12 @@
12289 #define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
12290 #define MODE_Json 13 /* Output JSON */
12291 #define MODE_Markdown 14 /* Markdown formatting */
12292 #define MODE_Table 15 /* MySQL-style table formatting */
12293 #define MODE_Box 16 /* Unicode box-drawing characters */
 
 
12294
12295 static const char *modeDescr[] = {
12296 "line",
12297 "column",
12298 "list",
@@ -12307,11 +12329,13 @@
12307 "prettyprint",
12308 "eqp",
12309 "json",
12310 "markdown",
12311 "table",
12312 "box"
 
 
12313 };
12314
12315 /*
12316 ** These are the column/row/line separators used by the various
12317 ** import/export modes.
@@ -12798,21 +12822,18 @@
12798 static void output_csv(ShellState *p, const char *z, int bSep){
12799 FILE *out = p->out;
12800 if( z==0 ){
12801 utf8_printf(out,"%s",p->nullValue);
12802 }else{
12803 int i;
12804 int nSep = strlen30(p->colSeparator);
12805 for(i=0; z[i]; i++){
12806 if( needCsvQuote[((unsigned char*)z)[i]]
12807 || (z[i]==p->colSeparator[0] &&
12808 (nSep==1 || memcmp(z, p->colSeparator, nSep)==0)) ){
12809 i = 0;
12810 break;
12811 }
12812 }
12813 if( i==0 ){
12814 char *zQuoted = sqlite3_mprintf("\"%w\"", z);
12815 utf8_printf(out, "%s", zQuoted);
12816 sqlite3_free(zQuoted);
12817 }else{
12818 utf8_printf(out, "%s", z);
@@ -13132,10 +13153,14 @@
13132 int i;
13133 ShellState *p = (ShellState*)pArg;
13134
13135 if( azArg==0 ) return 0;
13136 switch( p->cMode ){
 
 
 
 
13137 case MODE_Line: {
13138 int w = 5;
13139 if( azArg==0 ) break;
13140 for(i=0; i<nArg; i++){
13141 int len = strlen30(azCol[i] ? azCol[i] : "");
@@ -13642,21 +13667,20 @@
13642 }
13643 return rc;
13644 }
13645
13646 /*
13647 ** Allocate space and save off current error string.
13648 */
13649 static char *save_err_msg(
13650 sqlite3 *db /* Database to query */
 
 
13651 ){
13652 int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
13653 char *zErrMsg = sqlite3_malloc64(nErrMsg);
13654 if( zErrMsg ){
13655 memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
13656 }
13657 return zErrMsg;
13658 }
13659
13660 #ifdef __linux__
13661 /*
13662 ** Attempt to display I/O stats on Linux using /proc/PID/io
@@ -13830,17 +13854,24 @@
13830 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
13831 iCur);
13832 }
13833
13834 if( pArg->pStmt ){
 
13835 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
13836 bReset);
13837 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
13838 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
13839 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
13840 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
13841 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
 
 
 
 
 
 
13842 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
13843 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
13844 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
13845 raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
13846 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
@@ -14343,10 +14374,11 @@
14343 static void exec_prepared_stmt(
14344 ShellState *pArg, /* Pointer to ShellState */
14345 sqlite3_stmt *pStmt /* Statment to run */
14346 ){
14347 int rc;
 
14348
14349 if( pArg->cMode==MODE_Column
14350 || pArg->cMode==MODE_Table
14351 || pArg->cMode==MODE_Box
14352 || pArg->cMode==MODE_Markdown
@@ -14375,10 +14407,11 @@
14375 /* save off ptrs to column names */
14376 for(i=0; i<nCol; i++){
14377 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
14378 }
14379 do{
 
14380 /* extract the data and data types */
14381 for(i=0; i<nCol; i++){
14382 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
14383 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
14384 azVals[i] = "";
@@ -14402,10 +14435,12 @@
14402 }
14403 } while( SQLITE_ROW == rc );
14404 sqlite3_free(pData);
14405 if( pArg->cMode==MODE_Json ){
14406 fputs("]\n", pArg->out);
 
 
14407 }
14408 }
14409 }
14410 }
14411
@@ -14574,11 +14609,11 @@
14574 while( zSql[0] && (SQLITE_OK == rc) ){
14575 static const char *zStmtSql;
14576 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14577 if( SQLITE_OK != rc ){
14578 if( pzErrMsg ){
14579 *pzErrMsg = save_err_msg(db);
14580 }
14581 }else{
14582 if( !pStmt ){
14583 /* this happens for a comment or white-space */
14584 zSql = zLeftover;
@@ -14688,11 +14723,11 @@
14688 if( rc!=SQLITE_NOMEM ) rc = rc2;
14689 if( rc==SQLITE_OK ){
14690 zSql = zLeftover;
14691 while( IsSpace(zSql[0]) ) zSql++;
14692 }else if( pzErrMsg ){
14693 *pzErrMsg = save_err_msg(db);
14694 }
14695
14696 /* clear saved stmt handle */
14697 if( pArg ){
14698 pArg->pStmt = NULL;
@@ -15002,17 +15037,19 @@
15002 ".archive ... Manage SQL archives",
15003 " Each command must have exactly one of the following options:",
15004 " -c, --create Create a new archive",
15005 " -u, --update Add or update files with changed mtime",
15006 " -i, --insert Like -u but always add even if unchanged",
 
15007 " -t, --list List contents of archive",
15008 " -x, --extract Extract files from archive",
15009 " Optional arguments:",
15010 " -v, --verbose Print each filename as it is processed",
15011 " -f FILE, --file FILE Use archive FILE (default is current db)",
15012 " -a FILE, --append FILE Open FILE using the apndvfs VFS",
15013 " -C DIR, --directory DIR Read/extract files from directory DIR",
 
15014 " -n, --dryrun Show the SQL that would have occurred",
15015 " Examples:",
15016 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
15017 " .ar -tf ARCHIVE # List members of ARCHIVE",
15018 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
@@ -17169,10 +17206,11 @@
17169 u8 eCmd; /* An AR_CMD_* value */
17170 u8 bVerbose; /* True if --verbose */
17171 u8 bZip; /* True if the archive is a ZIP */
17172 u8 bDryRun; /* True if --dry-run */
17173 u8 bAppend; /* True if --append */
 
17174 u8 fromCmdLine; /* Run from -A instead of .archive */
17175 int nArg; /* Number of command arguments */
17176 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
17177 const char *zFile; /* --file argument, or NULL */
17178 const char *zDir; /* --directory argument, or NULL */
@@ -17216,25 +17254,28 @@
17216 #define AR_CMD_UPDATE 2
17217 #define AR_CMD_INSERT 3
17218 #define AR_CMD_EXTRACT 4
17219 #define AR_CMD_LIST 5
17220 #define AR_CMD_HELP 6
 
17221
17222 /*
17223 ** Other (non-command) switches.
17224 */
17225 #define AR_SWITCH_VERBOSE 7
17226 #define AR_SWITCH_FILE 8
17227 #define AR_SWITCH_DIRECTORY 9
17228 #define AR_SWITCH_APPEND 10
17229 #define AR_SWITCH_DRYRUN 11
 
17230
17231 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
17232 switch( eSwitch ){
17233 case AR_CMD_CREATE:
17234 case AR_CMD_EXTRACT:
17235 case AR_CMD_LIST:
 
17236 case AR_CMD_UPDATE:
17237 case AR_CMD_INSERT:
17238 case AR_CMD_HELP:
17239 if( pAr->eCmd ){
17240 return arErrorMsg(pAr, "multiple command options");
@@ -17242,10 +17283,13 @@
17242 pAr->eCmd = eSwitch;
17243 break;
17244
17245 case AR_SWITCH_DRYRUN:
17246 pAr->bDryRun = 1;
 
 
 
17247 break;
17248 case AR_SWITCH_VERBOSE:
17249 pAr->bVerbose = 1;
17250 break;
17251 case AR_SWITCH_APPEND:
@@ -17281,17 +17325,19 @@
17281 } aSwitch[] = {
17282 { "create", 'c', AR_CMD_CREATE, 0 },
17283 { "extract", 'x', AR_CMD_EXTRACT, 0 },
17284 { "insert", 'i', AR_CMD_INSERT, 0 },
17285 { "list", 't', AR_CMD_LIST, 0 },
 
17286 { "update", 'u', AR_CMD_UPDATE, 0 },
17287 { "help", 'h', AR_CMD_HELP, 0 },
17288 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
17289 { "file", 'f', AR_SWITCH_FILE, 1 },
17290 { "append", 'a', AR_SWITCH_APPEND, 1 },
17291 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
17292 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
 
17293 };
17294 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
17295 struct ArSwitch *pEnd = &aSwitch[nSwitch];
17296
17297 if( nArg<=1 ){
@@ -17404,15 +17450,17 @@
17404 return SQLITE_OK;
17405 }
17406
17407 /*
17408 ** This function assumes that all arguments within the ArCommand.azArg[]
17409 ** array refer to archive members, as for the --extract or --list commands.
17410 ** It checks that each of them are present. If any specified file is not
17411 ** present in the archive, an error is printed to stderr and an error
17412 ** code returned. Otherwise, if all specified arguments are present in
17413 ** the archive, SQLITE_OK is returned.
 
 
17414 **
17415 ** This function strips any trailing '/' characters from each argument.
17416 ** This is consistent with the way the [tar] command seems to work on
17417 ** Linux.
17418 */
@@ -17419,15 +17467,15 @@
17419 static int arCheckEntries(ArCommand *pAr){
17420 int rc = SQLITE_OK;
17421 if( pAr->nArg ){
17422 int i, j;
17423 sqlite3_stmt *pTest = 0;
 
 
 
17424
17425 shellPreparePrintf(pAr->db, &rc, &pTest,
17426 "SELECT name FROM %s WHERE name=$name",
17427 pAr->zSrcTable
17428 );
17429 j = sqlite3_bind_parameter_index(pTest, "$name");
17430 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
17431 char *z = pAr->azArg[i];
17432 int n = strlen30(z);
17433 int bOk = 0;
@@ -17451,29 +17499,31 @@
17451 /*
17452 ** Format a WHERE clause that can be used against the "sqlar" table to
17453 ** identify all archive members that match the command arguments held
17454 ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
17455 ** The caller is responsible for eventually calling sqlite3_free() on
17456 ** any non-NULL (*pzWhere) value.
 
17457 */
17458 static void arWhereClause(
17459 int *pRc,
17460 ArCommand *pAr,
17461 char **pzWhere /* OUT: New WHERE clause */
17462 ){
17463 char *zWhere = 0;
 
17464 if( *pRc==SQLITE_OK ){
17465 if( pAr->nArg==0 ){
17466 zWhere = sqlite3_mprintf("1");
17467 }else{
17468 int i;
17469 const char *zSep = "";
17470 for(i=0; i<pAr->nArg; i++){
17471 const char *z = pAr->azArg[i];
17472 zWhere = sqlite3_mprintf(
17473 "%z%s name = '%q' OR substr(name,1,%d) = '%q/'",
17474 zWhere, zSep, z, strlen30(z)+1, z
17475 );
17476 if( zWhere==0 ){
17477 *pRc = SQLITE_NOMEM;
17478 break;
17479 }
@@ -17522,10 +17572,51 @@
17522 shellFinalize(&rc, pSql);
17523 sqlite3_free(zWhere);
17524 return rc;
17525 }
17526
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17527
17528 /*
17529 ** Implementation of .ar "eXtract" command.
17530 */
17531 static int arExtractCommand(ArCommand *pAr){
@@ -17775,11 +17866,11 @@
17775 cmd.bZip = 1;
17776 }else if( cmd.zFile ){
17777 int flags;
17778 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
17779 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
17780 || cmd.eCmd==AR_CMD_UPDATE ){
17781 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
17782 }else{
17783 flags = SQLITE_OPEN_READONLY;
17784 }
17785 cmd.db = 0;
@@ -17830,10 +17921,14 @@
17830 break;
17831
17832 case AR_CMD_INSERT:
17833 rc = arCreateOrUpdateCommand(&cmd, 1, 0);
17834 break;
 
 
 
 
17835
17836 default:
17837 assert( cmd.eCmd==AR_CMD_UPDATE );
17838 rc = arCreateOrUpdateCommand(&cmd, 1, 1);
17839 break;
@@ -19319,10 +19414,15 @@
19319 int nSkip = 0; /* Initial lines to skip */
19320 int useOutputMode = 1; /* Use output mode to determine separators */
19321
19322 failIfSafeMode(p, "cannot run .import in safe mode");
19323 memset(&sCtx, 0, sizeof(sCtx));
 
 
 
 
 
19324 if( p->mode==MODE_Ascii ){
19325 xRead = ascii_read_one_field;
19326 }else{
19327 xRead = csv_read_one_field;
19328 }
@@ -19428,10 +19528,11 @@
19428 sCtx.xCloser = fclose;
19429 }
19430 if( sCtx.in==0 ){
19431 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
19432 rc = 1;
 
19433 goto meta_command_exit;
19434 }
19435 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
19436 char zSep[2];
19437 zSep[1] = 0;
@@ -19846,10 +19947,14 @@
19846 p->mode = MODE_Markdown;
19847 }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
19848 p->mode = MODE_Table;
19849 }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
19850 p->mode = MODE_Box;
 
 
 
 
19851 }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
19852 p->mode = MODE_Json;
19853 }else if( nArg==1 ){
19854 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
19855 }else{
@@ -19915,42 +20020,32 @@
19915
19916 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
19917 char *zNewFilename = 0; /* Name of the database file to open */
19918 int iName = 1; /* Index in azArg[] of the filename */
19919 int newFlag = 0; /* True to delete file before opening */
19920 /* Close the existing database */
19921 session_close_all(p, -1);
19922 close_db(p->db);
19923 p->db = 0;
19924 p->pAuxDb->zDbFilename = 0;
19925 sqlite3_free(p->pAuxDb->zFreeOnClose);
19926 p->pAuxDb->zFreeOnClose = 0;
19927 p->openMode = SHELL_OPEN_UNSPEC;
19928 p->openFlags = 0;
19929 p->szMax = 0;
19930 /* Check for command-line arguments */
19931 for(iName=1; iName<nArg; iName++){
19932 const char *z = azArg[iName];
19933 if( optionMatch(z,"new") ){
19934 newFlag = 1;
19935 #ifdef SQLITE_HAVE_ZLIB
19936 }else if( optionMatch(z, "zip") ){
19937 p->openMode = SHELL_OPEN_ZIPFILE;
19938 #endif
19939 }else if( optionMatch(z, "append") ){
19940 p->openMode = SHELL_OPEN_APPENDVFS;
19941 }else if( optionMatch(z, "readonly") ){
19942 p->openMode = SHELL_OPEN_READONLY;
19943 }else if( optionMatch(z, "nofollow") ){
19944 p->openFlags |= SQLITE_OPEN_NOFOLLOW;
19945 }else if( optionMatch(z, "excl") ){
19946 p->openFlags |= SQLITE_OPEN_EXCLUSIVE;
19947 #ifndef SQLITE_OMIT_DESERIALIZE
19948 }else if( optionMatch(z, "deserialize") ){
19949 p->openMode = SHELL_OPEN_DESERIALIZE;
19950 }else if( optionMatch(z, "hexdb") ){
19951 p->openMode = SHELL_OPEN_HEXDB;
19952 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
19953 p->szMax = integerValue(azArg[++iName]);
19954 #endif /* SQLITE_OMIT_DESERIALIZE */
19955 }else if( z[0]=='-' ){
19956 utf8_printf(stderr, "unknown option: %s\n", z);
@@ -19962,10 +20057,22 @@
19962 goto meta_command_exit;
19963 }else{
19964 zNewFilename = sqlite3_mprintf("%s", z);
19965 }
19966 }
 
 
 
 
 
 
 
 
 
 
 
 
19967 /* If a filename is specified, try to open it first */
19968 if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
19969 if( newFlag && !p->bSafeMode ) shellDeleteFile(zNewFilename);
19970 if( p->bSafeMode
19971 && p->openMode!=SHELL_OPEN_HEXDB
@@ -21180,34 +21287,35 @@
21180 #ifndef SQLITE_UNTESTABLE
21181 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
21182 static const struct {
21183 const char *zCtrlName; /* Name of a test-control option */
21184 int ctrlCode; /* Integer code for that option */
 
21185 const char *zUsage; /* Usage notes */
21186 } aCtrl[] = {
21187 { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" },
21188 { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" },
21189 /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/
21190 /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/
21191 { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" },
21192 { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" },
21193 /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/
21194 { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"},
21195 { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "" },
21196 { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" },
21197 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" },
21198 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" },
21199 #ifdef YYCOVERAGE
21200 { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" },
21201 #endif
21202 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " },
21203 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" },
21204 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" },
21205 { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" },
21206 { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, "" },
21207 { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, "NMAX" },
21208 { "tune", SQLITE_TESTCTRL_TUNE, "ID VALUE" },
21209 };
21210 int testctrl = -1;
21211 int iCtrl = -1;
21212 int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
21213 int isOk = 0;
@@ -21251,10 +21359,15 @@
21251 }
21252 }
21253 if( testctrl<0 ){
21254 utf8_printf(stderr,"Error: unknown test-control: %s\n"
21255 "Use \".testctrl --help\" for help\n", zCmd);
 
 
 
 
 
21256 }else{
21257 switch(testctrl){
21258
21259 /* sqlite3_test_control(int, db, int) */
21260 case SQLITE_TESTCTRL_OPTIMIZATIONS:
21261
--- src/shell.c
+++ src/shell.c
@@ -872,11 +872,11 @@
872 for(i=0; i<nAppend; i++){
873 if( zAppend[i]==quote ) len++;
874 }
875 }
876
877 if( p->z==0 || p->n+len>=p->nAlloc ){
878 p->nAlloc = p->nAlloc*2 + len + 20;
879 p->z = realloc(p->z, p->nAlloc);
880 if( p->z==0 ) shell_out_of_memory();
881 }
882
@@ -6261,13 +6261,13 @@
6261 rc = 1;
6262 goto re_match_end;
6263 }
6264 case RE_OP_CC_EXC: {
6265 if( c==0 ) break;
6266 /* fall-through */ goto re_op_cc_inc;
6267 }
6268 case RE_OP_CC_INC: re_op_cc_inc: {
6269 int j = 1;
6270 int n = pRe->aArg[x];
6271 int hit = 0;
6272 for(j=1; j>0 && j<n; j++){
6273 if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
@@ -6794,10 +6794,13 @@
6794 typedef UINT32_TYPE u32; /* 4-byte unsigned integer */
6795 typedef UINT16_TYPE u16; /* 2-byte unsigned integer */
6796 #define MIN(a,b) ((a)<(b) ? (a) : (b))
6797
6798 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
6799 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
6800 #endif
6801 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
6802 # define ALWAYS(X) (1)
6803 # define NEVER(X) (0)
6804 #elif !defined(NDEBUG)
6805 # define ALWAYS(X) ((X)?1:(assert(0),0))
6806 # define NEVER(X) ((X)?(assert(0),1):0)
@@ -8672,11 +8675,11 @@
8675 **
8676 ** SELECT zipfile(name,data) ...
8677 ** SELECT zipfile(name,mode,mtime,data) ...
8678 ** SELECT zipfile(name,mode,mtime,data,method) ...
8679 */
8680 static void zipfileStep(sqlite3_context *pCtx, int nVal, sqlite3_value **apVal){
8681 ZipfileCtx *p; /* Aggregate function context */
8682 ZipfileEntry e; /* New entry to add to zip archive */
8683
8684 sqlite3_value *pName = 0;
8685 sqlite3_value *pMode = 0;
@@ -8847,11 +8850,11 @@
8850 }
8851
8852 /*
8853 ** xFinalize() callback for zipfile aggregate function.
8854 */
8855 static void zipfileFinal(sqlite3_context *pCtx){
8856 ZipfileCtx *p;
8857 ZipfileEOCD eocd;
8858 sqlite3_int64 nZip;
8859 u8 *aZip;
8860
@@ -9253,10 +9256,27 @@
9256 */
9257 /* #include "sqlite3expert.h" */
9258 #include <assert.h>
9259 #include <string.h>
9260 #include <stdio.h>
9261
9262 #if !defined(SQLITE_AMALGAMATION)
9263 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
9264 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
9265 #endif
9266 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
9267 # define ALWAYS(X) (1)
9268 # define NEVER(X) (0)
9269 #elif !defined(NDEBUG)
9270 # define ALWAYS(X) ((X)?1:(assert(0),0))
9271 # define NEVER(X) ((X)?(assert(0),1):0)
9272 #else
9273 # define ALWAYS(X) (X)
9274 # define NEVER(X) (X)
9275 #endif
9276 #endif /* !defined(SQLITE_AMALGAMATION) */
9277
9278
9279 #ifndef SQLITE_OMIT_VIRTUALTABLE
9280
9281 /* typedef sqlite3_int64 i64; */
9282 /* typedef sqlite3_uint64 u64; */
@@ -9980,13 +10000,13 @@
10000 idxFinalize(&rc, p1);
10001
10002 if( rc!=SQLITE_OK ){
10003 sqlite3_free(pNew);
10004 pNew = 0;
10005 }else if( ALWAYS(pNew!=0) ){
10006 pNew->zName = pCsr;
10007 if( ALWAYS(pNew->zName!=0) ) memcpy(pNew->zName, zTab, nTab+1);
10008 }
10009
10010 *ppOut = pNew;
10011 return rc;
10012 }
@@ -10390,11 +10410,11 @@
10410 /*
10411 ** This function is called after candidate indexes have been created. It
10412 ** runs all the queries to see which indexes they prefer, and populates
10413 ** IdxStatement.zIdx and IdxStatement.zEQP with the results.
10414 */
10415 static int idxFindIndexes(
10416 sqlite3expert *p,
10417 char **pzErr /* OUT: Error message (sqlite3_malloc) */
10418 ){
10419 IdxStatement *pStmt;
10420 sqlite3 *dbm = p->dbm;
@@ -12289,10 +12309,12 @@
12309 #define MODE_EQP 12 /* Converts EXPLAIN QUERY PLAN output into a graph */
12310 #define MODE_Json 13 /* Output JSON */
12311 #define MODE_Markdown 14 /* Markdown formatting */
12312 #define MODE_Table 15 /* MySQL-style table formatting */
12313 #define MODE_Box 16 /* Unicode box-drawing characters */
12314 #define MODE_Count 17 /* Output only a count of the rows of output */
12315 #define MODE_Off 18 /* No query output shown */
12316
12317 static const char *modeDescr[] = {
12318 "line",
12319 "column",
12320 "list",
@@ -12307,11 +12329,13 @@
12329 "prettyprint",
12330 "eqp",
12331 "json",
12332 "markdown",
12333 "table",
12334 "box",
12335 "count",
12336 "off"
12337 };
12338
12339 /*
12340 ** These are the column/row/line separators used by the various
12341 ** import/export modes.
@@ -12798,21 +12822,18 @@
12822 static void output_csv(ShellState *p, const char *z, int bSep){
12823 FILE *out = p->out;
12824 if( z==0 ){
12825 utf8_printf(out,"%s",p->nullValue);
12826 }else{
12827 unsigned i;
 
12828 for(i=0; z[i]; i++){
12829 if( needCsvQuote[((unsigned char*)z)[i]] ){
 
 
12830 i = 0;
12831 break;
12832 }
12833 }
12834 if( i==0 || strstr(z, p->colSeparator)!=0 ){
12835 char *zQuoted = sqlite3_mprintf("\"%w\"", z);
12836 utf8_printf(out, "%s", zQuoted);
12837 sqlite3_free(zQuoted);
12838 }else{
12839 utf8_printf(out, "%s", z);
@@ -13132,10 +13153,14 @@
13153 int i;
13154 ShellState *p = (ShellState*)pArg;
13155
13156 if( azArg==0 ) return 0;
13157 switch( p->cMode ){
13158 case MODE_Count:
13159 case MODE_Off: {
13160 break;
13161 }
13162 case MODE_Line: {
13163 int w = 5;
13164 if( azArg==0 ) break;
13165 for(i=0; i<nArg; i++){
13166 int len = strlen30(azCol[i] ? azCol[i] : "");
@@ -13642,21 +13667,20 @@
13667 }
13668 return rc;
13669 }
13670
13671 /*
13672 ** Allocate space and save off string indicating current error.
13673 */
13674 static char *save_err_msg(
13675 sqlite3 *db, /* Database to query */
13676 const char *zWhen, /* Qualifier (format) wrapper */
13677 int rc /* Error code returned from API */
13678 ){
13679 if( zWhen==0 )
13680 zWhen = "%s (%d)";
13681 return sqlite3_mprintf(zWhen, sqlite3_errmsg(db), rc);
 
 
 
13682 }
13683
13684 #ifdef __linux__
13685 /*
13686 ** Attempt to display I/O stats on Linux using /proc/PID/io
@@ -13830,17 +13854,24 @@
13854 raw_printf(pArg->out, "Statement Heap/Lookaside Usage: %d bytes\n",
13855 iCur);
13856 }
13857
13858 if( pArg->pStmt ){
13859 int iHit, iMiss;
13860 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP,
13861 bReset);
13862 raw_printf(pArg->out, "Fullscan Steps: %d\n", iCur);
13863 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
13864 raw_printf(pArg->out, "Sort Operations: %d\n", iCur);
13865 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
13866 raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur);
13867 iHit = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_HIT, bReset);
13868 iMiss = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FILTER_MISS, bReset);
13869 if( iHit || iMiss ){
13870 raw_printf(pArg->out, "Bloom filter bypass taken: %d/%d\n",
13871 iHit, iHit+iMiss);
13872 }
13873 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
13874 raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur);
13875 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset);
13876 raw_printf(pArg->out, "Reprepare operations: %d\n", iCur);
13877 iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset);
@@ -14343,10 +14374,11 @@
14374 static void exec_prepared_stmt(
14375 ShellState *pArg, /* Pointer to ShellState */
14376 sqlite3_stmt *pStmt /* Statment to run */
14377 ){
14378 int rc;
14379 sqlite3_uint64 nRow = 0;
14380
14381 if( pArg->cMode==MODE_Column
14382 || pArg->cMode==MODE_Table
14383 || pArg->cMode==MODE_Box
14384 || pArg->cMode==MODE_Markdown
@@ -14375,10 +14407,11 @@
14407 /* save off ptrs to column names */
14408 for(i=0; i<nCol; i++){
14409 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
14410 }
14411 do{
14412 nRow++;
14413 /* extract the data and data types */
14414 for(i=0; i<nCol; i++){
14415 aiTypes[i] = x = sqlite3_column_type(pStmt, i);
14416 if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
14417 azVals[i] = "";
@@ -14402,10 +14435,12 @@
14435 }
14436 } while( SQLITE_ROW == rc );
14437 sqlite3_free(pData);
14438 if( pArg->cMode==MODE_Json ){
14439 fputs("]\n", pArg->out);
14440 }else if( pArg->cMode==MODE_Count ){
14441 printf("%llu row%s\n", nRow, nRow!=1 ? "s" : "");
14442 }
14443 }
14444 }
14445 }
14446
@@ -14574,11 +14609,11 @@
14609 while( zSql[0] && (SQLITE_OK == rc) ){
14610 static const char *zStmtSql;
14611 rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
14612 if( SQLITE_OK != rc ){
14613 if( pzErrMsg ){
14614 *pzErrMsg = save_err_msg(db, "in prepare, %s (%d)", rc);
14615 }
14616 }else{
14617 if( !pStmt ){
14618 /* this happens for a comment or white-space */
14619 zSql = zLeftover;
@@ -14688,11 +14723,11 @@
14723 if( rc!=SQLITE_NOMEM ) rc = rc2;
14724 if( rc==SQLITE_OK ){
14725 zSql = zLeftover;
14726 while( IsSpace(zSql[0]) ) zSql++;
14727 }else if( pzErrMsg ){
14728 *pzErrMsg = save_err_msg(db, "stepping, %s (%d)", rc);
14729 }
14730
14731 /* clear saved stmt handle */
14732 if( pArg ){
14733 pArg->pStmt = NULL;
@@ -15002,17 +15037,19 @@
15037 ".archive ... Manage SQL archives",
15038 " Each command must have exactly one of the following options:",
15039 " -c, --create Create a new archive",
15040 " -u, --update Add or update files with changed mtime",
15041 " -i, --insert Like -u but always add even if unchanged",
15042 " -r, --remove Remove files from archive",
15043 " -t, --list List contents of archive",
15044 " -x, --extract Extract files from archive",
15045 " Optional arguments:",
15046 " -v, --verbose Print each filename as it is processed",
15047 " -f FILE, --file FILE Use archive FILE (default is current db)",
15048 " -a FILE, --append FILE Open FILE using the apndvfs VFS",
15049 " -C DIR, --directory DIR Read/extract files from directory DIR",
15050 " -g, --glob Use glob matching for names in archive",
15051 " -n, --dryrun Show the SQL that would have occurred",
15052 " Examples:",
15053 " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar",
15054 " .ar -tf ARCHIVE # List members of ARCHIVE",
15055 " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE",
@@ -17169,10 +17206,11 @@
17206 u8 eCmd; /* An AR_CMD_* value */
17207 u8 bVerbose; /* True if --verbose */
17208 u8 bZip; /* True if the archive is a ZIP */
17209 u8 bDryRun; /* True if --dry-run */
17210 u8 bAppend; /* True if --append */
17211 u8 bGlob; /* True if --glob */
17212 u8 fromCmdLine; /* Run from -A instead of .archive */
17213 int nArg; /* Number of command arguments */
17214 char *zSrcTable; /* "sqlar", "zipfile($file)" or "zip" */
17215 const char *zFile; /* --file argument, or NULL */
17216 const char *zDir; /* --directory argument, or NULL */
@@ -17216,25 +17254,28 @@
17254 #define AR_CMD_UPDATE 2
17255 #define AR_CMD_INSERT 3
17256 #define AR_CMD_EXTRACT 4
17257 #define AR_CMD_LIST 5
17258 #define AR_CMD_HELP 6
17259 #define AR_CMD_REMOVE 7
17260
17261 /*
17262 ** Other (non-command) switches.
17263 */
17264 #define AR_SWITCH_VERBOSE 8
17265 #define AR_SWITCH_FILE 9
17266 #define AR_SWITCH_DIRECTORY 10
17267 #define AR_SWITCH_APPEND 11
17268 #define AR_SWITCH_DRYRUN 12
17269 #define AR_SWITCH_GLOB 13
17270
17271 static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
17272 switch( eSwitch ){
17273 case AR_CMD_CREATE:
17274 case AR_CMD_EXTRACT:
17275 case AR_CMD_LIST:
17276 case AR_CMD_REMOVE:
17277 case AR_CMD_UPDATE:
17278 case AR_CMD_INSERT:
17279 case AR_CMD_HELP:
17280 if( pAr->eCmd ){
17281 return arErrorMsg(pAr, "multiple command options");
@@ -17242,10 +17283,13 @@
17283 pAr->eCmd = eSwitch;
17284 break;
17285
17286 case AR_SWITCH_DRYRUN:
17287 pAr->bDryRun = 1;
17288 break;
17289 case AR_SWITCH_GLOB:
17290 pAr->bGlob = 1;
17291 break;
17292 case AR_SWITCH_VERBOSE:
17293 pAr->bVerbose = 1;
17294 break;
17295 case AR_SWITCH_APPEND:
@@ -17281,17 +17325,19 @@
17325 } aSwitch[] = {
17326 { "create", 'c', AR_CMD_CREATE, 0 },
17327 { "extract", 'x', AR_CMD_EXTRACT, 0 },
17328 { "insert", 'i', AR_CMD_INSERT, 0 },
17329 { "list", 't', AR_CMD_LIST, 0 },
17330 { "remove", 'r', AR_CMD_REMOVE, 0 },
17331 { "update", 'u', AR_CMD_UPDATE, 0 },
17332 { "help", 'h', AR_CMD_HELP, 0 },
17333 { "verbose", 'v', AR_SWITCH_VERBOSE, 0 },
17334 { "file", 'f', AR_SWITCH_FILE, 1 },
17335 { "append", 'a', AR_SWITCH_APPEND, 1 },
17336 { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
17337 { "dryrun", 'n', AR_SWITCH_DRYRUN, 0 },
17338 { "glob", 'g', AR_SWITCH_GLOB, 0 },
17339 };
17340 int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
17341 struct ArSwitch *pEnd = &aSwitch[nSwitch];
17342
17343 if( nArg<=1 ){
@@ -17404,15 +17450,17 @@
17450 return SQLITE_OK;
17451 }
17452
17453 /*
17454 ** This function assumes that all arguments within the ArCommand.azArg[]
17455 ** array refer to archive members, as for the --extract, --list or --remove
17456 ** commands. It checks that each of them are "present". If any specified
17457 ** file is not present in the archive, an error is printed to stderr and an
17458 ** error code returned. Otherwise, if all specified arguments are present
17459 ** in the archive, SQLITE_OK is returned. Here, "present" means either an
17460 ** exact equality when pAr->bGlob is false or a "name GLOB pattern" match
17461 ** when pAr->bGlob is true.
17462 **
17463 ** This function strips any trailing '/' characters from each argument.
17464 ** This is consistent with the way the [tar] command seems to work on
17465 ** Linux.
17466 */
@@ -17419,15 +17467,15 @@
17467 static int arCheckEntries(ArCommand *pAr){
17468 int rc = SQLITE_OK;
17469 if( pAr->nArg ){
17470 int i, j;
17471 sqlite3_stmt *pTest = 0;
17472 const char *zSel = (pAr->bGlob)
17473 ? "SELECT name FROM %s WHERE glob($name,name)"
17474 : "SELECT name FROM %s WHERE name=$name";
17475
17476 shellPreparePrintf(pAr->db, &rc, &pTest, zSel, pAr->zSrcTable);
 
 
 
17477 j = sqlite3_bind_parameter_index(pTest, "$name");
17478 for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
17479 char *z = pAr->azArg[i];
17480 int n = strlen30(z);
17481 int bOk = 0;
@@ -17451,29 +17499,31 @@
17499 /*
17500 ** Format a WHERE clause that can be used against the "sqlar" table to
17501 ** identify all archive members that match the command arguments held
17502 ** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
17503 ** The caller is responsible for eventually calling sqlite3_free() on
17504 ** any non-NULL (*pzWhere) value. Here, "match" means strict equality
17505 ** when pAr->bGlob is false and GLOB match when pAr->bGlob is true.
17506 */
17507 static void arWhereClause(
17508 int *pRc,
17509 ArCommand *pAr,
17510 char **pzWhere /* OUT: New WHERE clause */
17511 ){
17512 char *zWhere = 0;
17513 const char *zSameOp = (pAr->bGlob)? "GLOB" : "=";
17514 if( *pRc==SQLITE_OK ){
17515 if( pAr->nArg==0 ){
17516 zWhere = sqlite3_mprintf("1");
17517 }else{
17518 int i;
17519 const char *zSep = "";
17520 for(i=0; i<pAr->nArg; i++){
17521 const char *z = pAr->azArg[i];
17522 zWhere = sqlite3_mprintf(
17523 "%z%s name %s '%q' OR substr(name,1,%d) %s '%q/'",
17524 zWhere, zSep, zSameOp, z, strlen30(z)+1, zSameOp, z
17525 );
17526 if( zWhere==0 ){
17527 *pRc = SQLITE_NOMEM;
17528 break;
17529 }
@@ -17522,10 +17572,51 @@
17572 shellFinalize(&rc, pSql);
17573 sqlite3_free(zWhere);
17574 return rc;
17575 }
17576
17577
17578 /*
17579 ** Implementation of .ar "Remove" command.
17580 */
17581 static int arRemoveCommand(ArCommand *pAr){
17582 int rc = 0;
17583 char *zSql = 0;
17584 char *zWhere = 0;
17585
17586 if( pAr->nArg ){
17587 /* Verify that args actually exist within the archive before proceeding.
17588 ** And formulate a WHERE clause to match them. */
17589 rc = arCheckEntries(pAr);
17590 arWhereClause(&rc, pAr, &zWhere);
17591 }
17592 if( rc==SQLITE_OK ){
17593 zSql = sqlite3_mprintf("DELETE FROM %s WHERE %s;",
17594 pAr->zSrcTable, zWhere);
17595 if( pAr->bDryRun ){
17596 utf8_printf(pAr->p->out, "%s\n", zSql);
17597 }else{
17598 char *zErr = 0;
17599 rc = sqlite3_exec(pAr->db, "SAVEPOINT ar;", 0, 0, 0);
17600 if( rc==SQLITE_OK ){
17601 rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
17602 if( rc!=SQLITE_OK ){
17603 sqlite3_exec(pAr->db, "ROLLBACK TO ar; RELEASE ar;", 0, 0, 0);
17604 }else{
17605 rc = sqlite3_exec(pAr->db, "RELEASE ar;", 0, 0, 0);
17606 }
17607 }
17608 if( zErr ){
17609 utf8_printf(stdout, "ERROR: %s\n", zErr);
17610 sqlite3_free(zErr);
17611 }
17612 }
17613 }
17614 sqlite3_free(zWhere);
17615 sqlite3_free(zSql);
17616 return rc;
17617 }
17618
17619 /*
17620 ** Implementation of .ar "eXtract" command.
17621 */
17622 static int arExtractCommand(ArCommand *pAr){
@@ -17775,11 +17866,11 @@
17866 cmd.bZip = 1;
17867 }else if( cmd.zFile ){
17868 int flags;
17869 if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
17870 if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_INSERT
17871 || cmd.eCmd==AR_CMD_REMOVE || cmd.eCmd==AR_CMD_UPDATE ){
17872 flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
17873 }else{
17874 flags = SQLITE_OPEN_READONLY;
17875 }
17876 cmd.db = 0;
@@ -17830,10 +17921,14 @@
17921 break;
17922
17923 case AR_CMD_INSERT:
17924 rc = arCreateOrUpdateCommand(&cmd, 1, 0);
17925 break;
17926
17927 case AR_CMD_REMOVE:
17928 rc = arRemoveCommand(&cmd);
17929 break;
17930
17931 default:
17932 assert( cmd.eCmd==AR_CMD_UPDATE );
17933 rc = arCreateOrUpdateCommand(&cmd, 1, 1);
17934 break;
@@ -19319,10 +19414,15 @@
19414 int nSkip = 0; /* Initial lines to skip */
19415 int useOutputMode = 1; /* Use output mode to determine separators */
19416
19417 failIfSafeMode(p, "cannot run .import in safe mode");
19418 memset(&sCtx, 0, sizeof(sCtx));
19419 sCtx.z = sqlite3_malloc64(120);
19420 if( sCtx.z==0 ){
19421 import_cleanup(&sCtx);
19422 shell_out_of_memory();
19423 }
19424 if( p->mode==MODE_Ascii ){
19425 xRead = ascii_read_one_field;
19426 }else{
19427 xRead = csv_read_one_field;
19428 }
@@ -19428,10 +19528,11 @@
19528 sCtx.xCloser = fclose;
19529 }
19530 if( sCtx.in==0 ){
19531 utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
19532 rc = 1;
19533 import_cleanup(&sCtx);
19534 goto meta_command_exit;
19535 }
19536 if( eVerbose>=2 || (eVerbose>=1 && useOutputMode) ){
19537 char zSep[2];
19538 zSep[1] = 0;
@@ -19846,10 +19947,14 @@
19947 p->mode = MODE_Markdown;
19948 }else if( c2=='t' && strncmp(azArg[1],"table",n2)==0 ){
19949 p->mode = MODE_Table;
19950 }else if( c2=='b' && strncmp(azArg[1],"box",n2)==0 ){
19951 p->mode = MODE_Box;
19952 }else if( c2=='c' && strncmp(azArg[1],"count",n2)==0 ){
19953 p->mode = MODE_Count;
19954 }else if( c2=='o' && strncmp(azArg[1],"off",n2)==0 ){
19955 p->mode = MODE_Off;
19956 }else if( c2=='j' && strncmp(azArg[1],"json",n2)==0 ){
19957 p->mode = MODE_Json;
19958 }else if( nArg==1 ){
19959 raw_printf(p->out, "current output mode: %s\n", modeDescr[p->mode]);
19960 }else{
@@ -19915,42 +20020,32 @@
20020
20021 if( c=='o' && strncmp(azArg[0], "open", n)==0 && n>=2 ){
20022 char *zNewFilename = 0; /* Name of the database file to open */
20023 int iName = 1; /* Index in azArg[] of the filename */
20024 int newFlag = 0; /* True to delete file before opening */
20025 int openMode = SHELL_OPEN_UNSPEC;
20026
 
 
 
 
 
 
 
 
20027 /* Check for command-line arguments */
20028 for(iName=1; iName<nArg; iName++){
20029 const char *z = azArg[iName];
20030 if( optionMatch(z,"new") ){
20031 newFlag = 1;
20032 #ifdef SQLITE_HAVE_ZLIB
20033 }else if( optionMatch(z, "zip") ){
20034 openMode = SHELL_OPEN_ZIPFILE;
20035 #endif
20036 }else if( optionMatch(z, "append") ){
20037 openMode = SHELL_OPEN_APPENDVFS;
20038 }else if( optionMatch(z, "readonly") ){
20039 openMode = SHELL_OPEN_READONLY;
20040 }else if( optionMatch(z, "nofollow") ){
20041 p->openFlags |= SQLITE_OPEN_NOFOLLOW;
 
 
20042 #ifndef SQLITE_OMIT_DESERIALIZE
20043 }else if( optionMatch(z, "deserialize") ){
20044 openMode = SHELL_OPEN_DESERIALIZE;
20045 }else if( optionMatch(z, "hexdb") ){
20046 openMode = SHELL_OPEN_HEXDB;
20047 }else if( optionMatch(z, "maxsize") && iName+1<nArg ){
20048 p->szMax = integerValue(azArg[++iName]);
20049 #endif /* SQLITE_OMIT_DESERIALIZE */
20050 }else if( z[0]=='-' ){
20051 utf8_printf(stderr, "unknown option: %s\n", z);
@@ -19962,10 +20057,22 @@
20057 goto meta_command_exit;
20058 }else{
20059 zNewFilename = sqlite3_mprintf("%s", z);
20060 }
20061 }
20062
20063 /* Close the existing database */
20064 session_close_all(p, -1);
20065 close_db(p->db);
20066 p->db = 0;
20067 p->pAuxDb->zDbFilename = 0;
20068 sqlite3_free(p->pAuxDb->zFreeOnClose);
20069 p->pAuxDb->zFreeOnClose = 0;
20070 p->openMode = openMode;
20071 p->openFlags = 0;
20072 p->szMax = 0;
20073
20074 /* If a filename is specified, try to open it first */
20075 if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
20076 if( newFlag && !p->bSafeMode ) shellDeleteFile(zNewFilename);
20077 if( p->bSafeMode
20078 && p->openMode!=SHELL_OPEN_HEXDB
@@ -21180,34 +21287,35 @@
21287 #ifndef SQLITE_UNTESTABLE
21288 if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 ){
21289 static const struct {
21290 const char *zCtrlName; /* Name of a test-control option */
21291 int ctrlCode; /* Integer code for that option */
21292 int unSafe; /* Not valid for --safe mode */
21293 const char *zUsage; /* Usage notes */
21294 } aCtrl[] = {
21295 { "always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" },
21296 { "assert", SQLITE_TESTCTRL_ASSERT, 1, "BOOLEAN" },
21297 /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS,1, "" },*/
21298 /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, 1, "" },*/
21299 { "byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" },
21300 { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" },
21301 /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/
21302 { "imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"},
21303 { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" },
21304 { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" },
21305 { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT,1, "BOOLEAN" },
21306 { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS,0,"DISABLE-MASK" },
21307 #ifdef YYCOVERAGE
21308 { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE,0,"" },
21309 #endif
21310 { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
21311 { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
21312 { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
21313 { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
21314 { "seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
21315 { "sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
21316 { "tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
21317 };
21318 int testctrl = -1;
21319 int iCtrl = -1;
21320 int rc2 = 0; /* 0: usage. 1: %d 2: %x 3: no-output */
21321 int isOk = 0;
@@ -21251,10 +21359,15 @@
21359 }
21360 }
21361 if( testctrl<0 ){
21362 utf8_printf(stderr,"Error: unknown test-control: %s\n"
21363 "Use \".testctrl --help\" for help\n", zCmd);
21364 }else if( aCtrl[iCtrl].unSafe && p->bSafeMode ){
21365 utf8_printf(stderr,
21366 "line %d: \".testctrl %s\" may not be used in safe mode\n",
21367 p->lineno, aCtrl[iCtrl].zCtrlName);
21368 exit(1);
21369 }else{
21370 switch(testctrl){
21371
21372 /* sqlite3_test_control(int, db, int) */
21373 case SQLITE_TESTCTRL_OPTIMIZATIONS:
21374
+1 -1
--- src/shun.c
+++ src/shun.c
@@ -60,11 +60,11 @@
6060
}
6161
if( P("rebuild") ){
6262
db_close(1);
6363
db_open_repository(g.zRepositoryName);
6464
db_begin_transaction();
65
- rebuild_db(0, 0, 0);
65
+ rebuild_db(0, 0);
6666
admin_log("Rebuilt database.");
6767
db_end_transaction(0);
6868
}
6969
if( zUuid ){
7070
char *p;
7171
--- src/shun.c
+++ src/shun.c
@@ -60,11 +60,11 @@
60 }
61 if( P("rebuild") ){
62 db_close(1);
63 db_open_repository(g.zRepositoryName);
64 db_begin_transaction();
65 rebuild_db(0, 0, 0);
66 admin_log("Rebuilt database.");
67 db_end_transaction(0);
68 }
69 if( zUuid ){
70 char *p;
71
--- src/shun.c
+++ src/shun.c
@@ -60,11 +60,11 @@
60 }
61 if( P("rebuild") ){
62 db_close(1);
63 db_open_repository(g.zRepositoryName);
64 db_begin_transaction();
65 rebuild_db(0, 0);
66 admin_log("Rebuilt database.");
67 db_end_transaction(0);
68 }
69 if( zUuid ){
70 char *p;
71
+3354 -1665
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
11
/******************************************************************************
22
** This file is an amalgamation of many separate C source files from SQLite
3
-** version 3.37.0. By combining all the individual C code files into this
3
+** version 3.38.0. By combining all the individual C code files into this
44
** single large file, the entire code can be compiled as a single translation
55
** unit. This allows many compilers to do optimizations that would not be
66
** possible if the files were compiled separately. Performance improvements
77
** of 5% or more are commonly seen when SQLite is compiled as a single
88
** translation unit.
@@ -450,13 +450,13 @@
450450
**
451451
** See also: [sqlite3_libversion()],
452452
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453453
** [sqlite_version()] and [sqlite_source_id()].
454454
*/
455
-#define SQLITE_VERSION "3.37.0"
456
-#define SQLITE_VERSION_NUMBER 3037000
457
-#define SQLITE_SOURCE_ID "2021-10-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813"
455
+#define SQLITE_VERSION "3.38.0"
456
+#define SQLITE_VERSION_NUMBER 3038000
457
+#define SQLITE_SOURCE_ID "2021-12-09 20:06:18 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882"
458458
459459
/*
460460
** CAPI3REF: Run-Time Library Version Numbers
461461
** KEYWORDS: sqlite3_version sqlite3_sourceid
462462
**
@@ -843,11 +843,10 @@
843843
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
844844
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
845845
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
846846
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
847847
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
848
-#define SQLITE_CANTOPEN_EXISTS (SQLITE_CANTOPEN | (7<<8))
849848
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
850849
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
851850
#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
852851
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
853852
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -879,10 +878,23 @@
879878
** CAPI3REF: Flags For File Open Operations
880879
**
881880
** These bit values are intended for use in the
882881
** 3rd parameter to the [sqlite3_open_v2()] interface and
883882
** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
883
+**
884
+** Only those flags marked as "Ok for sqlite3_open_v2()" may be
885
+** used as the third argument to the [sqlite3_open_v2()] interface.
886
+** The other flags have historically been ignored by sqlite3_open_v2(),
887
+** though future versions of SQLite might change so that an error is
888
+** raised if any of the disallowed bits are passed into sqlite3_open_v2().
889
+** Applications should not depend on the historical behavior.
890
+**
891
+** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into
892
+** [sqlite3_open_v2()] does *not* cause the underlying database file
893
+** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into
894
+** [sqlite3_open_v2()] has historically be a no-op and might become an
895
+** error in future versions of SQLite.
884896
*/
885897
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
886898
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
887899
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
888900
#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
@@ -901,10 +913,11 @@
901913
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
902914
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
903915
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
904916
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
905917
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
918
+#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
906919
907920
/* Reserved: 0x00F00000 */
908921
/* Legacy compatibility: */
909922
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
910923
@@ -3720,25 +3733,35 @@
37203733
**
37213734
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
37223735
** <dd>The database is opened [shared cache] disabled, overriding
37233736
** the default shared cache setting provided by
37243737
** [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>
37253746
**
37263747
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
37273748
** <dd>The database filename is not allowed to be a symbolic link</dd>
3728
-**
3729
-** [[OPEN_EXCLUSIVE]] ^(<dt>[SQLITE_OPEN_EXCLUSIVE]</dt>
3730
-** <dd>This flag causes the open to fail if the database file already
3731
-** exists. The open will only be success if this flag is used in combination
3732
-** with the SQLITE_OPEN_CREATE and SQLITE_OPEN_READWRITE flags and if
3733
-** the file does not previously exist.</dd>
37343749
** </dl>)^
37353750
**
37363751
** If the 3rd parameter to sqlite3_open_v2() is not one of the
37373752
** required combinations shown above optionally combined with other
37383753
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
3739
-** then the behavior is undefined.
3754
+** then the behavior is undefined. Historic versions of SQLite
3755
+** have silently ignored surplus bits in the flags parameter to
3756
+** sqlite3_open_v2(), however that behavior might not be carried through
3757
+** into future versions of SQLite and so applications should not rely
3758
+** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op
3759
+** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause
3760
+** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE
3761
+** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not
3762
+** by sqlite3_open_v2().
37403763
**
37413764
** ^The fourth parameter to sqlite3_open_v2() is the name of the
37423765
** [sqlite3_vfs] object that defines the operating system interface that
37433766
** the new database connection should use. ^If the fourth parameter is
37443767
** a NULL pointer then the default [sqlite3_vfs] object is used.
@@ -6695,10 +6718,76 @@
66956718
**
66966719
** See also the [sqlite3_update_hook()] interface.
66976720
*/
66986721
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
66996722
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
+
67006789
67016790
/*
67026791
** CAPI3REF: Data Change Notification Callbacks
67036792
** METHOD: sqlite3
67046793
**
@@ -8159,11 +8248,12 @@
81598248
#define SQLITE_TESTCTRL_PRNG_SEED 28
81608249
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
81618250
#define SQLITE_TESTCTRL_SEEK_COUNT 30
81628251
#define SQLITE_TESTCTRL_TRACEFLAGS 31
81638252
#define SQLITE_TESTCTRL_TUNE 32
8164
-#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */
8253
+#define SQLITE_TESTCTRL_LOGEST 33
8254
+#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */
81658255
81668256
/*
81678257
** CAPI3REF: SQL Keyword Checking
81688258
**
81698259
** These routines provide access to the set of SQL language keywords
@@ -8681,10 +8771,20 @@
86818771
** <dd>^This is the number of times that the prepared statement has
86828772
** been run. A single "run" for the purposes of this counter is one
86838773
** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
86848774
** The counter is incremented on the first [sqlite3_step()] call of each
86858775
** cycle.
8776
+**
8777
+** [[SQLITE_STMTSTATUS_FILTER_MISS]]
8778
+** [[SQLITE_STMTSTATUS_FILTER HIT]]
8779
+** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br>
8780
+** SQLITE_STMTSTATUS_FILTER_MISS</dt>
8781
+** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join
8782
+** step was bypassed because a Bloom filter returned not-found. The
8783
+** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of
8784
+** times that the Bloom filter returned a find, and thus the join step
8785
+** had to be processed as normal.
86868786
**
86878787
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
86888788
** <dd>^This is the approximate number of bytes of heap memory
86898789
** used to store the prepared statement. ^This value is not actually
86908790
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -8696,10 +8796,12 @@
86968796
#define SQLITE_STMTSTATUS_SORT 2
86978797
#define SQLITE_STMTSTATUS_AUTOINDEX 3
86988798
#define SQLITE_STMTSTATUS_VM_STEP 4
86998799
#define SQLITE_STMTSTATUS_REPREPARE 5
87008800
#define SQLITE_STMTSTATUS_RUN 6
8801
+#define SQLITE_STMTSTATUS_FILTER_MISS 7
8802
+#define SQLITE_STMTSTATUS_FILTER_HIT 8
87018803
#define SQLITE_STMTSTATUS_MEMUSED 99
87028804
87038805
/*
87048806
** CAPI3REF: Custom Page Cache Object
87058807
**
@@ -13160,15 +13262,16 @@
1316013262
** can be used to make sure boundary values are tested. For
1316113263
** bitmask tests, testcase() can be used to make sure each bit
1316213264
** is significant and used at least once. On switch statements
1316313265
** where multiple cases go to the same block of code, testcase()
1316413266
** can insure that all cases are evaluated.
13165
-**
1316613267
*/
13167
-#ifdef SQLITE_COVERAGE_TEST
13168
-SQLITE_PRIVATE void sqlite3Coverage(int);
13169
-# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); }
13268
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
13269
+# ifndef SQLITE_AMALGAMATION
13270
+ extern unsigned int sqlite3CoverageCounter;
13271
+# endif
13272
+# define testcase(X) if( X ){ sqlite3CoverageCounter += (unsigned)__LINE__; }
1317013273
#else
1317113274
# define testcase(X)
1317213275
#endif
1317313276
1317413277
/*
@@ -13194,10 +13297,18 @@
1319413297
# define VVA_ONLY(X) X
1319513298
#else
1319613299
# define VVA_ONLY(X)
1319713300
#endif
1319813301
13302
+/*
13303
+** Disable ALWAYS() and NEVER() (make them pass-throughs) for coverage
13304
+** and mutation testing
13305
+*/
13306
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
13307
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
13308
+#endif
13309
+
1319913310
/*
1320013311
** The ALWAYS and NEVER macros surround boolean expressions which
1320113312
** are intended to always be true or false, respectively. Such
1320213313
** expressions could be omitted from the code completely. But they
1320313314
** are included in a few cases in order to enhance the resilience
@@ -13209,11 +13320,11 @@
1320913320
**
1321013321
** When doing coverage testing ALWAYS and NEVER are hard-coded to
1321113322
** be true and false so that the unreachable code they specify will
1321213323
** not be counted as untested code.
1321313324
*/
13214
-#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
13325
+#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
1321513326
# define ALWAYS(X) (1)
1321613327
# define NEVER(X) (0)
1321713328
#elif !defined(NDEBUG)
1321813329
# define ALWAYS(X) ((X)?1:(assert(0),0))
1321913330
# define NEVER(X) ((X)?(assert(0),1):0)
@@ -13220,30 +13331,10 @@
1322013331
#else
1322113332
# define ALWAYS(X) (X)
1322213333
# define NEVER(X) (X)
1322313334
#endif
1322413335
13225
-/*
13226
-** The harmless(X) macro indicates that expression X is usually false
13227
-** but can be true without causing any problems, but we don't know of
13228
-** any way to cause X to be true.
13229
-**
13230
-** In debugging and testing builds, this macro will abort if X is ever
13231
-** true. In this way, developers are alerted to a possible test case
13232
-** that causes X to be true. If a harmless macro ever fails, that is
13233
-** an opportunity to change the macro into a testcase() and add a new
13234
-** test case to the test suite.
13235
-**
13236
-** For normal production builds, harmless(X) is a no-op, since it does
13237
-** not matter whether expression X is true or false.
13238
-*/
13239
-#ifdef SQLITE_DEBUG
13240
-# define harmless(X) assert(!(X));
13241
-#else
13242
-# define harmless(X)
13243
-#endif
13244
-
1324513336
/*
1324613337
** Some conditionals are optimizations only. In other words, if the
1324713338
** conditionals are replaced with a constant 1 (true) or 0 (false) then
1324813339
** the correct answer is still obtained, though perhaps not as quickly.
1324913340
**
@@ -13422,11 +13513,11 @@
1342213513
/* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
1342313514
1342413515
/*
1342513516
** Number of entries in a hash table
1342613517
*/
13427
-/* #define sqliteHashCount(H) ((H)->count) // NOT USED */
13518
+#define sqliteHashCount(H) ((H)->count)
1342813519
1342913520
#endif /* SQLITE_HASH_H */
1343013521
1343113522
/************** End of hash.h ************************************************/
1343213523
/************** Continuing where we left off in sqliteInt.h ******************/
@@ -13474,14 +13565,14 @@
1347413565
#define TK_DETACH 40
1347513566
#define TK_EACH 41
1347613567
#define TK_FAIL 42
1347713568
#define TK_OR 43
1347813569
#define TK_AND 44
13479
-#define TK_IS 45
13480
-#define TK_MATCH 46
13481
-#define TK_LIKE_KW 47
13482
-#define TK_BETWEEN 48
13570
+#define TK_MATCH 45
13571
+#define TK_LIKE_KW 46
13572
+#define TK_BETWEEN 47
13573
+#define TK_IS 48
1348313574
#define TK_IN 49
1348413575
#define TK_ISNULL 50
1348513576
#define TK_NOTNULL 51
1348613577
#define TK_NE 52
1348713578
#define TK_EQ 53
@@ -13718,11 +13809,11 @@
1371813809
** The default initial allocation for the pagecache when using separate
1371913810
** pagecaches for each database connection. A positive number is the
1372013811
** number of pages. A negative number N translations means that a buffer
1372113812
** of -1024*N bytes is allocated and used for as many pages as it will hold.
1372213813
**
13723
-** The default value of "20" was choosen to minimize the run-time of the
13814
+** The default value of "20" was chosen to minimize the run-time of the
1372413815
** speedtest1 test program with options: --shrink-memory --reprepare
1372513816
*/
1372613817
#ifndef SQLITE_DEFAULT_PCACHE_INITSZ
1372713818
# define SQLITE_DEFAULT_PCACHE_INITSZ 20
1372813819
#endif
@@ -14075,15 +14166,29 @@
1407514166
int nBusy; /* Incremented with each busy call */
1407614167
};
1407714168
1407814169
/*
1407914170
** Name of table that holds the database schema.
14171
+**
14172
+** The PREFERRED names are used whereever possible. But LEGACY is also
14173
+** used for backwards compatibility.
14174
+**
14175
+** 1. Queries can use either the PREFERRED or the LEGACY names
14176
+** 2. The sqlite3_set_authorizer() callback uses the LEGACY name
14177
+** 3. The PRAGMA table_list statement uses the PREFERRED name
14178
+**
14179
+** The LEGACY names are stored in the internal symbol hash table
14180
+** in support of (2). Names are translated using sqlite3PreferredTableName()
14181
+** for (3). The sqlite3FindTable() function takes care of translating
14182
+** names for (1).
14183
+**
14184
+** Note that "sqlite_temp_schema" can also be called "temp.sqlite_schema".
1408014185
*/
14081
-#define DFLT_SCHEMA_TABLE "sqlite_master"
14082
-#define DFLT_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14083
-#define ALT_SCHEMA_TABLE "sqlite_schema"
14084
-#define ALT_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
14186
+#define LEGACY_SCHEMA_TABLE "sqlite_master"
14187
+#define LEGACY_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14188
+#define PREFERRED_SCHEMA_TABLE "sqlite_schema"
14189
+#define PREFERRED_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
1408514190
1408614191
1408714192
/*
1408814193
** The root-page of the schema table.
1408914194
*/
@@ -14091,11 +14196,11 @@
1409114196
1409214197
/*
1409314198
** The name of the schema table. The name is different for TEMP.
1409414199
*/
1409514200
#define SCHEMA_TABLE(x) \
14096
- ((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE)
14201
+ ((!OMIT_TEMPDB)&&(x==1)?LEGACY_TEMP_SCHEMA_TABLE:LEGACY_SCHEMA_TABLE)
1409714202
1409814203
/*
1409914204
** A convenience macro that returns the number of elements in
1410014205
** an array.
1410114206
*/
@@ -15159,49 +15264,49 @@
1515915264
#define OP_ElseEq 58 /* jump, same as TK_ESCAPE */
1516015265
#define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
1516115266
#define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */
1516215267
#define OP_IncrVacuum 61 /* jump */
1516315268
#define OP_VNext 62 /* jump */
15164
-#define OP_Init 63 /* jump, synopsis: Start at P2 */
15165
-#define OP_PureFunc 64 /* synopsis: r[P3]=func(r[P2@NP]) */
15166
-#define OP_Function 65 /* synopsis: r[P3]=func(r[P2@NP]) */
15167
-#define OP_Return 66
15168
-#define OP_EndCoroutine 67
15169
-#define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */
15170
-#define OP_Halt 69
15171
-#define OP_Integer 70 /* synopsis: r[P2]=P1 */
15172
-#define OP_Int64 71 /* synopsis: r[P2]=P4 */
15173
-#define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */
15174
-#define OP_Null 73 /* synopsis: r[P2..P3]=NULL */
15175
-#define OP_SoftNull 74 /* synopsis: r[P1]=NULL */
15176
-#define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */
15177
-#define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */
15178
-#define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */
15179
-#define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15180
-#define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */
15181
-#define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */
15182
-#define OP_ChngCntRow 81 /* synopsis: output=r[P1] */
15183
-#define OP_ResultRow 82 /* synopsis: output=r[P1@P2] */
15184
-#define OP_CollSeq 83
15185
-#define OP_AddImm 84 /* synopsis: r[P1]=r[P1]+P2 */
15186
-#define OP_RealAffinity 85
15187
-#define OP_Cast 86 /* synopsis: affinity(r[P1]) */
15188
-#define OP_Permutation 87
15189
-#define OP_Compare 88 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15190
-#define OP_IsTrue 89 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15191
-#define OP_ZeroOrNull 90 /* synopsis: r[P2] = 0 OR NULL */
15192
-#define OP_Offset 91 /* synopsis: r[P3] = sqlite_offset(P1) */
15193
-#define OP_Column 92 /* synopsis: r[P3]=PX */
15194
-#define OP_TypeCheck 93 /* synopsis: typecheck(r[P1@P2]) */
15195
-#define OP_Affinity 94 /* synopsis: affinity(r[P1@P2]) */
15196
-#define OP_MakeRecord 95 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15197
-#define OP_Count 96 /* synopsis: r[P2]=count() */
15198
-#define OP_ReadCookie 97
15199
-#define OP_SetCookie 98
15200
-#define OP_ReopenIdx 99 /* synopsis: root=P2 iDb=P3 */
15201
-#define OP_OpenRead 100 /* synopsis: root=P2 iDb=P3 */
15202
-#define OP_OpenWrite 101 /* synopsis: root=P2 iDb=P3 */
15269
+#define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */
15270
+#define OP_Init 64 /* jump, synopsis: Start at P2 */
15271
+#define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */
15272
+#define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15273
+#define OP_Return 67
15274
+#define OP_EndCoroutine 68
15275
+#define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15276
+#define OP_Halt 70
15277
+#define OP_Integer 71 /* synopsis: r[P2]=P1 */
15278
+#define OP_Int64 72 /* synopsis: r[P2]=P4 */
15279
+#define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15280
+#define OP_Null 74 /* synopsis: r[P2..P3]=NULL */
15281
+#define OP_SoftNull 75 /* synopsis: r[P1]=NULL */
15282
+#define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */
15283
+#define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */
15284
+#define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */
15285
+#define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15286
+#define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */
15287
+#define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */
15288
+#define OP_FkCheck 82
15289
+#define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */
15290
+#define OP_CollSeq 84
15291
+#define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */
15292
+#define OP_RealAffinity 86
15293
+#define OP_Cast 87 /* synopsis: affinity(r[P1]) */
15294
+#define OP_Permutation 88
15295
+#define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15296
+#define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15297
+#define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */
15298
+#define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */
15299
+#define OP_Column 93 /* synopsis: r[P3]=PX */
15300
+#define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */
15301
+#define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */
15302
+#define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15303
+#define OP_Count 97 /* synopsis: r[P2]=count() */
15304
+#define OP_ReadCookie 98
15305
+#define OP_SetCookie 99
15306
+#define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */
15307
+#define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */
1520315308
#define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
1520415309
#define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
1520515310
#define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
1520615311
#define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
1520715312
#define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15208,80 +15313,82 @@
1520815313
#define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
1520915314
#define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
1521015315
#define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
1521115316
#define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
1521215317
#define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15213
-#define OP_OpenDup 112
15318
+#define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */
1521415319
#define OP_BitNot 113 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15215
-#define OP_OpenAutoindex 114 /* synopsis: nColumn=P2 */
15216
-#define OP_OpenEphemeral 115 /* synopsis: nColumn=P2 */
15320
+#define OP_OpenDup 114
15321
+#define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */
1521715322
#define OP_String8 116 /* same as TK_STRING, synopsis: r[P2]='P4' */
15218
-#define OP_SorterOpen 117
15219
-#define OP_SequenceTest 118 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15220
-#define OP_OpenPseudo 119 /* synopsis: P3 columns in r[P2] */
15221
-#define OP_Close 120
15222
-#define OP_ColumnsUsed 121
15223
-#define OP_SeekScan 122 /* synopsis: Scan-ahead up to P1 rows */
15224
-#define OP_SeekHit 123 /* synopsis: set P2<=seekHit<=P3 */
15225
-#define OP_Sequence 124 /* synopsis: r[P2]=cursor[P1].ctr++ */
15226
-#define OP_NewRowid 125 /* synopsis: r[P2]=rowid */
15227
-#define OP_Insert 126 /* synopsis: intkey=r[P3] data=r[P2] */
15228
-#define OP_RowCell 127
15229
-#define OP_Delete 128
15230
-#define OP_ResetCount 129
15231
-#define OP_SorterCompare 130 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15232
-#define OP_SorterData 131 /* synopsis: r[P2]=data */
15233
-#define OP_RowData 132 /* synopsis: r[P2]=data */
15234
-#define OP_Rowid 133 /* synopsis: r[P2]=rowid */
15235
-#define OP_NullRow 134
15236
-#define OP_SeekEnd 135
15237
-#define OP_IdxInsert 136 /* synopsis: key=r[P2] */
15238
-#define OP_SorterInsert 137 /* synopsis: key=r[P2] */
15239
-#define OP_IdxDelete 138 /* synopsis: key=r[P2@P3] */
15240
-#define OP_DeferredSeek 139 /* synopsis: Move P3 to P1.rowid if needed */
15241
-#define OP_IdxRowid 140 /* synopsis: r[P2]=rowid */
15242
-#define OP_FinishSeek 141
15243
-#define OP_Destroy 142
15244
-#define OP_Clear 143
15245
-#define OP_ResetSorter 144
15246
-#define OP_CreateBtree 145 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15247
-#define OP_SqlExec 146
15248
-#define OP_ParseSchema 147
15249
-#define OP_LoadAnalysis 148
15250
-#define OP_DropTable 149
15251
-#define OP_DropIndex 150
15252
-#define OP_DropTrigger 151
15323
+#define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */
15324
+#define OP_SorterOpen 118
15325
+#define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15326
+#define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */
15327
+#define OP_Close 121
15328
+#define OP_ColumnsUsed 122
15329
+#define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */
15330
+#define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */
15331
+#define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */
15332
+#define OP_NewRowid 126 /* synopsis: r[P2]=rowid */
15333
+#define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */
15334
+#define OP_RowCell 128
15335
+#define OP_Delete 129
15336
+#define OP_ResetCount 130
15337
+#define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15338
+#define OP_SorterData 132 /* synopsis: r[P2]=data */
15339
+#define OP_RowData 133 /* synopsis: r[P2]=data */
15340
+#define OP_Rowid 134 /* synopsis: r[P2]=rowid */
15341
+#define OP_NullRow 135
15342
+#define OP_SeekEnd 136
15343
+#define OP_IdxInsert 137 /* synopsis: key=r[P2] */
15344
+#define OP_SorterInsert 138 /* synopsis: key=r[P2] */
15345
+#define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */
15346
+#define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */
15347
+#define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */
15348
+#define OP_FinishSeek 142
15349
+#define OP_Destroy 143
15350
+#define OP_Clear 144
15351
+#define OP_ResetSorter 145
15352
+#define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15353
+#define OP_SqlExec 147
15354
+#define OP_ParseSchema 148
15355
+#define OP_LoadAnalysis 149
15356
+#define OP_DropTable 150
15357
+#define OP_DropIndex 151
1525315358
#define OP_Real 152 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15254
-#define OP_IntegrityCk 153
15255
-#define OP_RowSetAdd 154 /* synopsis: rowset(P1)=r[P2] */
15256
-#define OP_Param 155
15257
-#define OP_FkCounter 156 /* synopsis: fkctr[P1]+=P2 */
15258
-#define OP_MemMax 157 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15259
-#define OP_OffsetLimit 158 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15260
-#define OP_AggInverse 159 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15261
-#define OP_AggStep 160 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15262
-#define OP_AggStep1 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15263
-#define OP_AggValue 162 /* synopsis: r[P3]=value N=P2 */
15264
-#define OP_AggFinal 163 /* synopsis: accum=r[P1] N=P2 */
15265
-#define OP_Expire 164
15266
-#define OP_CursorLock 165
15267
-#define OP_CursorUnlock 166
15268
-#define OP_TableLock 167 /* synopsis: iDb=P1 root=P2 write=P3 */
15269
-#define OP_VBegin 168
15270
-#define OP_VCreate 169
15271
-#define OP_VDestroy 170
15272
-#define OP_VOpen 171
15273
-#define OP_VColumn 172 /* synopsis: r[P3]=vcolumn(P2) */
15274
-#define OP_VRename 173
15275
-#define OP_Pagecount 174
15276
-#define OP_MaxPgcnt 175
15277
-#define OP_Trace 176
15278
-#define OP_CursorHint 177
15279
-#define OP_ReleaseReg 178 /* synopsis: release r[P1@P2] mask P3 */
15280
-#define OP_Noop 179
15281
-#define OP_Explain 180
15282
-#define OP_Abortable 181
15359
+#define OP_DropTrigger 153
15360
+#define OP_IntegrityCk 154
15361
+#define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */
15362
+#define OP_Param 156
15363
+#define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */
15364
+#define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15365
+#define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15366
+#define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15367
+#define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15368
+#define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15369
+#define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */
15370
+#define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */
15371
+#define OP_Expire 165
15372
+#define OP_CursorLock 166
15373
+#define OP_CursorUnlock 167
15374
+#define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */
15375
+#define OP_VBegin 169
15376
+#define OP_VCreate 170
15377
+#define OP_VDestroy 171
15378
+#define OP_VOpen 172
15379
+#define OP_VColumn 173 /* synopsis: r[P3]=vcolumn(P2) */
15380
+#define OP_VRename 174
15381
+#define OP_Pagecount 175
15382
+#define OP_MaxPgcnt 176
15383
+#define OP_FilterAdd 177 /* synopsis: filter(P1) += key(P3@P4) */
15384
+#define OP_Trace 178
15385
+#define OP_CursorHint 179
15386
+#define OP_ReleaseReg 180 /* synopsis: release r[P1@P2] mask P3 */
15387
+#define OP_Noop 181
15388
+#define OP_Explain 182
15389
+#define OP_Abortable 183
1528315390
1528415391
/* Properties such as "out2" or "jump" that are specified in
1528515392
** comments following the "case" for each opcode in the vdbe.c
1528615393
** are encoded into bitvectors as follows:
1528715394
*/
@@ -15298,33 +15405,34 @@
1529815405
/* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
1529915406
/* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
1530015407
/* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
1530115408
/* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
1530215409
/* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15303
-/* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
15304
-/* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
15305
-/* 80 */ 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\
15306
-/* 88 */ 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00,\
15307
-/* 96 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26,\
15410
+/* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15411
+/* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
15412
+/* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
15413
+/* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
15414
+/* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
1530815415
/* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
1530915416
/* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\
15310
-/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
15311
-/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\
15312
-/* 136 */ 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,\
15313
-/* 144 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15314
-/* 152 */ 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00,\
15417
+/* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
15418
+/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15419
+/* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
15420
+/* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15421
+/* 152 */ 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
1531515422
/* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15316
-/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
15317
-/* 176 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
15423
+/* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15424
+/* 176 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15425
+}
1531815426
1531915427
/* The resolve3P2Values() routine is able to run faster if it knows
1532015428
** the value of the largest JUMP opcode. The smaller the maximum
1532115429
** JUMP opcode the better, so the mkopcodeh.tcl script that
1532215430
** generated this include file strives to group all JUMP opcodes
1532315431
** together near the beginning of the list.
1532415432
*/
15325
-#define SQLITE_MX_JUMP_OPCODE 63 /* Maximum JUMP opcode */
15433
+#define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */
1532615434
1532715435
/************** End of opcodes.h *********************************************/
1532815436
/************** Continuing where we left off in vdbe.h ***********************/
1532915437
1533015438
/*
@@ -16420,14 +16528,14 @@
1642016528
int nVdbeExec; /* Number of nested calls to VdbeExec() */
1642116529
int nVDestroy; /* Number of active OP_VDestroy operations */
1642216530
int nExtension; /* Number of loaded extensions */
1642316531
void **aExtension; /* Array of shared library handles */
1642416532
union {
16425
- void (*xLegacy)(void*,const char*); /* Legacy trace function */
16426
- int (*xV2)(u32,void*,void*,void*); /* V2 Trace function */
16533
+ void (*xLegacy)(void*,const char*); /* mTrace==SQLITE_TRACE_LEGACY */
16534
+ int (*xV2)(u32,void*,void*,void*); /* All other mTrace values */
1642716535
} trace;
16428
- void *pTraceArg; /* Argument to the trace function */
16536
+ void *pTraceArg; /* Argument to the trace function */
1642916537
#ifndef SQLITE_OMIT_DEPRECATED
1643016538
void (*xProfile)(void*,const char*,u64); /* Profiling function */
1643116539
void *pProfileArg; /* Argument to profile function */
1643216540
#endif
1643316541
void *pCommitArg; /* Argument to xCommitCallback() */
@@ -16434,10 +16542,13 @@
1643416542
int (*xCommitCallback)(void*); /* Invoked at every commit. */
1643516543
void *pRollbackArg; /* Argument to xRollbackCallback() */
1643616544
void (*xRollbackCallback)(void*); /* Invoked at every commit. */
1643716545
void *pUpdateArg;
1643816546
void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
16547
+ void *pAutovacPagesArg; /* Client argument to autovac_pages */
16548
+ void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
16549
+ unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
1643916550
Parse *pParse; /* Current parse */
1644016551
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
1644116552
void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
1644216553
void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
1644316554
void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
@@ -16563,10 +16674,11 @@
1656316674
#define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
1656416675
#define SQLITE_EnableView 0x80000000 /* Enable the use of views */
1656516676
#define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
1656616677
/* DELETE, or UPDATE and return */
1656716678
/* the count using a callback. */
16679
+#define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
1656816680
1656916681
/* Flags used only if debugging */
1657016682
#ifdef SQLITE_DEBUG
1657116683
#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
1657216684
#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -16611,10 +16723,12 @@
1661116723
#define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
1661216724
#define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
1661316725
#define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */
1661416726
#define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
1661516727
/* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
16728
+#define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */
16729
+#define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */
1661616730
#define SQLITE_AllOpts 0xffffffff /* All optimizations */
1661716731
1661816732
/*
1661916733
** Macros for testing whether or not optimizations are enabled or disabled.
1662016734
*/
@@ -16659,11 +16773,11 @@
1665916773
void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
1666016774
const char *zName; /* SQL name of the function. */
1666116775
union {
1666216776
FuncDef *pHash; /* Next with a different name but the same hash */
1666316777
FuncDestructor *pDestructor; /* Reference counted destructor function */
16664
- } u;
16778
+ } u; /* pHash if SQLITE_FUNC_BUILTIN, pDestructor otherwise */
1666516779
};
1666616780
1666716781
/*
1666816782
** This structure encapsulates a user-function destructor callback (as
1666916783
** configured using create_function_v2()) and a reference counter. When
@@ -16720,10 +16834,11 @@
1672016834
#define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
1672116835
#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
1672216836
#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
1672316837
#define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
1672416838
#define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */
16839
+#define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */
1672516840
#define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */
1672616841
1672716842
/* Identifier numbers for each in-line function */
1672816843
#define INLINEFUNC_coalesce 0
1672916844
#define INLINEFUNC_implies_nonnull_row 1
@@ -16798,48 +16913,55 @@
1679816913
** available as the function user-data (sqlite3_user_data()). The
1679916914
** FuncDef.flags variable is set to the value passed as the flags
1680016915
** parameter.
1680116916
*/
1680216917
#define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
16803
- {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16918
+ {nArg, SQLITE_FUNC_BUILTIN|\
16919
+ SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
1680416920
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
1680516921
#define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16806
- {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16922
+ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
1680716923
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
1680816924
#define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16809
- {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
16925
+ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
1681016926
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
1681116927
#define MFUNCTION(zName, nArg, xPtr, xFunc) \
16812
- {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
16928
+ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
1681316929
xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
1681416930
#define INLINE_FUNC(zName, nArg, iArg, mFlags) \
16815
- {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
16931
+ {nArg, SQLITE_FUNC_BUILTIN|\
16932
+ SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
1681616933
SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
1681716934
#define TEST_FUNC(zName, nArg, iArg, mFlags) \
16818
- {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
16935
+ {nArg, SQLITE_FUNC_BUILTIN|\
16936
+ SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
1681916937
SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
1682016938
SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
1682116939
#define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16822
- {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
16940
+ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
1682316941
0, 0, xFunc, 0, 0, 0, #zName, {0} }
1682416942
#define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
16825
- {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
16943
+ {nArg, SQLITE_FUNC_BUILTIN|\
16944
+ SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
1682616945
(void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
1682716946
#define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
16828
- {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
16947
+ {nArg, SQLITE_FUNC_BUILTIN|\
16948
+ SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
1682916949
SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
1683016950
#define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
16831
- {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16951
+ {nArg, SQLITE_FUNC_BUILTIN|\
16952
+ SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
1683216953
pArg, 0, xFunc, 0, 0, 0, #zName, }
1683316954
#define LIKEFUNC(zName, nArg, arg, flags) \
16834
- {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
16955
+ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
1683516956
(void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
1683616957
#define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
16837
- {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
16958
+ {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
1683816959
SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
1683916960
#define INTERNAL_FUNCTION(zName, nArg, xFunc) \
16840
- {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
16961
+ {nArg, SQLITE_FUNC_BUILTIN|\
16962
+ SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
1684116963
0, 0, xFunc, 0, 0, 0, #zName, {0} }
1684216964
1684316965
1684416966
/*
1684516967
** All current savepoints are stored in a linked list starting at
@@ -17558,14 +17680,14 @@
1755817680
** code representing the ">=" operator. This same integer code is reused
1755917681
** to represent the greater-than-or-equal-to operator in the expression
1756017682
** tree.
1756117683
**
1756217684
** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
17563
-** or TK_STRING), then Expr.token contains the text of the SQL literal. If
17564
-** the expression is a variable (TK_VARIABLE), then Expr.token contains the
17685
+** or TK_STRING), then Expr.u.zToken contains the text of the SQL literal. If
17686
+** the expression is a variable (TK_VARIABLE), then Expr.u.zToken contains the
1756517687
** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
17566
-** then Expr.token contains the name of the function.
17688
+** then Expr.u.zToken contains the name of the function.
1756717689
**
1756817690
** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
1756917691
** binary operator. Either or both may be NULL.
1757017692
**
1757117693
** Expr.x.pList is a list of arguments if the expression is an SQL function,
@@ -17601,11 +17723,11 @@
1760117723
**
1760217724
** Expr objects can use a lot of memory space in database schema. To
1760317725
** help reduce memory requirements, sometimes an Expr object will be
1760417726
** truncated. And to reduce the number of memory allocations, sometimes
1760517727
** two or more Expr objects will be stored in a single memory allocation,
17606
-** together with Expr.zToken strings.
17728
+** together with Expr.u.zToken strings.
1760717729
**
1760817730
** If the EP_Reduced and EP_TokenOnly flags are set when
1760917731
** an Expr object is truncated. When EP_Reduced is set, then all
1761017732
** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
1761117733
** are contained within the same memory allocation. Note, however, that
@@ -17670,12 +17792,11 @@
1767017792
int regReturn; /* Register used to hold return address */
1767117793
} sub;
1767217794
} y;
1767317795
};
1767417796
17675
-/*
17676
-** The following are the meanings of bits in the Expr.flags field.
17797
+/* The following are the meanings of bits in the Expr.flags field.
1767717798
** Value restrictions:
1767817799
**
1767917800
** EP_Agg == NC_HasAgg == SF_HasAgg
1768017801
** EP_Win == NC_HasWin
1768117802
*/
@@ -17710,27 +17831,35 @@
1771017831
#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
1771117832
#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
1771217833
#define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
1771317834
/* 0x80000000 // Available */
1771417835
17715
-/*
17716
-** The EP_Propagate mask is a set of properties that automatically propagate
17836
+/* The EP_Propagate mask is a set of properties that automatically propagate
1771717837
** upwards into parent nodes.
1771817838
*/
1771917839
#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
1772017840
17721
-/*
17722
-** These macros can be used to test, set, or clear bits in the
17841
+/* Macros can be used to test, set, or clear bits in the
1772317842
** Expr.flags field.
1772417843
*/
1772517844
#define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
1772617845
#define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
1772717846
#define ExprSetProperty(E,P) (E)->flags|=(P)
1772817847
#define ExprClearProperty(E,P) (E)->flags&=~(P)
1772917848
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
1773017849
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
1773117850
17851
+/* Macros used to ensure that the correct members of unions are accessed
17852
+** in Expr.
17853
+*/
17854
+#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
17855
+#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0)
17856
+#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0)
17857
+#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0)
17858
+#define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0)
17859
+#define ExprUseYWin(E) (((E)->flags&EP_WinFunc)!=0)
17860
+#define ExprUseYSub(E) (((E)->flags&EP_Subrtn)!=0)
1773217861
1773317862
/* Flags for use with Expr.vvaFlags
1773417863
*/
1773517864
#define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */
1773617865
#define EP_Immutable 0x02 /* Do not change this Expr node */
@@ -17809,15 +17938,16 @@
1780917938
unsigned done :1; /* A flag to indicate when processing is finished */
1781017939
unsigned reusable :1; /* Constant expression is reusable */
1781117940
unsigned bSorterRef :1; /* Defer evaluation until after sorting */
1781217941
unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
1781317942
union {
17814
- struct {
17943
+ struct { /* Used by any ExprList other than Parse.pConsExpr */
1781517944
u16 iOrderByCol; /* For ORDER BY, column number in result set */
1781617945
u16 iAlias; /* Index into Parse.aAlias[] for zName */
1781717946
} x;
17818
- int iConstExprReg; /* Register in which Expr value is cached */
17947
+ int iConstExprReg; /* Register in which Expr value is cached. Used only
17948
+ ** by Parse.pConstExpr */
1781917949
} u;
1782017950
} a[1]; /* One slot for each expression in the list */
1782117951
};
1782217952
1782317953
/*
@@ -17851,10 +17981,17 @@
1785117981
};
1785217982
1785317983
/*
1785417984
** The SrcItem object represents a single term in the FROM clause of a query.
1785517985
** The SrcList object is mostly an array of SrcItems.
17986
+**
17987
+** Union member validity:
17988
+**
17989
+** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
17990
+** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
17991
+** u2.pIBIndex fg.isIndexedBy && !fg.isCte
17992
+** u2.pCteUse fg.isCte && !fg.isIndexedBy
1785617993
*/
1785717994
struct SrcItem {
1785817995
Schema *pSchema; /* Schema to which this item is fixed */
1785917996
char *zDatabase; /* Name of database holding this table */
1786017997
char *zName; /* Name of the table */
@@ -18382,11 +18519,10 @@
1838218519
TableLock *aTableLock; /* Required table locks for shared-cache mode */
1838318520
#endif
1838418521
AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
1838518522
Parse *pToplevel; /* Parse structure for main program (or NULL) */
1838618523
Table *pTriggerTab; /* Table triggers are being coded for */
18387
- Parse *pParentParse; /* Parent parser if this parser is nested */
1838818524
union {
1838918525
int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
1839018526
Returning *pReturning; /* The RETURNING clause */
1839118527
} u1;
1839218528
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
@@ -18445,10 +18581,12 @@
1844518581
#ifndef SQLITE_OMIT_ALTERTABLE
1844618582
RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */
1844718583
#endif
1844818584
};
1844918585
18586
+/* Allowed values for Parse.eParseMode
18587
+*/
1845018588
#define PARSE_MODE_NORMAL 0
1845118589
#define PARSE_MODE_DECLARE_VTAB 1
1845218590
#define PARSE_MODE_RENAME 2
1845318591
#define PARSE_MODE_UNMAP 3
1845418592
@@ -18666,12 +18804,14 @@
1866618804
} InitData;
1866718805
1866818806
/*
1866918807
** Allowed values for mInitFlags
1867018808
*/
18809
+#define INITFLAG_AlterMask 0x0003 /* Types of ALTER */
1867118810
#define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
1867218811
#define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
18812
+#define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */
1867318813
1867418814
/* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
1867518815
** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
1867618816
** parameters are for temporary use during development, to help find
1867718817
** optimial values for parameters in the query planner. The should not
@@ -18788,12 +18928,12 @@
1878818928
union { /* Extra data for callback */
1878918929
NameContext *pNC; /* Naming context */
1879018930
int n; /* A counter */
1879118931
int iCur; /* A cursor number */
1879218932
SrcList *pSrcList; /* FROM clause */
18793
- struct SrcCount *pSrcCount; /* Counting column references */
1879418933
struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
18934
+ struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */
1879518935
int *aiCol; /* array of column indexes */
1879618936
struct IdxCover *pIdxCover; /* Check for index coverage */
1879718937
struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
1879818938
ExprList *pGroupBy; /* GROUP BY clause */
1879918939
Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19387,10 +19527,11 @@
1938719527
SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
1938819528
SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
1938919529
#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
1939019530
SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
1939119531
#endif
19532
+SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
1939219533
SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
1939319534
SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
1939419535
Upsert*);
1939519536
SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
1939619537
SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
@@ -19430,10 +19571,11 @@
1943019571
SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
1943119572
SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
1943219573
#define LOCATE_VIEW 0x01
1943319574
#define LOCATE_NOERR 0x02
1943419575
SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
19576
+SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*);
1943519577
SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
1943619578
SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
1943719579
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
1943819580
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
1943919581
SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
@@ -19446,11 +19588,11 @@
1944619588
SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
1944719589
SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
1944819590
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
1944919591
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
1945019592
SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19451
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
19593
+SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*);
1945219594
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
1945319595
#ifndef SQLITE_UNTESTABLE
1945419596
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
1945519597
SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
1945619598
#endif
@@ -19596,18 +19738,12 @@
1959619738
#endif
1959719739
SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
1959819740
SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
1959919741
SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
1960019742
SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
19601
-#ifndef SQLITE_OMIT_VIRTUALTABLE
1960219743
SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
19603
-#endif
19604
-#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
19605
- defined(SQLITE_ENABLE_STAT4) || \
19606
- defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
1960719744
SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
19608
-#endif
1960919745
SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
1961019746
SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
1961119747
SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
1961219748
1961319749
/*
@@ -19888,13 +20024,15 @@
1988820024
#endif
1988920025
SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
1989020026
#ifndef SQLITE_OMIT_VIRTUALTABLE
1989120027
SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
1989220028
SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
20029
+SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*);
1989320030
#else
1989420031
# define sqlite3ShadowTableName(A,B) 0
1989520032
# define sqlite3IsShadowTableOf(A,B,C) 0
20033
+# define sqlite3MarkAllShadowTablesOf(A,B)
1989620034
#endif
1989720035
SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
1989820036
SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
1989920037
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
1990020038
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -19933,11 +20071,11 @@
1993320071
#else
1993420072
# define sqlite3CteNew(P,T,E,S) ((void*)0)
1993520073
# define sqlite3CteDelete(D,C)
1993620074
# define sqlite3CteWithAdd(P,W,C) ((void*)0)
1993720075
# define sqlite3WithDelete(x,y)
19938
-# define sqlite3WithPush(x,y,z)
20076
+# define sqlite3WithPush(x,y,z) ((void*)0)
1993920077
#endif
1994020078
#ifndef SQLITE_OMIT_UPSERT
1994120079
SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
1994220080
SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
1994320081
SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
@@ -20101,12 +20239,12 @@
2010120239
** All of this is no-op for a production build. It only comes into
2010220240
** play when the SQLITE_MEMDEBUG compile-time option is used.
2010320241
*/
2010420242
#ifdef SQLITE_MEMDEBUG
2010520243
SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8);
20106
-SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8);
20107
-SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8);
20244
+SQLITE_PRIVATE int sqlite3MemdebugHasType(const void*,u8);
20245
+SQLITE_PRIVATE int sqlite3MemdebugNoType(const void*,u8);
2010820246
#else
2010920247
# define sqlite3MemdebugSetType(X,Y) /* no-op */
2011020248
# define sqlite3MemdebugHasType(X,Y) 1
2011120249
# define sqlite3MemdebugNoType(X,Y) 1
2011220250
#endif
@@ -21425,10 +21563,22 @@
2142521563
** database connections. After initialization, this table is
2142621564
** read-only.
2142721565
*/
2142821566
SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
2142921567
21568
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
21569
+/*
21570
+** Counter used for coverage testing. Does not come into play for
21571
+** release builds.
21572
+**
21573
+** Access to this global variable is not mutex protected. This might
21574
+** result in TSAN warnings. But as the variable does not exist in
21575
+** release builds, that should not be a concern.
21576
+*/
21577
+SQLITE_PRIVATE unsigned int sqlite3CoverageCounter;
21578
+#endif /* SQLITE_COVERAGE_TEST || SQLITE_DEBUG */
21579
+
2143021580
#ifdef VDBE_PROFILE
2143121581
/*
2143221582
** The following performance counter can be used in place of
2143321583
** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
2143421584
*/
@@ -21969,11 +22119,11 @@
2196922119
bft usesStmtJournal:1; /* True if uses a statement journal */
2197022120
bft readOnly:1; /* True for statements that do not write */
2197122121
bft bIsReader:1; /* True for statements that read */
2197222122
yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
2197322123
yDbMask lockMask; /* Subset of btreeMask that requires a lock */
21974
- u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
22124
+ u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
2197522125
char *zSql; /* Text of the SQL statement that generated this */
2197622126
#ifdef SQLITE_ENABLE_NORMALIZE
2197722127
char *zNormSql; /* Normalization of the associated SQL statement */
2197822128
DblquoteStr *pDblStr; /* List of double-quoted string literals */
2197922129
#endif
@@ -22065,19 +22215,23 @@
2206522215
SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
2206622216
#endif
2206722217
SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
2206822218
SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
2206922219
SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
22220
+#ifndef SQLITE_OMIT_INCRBLOB
2207022221
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
22222
+#else
22223
+SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int);
22224
+#endif
2207122225
#ifdef SQLITE_DEBUG
2207222226
SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
2207322227
#endif
2207422228
SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
2207522229
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
2207622230
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
2207722231
SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
22078
-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
22232
+SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*);
2207922233
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
2208022234
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
2208122235
SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
2208222236
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
2208322237
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
@@ -23071,11 +23225,13 @@
2307123225
pX = localtime(t);
2307223226
#ifndef SQLITE_UNTESTABLE
2307323227
if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
2307423228
#endif
2307523229
if( pX ) *pTm = *pX;
23230
+#if SQLITE_THREADSAFE>0
2307623231
sqlite3_mutex_leave(mutex);
23232
+#endif
2307723233
rc = pX==0;
2307823234
#else
2307923235
#ifndef SQLITE_UNTESTABLE
2308023236
if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
2308123237
#endif
@@ -23210,10 +23366,49 @@
2321023366
DateTime *p /* The date/time value to be modified */
2321123367
){
2321223368
int rc = 1;
2321323369
double r;
2321423370
switch(sqlite3UpperToLower[(u8)z[0]] ){
23371
+ case 'a': {
23372
+ /*
23373
+ ** auto
23374
+ **
23375
+ ** If rawS is available, then interpret as a julian day number, or
23376
+ ** a unix timestamp, depending on its magnitude.
23377
+ */
23378
+ if( sqlite3_stricmp(z, "auto")==0 ){
23379
+ if( !p->rawS || p->validJD ){
23380
+ rc = 0;
23381
+ p->rawS = 0;
23382
+ }else if( p->s>=-210866760000 && p->s<=253402300799 ){
23383
+ r = p->s*1000.0 + 210866760000000.0;
23384
+ clearYMD_HMS_TZ(p);
23385
+ p->iJD = (sqlite3_int64)(r + 0.5);
23386
+ p->validJD = 1;
23387
+ p->rawS = 0;
23388
+ rc = 0;
23389
+ }
23390
+ }
23391
+ break;
23392
+ }
23393
+ case 'j': {
23394
+ /*
23395
+ ** julianday
23396
+ **
23397
+ ** Always interpret the prior number as a julian-day value. If this
23398
+ ** is not the first modifier, or if the prior argument is not a numeric
23399
+ ** value in the allowed range of julian day numbers understood by
23400
+ ** SQLite (0..5373484.5) then the result will be NULL.
23401
+ */
23402
+ if( sqlite3_stricmp(z, "julianday")==0 ){
23403
+ if( p->validJD && p->rawS ){
23404
+ rc = 0;
23405
+ p->rawS = 0;
23406
+ }
23407
+ }
23408
+ break;
23409
+ }
2321523410
#ifndef SQLITE_OMIT_LOCALTIME
2321623411
case 'l': {
2321723412
/* localtime
2321823413
**
2321923414
** Assuming the current time value is UTC (a.k.a. GMT), shift it to
@@ -23473,10 +23668,28 @@
2347323668
if( isDate(context, argc, argv, &x)==0 ){
2347423669
computeJD(&x);
2347523670
sqlite3_result_double(context, x.iJD/86400000.0);
2347623671
}
2347723672
}
23673
+
23674
+/*
23675
+** unixepoch( TIMESTRING, MOD, MOD, ...)
23676
+**
23677
+** Return the number of seconds (including fractional seconds) since
23678
+** the unix epoch of 1970-01-01 00:00:00 GMT.
23679
+*/
23680
+static void unixepochFunc(
23681
+ sqlite3_context *context,
23682
+ int argc,
23683
+ sqlite3_value **argv
23684
+){
23685
+ DateTime x;
23686
+ if( isDate(context, argc, argv, &x)==0 ){
23687
+ computeJD(&x);
23688
+ sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
23689
+ }
23690
+}
2347823691
2347923692
/*
2348023693
** datetime( TIMESTRING, MOD, MOD, ...)
2348123694
**
2348223695
** Return YYYY-MM-DD HH:MM:SS
@@ -23573,11 +23786,11 @@
2357323786
2357423787
computeJD(&x);
2357523788
computeYMD_HMS(&x);
2357623789
for(i=j=0; zFmt[i]; i++){
2357723790
if( zFmt[i]!='%' ) continue;
23578
- if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j);
23791
+ if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j));
2357923792
i++;
2358023793
j = i + 1;
2358123794
switch( zFmt[i] ){
2358223795
case 'd': {
2358323796
sqlite3_str_appendf(&sRes, "%02d", x.D);
@@ -23649,11 +23862,11 @@
2364923862
sqlite3_str_reset(&sRes);
2365023863
return;
2365123864
}
2365223865
}
2365323866
}
23654
- if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j);
23867
+ if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j));
2365523868
sqlite3ResultStrAccum(context, &sRes);
2365623869
}
2365723870
2365823871
/*
2365923872
** current_time()
@@ -23750,10 +23963,11 @@
2375023963
*/
2375123964
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
2375223965
static FuncDef aDateTimeFuncs[] = {
2375323966
#ifndef SQLITE_OMIT_DATETIME_FUNCS
2375423967
PURE_DATE(julianday, -1, 0, 0, juliandayFunc ),
23968
+ PURE_DATE(unixepoch, -1, 0, 0, unixepochFunc ),
2375523969
PURE_DATE(date, -1, 0, 0, dateFunc ),
2375623970
PURE_DATE(time, -1, 0, 0, timeFunc ),
2375723971
PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
2375823972
PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
2375923973
DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
@@ -24086,16 +24300,19 @@
2408624300
pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
2408724301
if( pFile ){
2408824302
rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
2408924303
if( rc!=SQLITE_OK ){
2409024304
sqlite3_free(pFile);
24305
+ *ppFile = 0;
2409124306
}else{
2409224307
*ppFile = pFile;
2409324308
}
2409424309
}else{
24310
+ *ppFile = 0;
2409524311
rc = SQLITE_NOMEM_BKPT;
2409624312
}
24313
+ assert( *ppFile!=0 || rc!=SQLITE_OK );
2409724314
return rc;
2409824315
}
2409924316
SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
2410024317
assert( pFile );
2410124318
sqlite3OsClose(pFile);
@@ -24809,11 +25026,11 @@
2480925026
** Given an allocation, find the MemBlockHdr for that allocation.
2481025027
**
2481125028
** This routine checks the guards at either end of the allocation and
2481225029
** if they are incorrect it asserts.
2481325030
*/
24814
-static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
25031
+static struct MemBlockHdr *sqlite3MemsysGetHeader(const void *pAllocation){
2481525032
struct MemBlockHdr *p;
2481625033
int *pInt;
2481725034
u8 *pU8;
2481825035
int nReserve;
2481925036
@@ -25056,11 +25273,11 @@
2505625273
** This routine is designed for use within an assert() statement, to
2505725274
** verify the type of an allocation. For example:
2505825275
**
2505925276
** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
2506025277
*/
25061
-SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
25278
+SQLITE_PRIVATE int sqlite3MemdebugHasType(const void *p, u8 eType){
2506225279
int rc = 1;
2506325280
if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
2506425281
struct MemBlockHdr *pHdr;
2506525282
pHdr = sqlite3MemsysGetHeader(p);
2506625283
assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
@@ -25078,11 +25295,11 @@
2507825295
** This routine is designed for use within an assert() statement, to
2507925296
** verify the type of an allocation. For example:
2508025297
**
2508125298
** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
2508225299
*/
25083
-SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
25300
+SQLITE_PRIVATE int sqlite3MemdebugNoType(const void *p, u8 eType){
2508425301
int rc = 1;
2508525302
if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
2508625303
struct MemBlockHdr *pHdr;
2508725304
pHdr = sqlite3MemsysGetHeader(p);
2508825305
assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
@@ -30543,10 +30760,11 @@
3054330760
zOp2[0] = 0;
3054430761
}
3054530762
sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s",
3054630763
pExpr->iColumn, zFlgs, zOp2);
3054730764
}else{
30765
+ assert( ExprUseYTab(pExpr) );
3054830766
sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s",
3054930767
pExpr->iTable, pExpr->iColumn,
3055030768
pExpr->y.pTab, zFlgs);
3055130769
}
3055230770
if( ExprHasProperty(pExpr, EP_FixedCol) ){
@@ -30562,15 +30780,17 @@
3056230780
}
3056330781
break;
3056430782
}
3056530783
#ifndef SQLITE_OMIT_FLOATING_POINT
3056630784
case TK_FLOAT: {
30785
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3056730786
sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
3056830787
break;
3056930788
}
3057030789
#endif
3057130790
case TK_STRING: {
30791
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3057230792
sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
3057330793
break;
3057430794
}
3057530795
case TK_NULL: {
3057630796
sqlite3TreeViewLine(pView,"NULL");
@@ -30581,30 +30801,34 @@
3058130801
sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs);
3058230802
break;
3058330803
}
3058430804
#ifndef SQLITE_OMIT_BLOB_LITERAL
3058530805
case TK_BLOB: {
30806
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3058630807
sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
3058730808
break;
3058830809
}
3058930810
#endif
3059030811
case TK_VARIABLE: {
30812
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3059130813
sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
3059230814
pExpr->u.zToken, pExpr->iColumn);
3059330815
break;
3059430816
}
3059530817
case TK_REGISTER: {
3059630818
sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
3059730819
break;
3059830820
}
3059930821
case TK_ID: {
30822
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3060030823
sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
3060130824
break;
3060230825
}
3060330826
#ifndef SQLITE_OMIT_CAST
3060430827
case TK_CAST: {
3060530828
/* Expressions of the form: CAST(pLeft AS token) */
30829
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3060630830
sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
3060730831
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
3060830832
break;
3060930833
}
3061030834
#endif /* SQLITE_OMIT_CAST */
@@ -30650,10 +30874,11 @@
3065030874
zUniOp = azOp[x];
3065130875
break;
3065230876
}
3065330877
3065430878
case TK_SPAN: {
30879
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3065530880
sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
3065630881
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
3065730882
break;
3065830883
}
3065930884
@@ -30661,10 +30886,11 @@
3066130886
/* COLLATE operators without the EP_Collate flag are intended to
3066230887
** emulate collation associated with a table column. These show
3066330888
** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
3066430889
** operators that appear in the original SQL always have the
3066530890
** EP_Collate bit set and appear in treeview output as just "COLLATE" */
30891
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3066630892
sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
3066730893
!ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
3066830894
pExpr->u.zToken, zFlgs);
3066930895
sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
3067030896
break;
@@ -30676,17 +30902,19 @@
3067630902
Window *pWin;
3067730903
if( ExprHasProperty(pExpr, EP_TokenOnly) ){
3067830904
pFarg = 0;
3067930905
pWin = 0;
3068030906
}else{
30907
+ assert( ExprUseXList(pExpr) );
3068130908
pFarg = pExpr->x.pList;
3068230909
#ifndef SQLITE_OMIT_WINDOWFUNC
3068330910
pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0;
3068430911
#else
3068530912
pWin = 0;
3068630913
#endif
3068730914
}
30915
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3068830916
if( pExpr->op==TK_AGG_FUNCTION ){
3068930917
sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
3069030918
pExpr->op2, pExpr->u.zToken, zFlgs,
3069130919
pExpr->pAggInfo ? pExpr->pAggInfo->selId : 0,
3069230920
pExpr->iAgg, pExpr->pAggInfo);
@@ -30714,23 +30942,25 @@
3071430942
#endif
3071530943
break;
3071630944
}
3071730945
#ifndef SQLITE_OMIT_SUBQUERY
3071830946
case TK_EXISTS: {
30947
+ assert( ExprUseXSelect(pExpr) );
3071930948
sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
3072030949
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
3072130950
break;
3072230951
}
3072330952
case TK_SELECT: {
30953
+ assert( ExprUseXSelect(pExpr) );
3072430954
sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags);
3072530955
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
3072630956
break;
3072730957
}
3072830958
case TK_IN: {
3072930959
sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
3073030960
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
30731
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
30961
+ if( ExprUseXSelect(pExpr) ){
3073230962
sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
3073330963
}else{
3073430964
sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
3073530965
}
3073630966
break;
@@ -30747,13 +30977,16 @@
3074730977
** X is stored in pExpr->pLeft.
3074830978
** Y is stored in pExpr->pList->a[0].pExpr.
3074930979
** Z is stored in pExpr->pList->a[1].pExpr.
3075030980
*/
3075130981
case TK_BETWEEN: {
30752
- Expr *pX = pExpr->pLeft;
30753
- Expr *pY = pExpr->x.pList->a[0].pExpr;
30754
- Expr *pZ = pExpr->x.pList->a[1].pExpr;
30982
+ const Expr *pX, *pY, *pZ;
30983
+ pX = pExpr->pLeft;
30984
+ assert( ExprUseXList(pExpr) );
30985
+ assert( pExpr->x.pList->nExpr==2 );
30986
+ pY = pExpr->x.pList->a[0].pExpr;
30987
+ pZ = pExpr->x.pList->a[1].pExpr;
3075530988
sqlite3TreeViewLine(pView, "BETWEEN");
3075630989
sqlite3TreeViewExpr(pView, pX, 1);
3075730990
sqlite3TreeViewExpr(pView, pY, 1);
3075830991
sqlite3TreeViewExpr(pView, pZ, 0);
3075930992
break;
@@ -30771,10 +31004,11 @@
3077131004
break;
3077231005
}
3077331006
case TK_CASE: {
3077431007
sqlite3TreeViewLine(pView, "CASE");
3077531008
sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
31009
+ assert( ExprUseXList(pExpr) );
3077631010
sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
3077731011
break;
3077831012
}
3077931013
#ifndef SQLITE_OMIT_TRIGGER
3078031014
case TK_RAISE: {
@@ -30783,10 +31017,11 @@
3078331017
case OE_Rollback: zType = "rollback"; break;
3078431018
case OE_Abort: zType = "abort"; break;
3078531019
case OE_Fail: zType = "fail"; break;
3078631020
case OE_Ignore: zType = "ignore"; break;
3078731021
}
31022
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
3078831023
sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
3078931024
break;
3079031025
}
3079131026
#endif
3079231027
case TK_MATCH: {
@@ -30795,18 +31030,20 @@
3079531030
sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
3079631031
break;
3079731032
}
3079831033
case TK_VECTOR: {
3079931034
char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
31035
+ assert( ExprUseXList(pExpr) );
3080031036
sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
3080131037
sqlite3_free(z);
3080231038
break;
3080331039
}
3080431040
case TK_SELECT_COLUMN: {
3080531041
sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s",
3080631042
pExpr->iColumn, pExpr->iTable-1,
3080731043
pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : "");
31044
+ assert( ExprUseXSelect(pExpr->pLeft) );
3080831045
sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
3080931046
break;
3081031047
}
3081131048
case TK_IF_NULL_ROW: {
3081231049
sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
@@ -31879,20 +32116,10 @@
3187932116
/* #include <stdarg.h> */
3188032117
#ifndef SQLITE_OMIT_FLOATING_POINT
3188132118
#include <math.h>
3188232119
#endif
3188332120
31884
-/*
31885
-** Routine needed to support the testcase() macro.
31886
-*/
31887
-#ifdef SQLITE_COVERAGE_TEST
31888
-SQLITE_PRIVATE void sqlite3Coverage(int x){
31889
- static unsigned dummy = 0;
31890
- dummy += (unsigned)x;
31891
-}
31892
-#endif
31893
-
3189432121
/*
3189532122
** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
3189632123
** or to bypass normal error detection during testing in order to let
3189732124
** execute proceed futher downstream.
3189832125
**
@@ -32135,10 +32362,11 @@
3213532362
}
3213632363
}
3213732364
z[j] = 0;
3213832365
}
3213932366
SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
32367
+ assert( !ExprHasProperty(p, EP_IntValue) );
3214032368
assert( sqlite3Isquote(p->u.zToken[0]) );
3214132369
p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted;
3214232370
sqlite3Dequote(p->u.zToken);
3214332371
}
3214432372
@@ -33453,11 +33681,10 @@
3345333681
#endif
3345433682
}
3345533683
return a[x&7] + y - 10;
3345633684
}
3345733685
33458
-#ifndef SQLITE_OMIT_VIRTUALTABLE
3345933686
/*
3346033687
** Convert a double into a LogEst
3346133688
** In other words, compute an approximation for 10*log2(x).
3346233689
*/
3346333690
SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
@@ -33468,38 +33695,23 @@
3346833695
if( x<=2000000000 ) return sqlite3LogEst((u64)x);
3346933696
memcpy(&a, &x, 8);
3347033697
e = (a>>52) - 1022;
3347133698
return e*10;
3347233699
}
33473
-#endif /* SQLITE_OMIT_VIRTUALTABLE */
3347433700
33475
-#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
33476
- defined(SQLITE_ENABLE_STAT4) || \
33477
- defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
3347833701
/*
3347933702
** Convert a LogEst into an integer.
33480
-**
33481
-** Note that this routine is only used when one or more of various
33482
-** non-standard compile-time options is enabled.
3348333703
*/
3348433704
SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
3348533705
u64 n;
3348633706
n = x%10;
3348733707
x /= 10;
3348833708
if( n>=5 ) n -= 2;
3348933709
else if( n>=1 ) n -= 1;
33490
-#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
33491
- defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
3349233710
if( x>60 ) return (u64)LARGEST_INT64;
33493
-#else
33494
- /* If only SQLITE_ENABLE_STAT4 is on, then the largest input
33495
- ** possible to this routine is 310, resulting in a maximum x of 31 */
33496
- assert( x<=60 );
33497
-#endif
3349833711
return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
3349933712
}
33500
-#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
3350133713
3350233714
/*
3350333715
** Add a new name/number pair to a VList. This might require that the
3350433716
** VList object be reallocated, so return the new VList. If an OOM
3350533717
** error occurs, the original VList returned and the
@@ -33949,49 +34161,49 @@
3394934161
/* 58 */ "ElseEq" OpHelp(""),
3395034162
/* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
3395134163
/* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
3395234164
/* 61 */ "IncrVacuum" OpHelp(""),
3395334165
/* 62 */ "VNext" OpHelp(""),
33954
- /* 63 */ "Init" OpHelp("Start at P2"),
33955
- /* 64 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
33956
- /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
33957
- /* 66 */ "Return" OpHelp(""),
33958
- /* 67 */ "EndCoroutine" OpHelp(""),
33959
- /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
33960
- /* 69 */ "Halt" OpHelp(""),
33961
- /* 70 */ "Integer" OpHelp("r[P2]=P1"),
33962
- /* 71 */ "Int64" OpHelp("r[P2]=P4"),
33963
- /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
33964
- /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"),
33965
- /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"),
33966
- /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
33967
- /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
33968
- /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
33969
- /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
33970
- /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"),
33971
- /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
33972
- /* 81 */ "ChngCntRow" OpHelp("output=r[P1]"),
33973
- /* 82 */ "ResultRow" OpHelp("output=r[P1@P2]"),
33974
- /* 83 */ "CollSeq" OpHelp(""),
33975
- /* 84 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
33976
- /* 85 */ "RealAffinity" OpHelp(""),
33977
- /* 86 */ "Cast" OpHelp("affinity(r[P1])"),
33978
- /* 87 */ "Permutation" OpHelp(""),
33979
- /* 88 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
33980
- /* 89 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
33981
- /* 90 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
33982
- /* 91 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
33983
- /* 92 */ "Column" OpHelp("r[P3]=PX"),
33984
- /* 93 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
33985
- /* 94 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
33986
- /* 95 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
33987
- /* 96 */ "Count" OpHelp("r[P2]=count()"),
33988
- /* 97 */ "ReadCookie" OpHelp(""),
33989
- /* 98 */ "SetCookie" OpHelp(""),
33990
- /* 99 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
33991
- /* 100 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
33992
- /* 101 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34166
+ /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"),
34167
+ /* 64 */ "Init" OpHelp("Start at P2"),
34168
+ /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
34169
+ /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34170
+ /* 67 */ "Return" OpHelp(""),
34171
+ /* 68 */ "EndCoroutine" OpHelp(""),
34172
+ /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34173
+ /* 70 */ "Halt" OpHelp(""),
34174
+ /* 71 */ "Integer" OpHelp("r[P2]=P1"),
34175
+ /* 72 */ "Int64" OpHelp("r[P2]=P4"),
34176
+ /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34177
+ /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"),
34178
+ /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"),
34179
+ /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34180
+ /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34181
+ /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34182
+ /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34183
+ /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34184
+ /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34185
+ /* 82 */ "FkCheck" OpHelp(""),
34186
+ /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34187
+ /* 84 */ "CollSeq" OpHelp(""),
34188
+ /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34189
+ /* 86 */ "RealAffinity" OpHelp(""),
34190
+ /* 87 */ "Cast" OpHelp("affinity(r[P1])"),
34191
+ /* 88 */ "Permutation" OpHelp(""),
34192
+ /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34193
+ /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34194
+ /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34195
+ /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34196
+ /* 93 */ "Column" OpHelp("r[P3]=PX"),
34197
+ /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34198
+ /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34199
+ /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34200
+ /* 97 */ "Count" OpHelp("r[P2]=count()"),
34201
+ /* 98 */ "ReadCookie" OpHelp(""),
34202
+ /* 99 */ "SetCookie" OpHelp(""),
34203
+ /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34204
+ /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
3399334205
/* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
3399434206
/* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
3399534207
/* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
3399634208
/* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
3399734209
/* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -33998,80 +34210,82 @@
3399834210
/* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
3399934211
/* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
3400034212
/* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
3400134213
/* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
3400234214
/* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34003
- /* 112 */ "OpenDup" OpHelp(""),
34215
+ /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
3400434216
/* 113 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34005
- /* 114 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34006
- /* 115 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34217
+ /* 114 */ "OpenDup" OpHelp(""),
34218
+ /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"),
3400734219
/* 116 */ "String8" OpHelp("r[P2]='P4'"),
34008
- /* 117 */ "SorterOpen" OpHelp(""),
34009
- /* 118 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34010
- /* 119 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34011
- /* 120 */ "Close" OpHelp(""),
34012
- /* 121 */ "ColumnsUsed" OpHelp(""),
34013
- /* 122 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34014
- /* 123 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34015
- /* 124 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34016
- /* 125 */ "NewRowid" OpHelp("r[P2]=rowid"),
34017
- /* 126 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34018
- /* 127 */ "RowCell" OpHelp(""),
34019
- /* 128 */ "Delete" OpHelp(""),
34020
- /* 129 */ "ResetCount" OpHelp(""),
34021
- /* 130 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34022
- /* 131 */ "SorterData" OpHelp("r[P2]=data"),
34023
- /* 132 */ "RowData" OpHelp("r[P2]=data"),
34024
- /* 133 */ "Rowid" OpHelp("r[P2]=rowid"),
34025
- /* 134 */ "NullRow" OpHelp(""),
34026
- /* 135 */ "SeekEnd" OpHelp(""),
34027
- /* 136 */ "IdxInsert" OpHelp("key=r[P2]"),
34028
- /* 137 */ "SorterInsert" OpHelp("key=r[P2]"),
34029
- /* 138 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34030
- /* 139 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34031
- /* 140 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34032
- /* 141 */ "FinishSeek" OpHelp(""),
34033
- /* 142 */ "Destroy" OpHelp(""),
34034
- /* 143 */ "Clear" OpHelp(""),
34035
- /* 144 */ "ResetSorter" OpHelp(""),
34036
- /* 145 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34037
- /* 146 */ "SqlExec" OpHelp(""),
34038
- /* 147 */ "ParseSchema" OpHelp(""),
34039
- /* 148 */ "LoadAnalysis" OpHelp(""),
34040
- /* 149 */ "DropTable" OpHelp(""),
34041
- /* 150 */ "DropIndex" OpHelp(""),
34042
- /* 151 */ "DropTrigger" OpHelp(""),
34220
+ /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34221
+ /* 118 */ "SorterOpen" OpHelp(""),
34222
+ /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34223
+ /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34224
+ /* 121 */ "Close" OpHelp(""),
34225
+ /* 122 */ "ColumnsUsed" OpHelp(""),
34226
+ /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34227
+ /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34228
+ /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34229
+ /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"),
34230
+ /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34231
+ /* 128 */ "RowCell" OpHelp(""),
34232
+ /* 129 */ "Delete" OpHelp(""),
34233
+ /* 130 */ "ResetCount" OpHelp(""),
34234
+ /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34235
+ /* 132 */ "SorterData" OpHelp("r[P2]=data"),
34236
+ /* 133 */ "RowData" OpHelp("r[P2]=data"),
34237
+ /* 134 */ "Rowid" OpHelp("r[P2]=rowid"),
34238
+ /* 135 */ "NullRow" OpHelp(""),
34239
+ /* 136 */ "SeekEnd" OpHelp(""),
34240
+ /* 137 */ "IdxInsert" OpHelp("key=r[P2]"),
34241
+ /* 138 */ "SorterInsert" OpHelp("key=r[P2]"),
34242
+ /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34243
+ /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34244
+ /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34245
+ /* 142 */ "FinishSeek" OpHelp(""),
34246
+ /* 143 */ "Destroy" OpHelp(""),
34247
+ /* 144 */ "Clear" OpHelp(""),
34248
+ /* 145 */ "ResetSorter" OpHelp(""),
34249
+ /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34250
+ /* 147 */ "SqlExec" OpHelp(""),
34251
+ /* 148 */ "ParseSchema" OpHelp(""),
34252
+ /* 149 */ "LoadAnalysis" OpHelp(""),
34253
+ /* 150 */ "DropTable" OpHelp(""),
34254
+ /* 151 */ "DropIndex" OpHelp(""),
3404334255
/* 152 */ "Real" OpHelp("r[P2]=P4"),
34044
- /* 153 */ "IntegrityCk" OpHelp(""),
34045
- /* 154 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34046
- /* 155 */ "Param" OpHelp(""),
34047
- /* 156 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34048
- /* 157 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34049
- /* 158 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34050
- /* 159 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34051
- /* 160 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34052
- /* 161 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34053
- /* 162 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34054
- /* 163 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34055
- /* 164 */ "Expire" OpHelp(""),
34056
- /* 165 */ "CursorLock" OpHelp(""),
34057
- /* 166 */ "CursorUnlock" OpHelp(""),
34058
- /* 167 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34059
- /* 168 */ "VBegin" OpHelp(""),
34060
- /* 169 */ "VCreate" OpHelp(""),
34061
- /* 170 */ "VDestroy" OpHelp(""),
34062
- /* 171 */ "VOpen" OpHelp(""),
34063
- /* 172 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34064
- /* 173 */ "VRename" OpHelp(""),
34065
- /* 174 */ "Pagecount" OpHelp(""),
34066
- /* 175 */ "MaxPgcnt" OpHelp(""),
34067
- /* 176 */ "Trace" OpHelp(""),
34068
- /* 177 */ "CursorHint" OpHelp(""),
34069
- /* 178 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34070
- /* 179 */ "Noop" OpHelp(""),
34071
- /* 180 */ "Explain" OpHelp(""),
34072
- /* 181 */ "Abortable" OpHelp(""),
34256
+ /* 153 */ "DropTrigger" OpHelp(""),
34257
+ /* 154 */ "IntegrityCk" OpHelp(""),
34258
+ /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34259
+ /* 156 */ "Param" OpHelp(""),
34260
+ /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34261
+ /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34262
+ /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34263
+ /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34264
+ /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34265
+ /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34266
+ /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34267
+ /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34268
+ /* 165 */ "Expire" OpHelp(""),
34269
+ /* 166 */ "CursorLock" OpHelp(""),
34270
+ /* 167 */ "CursorUnlock" OpHelp(""),
34271
+ /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34272
+ /* 169 */ "VBegin" OpHelp(""),
34273
+ /* 170 */ "VCreate" OpHelp(""),
34274
+ /* 171 */ "VDestroy" OpHelp(""),
34275
+ /* 172 */ "VOpen" OpHelp(""),
34276
+ /* 173 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34277
+ /* 174 */ "VRename" OpHelp(""),
34278
+ /* 175 */ "Pagecount" OpHelp(""),
34279
+ /* 176 */ "MaxPgcnt" OpHelp(""),
34280
+ /* 177 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34281
+ /* 178 */ "Trace" OpHelp(""),
34282
+ /* 179 */ "CursorHint" OpHelp(""),
34283
+ /* 180 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34284
+ /* 181 */ "Noop" OpHelp(""),
34285
+ /* 182 */ "Explain" OpHelp(""),
34286
+ /* 183 */ "Abortable" OpHelp(""),
3407334287
};
3407434288
return azName[i];
3407534289
}
3407634290
#endif
3407734291
@@ -38028,11 +38242,13 @@
3802838242
}
3802938243
}
3803038244
3803138245
/* Forward declaration */
3803238246
static int unixGetTempname(int nBuf, char *zBuf);
38033
-static int unixFcntlExternalReader(unixFile*, int*);
38247
+#ifndef SQLITE_OMIT_WAL
38248
+ static int unixFcntlExternalReader(unixFile*, int*);
38249
+#endif
3803438250
3803538251
/*
3803638252
** Information and control of an open file handle.
3803738253
*/
3803838254
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -38147,11 +38363,16 @@
3814738363
return proxyFileControl(id,op,pArg);
3814838364
}
3814938365
#endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
3815038366
3815138367
case SQLITE_FCNTL_EXTERNAL_READER: {
38368
+#ifndef SQLITE_OMIT_WAL
3815238369
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
38370
+#else
38371
+ *(int*)pArg = 0;
38372
+ return SQLITE_OK;
38373
+#endif
3815338374
}
3815438375
}
3815538376
return SQLITE_NOTFOUND;
3815638377
}
3815738378
@@ -39867,40 +40088,50 @@
3986740088
OpenCounter(+1);
3986840089
verifyDbFile(pNew);
3986940090
}
3987040091
return rc;
3987140092
}
40093
+
40094
+/*
40095
+** Directories to consider for temp files.
40096
+*/
40097
+static const char *azTempDirs[] = {
40098
+ 0,
40099
+ 0,
40100
+ "/var/tmp",
40101
+ "/usr/tmp",
40102
+ "/tmp",
40103
+ "."
40104
+};
40105
+
40106
+/*
40107
+** Initialize first two members of azTempDirs[] array.
40108
+*/
40109
+static void unixTempFileInit(void){
40110
+ azTempDirs[0] = getenv("SQLITE_TMPDIR");
40111
+ azTempDirs[1] = getenv("TMPDIR");
40112
+}
3987240113
3987340114
/*
3987440115
** Return the name of a directory in which to put temporary files.
3987540116
** If no suitable temporary file directory can be found, return NULL.
3987640117
*/
3987740118
static const char *unixTempFileDir(void){
39878
- static const char *azDirs[] = {
39879
- 0,
39880
- 0,
39881
- "/var/tmp",
39882
- "/usr/tmp",
39883
- "/tmp",
39884
- "."
39885
- };
3988640119
unsigned int i = 0;
3988740120
struct stat buf;
3988840121
const char *zDir = sqlite3_temp_directory;
3988940122
39890
- if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
39891
- if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
3989240123
while(1){
3989340124
if( zDir!=0
3989440125
&& osStat(zDir, &buf)==0
3989540126
&& S_ISDIR(buf.st_mode)
3989640127
&& osAccess(zDir, 03)==0
3989740128
){
3989840129
return zDir;
3989940130
}
39900
- if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break;
39901
- zDir = azDirs[i++];
40131
+ if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break;
40132
+ zDir = azTempDirs[i++];
3990240133
}
3990340134
return 0;
3990440135
}
3990540136
3990640137
/*
@@ -40201,10 +40432,15 @@
4020140432
if( randomnessPid!=osGetpid(0) ){
4020240433
randomnessPid = osGetpid(0);
4020340434
sqlite3_randomness(0,0);
4020440435
}
4020540436
memset(p, 0, sizeof(unixFile));
40437
+
40438
+#ifdef SQLITE_ASSERT_NO_FILES
40439
+ /* Applications that never read or write a persistent disk files */
40440
+ assert( zName==0 );
40441
+#endif
4020640442
4020740443
if( eType==SQLITE_OPEN_MAIN_DB ){
4020840444
UnixUnusedFd *pUnused;
4020940445
pUnused = findReusableFd(zName, flags);
4021040446
if( pUnused ){
@@ -40262,12 +40498,10 @@
4026240498
if( fd<0 ){
4026340499
if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
4026440500
/* If unable to create a journal because the directory is not
4026540501
** writable, change the error code to indicate that. */
4026640502
rc = SQLITE_READONLY_DIRECTORY;
40267
- }else if( errno==EEXIST ){
40268
- rc = SQLITE_CANTOPEN_EXISTS;
4026940503
}else if( errno!=EISDIR && isReadWrite ){
4027040504
/* Failed to open the file for read/write access. Try read-only. */
4027140505
flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
4027240506
openFlags &= ~(O_RDWR|O_CREAT);
4027340507
flags |= SQLITE_OPEN_READONLY;
@@ -42164,10 +42398,13 @@
4216442398
** READ-4 UNIX_SHM_BASE+7 127
4216542399
** DMS UNIX_SHM_BASE+8 128
4216642400
*/
4216742401
assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */
4216842402
#endif
42403
+
42404
+ /* Initialize temp file dir array. */
42405
+ unixTempFileInit();
4216942406
4217042407
return SQLITE_OK;
4217142408
}
4217242409
4217342410
/*
@@ -48615,11 +48852,11 @@
4861548852
/*
4861648853
** Try to enlarge the memory allocation to hold at least sz bytes
4861748854
*/
4861848855
static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
4861948856
unsigned char *pNew;
48620
- if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
48857
+ if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){
4862148858
return SQLITE_FULL;
4862248859
}
4862348860
if( newSz>p->szMax ){
4862448861
return SQLITE_FULL;
4862548862
}
@@ -48674,12 +48911,13 @@
4867448911
*/
4867548912
static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
4867648913
MemStore *p = ((MemFile*)pFile)->pStore;
4867748914
int rc = SQLITE_OK;
4867848915
memdbEnter(p);
48679
- if( NEVER(size>p->sz) ){
48680
- rc = SQLITE_FULL;
48916
+ if( size>p->sz ){
48917
+ /* This can only happen with a corrupt wal mode db */
48918
+ rc = SQLITE_CORRUPT;
4868148919
}else{
4868248920
p->sz = size;
4868348921
}
4868448922
memdbLeave(p);
4868548923
return rc;
@@ -48814,11 +49052,11 @@
4881449052
int iAmt,
4881549053
void **pp
4881649054
){
4881749055
MemStore *p = ((MemFile*)pFile)->pStore;
4881849056
memdbEnter(p);
48819
- if( iOfst+iAmt>p->sz ){
49057
+ if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){
4882049058
*pp = 0;
4882149059
}else{
4882249060
p->nMmap++;
4882349061
*pp = (void*)(p->aData + iOfst);
4882449062
}
@@ -48848,13 +49086,12 @@
4884849086
int *pOutFlags
4884949087
){
4885049088
MemFile *pFile = (MemFile*)pFd;
4885149089
MemStore *p = 0;
4885249090
int szName;
48853
- if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
48854
- return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
48855
- }
49091
+ UNUSED_PARAMETER(pVfs);
49092
+
4885649093
memset(pFile, 0, sizeof(*pFile));
4885749094
szName = sqlite3Strlen30(zName);
4885849095
if( szName>1 && zName[0]=='/' ){
4885949096
int i;
4886049097
#ifndef SQLITE_MUTEX_OMIT
@@ -48910,12 +49147,13 @@
4891049147
memset(p, 0, sizeof(*p));
4891149148
p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
4891249149
p->szMax = sqlite3GlobalConfig.mxMemdbSize;
4891349150
}
4891449151
pFile->pStore = p;
48915
- assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
48916
- *pOutFlags = flags | SQLITE_OPEN_MEMORY;
49152
+ if( pOutFlags!=0 ){
49153
+ *pOutFlags = flags | SQLITE_OPEN_MEMORY;
49154
+ }
4891749155
pFd->pMethods = &memdb_io_methods;
4891849156
memdbLeave(p);
4891949157
return SQLITE_OK;
4892049158
}
4892149159
@@ -49576,11 +49814,11 @@
4957649814
/* NULL pBitvec tests */
4957749815
sqlite3BitvecSet(0, 1);
4957849816
sqlite3BitvecClear(0, 1, pTmpSpace);
4957949817
4958049818
/* Run the program */
49581
- pc = 0;
49819
+ pc = i = 0;
4958249820
while( (op = aOp[pc])!=0 ){
4958349821
switch( op ){
4958449822
case 1:
4958549823
case 2:
4958649824
case 5: {
@@ -53106,10 +53344,11 @@
5310653344
u8 walSyncFlags; /* See description above */
5310753345
u8 tempFile; /* zFilename is a temporary or immutable file */
5310853346
u8 noLock; /* Do not lock (except in WAL mode) */
5310953347
u8 readOnly; /* True for a read-only database */
5311053348
u8 memDb; /* True to inhibit all file I/O */
53349
+ u8 memVfs; /* VFS-implemented memory database */
5311153350
5311253351
/**************************************************************************
5311353352
** The following block contains those class members that change during
5311453353
** routine operation. Class members not in this block are either fixed
5311553354
** when the pager is first created or else only change when there is a
@@ -55500,10 +55739,11 @@
5550055739
** routine which only updates the change-counter if the update is actually
5550155740
** needed, as determined by the pPager->changeCountDone state variable.
5550255741
*/
5550355742
static void pager_write_changecounter(PgHdr *pPg){
5550455743
u32 change_counter;
55744
+ if( NEVER(pPg==0) ) return;
5550555745
5550655746
/* Increment the value just read and write it back to byte 24. */
5550755747
change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
5550855748
put32bits(((char*)pPg->pData)+24, change_counter);
5550955749
@@ -57347,11 +57587,11 @@
5734757587
if( zFilename && zFilename[0] ){
5734857588
int fout = 0; /* VFS flags returned by xOpen() */
5734957589
rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
5735057590
assert( !memDb );
5735157591
#ifndef SQLITE_OMIT_DESERIALIZE
57352
- memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
57592
+ pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
5735357593
#endif
5735457594
readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
5735557595
5735657596
/* If the file was successfully opened for read/write access,
5735757597
** choose a default page size in case we have to create the
@@ -59284,11 +59524,11 @@
5928459524
5928559525
/*
5928659526
** Return true if this is an in-memory or temp-file backed pager.
5928759527
*/
5928859528
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
59289
- return pPager->tempFile;
59529
+ return pPager->tempFile || pPager->memVfs;
5929059530
}
5929159531
5929259532
/*
5929359533
** Check that there are at least nSavepoint savepoints open. If there are
5929459534
** currently less than nSavepoints open, then open one or more savepoints
@@ -59604,11 +59844,11 @@
5960459844
*/
5960559845
pPg->flags &= ~PGHDR_NEED_SYNC;
5960659846
pPgOld = sqlite3PagerLookup(pPager, pgno);
5960759847
assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB );
5960859848
if( pPgOld ){
59609
- if( pPgOld->nRef>1 ){
59849
+ if( NEVER(pPgOld->nRef>1) ){
5961059850
sqlite3PagerUnrefNotNull(pPgOld);
5961159851
return SQLITE_CORRUPT_BKPT;
5961259852
}
5961359853
pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
5961459854
if( pPager->tempFile ){
@@ -60809,13 +61049,17 @@
6080961049
** If the wal-index is currently smaller the iPage pages then the size
6081061050
** of the wal-index might be increased, but only if it is safe to do
6081161051
** so. It is safe to enlarge the wal-index if pWal->writeLock is true
6081261052
** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
6081361053
**
60814
-** If this call is successful, *ppPage is set to point to the wal-index
60815
-** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
60816
-** then an SQLite error code is returned and *ppPage is set to 0.
61054
+** Three possible result scenarios:
61055
+**
61056
+** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
61057
+** (2) rc>=SQLITE_ERROR and *ppPage==NULL
61058
+** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0
61059
+**
61060
+** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
6081761061
*/
6081861062
static SQLITE_NOINLINE int walIndexPageRealloc(
6081961063
Wal *pWal, /* The WAL context */
6082061064
int iPage, /* The page we seek */
6082161065
volatile u32 **ppPage /* Write the page pointer here */
@@ -60844,11 +61088,13 @@
6084461088
if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
6084561089
}else{
6084661090
rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
6084761091
pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
6084861092
);
60849
- assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
61093
+ assert( pWal->apWiData[iPage]!=0
61094
+ || rc!=SQLITE_OK
61095
+ || (pWal->writeLock==0 && iPage==0) );
6085061096
testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
6085161097
if( rc==SQLITE_OK ){
6085261098
if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
6085361099
}else if( (rc&0xff)==SQLITE_READONLY ){
6085461100
pWal->readOnly |= WAL_SHM_RDONLY;
@@ -61183,12 +61429,12 @@
6118361429
** in the wal-index file. Set pLoc->iZero to one less than the frame
6118461430
** number of the first frame indexed by this hash table. If a
6118561431
** slot in the hash table is set to N, it refers to frame number
6118661432
** (pLoc->iZero+N) in the log.
6118761433
**
61188
-** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
61189
-** first frame indexed by the hash table, frame (pLoc->iZero+1).
61434
+** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the
61435
+** first frame indexed by the hash table, frame (pLoc->iZero).
6119061436
*/
6119161437
static int walHashGet(
6119261438
Wal *pWal, /* WAL handle */
6119361439
int iHash, /* Find the iHash'th table */
6119461440
WalHashLoc *pLoc /* OUT: Hash table location */
@@ -61196,19 +61442,20 @@
6119661442
int rc; /* Return code */
6119761443
6119861444
rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
6119961445
assert( rc==SQLITE_OK || iHash>0 );
6120061446
61201
- if( rc==SQLITE_OK ){
61447
+ if( pLoc->aPgno ){
6120261448
pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
6120361449
if( iHash==0 ){
6120461450
pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
6120561451
pLoc->iZero = 0;
6120661452
}else{
6120761453
pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
6120861454
}
61209
- pLoc->aPgno = &pLoc->aPgno[-1];
61455
+ }else if( NEVER(rc==SQLITE_OK) ){
61456
+ rc = SQLITE_ERROR;
6121061457
}
6121161458
return rc;
6121261459
}
6121361460
6121461461
/*
@@ -61286,25 +61533,26 @@
6128661533
}
6128761534
6128861535
/* Zero the entries in the aPgno array that correspond to frames with
6128961536
** frame numbers greater than pWal->hdr.mxFrame.
6129061537
*/
61291
- nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
61292
- memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
61538
+ nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]);
61539
+ assert( nByte>=0 );
61540
+ memset((void *)&sLoc.aPgno[iLimit], 0, nByte);
6129361541
6129461542
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
6129561543
/* Verify that the every entry in the mapping region is still reachable
6129661544
** via the hash table even after the cleanup.
6129761545
*/
6129861546
if( iLimit ){
6129961547
int j; /* Loop counter */
6130061548
int iKey; /* Hash key */
61301
- for(j=1; j<=iLimit; j++){
61549
+ for(j=0; j<iLimit; j++){
6130261550
for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
61303
- if( sLoc.aHash[iKey]==j ) break;
61551
+ if( sLoc.aHash[iKey]==j+1 ) break;
6130461552
}
61305
- assert( sLoc.aHash[iKey]==j );
61553
+ assert( sLoc.aHash[iKey]==j+1 );
6130661554
}
6130761555
}
6130861556
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
6130961557
}
6131061558
@@ -61332,32 +61580,32 @@
6133261580
6133361581
/* If this is the first entry to be added to this hash-table, zero the
6133461582
** entire hash table and aPgno[] array before proceeding.
6133561583
*/
6133661584
if( idx==1 ){
61337
- int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
61338
- - (u8 *)&sLoc.aPgno[1]);
61339
- memset((void*)&sLoc.aPgno[1], 0, nByte);
61585
+ int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno);
61586
+ assert( nByte>=0 );
61587
+ memset((void*)sLoc.aPgno, 0, nByte);
6134061588
}
6134161589
6134261590
/* If the entry in aPgno[] is already set, then the previous writer
6134361591
** must have exited unexpectedly in the middle of a transaction (after
6134461592
** writing one or more dirty pages to the WAL to free up memory).
6134561593
** Remove the remnants of that writers uncommitted transaction from
6134661594
** the hash-table before writing any new entries.
6134761595
*/
61348
- if( sLoc.aPgno[idx] ){
61596
+ if( sLoc.aPgno[idx-1] ){
6134961597
walCleanupHash(pWal);
61350
- assert( !sLoc.aPgno[idx] );
61598
+ assert( !sLoc.aPgno[idx-1] );
6135161599
}
6135261600
6135361601
/* Write the aPgno[] array entry and the hash-table slot. */
6135461602
nCollide = idx;
6135561603
for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
6135661604
if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
6135761605
}
61358
- sLoc.aPgno[idx] = iPage;
61606
+ sLoc.aPgno[idx-1] = iPage;
6135961607
AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
6136061608
6136161609
#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
6136261610
/* Verify that the number of entries in the hash table exactly equals
6136361611
** the number of entries in the mapping region.
@@ -61374,22 +61622,21 @@
6137461622
** thing to check, so only do this occasionally - not on every
6137561623
** iteration.
6137661624
*/
6137761625
if( (idx&0x3ff)==0 ){
6137861626
int i; /* Loop counter */
61379
- for(i=1; i<=idx; i++){
61627
+ for(i=0; i<idx; i++){
6138061628
for(iKey=walHash(sLoc.aPgno[i]);
6138161629
sLoc.aHash[iKey];
6138261630
iKey=walNextHash(iKey)){
61383
- if( sLoc.aHash[iKey]==i ) break;
61631
+ if( sLoc.aHash[iKey]==i+1 ) break;
6138461632
}
61385
- assert( sLoc.aHash[iKey]==i );
61633
+ assert( sLoc.aHash[iKey]==i+1 );
6138661634
}
6138761635
}
6138861636
#endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
6138961637
}
61390
-
6139161638
6139261639
return rc;
6139361640
}
6139461641
6139561642
@@ -61507,11 +61754,12 @@
6150761754
u32 iFrame; /* Index of last frame read */
6150861755
u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
6150961756
u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
6151061757
u32 nHdr, nHdr32;
6151161758
rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
61512
- if( rc ) break;
61759
+ assert( aShare!=0 || rc!=SQLITE_OK );
61760
+ if( aShare==0 ) break;
6151361761
pWal->apWiData[iPg] = aPrivate;
6151461762
6151561763
for(iFrame=iFirst; iFrame<=iLast; iFrame++){
6151661764
i64 iOffset = walFrameOffset(iFrame, szPage);
6151761765
u32 pgno; /* Database page number for frame */
@@ -62004,11 +62252,10 @@
6200462252
if( rc==SQLITE_OK ){
6200562253
int j; /* Counter variable */
6200662254
int nEntry; /* Number of entries in this segment */
6200762255
ht_slot *aIndex; /* Sorted index for this segment */
6200862256
62009
- sLoc.aPgno++;
6201062257
if( (i+1)==nSegment ){
6201162258
nEntry = (int)(iLast - sLoc.iZero);
6201262259
}else{
6201362260
nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
6201462261
}
@@ -63143,11 +63390,12 @@
6314363390
i64 iDbOff; /* Offset of db file entry */
6314463391
i64 iWalOff; /* Offset of wal file entry */
6314563392
6314663393
rc = walHashGet(pWal, walFramePage(i), &sLoc);
6314763394
if( rc!=SQLITE_OK ) break;
63148
- pgno = sLoc.aPgno[i-sLoc.iZero];
63395
+ assert( i - sLoc.iZero - 1 >=0 );
63396
+ pgno = sLoc.aPgno[i-sLoc.iZero-1];
6314963397
iDbOff = (i64)(pgno-1) * szPage;
6315063398
6315163399
if( iDbOff+szPage<=szDb ){
6315263400
iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
6315363401
rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
@@ -63376,11 +63624,11 @@
6337663624
}
6337763625
nCollide = HASHTABLE_NSLOT;
6337863626
iKey = walHash(pgno);
6337963627
while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
6338063628
u32 iFrame = iH + sLoc.iZero;
63381
- if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
63629
+ if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){
6338263630
assert( iFrame>iRead || CORRUPT_DB );
6338363631
iRead = iFrame;
6338463632
}
6338563633
if( (nCollide--)==0 ){
6338663634
return SQLITE_CORRUPT_BKPT;
@@ -64628,11 +64876,10 @@
6462864876
** Access to all fields of this structure is controlled by the mutex
6462964877
** stored in MemPage.pBt->mutex.
6463064878
*/
6463164879
struct MemPage {
6463264880
u8 isInit; /* True if previously initialized. MUST BE FIRST! */
64633
- u8 bBusy; /* Prevent endless loops on corrupt database files */
6463464881
u8 intKey; /* True if table b-trees. False for index b-trees */
6463564882
u8 intKeyLeaf; /* True if the leaf of an intKey table */
6463664883
Pgno pgno; /* Page number for this page */
6463764884
/* Only the first 8 bytes (above) are zeroed by pager.c when a new page
6463864885
** is allocated. All fields that follow must be initialized before use */
@@ -66870,11 +67117,11 @@
6687067117
if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
6687167118
sz2 = get2byte(&data[iFree2+2]);
6687267119
if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
6687367120
memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
6687467121
sz += sz2;
66875
- }else if( iFree+sz>usableSize ){
67122
+ }else if( NEVER(iFree+sz>usableSize) ){
6687667123
return SQLITE_CORRUPT_PAGE(pPage);
6687767124
}
6687867125
6687967126
cbrk = top+sz;
6688067127
assert( cbrk+(iFree-top) <= usableSize );
@@ -68075,34 +68322,42 @@
6807568322
/*
6807668323
** Make sure pBt->pTmpSpace points to an allocation of
6807768324
** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
6807868325
** pointer.
6807968326
*/
68080
-static void allocateTempSpace(BtShared *pBt){
68081
- if( !pBt->pTmpSpace ){
68082
- pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
68083
-
68084
- /* One of the uses of pBt->pTmpSpace is to format cells before
68085
- ** inserting them into a leaf page (function fillInCell()). If
68086
- ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
68087
- ** by the various routines that manipulate binary cells. Which
68088
- ** can mean that fillInCell() only initializes the first 2 or 3
68089
- ** bytes of pTmpSpace, but that the first 4 bytes are copied from
68090
- ** it into a database page. This is not actually a problem, but it
68091
- ** does cause a valgrind error when the 1 or 2 bytes of unitialized
68092
- ** data is passed to system call write(). So to avoid this error,
68093
- ** zero the first 4 bytes of temp space here.
68094
- **
68095
- ** Also: Provide four bytes of initialized space before the
68096
- ** beginning of pTmpSpace as an area available to prepend the
68097
- ** left-child pointer to the beginning of a cell.
68098
- */
68099
- if( pBt->pTmpSpace ){
68100
- memset(pBt->pTmpSpace, 0, 8);
68101
- pBt->pTmpSpace += 4;
68102
- }
68103
- }
68327
+static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){
68328
+ assert( pBt!=0 );
68329
+ assert( pBt->pTmpSpace==0 );
68330
+ /* This routine is called only by btreeCursor() when allocating the
68331
+ ** first write cursor for the BtShared object */
68332
+ assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 );
68333
+ pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
68334
+ if( pBt->pTmpSpace==0 ){
68335
+ BtCursor *pCur = pBt->pCursor;
68336
+ pBt->pCursor = pCur->pNext; /* Unlink the cursor */
68337
+ memset(pCur, 0, sizeof(*pCur));
68338
+ return SQLITE_NOMEM_BKPT;
68339
+ }
68340
+
68341
+ /* One of the uses of pBt->pTmpSpace is to format cells before
68342
+ ** inserting them into a leaf page (function fillInCell()). If
68343
+ ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
68344
+ ** by the various routines that manipulate binary cells. Which
68345
+ ** can mean that fillInCell() only initializes the first 2 or 3
68346
+ ** bytes of pTmpSpace, but that the first 4 bytes are copied from
68347
+ ** it into a database page. This is not actually a problem, but it
68348
+ ** does cause a valgrind error when the 1 or 2 bytes of unitialized
68349
+ ** data is passed to system call write(). So to avoid this error,
68350
+ ** zero the first 4 bytes of temp space here.
68351
+ **
68352
+ ** Also: Provide four bytes of initialized space before the
68353
+ ** beginning of pTmpSpace as an area available to prepend the
68354
+ ** left-child pointer to the beginning of a cell.
68355
+ */
68356
+ memset(pBt->pTmpSpace, 0, 8);
68357
+ pBt->pTmpSpace += 4;
68358
+ return SQLITE_OK;
6810468359
}
6810568360
6810668361
/*
6810768362
** Free the pBt->pTmpSpace allocation
6810868363
*/
@@ -68477,11 +68732,10 @@
6847768732
static int lockBtree(BtShared *pBt){
6847868733
int rc; /* Result code from subfunctions */
6847968734
MemPage *pPage1; /* Page 1 of the database file */
6848068735
u32 nPage; /* Number of pages in the database */
6848168736
u32 nPageFile = 0; /* Number of pages in the database file */
68482
- u32 nPageHeader; /* Number of pages in the database according to hdr */
6848368737
6848468738
assert( sqlite3_mutex_held(pBt->mutex) );
6848568739
assert( pBt->pPage1==0 );
6848668740
rc = sqlite3PagerSharedLock(pBt->pPager);
6848768741
if( rc!=SQLITE_OK ) return rc;
@@ -68489,11 +68743,11 @@
6848968743
if( rc!=SQLITE_OK ) return rc;
6849068744
6849168745
/* Do some checking to help insure the file we opened really is
6849268746
** a valid database file.
6849368747
*/
68494
- nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
68748
+ nPage = get4byte(28+(u8*)pPage1->aData);
6849568749
sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile);
6849668750
if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
6849768751
nPage = nPageFile;
6849868752
}
6849968753
if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
@@ -69322,27 +69576,30 @@
6932269576
}
6932369577
6932469578
/*
6932569579
** This routine is called prior to sqlite3PagerCommit when a transaction
6932669580
** is committed for an auto-vacuum database.
69327
-**
69328
-** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
69329
-** the database file should be truncated to during the commit process.
69330
-** i.e. the database has been reorganized so that only the first *pnTrunc
69331
-** pages are in use.
6933269581
*/
69333
-static int autoVacuumCommit(BtShared *pBt){
69582
+static int autoVacuumCommit(Btree *p){
6933469583
int rc = SQLITE_OK;
69335
- Pager *pPager = pBt->pPager;
69336
- VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
69584
+ Pager *pPager;
69585
+ BtShared *pBt;
69586
+ sqlite3 *db;
69587
+ VVA_ONLY( int nRef );
69588
+
69589
+ assert( p!=0 );
69590
+ pBt = p->pBt;
69591
+ pPager = pBt->pPager;
69592
+ VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); )
6933769593
6933869594
assert( sqlite3_mutex_held(pBt->mutex) );
6933969595
invalidateAllOverflowCache(pBt);
6934069596
assert(pBt->autoVacuum);
6934169597
if( !pBt->incrVacuum ){
6934269598
Pgno nFin; /* Number of pages in database after autovacuuming */
6934369599
Pgno nFree; /* Number of pages on the freelist initially */
69600
+ Pgno nVac; /* Number of pages to vacuum */
6934469601
Pgno iFree; /* The next page to be freed */
6934569602
Pgno nOrig; /* Database size before freeing */
6934669603
6934769604
nOrig = btreePagecount(pBt);
6934869605
if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
@@ -69352,22 +69609,46 @@
6935269609
*/
6935369610
return SQLITE_CORRUPT_BKPT;
6935469611
}
6935569612
6935669613
nFree = get4byte(&pBt->pPage1->aData[36]);
69357
- nFin = finalDbSize(pBt, nOrig, nFree);
69614
+ db = p->db;
69615
+ if( db->xAutovacPages ){
69616
+ int iDb;
69617
+ for(iDb=0; ALWAYS(iDb<db->nDb); iDb++){
69618
+ if( db->aDb[iDb].pBt==p ) break;
69619
+ }
69620
+ nVac = db->xAutovacPages(
69621
+ db->pAutovacPagesArg,
69622
+ db->aDb[iDb].zDbSName,
69623
+ nOrig,
69624
+ nFree,
69625
+ pBt->pageSize
69626
+ );
69627
+ if( nVac>nFree ){
69628
+ nVac = nFree;
69629
+ }
69630
+ if( nVac==0 ){
69631
+ return SQLITE_OK;
69632
+ }
69633
+ }else{
69634
+ nVac = nFree;
69635
+ }
69636
+ nFin = finalDbSize(pBt, nOrig, nVac);
6935869637
if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
6935969638
if( nFin<nOrig ){
6936069639
rc = saveAllCursors(pBt, 0, 0);
6936169640
}
6936269641
for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
69363
- rc = incrVacuumStep(pBt, nFin, iFree, 1);
69642
+ rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree);
6936469643
}
6936569644
if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
6936669645
rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
69367
- put4byte(&pBt->pPage1->aData[32], 0);
69368
- put4byte(&pBt->pPage1->aData[36], 0);
69646
+ if( nVac==nFree ){
69647
+ put4byte(&pBt->pPage1->aData[32], 0);
69648
+ put4byte(&pBt->pPage1->aData[36], 0);
69649
+ }
6936969650
put4byte(&pBt->pPage1->aData[28], nFin);
6937069651
pBt->bDoTruncate = 1;
6937169652
pBt->nPage = nFin;
6937269653
}
6937369654
if( rc!=SQLITE_OK ){
@@ -69414,11 +69695,11 @@
6941469695
if( p->inTrans==TRANS_WRITE ){
6941569696
BtShared *pBt = p->pBt;
6941669697
sqlite3BtreeEnter(p);
6941769698
#ifndef SQLITE_OMIT_AUTOVACUUM
6941869699
if( pBt->autoVacuum ){
69419
- rc = autoVacuumCommit(pBt);
69700
+ rc = autoVacuumCommit(p);
6942069701
if( rc!=SQLITE_OK ){
6942169702
sqlite3BtreeLeave(p);
6942269703
return rc;
6942369704
}
6942469705
}
@@ -69813,14 +70094,10 @@
6981370094
assert( p->inTrans>TRANS_NONE );
6981470095
assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
6981570096
assert( pBt->pPage1 && pBt->pPage1->aData );
6981670097
assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );
6981770098
69818
- if( wrFlag ){
69819
- allocateTempSpace(pBt);
69820
- if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
69821
- }
6982270099
if( iTable<=1 ){
6982370100
if( iTable<1 ){
6982470101
return SQLITE_CORRUPT_BKPT;
6982570102
}else if( btreePagecount(pBt)==0 ){
6982670103
assert( wrFlag==0 );
@@ -69833,23 +70110,29 @@
6983370110
pCur->pgnoRoot = iTable;
6983470111
pCur->iPage = -1;
6983570112
pCur->pKeyInfo = pKeyInfo;
6983670113
pCur->pBtree = p;
6983770114
pCur->pBt = pBt;
69838
- pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
69839
- pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
70115
+ pCur->curFlags = 0;
6984070116
/* If there are two or more cursors on the same btree, then all such
6984170117
** cursors *must* have the BTCF_Multiple flag set. */
6984270118
for(pX=pBt->pCursor; pX; pX=pX->pNext){
6984370119
if( pX->pgnoRoot==iTable ){
6984470120
pX->curFlags |= BTCF_Multiple;
69845
- pCur->curFlags |= BTCF_Multiple;
70121
+ pCur->curFlags = BTCF_Multiple;
6984670122
}
6984770123
}
70124
+ pCur->eState = CURSOR_INVALID;
6984870125
pCur->pNext = pBt->pCursor;
6984970126
pBt->pCursor = pCur;
69850
- pCur->eState = CURSOR_INVALID;
70127
+ if( wrFlag ){
70128
+ pCur->curFlags |= BTCF_WriteFlag;
70129
+ pCur->curPagerFlags = 0;
70130
+ if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt);
70131
+ }else{
70132
+ pCur->curPagerFlags = PAGER_GET_READONLY;
70133
+ }
6985170134
return SQLITE_OK;
6985270135
}
6985370136
static int btreeCursorWithLock(
6985470137
Btree *p, /* The btree */
6985570138
Pgno iTable, /* Root page of table to open */
@@ -70219,11 +70502,13 @@
7021970502
#endif
7022070503
7022170504
assert( pPage );
7022270505
assert( eOp==0 || eOp==1 );
7022370506
assert( pCur->eState==CURSOR_VALID );
70224
- assert( pCur->ix<pPage->nCell );
70507
+ if( pCur->ix>=pPage->nCell ){
70508
+ return SQLITE_CORRUPT_PAGE(pPage);
70509
+ }
7022570510
assert( cursorHoldsMutex(pCur) );
7022670511
7022770512
getCellInfo(pCur);
7022870513
aPayload = pCur->info.pPayload;
7022970514
assert( offset+amt <= pCur->info.nPayload );
@@ -70406,11 +70691,10 @@
7040670691
*/
7040770692
SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
7040870693
assert( cursorHoldsMutex(pCur) );
7040970694
assert( pCur->eState==CURSOR_VALID );
7041070695
assert( pCur->iPage>=0 && pCur->pPage );
70411
- assert( pCur->ix<pCur->pPage->nCell );
7041270696
return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
7041370697
}
7041470698
7041570699
/*
7041670700
** This variant of sqlite3BtreePayload() works even if the cursor has not
@@ -70468,11 +70752,11 @@
7046870752
int amt;
7046970753
assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
7047070754
assert( pCur->eState==CURSOR_VALID );
7047170755
assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
7047270756
assert( cursorOwnsBtShared(pCur) );
70473
- assert( pCur->ix<pCur->pPage->nCell );
70757
+ assert( pCur->ix<pCur->pPage->nCell || CORRUPT_DB );
7047470758
assert( pCur->info.nSize>0 );
7047570759
assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
7047670760
assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
7047770761
amt = pCur->info.nLocal;
7047870762
if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
@@ -71254,20 +71538,10 @@
7125471538
** module cov1/btree78.test testcase 220 (2018-06-08) for an
7125571539
** example. */
7125671540
return SQLITE_CORRUPT_BKPT;
7125771541
}
7125871542
71259
- /* If the database file is corrupt, it is possible for the value of idx
71260
- ** to be invalid here. This can only occur if a second cursor modifies
71261
- ** the page while cursor pCur is holding a reference to it. Which can
71262
- ** only happen if the database is corrupt in such a way as to link the
71263
- ** page into more than one b-tree structure.
71264
- **
71265
- ** Update 2019-12-23: appears to long longer be possible after the
71266
- ** addition of anotherValidCursor() condition on balance_deeper(). */
71267
- harmless( idx>pPage->nCell );
71268
-
7126971543
if( idx>=pPage->nCell ){
7127071544
if( !pPage->leaf ){
7127171545
rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
7127271546
if( rc ) return rc;
7127371547
return moveToLeftmost(pCur);
@@ -71751,11 +72025,11 @@
7175172025
7175272026
assert( sqlite3_mutex_held(pBt->mutex) );
7175372027
assert( CORRUPT_DB || iPage>1 );
7175472028
assert( !pMemPage || pMemPage->pgno==iPage );
7175572029
71756
- if( iPage<2 || iPage>pBt->nPage ){
72030
+ if( NEVER(iPage<2) || iPage>pBt->nPage ){
7175772031
return SQLITE_CORRUPT_BKPT;
7175872032
}
7175972033
if( pMemPage ){
7176072034
pPage = pMemPage;
7176172035
sqlite3PagerRef(pPage->pDbPage);
@@ -73069,15 +73343,14 @@
7306973343
Pgno pgno; /* Temp var to store a page number in */
7307073344
u8 abDone[NB+2]; /* True after i'th new page is populated */
7307173345
Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */
7307273346
Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */
7307373347
u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */
73074
- CellArray b; /* Parsed information on cells being balanced */
73348
+ CellArray b; /* Parsed information on cells being balanced */
7307573349
7307673350
memset(abDone, 0, sizeof(abDone));
73077
- b.nCell = 0;
73078
- b.apCell = 0;
73351
+ memset(&b, 0, sizeof(b));
7307973352
pBt = pParent->pBt;
7308073353
assert( sqlite3_mutex_held(pBt->mutex) );
7308173354
assert( sqlite3PagerIswriteable(pParent->pDbPage) );
7308273355
7308373356
/* At this point pParent may have at most one overflow cell. And if
@@ -73884,11 +74157,11 @@
7388474157
7388574158
/*
7388674159
** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
7388774160
** on the same B-tree as pCur.
7388874161
**
73889
-** This can if a database is corrupt with two or more SQL tables
74162
+** This can occur if a database is corrupt with two or more SQL tables
7389074163
** pointing to the same b-tree. If an insert occurs on one SQL table
7389174164
** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
7389274165
** table linked to the same b-tree. If the secondary insert causes a
7389374166
** rebalance, that can change content out from under the cursor on the
7389474167
** first SQL table, violating invariants on the first insert.
@@ -74353,11 +74626,14 @@
7435374626
assert( szNew==pPage->xCellSize(pPage, newCell) );
7435474627
assert( szNew <= MX_CELL_SIZE(pBt) );
7435574628
idx = pCur->ix;
7435674629
if( loc==0 ){
7435774630
CellInfo info;
74358
- assert( idx<pPage->nCell );
74631
+ assert( idx>=0 );
74632
+ if( idx>=pPage->nCell ){
74633
+ return SQLITE_CORRUPT_BKPT;
74634
+ }
7435974635
rc = sqlite3PagerWrite(pPage->pDbPage);
7436074636
if( rc ){
7436174637
goto end_insert;
7436274638
}
7436374639
oldCell = findCell(pPage, idx);
@@ -74939,15 +75215,16 @@
7493975215
if( pgno>btreePagecount(pBt) ){
7494075216
return SQLITE_CORRUPT_BKPT;
7494175217
}
7494275218
rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
7494375219
if( rc ) return rc;
74944
- if( pPage->bBusy ){
75220
+ if( (pBt->openFlags & BTREE_SINGLE)==0
75221
+ && sqlite3PagerPageRefcount(pPage->pDbPage)!=1
75222
+ ){
7494575223
rc = SQLITE_CORRUPT_BKPT;
7494675224
goto cleardatabasepage_out;
7494775225
}
74948
- pPage->bBusy = 1;
7494975226
hdr = pPage->hdrOffset;
7495075227
for(i=0; i<pPage->nCell; i++){
7495175228
pCell = findCell(pPage, i);
7495275229
if( !pPage->leaf ){
7495375230
rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
@@ -74970,11 +75247,10 @@
7497075247
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
7497175248
zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
7497275249
}
7497375250
7497475251
cleardatabasepage_out:
74975
- pPage->bBusy = 0;
7497675252
releasePage(pPage);
7497775253
return rc;
7497875254
}
7497975255
7498075256
/*
@@ -75049,14 +75325,14 @@
7504975325
assert( iTable>=2 );
7505075326
if( iTable>btreePagecount(pBt) ){
7505175327
return SQLITE_CORRUPT_BKPT;
7505275328
}
7505375329
75054
- rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
75055
- if( rc ) return rc;
7505675330
rc = sqlite3BtreeClearTable(p, iTable, 0);
75057
- if( rc ){
75331
+ if( rc ) return rc;
75332
+ rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
75333
+ if( NEVER(rc) ){
7505875334
releasePage(pPage);
7505975335
return rc;
7506075336
}
7506175337
7506275338
*piMoved = 0;
@@ -77209,10 +77485,11 @@
7720977485
*/
7721077486
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
7721177487
#ifndef SQLITE_OMIT_UTF16
7721277488
int rc;
7721377489
#endif
77490
+ assert( pMem!=0 );
7721477491
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7721577492
assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
7721677493
|| desiredEnc==SQLITE_UTF16BE );
7721777494
if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
7721877495
return SQLITE_OK;
@@ -77341,10 +77618,11 @@
7734177618
** MEM.zMalloc, where it can be safely written.
7734277619
**
7734377620
** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
7734477621
*/
7734577622
SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
77623
+ assert( pMem!=0 );
7734677624
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7734777625
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7734877626
if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
7734977627
if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
7735077628
if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
@@ -77365,10 +77643,11 @@
7736577643
** blob stored in dynamically allocated space.
7736677644
*/
7736777645
#ifndef SQLITE_OMIT_INCRBLOB
7736877646
SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
7736977647
int nByte;
77648
+ assert( pMem!=0 );
7737077649
assert( pMem->flags & MEM_Zero );
7737177650
assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
7737277651
testcase( sqlite3_value_nochange(pMem) );
7737377652
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7737477653
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -77380,10 +77659,12 @@
7738077659
nByte = 1;
7738177660
}
7738277661
if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
7738377662
return SQLITE_NOMEM_BKPT;
7738477663
}
77664
+ assert( pMem->z!=0 );
77665
+ assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
7738577666
7738677667
memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
7738777668
pMem->n += pMem->u.nZero;
7738877669
pMem->flags &= ~(MEM_Zero|MEM_Term);
7738977670
return SQLITE_OK;
@@ -77392,10 +77673,11 @@
7739277673
7739377674
/*
7739477675
** Make sure the given Mem is \u0000 terminated.
7739577676
*/
7739677677
SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
77678
+ assert( pMem!=0 );
7739777679
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7739877680
testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) );
7739977681
testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 );
7740077682
if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){
7740177683
return SQLITE_OK; /* Nothing to do */
@@ -77419,10 +77701,11 @@
7741977701
** user and the latter is an internal programming error.
7742077702
*/
7742177703
SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
7742277704
const int nByte = 32;
7742377705
77706
+ assert( pMem!=0 );
7742477707
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7742577708
assert( !(pMem->flags&MEM_Zero) );
7742677709
assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
7742777710
assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
7742877711
assert( !sqlite3VdbeMemIsRowSet(pMem) );
@@ -77454,10 +77737,11 @@
7745477737
*/
7745577738
SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
7745677739
sqlite3_context ctx;
7745777740
Mem t;
7745877741
assert( pFunc!=0 );
77742
+ assert( pMem!=0 );
7745977743
assert( pFunc->xFinalize!=0 );
7746077744
assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
7746177745
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7746277746
memset(&ctx, 0, sizeof(ctx));
7746377747
memset(&t, 0, sizeof(t));
@@ -77597,17 +77881,18 @@
7759777881
** it into an integer and return that. If pMem represents an
7759877882
** an SQL-NULL value, return 0.
7759977883
**
7760077884
** If pMem represents a string value, its encoding might be changed.
7760177885
*/
77602
-static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
77886
+static SQLITE_NOINLINE i64 memIntValue(const Mem *pMem){
7760377887
i64 value = 0;
7760477888
sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
7760577889
return value;
7760677890
}
77607
-SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
77891
+SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){
7760877892
int flags;
77893
+ assert( pMem!=0 );
7760977894
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7761077895
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7761177896
flags = pMem->flags;
7761277897
if( flags & (MEM_Int|MEM_IntReal) ){
7761377898
testcase( flags & MEM_IntReal );
@@ -77632,10 +77917,11 @@
7763277917
double val = (double)0;
7763377918
sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
7763477919
return val;
7763577920
}
7763677921
SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
77922
+ assert( pMem!=0 );
7763777923
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7763877924
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7763977925
if( pMem->flags & MEM_Real ){
7764077926
return pMem->u.r;
7764177927
}else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
@@ -77664,10 +77950,11 @@
7766477950
** The MEM structure is already a MEM_Real. Try to also make it a
7766577951
** MEM_Int if we can.
7766677952
*/
7766777953
SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
7766877954
i64 ix;
77955
+ assert( pMem!=0 );
7766977956
assert( pMem->flags & MEM_Real );
7767077957
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7767177958
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7767277959
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7767377960
@@ -77691,10 +77978,11 @@
7769177978
7769277979
/*
7769377980
** Convert pMem to type integer. Invalidate any prior representations.
7769477981
*/
7769577982
SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
77983
+ assert( pMem!=0 );
7769677984
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7769777985
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7769877986
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7769977987
7770077988
pMem->u.i = sqlite3VdbeIntValue(pMem);
@@ -77705,10 +77993,11 @@
7770577993
/*
7770677994
** Convert pMem so that it is of type MEM_Real.
7770777995
** Invalidate any prior representations.
7770877996
*/
7770977997
SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
77998
+ assert( pMem!=0 );
7771077999
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7771178000
assert( EIGHT_BYTE_ALIGNMENT(pMem) );
7771278001
7771378002
pMem->u.r = sqlite3VdbeRealValue(pMem);
7771478003
MemSetTypeFlag(pMem, MEM_Real);
@@ -77738,10 +78027,11 @@
7773878027
** Every effort is made to force the conversion, even if the input
7773978028
** is a string that does not look completely like a number. Convert
7774078029
** as much of the string as we can and ignore the rest.
7774178030
*/
7774278031
SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
78032
+ assert( pMem!=0 );
7774378033
testcase( pMem->flags & MEM_Int );
7774478034
testcase( pMem->flags & MEM_Real );
7774578035
testcase( pMem->flags & MEM_IntReal );
7774678036
testcase( pMem->flags & MEM_Null );
7774778037
if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
@@ -77847,19 +78137,35 @@
7784778137
7784878138
/*
7784978139
** Delete any previous value and set the value to be a BLOB of length
7785078140
** n containing all zeros.
7785178141
*/
78142
+#ifndef SQLITE_OMIT_INCRBLOB
7785278143
SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
7785378144
sqlite3VdbeMemRelease(pMem);
7785478145
pMem->flags = MEM_Blob|MEM_Zero;
7785578146
pMem->n = 0;
7785678147
if( n<0 ) n = 0;
7785778148
pMem->u.nZero = n;
7785878149
pMem->enc = SQLITE_UTF8;
7785978150
pMem->z = 0;
7786078151
}
78152
+#else
78153
+SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78154
+ int nByte = n>0?n:1;
78155
+ if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
78156
+ return SQLITE_NOMEM_BKPT;
78157
+ }
78158
+ assert( pMem->z!=0 );
78159
+ assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte );
78160
+ memset(pMem->z, 0, nByte);
78161
+ pMem->n = n>0?n:0;
78162
+ pMem->flags = MEM_Blob;
78163
+ pMem->enc = SQLITE_UTF8;
78164
+ return SQLITE_OK;
78165
+}
78166
+#endif
7786178167
7786278168
/*
7786378169
** The pMem is known to contain content that needs to be destroyed prior
7786478170
** to a value change. So invoke the destructor, then set the value to
7786578171
** a 64-bit integer.
@@ -78089,10 +78395,11 @@
7808978395
){
7809078396
i64 nByte = n; /* New value for pMem->n */
7809178397
int iLimit; /* Maximum allowed string or blob size */
7809278398
u16 flags = 0; /* New value for pMem->flags */
7809378399
78400
+ assert( pMem!=0 );
7809478401
assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
7809578402
assert( !sqlite3VdbeMemIsRowSet(pMem) );
7809678403
7809778404
/* If z is a NULL pointer, set pMem to contain an SQL NULL. */
7809878405
if( !z ){
@@ -78414,12 +78721,14 @@
7841478721
ExprList *pList = 0; /* Function arguments */
7841578722
int i; /* Iterator variable */
7841678723
7841778724
assert( pCtx!=0 );
7841878725
assert( (p->flags & EP_TokenOnly)==0 );
78726
+ assert( ExprUseXList(p) );
7841978727
pList = p->x.pList;
7842078728
if( pList ) nVal = pList->nExpr;
78729
+ assert( !ExprHasProperty(p, EP_IntValue) );
7842178730
pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
7842278731
assert( pFunc );
7842378732
if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
7842478733
|| (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
7842578734
){
@@ -78519,11 +78828,13 @@
7851978828
** check ensures that an EP_TokenOnly expression is never passed down
7852078829
** into valueFromFunction(). */
7852178830
assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
7852278831
7852378832
if( op==TK_CAST ){
78524
- u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
78833
+ u8 aff;
78834
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
78835
+ aff = sqlite3AffinityType(pExpr->u.zToken,0);
7852578836
rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
7852678837
testcase( rc!=SQLITE_OK );
7852778838
if( *ppVal ){
7852878839
sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
7852978840
sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
@@ -78592,10 +78903,11 @@
7859278903
sqlite3VdbeMemSetNull(pVal);
7859378904
}
7859478905
#ifndef SQLITE_OMIT_BLOB_LITERAL
7859578906
else if( op==TK_BLOB ){
7859678907
int nVal;
78908
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
7859778909
assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
7859878910
assert( pExpr->u.zToken[1]=='\'' );
7859978911
pVal = valueNew(db, pCtx);
7860078912
if( !pVal ) goto no_mem;
7860178913
zVal = &pExpr->u.zToken[2];
@@ -78609,10 +78921,11 @@
7860978921
else if( op==TK_FUNCTION && pCtx!=0 ){
7861078922
rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
7861178923
}
7861278924
#endif
7861378925
else if( op==TK_TRUEFALSE ){
78926
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
7861478927
pVal = valueNew(db, pCtx);
7861578928
if( pVal ){
7861678929
pVal->flags = MEM_Int;
7861778930
pVal->u.i = pExpr->u.zToken[4]==0;
7861878931
}
@@ -79162,12 +79475,14 @@
7916279475
assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
7916379476
assert( op>=0 && op<0xff );
7916479477
if( p->nOpAlloc<=i ){
7916579478
return growOp3(p, op, p1, p2, p3);
7916679479
}
79480
+ assert( p->aOp!=0 );
7916779481
p->nOp++;
7916879482
pOp = &p->aOp[i];
79483
+ assert( pOp!=0 );
7916979484
pOp->opcode = (u8)op;
7917079485
pOp->p5 = 0;
7917179486
pOp->p1 = p1;
7917279487
pOp->p2 = p2;
7917379488
pOp->p3 = p3;
@@ -80406,11 +80721,11 @@
8040680721
zOpName = sqlite3OpcodeName(pOp->opcode);
8040780722
nOpName = sqlite3Strlen30(zOpName);
8040880723
if( zOpName[nOpName+1] ){
8040980724
int seenCom = 0;
8041080725
char c;
80411
- zSynopsis = zOpName += nOpName + 1;
80726
+ zSynopsis = zOpName + nOpName + 1;
8041280727
if( strncmp(zSynopsis,"IF ",3)==0 ){
8041380728
sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
8041480729
zSynopsis = zAlt;
8041580730
}
8041680731
for(ii=0; (c = zSynopsis[ii])!=0; ii++){
@@ -80479,10 +80794,11 @@
8047980794
*/
8048080795
static void displayP4Expr(StrAccum *p, Expr *pExpr){
8048180796
const char *zOp = 0;
8048280797
switch( pExpr->op ){
8048380798
case TK_STRING:
80799
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
8048480800
sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
8048580801
break;
8048680802
case TK_INTEGER:
8048780803
sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
8048880804
break;
@@ -80825,12 +81141,12 @@
8082581141
** with no indexes using a single prepared INSERT statement, bind()
8082681142
** and reset(). Inserts are grouped into a transaction.
8082781143
*/
8082881144
testcase( p->flags & MEM_Agg );
8082981145
testcase( p->flags & MEM_Dyn );
80830
- testcase( p->xDel==sqlite3VdbeFrameMemDel );
8083181146
if( p->flags&(MEM_Agg|MEM_Dyn) ){
81147
+ testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
8083281148
sqlite3VdbeMemRelease(p);
8083381149
}else if( p->szMalloc ){
8083481150
sqlite3DbFreeNN(db, p->zMalloc);
8083581151
p->szMalloc = 0;
8083681152
}
@@ -81974,13 +82290,19 @@
8197482290
8197582291
/* Lock all btrees used by the statement */
8197682292
sqlite3VdbeEnter(p);
8197782293
8197882294
/* Check for one of the special errors */
81979
- mrc = p->rc & 0xff;
81980
- isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
81981
- || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
82295
+ if( p->rc ){
82296
+ mrc = p->rc & 0xff;
82297
+ isSpecialError = mrc==SQLITE_NOMEM
82298
+ || mrc==SQLITE_IOERR
82299
+ || mrc==SQLITE_INTERRUPT
82300
+ || mrc==SQLITE_FULL;
82301
+ }else{
82302
+ mrc = isSpecialError = 0;
82303
+ }
8198282304
if( isSpecialError ){
8198382305
/* If the query was read-only and the error code is SQLITE_INTERRUPT,
8198482306
** no rollback is necessary. Otherwise, at least a savepoint
8198582307
** transaction must be rolled back to restore the database to a
8198682308
** consistent state.
@@ -82028,10 +82350,13 @@
8202882350
if( NEVER(p->readOnly) ){
8202982351
sqlite3VdbeLeave(p);
8203082352
return SQLITE_ERROR;
8203182353
}
8203282354
rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82355
+ }else if( db->flags & SQLITE_CorruptRdOnly ){
82356
+ rc = SQLITE_CORRUPT;
82357
+ db->flags &= ~SQLITE_CorruptRdOnly;
8203382358
}else{
8203482359
/* The auto-commit flag is true, the vdbe program was successful
8203582360
** or hit an 'OR FAIL' constraint and there are no deferred foreign
8203682361
** key constraints to hold up the transaction. This means a commit
8203782362
** is required. */
@@ -84132,10 +84457,12 @@
8413284457
}else{
8413384458
iKey2 = iKey1;
8413484459
}
8413584460
}
8413684461
84462
+ assert( pCsr!=0 );
84463
+ assert( pCsr->eCurType==CURTYPE_BTREE );
8413784464
assert( pCsr->nField==pTab->nCol
8413884465
|| (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
8413984466
);
8414084467
8414184468
preupdate.v = v;
@@ -84531,12 +84858,12 @@
8453184858
/**************************** sqlite3_result_ *******************************
8453284859
** The following routines are used by user-defined functions to specify
8453384860
** the function result.
8453484861
**
8453584862
** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the
84536
-** result as a string or blob but if the string or blob is too large, it
84537
-** then sets the error code to SQLITE_TOOBIG
84863
+** result as a string or blob. Appropriate errors are set if the string/blob
84864
+** is too big or if an OOM occurs.
8453884865
**
8453984866
** The invokeValueDestructor(P,X) routine invokes destructor function X()
8454084867
** on value P is not going to be used and need to be destroyed.
8454184868
*/
8454284869
static void setResultStrOrError(
@@ -84544,12 +84871,20 @@
8454484871
const char *z, /* String pointer */
8454584872
int n, /* Bytes in string, or negative */
8454684873
u8 enc, /* Encoding of z. 0 for BLOBs */
8454784874
void (*xDel)(void*) /* Destructor function */
8454884875
){
84549
- if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){
84550
- sqlite3_result_error_toobig(pCtx);
84876
+ int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel);
84877
+ if( rc ){
84878
+ if( rc==SQLITE_TOOBIG ){
84879
+ sqlite3_result_error_toobig(pCtx);
84880
+ }else{
84881
+ /* The only errors possible from sqlite3VdbeMemSetStr are
84882
+ ** SQLITE_TOOBIG and SQLITE_NOMEM */
84883
+ assert( rc==SQLITE_NOMEM );
84884
+ sqlite3_result_error_nomem(pCtx);
84885
+ }
8455184886
}
8455284887
}
8455384888
static int invokeValueDestructor(
8455484889
const void *p, /* Value to destroy */
8455584890
void (*xDel)(void*), /* The destructor */
@@ -84702,12 +85037,16 @@
8470285037
Mem *pOut = pCtx->pOut;
8470385038
assert( sqlite3_mutex_held(pOut->db->mutex) );
8470485039
if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
8470585040
return SQLITE_TOOBIG;
8470685041
}
85042
+#ifndef SQLITE_OMIT_INCRBLOB
8470785043
sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
8470885044
return SQLITE_OK;
85045
+#else
85046
+ return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
85047
+#endif
8470985048
}
8471085049
SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
8471185050
pCtx->isError = errCode ? errCode : -1;
8471285051
#ifdef SQLITE_DEBUG
8471385052
if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85715,11 +86054,15 @@
8571586054
SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
8571686055
int rc;
8571786056
Vdbe *p = (Vdbe *)pStmt;
8571886057
rc = vdbeUnbind(p, i);
8571986058
if( rc==SQLITE_OK ){
86059
+#ifndef SQLITE_OMIT_INCRBLOB
8572086060
sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
86061
+#else
86062
+ rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
86063
+#endif
8572186064
sqlite3_mutex_leave(p->db->mutex);
8572286065
}
8572386066
return rc;
8572486067
}
8572586068
SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86003,10 +86346,11 @@
8600386346
/* If the old.* record has not yet been loaded into memory, do so now. */
8600486347
if( p->pUnpacked==0 ){
8600586348
u32 nRec;
8600686349
u8 *aRec;
8600786350
86351
+ assert( p->pCsr->eCurType==CURTYPE_BTREE );
8600886352
nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
8600986353
aRec = sqlite3DbMallocRaw(db, nRec);
8601086354
if( !aRec ) goto preupdate_old_out;
8601186355
rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
8601286356
if( rc==SQLITE_OK ){
@@ -87091,10 +87435,35 @@
8709187435
}else{
8709287436
pOut->flags = MEM_Int;
8709387437
return pOut;
8709487438
}
8709587439
}
87440
+
87441
+/*
87442
+** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning
87443
+** with pOp->p3. Return the hash.
87444
+*/
87445
+static u64 filterHash(const Mem *aMem, const Op *pOp){
87446
+ int i, mx;
87447
+ u64 h = 0;
87448
+
87449
+ i = pOp->p3;
87450
+ assert( pOp->p4type==P4_INT32 );
87451
+ mx = i + pOp->p4.i;
87452
+ for(i=pOp->p3, mx=i+pOp->p4.i; i<mx; i++){
87453
+ const Mem *p = &aMem[i];
87454
+ if( p->flags & (MEM_Int|MEM_IntReal) ){
87455
+ h += p->u.i;
87456
+ }else if( p->flags & MEM_Real ){
87457
+ h += sqlite3VdbeIntValue(p);
87458
+ }else if( p->flags & (MEM_Str|MEM_Blob) ){
87459
+ h += p->n;
87460
+ if( p->flags & MEM_Zero ) h += p->u.nZero;
87461
+ }
87462
+ }
87463
+ return h;
87464
+}
8709687465
8709787466
/*
8709887467
** Return the symbolic name for the data type of a pMem
8709987468
*/
8710087469
static const char *vdbeMemTypeName(Mem *pMem){
@@ -87746,16 +88115,22 @@
8774688115
8774788116
/* Opcode: Blob P1 P2 * P4 *
8774888117
** Synopsis: r[P2]=P4 (len=P1)
8774988118
**
8775088119
** P4 points to a blob of data P1 bytes long. Store this
87751
-** blob in register P2.
88120
+** blob in register P2. If P4 is a NULL pointer, then construct
88121
+** a zero-filled blob that is P1 bytes long in P2.
8775288122
*/
8775388123
case OP_Blob: { /* out2 */
8775488124
assert( pOp->p1 <= SQLITE_MAX_LENGTH );
8775588125
pOut = out2Prerelease(p, pOp);
87756
- sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
88126
+ if( pOp->p4.z==0 ){
88127
+ sqlite3VdbeMemSetZeroBlob(pOut, pOp->p1);
88128
+ if( sqlite3VdbeMemExpandBlob(pOut) ) goto no_mem;
88129
+ }else{
88130
+ sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
88131
+ }
8775788132
pOut->enc = encoding;
8775888133
UPDATE_MAX_BLOBSIZE(pOut);
8775988134
break;
8776088135
}
8776188136
@@ -87900,28 +88275,26 @@
8790088275
pOut = &aMem[pOp->p2];
8790188276
sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
8790288277
break;
8790388278
}
8790488279
87905
-/* Opcode: ChngCntRow P1 P2 * * *
87906
-** Synopsis: output=r[P1]
87907
-**
87908
-** Output value in register P1 as the chance count for a DML statement,
87909
-** due to the "PRAGMA count_changes=ON" setting. Or, if there was a
87910
-** foreign key error in the statement, trigger the error now.
87911
-**
87912
-** This opcode is a variant of OP_ResultRow that checks the foreign key
87913
-** immediate constraint count and throws an error if the count is
87914
-** non-zero. The P2 opcode must be 1.
87915
-*/
87916
-case OP_ChngCntRow: {
87917
- assert( pOp->p2==1 );
88280
+/* Opcode: FkCheck * * * * *
88281
+**
88282
+** Halt with an SQLITE_CONSTRAINT error if there are any unresolved
88283
+** foreign key constraint violations. If there are no foreign key
88284
+** constraint violations, this is a no-op.
88285
+**
88286
+** FK constraint violations are also checked when the prepared statement
88287
+** exits. This opcode is used to raise foreign key constraint errors prior
88288
+** to returning results such as a row change count or the result of a
88289
+** RETURNING clause.
88290
+*/
88291
+case OP_FkCheck: {
8791888292
if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
8791988293
goto abort_due_to_error;
8792088294
}
87921
- /* Fall through to the next case, OP_ResultRow */
87922
- /* no break */ deliberate_fall_through
88295
+ break;
8792388296
}
8792488297
8792588298
/* Opcode: ResultRow P1 P2 * * *
8792688299
** Synopsis: output=r[P1@P2]
8792788300
**
@@ -89320,20 +89693,25 @@
8932089693
rc = SQLITE_CORRUPT_BKPT;
8932189694
goto abort_due_to_error;
8932289695
}
8932389696
}
8932489697
89325
-/* Opcode: TypeCheck P1 P2 * P4 *
89698
+/* Opcode: TypeCheck P1 P2 P3 P4 *
8932689699
** Synopsis: typecheck(r[P1@P2])
8932789700
**
8932889701
** Apply affinities to the range of P2 registers beginning with P1.
8932989702
** Take the affinities from the Table object in P4. If any value
8933089703
** cannot be coerced into the correct type, then raise an error.
8933189704
**
8933289705
** This opcode is similar to OP_Affinity except that this opcode
8933389706
** forces the register type to the Table column type. This is used
8933489707
** to implement "strict affinity".
89708
+**
89709
+** GENERATED ALWAYS AS ... STATIC columns are only checked if P3
89710
+** is zero. When P3 is non-zero, no type checking occurs for
89711
+** static generated columns. Virtual columns are computed at query time
89712
+** and so they are never checked.
8933589713
**
8933689714
** Preconditions:
8933789715
**
8933889716
** <ul>
8933989717
** <li> P2 should be the number of non-virtual columns in the
@@ -89353,11 +89731,14 @@
8935389731
assert( pTab->tabFlags & TF_Strict );
8935489732
assert( pTab->nNVCol==pOp->p2 );
8935589733
aCol = pTab->aCol;
8935689734
pIn1 = &aMem[pOp->p1];
8935789735
for(i=0; i<pTab->nCol; i++){
89358
- if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
89736
+ if( aCol[i].colFlags & COLFLAG_GENERATED ){
89737
+ if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
89738
+ if( pOp->p3 ){ pIn1++; continue; }
89739
+ }
8935989740
assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
8936089741
applyAffinity(pIn1, aCol[i].affinity, encoding);
8936189742
if( (pIn1->flags & MEM_Null)==0 ){
8936289743
switch( aCol[i].eCType ){
8936389744
case COLTYPE_BLOB: {
@@ -89756,11 +90137,11 @@
8975690137
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
8975790138
REGISTER_TRACE(pOp->p3, pOut);
8975890139
break;
8975990140
}
8976090141
89761
-/* Opcode: Count P1 P2 p3 * *
90142
+/* Opcode: Count P1 P2 P3 * *
8976290143
** Synopsis: r[P2]=count()
8976390144
**
8976490145
** Store the number of entries (an integer value) in the table or index
8976590146
** opened by cursor P1 in register P2.
8976690147
**
@@ -90077,12 +90458,20 @@
9007790458
assert( p->bIsReader );
9007890459
assert( p->readOnly==0 || pOp->p2==0 );
9007990460
assert( pOp->p2>=0 && pOp->p2<=2 );
9008090461
assert( pOp->p1>=0 && pOp->p1<db->nDb );
9008190462
assert( DbMaskTest(p->btreeMask, pOp->p1) );
90082
- if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
90083
- rc = SQLITE_READONLY;
90463
+ assert( rc==SQLITE_OK );
90464
+ if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){
90465
+ if( db->flags & SQLITE_QueryOnly ){
90466
+ /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */
90467
+ rc = SQLITE_READONLY;
90468
+ }else{
90469
+ /* Writes prohibited due to a prior SQLITE_CORRUPT in the current
90470
+ ** transaction */
90471
+ rc = SQLITE_CORRUPT;
90472
+ }
9008490473
goto abort_due_to_error;
9008590474
}
9008690475
pBt = db->aDb[pOp->p1].pBt;
9008790476
9008890477
if( pBt ){
@@ -90120,11 +90509,12 @@
9012090509
p->nStmtDefCons = db->nDeferredCons;
9012190510
p->nStmtDefImmCons = db->nDeferredImmCons;
9012290511
}
9012390512
}
9012490513
assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
90125
- if( pOp->p5
90514
+ if( rc==SQLITE_OK
90515
+ && pOp->p5
9012690516
&& (iMeta!=pOp->p3
9012790517
|| db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
9012890518
){
9012990519
/*
9013090520
** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -90514,11 +90904,11 @@
9051490904
assert( aMem[pOp->p3].flags & MEM_Null );
9051590905
aMem[pOp->p3].n = 0;
9051690906
aMem[pOp->p3].z = "";
9051790907
}
9051890908
pCx = p->apCsr[pOp->p1];
90519
- if( pCx && !pCx->hasBeenDuped ){
90909
+ if( pCx && !pCx->hasBeenDuped && ALWAYS(pOp->p2<=pCx->nField) ){
9052090910
/* If the ephermeral table is already open and has no duplicates from
9052190911
** OP_OpenDup, then erase all existing content so that the table is
9052290912
** empty again, rather than creating a new table. */
9052390913
assert( pCx->isEphemeral );
9052490914
pCx->seqCount = 0;
@@ -91677,11 +92067,11 @@
9167792067
zDb = db->aDb[pC->iDb].zDbSName;
9167892068
pTab = pOp->p4.pTab;
9167992069
assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
9168092070
}else{
9168192071
pTab = 0;
91682
- zDb = 0; /* Not needed. Silence a compiler warning. */
92072
+ zDb = 0;
9168392073
}
9168492074
9168592075
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
9168692076
/* Invoke the pre-update hook, if any */
9168792077
if( pTab ){
@@ -91830,17 +92220,18 @@
9183092220
pTab = pOp->p4.pTab;
9183192221
if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
9183292222
pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
9183392223
}
9183492224
}else{
91835
- zDb = 0; /* Not needed. Silence a compiler warning. */
91836
- pTab = 0; /* Not needed. Silence a compiler warning. */
92225
+ zDb = 0;
92226
+ pTab = 0;
9183792227
}
9183892228
9183992229
#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
9184092230
/* Invoke the pre-update-hook if required. */
91841
- if( db->xPreUpdateCallback && pOp->p4.pTab ){
92231
+ assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab );
92232
+ if( db->xPreUpdateCallback && pTab ){
9184292233
assert( !(opflags & OPFLAG_ISUPDATE)
9184392234
|| HasRowid(pTab)==0
9184492235
|| (aMem[pOp->p3].flags & MEM_Int)
9184592236
);
9184692237
sqlite3VdbePreUpdateHook(p, pC,
@@ -91877,11 +92268,11 @@
9187792268
if( rc ) goto abort_due_to_error;
9187892269
9187992270
/* Invoke the update-hook if required. */
9188092271
if( opflags & OPFLAG_NCHANGE ){
9188192272
p->nChange++;
91882
- if( db->xUpdateCallback && HasRowid(pTab) ){
92273
+ if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){
9188392274
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
9188492275
pC->movetoTarget);
9188592276
assert( pC->iDb>=0 );
9188692277
}
9188792278
}
@@ -92925,11 +93316,11 @@
9292593316
db->mDbFlags |= DBFLAG_SchemaChange;
9292693317
p->expired = 0;
9292793318
}else
9292893319
#endif
9292993320
{
92930
- zSchema = DFLT_SCHEMA_TABLE;
93321
+ zSchema = LEGACY_SCHEMA_TABLE;
9293193322
initData.db = db;
9293293323
initData.iDb = iDb;
9293393324
initData.pzErrMsg = &p->zErrMsg;
9293493325
initData.mInitFlags = 0;
9293593326
initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
@@ -94145,10 +94536,11 @@
9414594536
pQuery = &aMem[pOp->p3];
9414694537
pArgc = &pQuery[1];
9414794538
pCur = p->apCsr[pOp->p1];
9414894539
assert( memIsValid(pQuery) );
9414994540
REGISTER_TRACE(pOp->p3, pQuery);
94541
+ assert( pCur!=0 );
9415094542
assert( pCur->eCurType==CURTYPE_VTAB );
9415194543
pVCur = pCur->uc.pVCur;
9415294544
pVtab = pVCur->pVtab;
9415394545
pModule = pVtab->pModule;
9415494546
@@ -94193,10 +94585,11 @@
9419394585
const sqlite3_module *pModule;
9419494586
Mem *pDest;
9419594587
sqlite3_context sContext;
9419694588
9419794589
VdbeCursor *pCur = p->apCsr[pOp->p1];
94590
+ assert( pCur!=0 );
9419894591
assert( pCur->eCurType==CURTYPE_VTAB );
9419994592
assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
9420094593
pDest = &aMem[pOp->p3];
9420194594
memAboutToChange(p, pDest);
9420294595
if( pCur->nullRow ){
@@ -94246,10 +94639,11 @@
9424694639
const sqlite3_module *pModule;
9424794640
int res;
9424894641
VdbeCursor *pCur;
9424994642
9425094643
pCur = p->apCsr[pOp->p1];
94644
+ assert( pCur!=0 );
9425194645
assert( pCur->eCurType==CURTYPE_VTAB );
9425294646
if( pCur->nullRow ){
9425394647
break;
9425494648
}
9425594649
pVtab = pCur->uc.pVCur->pVtab;
@@ -94341,11 +94735,11 @@
9434194735
case OP_VUpdate: {
9434294736
sqlite3_vtab *pVtab;
9434394737
const sqlite3_module *pModule;
9434494738
int nArg;
9434594739
int i;
94346
- sqlite_int64 rowid;
94740
+ sqlite_int64 rowid = 0;
9434794741
Mem **apArg;
9434894742
Mem *pX;
9434994743
9435094744
assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
9435194745
|| pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -94528,10 +94922,81 @@
9452894922
9452994923
REGISTER_TRACE(pOp->p3, pOut);
9453094924
UPDATE_MAX_BLOBSIZE(pOut);
9453194925
break;
9453294926
}
94927
+
94928
+/* Opcode: FilterAdd P1 * P3 P4 *
94929
+** Synopsis: filter(P1) += key(P3@P4)
94930
+**
94931
+** Compute a hash on the P4 registers starting with r[P3] and
94932
+** add that hash to the bloom filter contained in r[P1].
94933
+*/
94934
+case OP_FilterAdd: {
94935
+ u64 h;
94936
+
94937
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
94938
+ pIn1 = &aMem[pOp->p1];
94939
+ assert( pIn1->flags & MEM_Blob );
94940
+ assert( pIn1->n>0 );
94941
+ h = filterHash(aMem, pOp);
94942
+#ifdef SQLITE_DEBUG
94943
+ if( db->flags&SQLITE_VdbeTrace ){
94944
+ int ii;
94945
+ for(ii=pOp->p3; ii<pOp->p3+pOp->p4.i; ii++){
94946
+ registerTrace(ii, &aMem[ii]);
94947
+ }
94948
+ printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n));
94949
+ }
94950
+#endif
94951
+ h %= pIn1->n;
94952
+ pIn1->z[h/8] |= 1<<(h&7);
94953
+ break;
94954
+}
94955
+
94956
+/* Opcode: Filter P1 P2 P3 P4 *
94957
+** Synopsis: if key(P3@P4) not in filter(P1) goto P2
94958
+**
94959
+** Compute a hash on the key contained in the P4 registers starting
94960
+** with r[P3]. Check to see if that hash is found in the
94961
+** bloom filter hosted by register P1. If it is not present then
94962
+** maybe jump to P2. Otherwise fall through.
94963
+**
94964
+** False negatives are harmless. It is always safe to fall through,
94965
+** even if the value is in the bloom filter. A false negative causes
94966
+** more CPU cycles to be used, but it should still yield the correct
94967
+** answer. However, an incorrect answer may well arise from a
94968
+** false positive - if the jump is taken when it should fall through.
94969
+*/
94970
+case OP_Filter: { /* jump */
94971
+ u64 h;
94972
+
94973
+ assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
94974
+ pIn1 = &aMem[pOp->p1];
94975
+ assert( (pIn1->flags & MEM_Blob)!=0 );
94976
+ assert( pIn1->n >= 1 );
94977
+ h = filterHash(aMem, pOp);
94978
+#ifdef SQLITE_DEBUG
94979
+ if( db->flags&SQLITE_VdbeTrace ){
94980
+ int ii;
94981
+ for(ii=pOp->p3; ii<pOp->p3+pOp->p4.i; ii++){
94982
+ registerTrace(ii, &aMem[ii]);
94983
+ }
94984
+ printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n));
94985
+ }
94986
+#endif
94987
+ h %= pIn1->n;
94988
+ if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){
94989
+ VdbeBranchTaken(1, 2);
94990
+ p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++;
94991
+ goto jump_to_p2;
94992
+ }else{
94993
+ p->aCounter[SQLITE_STMTSTATUS_FILTER_MISS]++;
94994
+ VdbeBranchTaken(0, 2);
94995
+ }
94996
+ break;
94997
+}
9453394998
9453494999
/* Opcode: Trace P1 P2 * P4 *
9453595000
**
9453695001
** Write P4 on the statement trace output if statement tracing is
9453795002
** enabled.
@@ -94788,11 +95253,18 @@
9478895253
rc = SQLITE_CORRUPT_BKPT;
9478995254
}
9479095255
assert( rc );
9479195256
#ifdef SQLITE_DEBUG
9479295257
if( db->flags & SQLITE_VdbeTrace ){
94793
- printf("ABORT-due-to-error. rc=%d\n", rc);
95258
+ const char *zTrace = p->zSql;
95259
+ if( zTrace==0 ){
95260
+ if( aOp[0].opcode==OP_Trace ){
95261
+ zTrace = aOp[0].p4.z;
95262
+ }
95263
+ if( zTrace==0 ) zTrace = "???";
95264
+ }
95265
+ printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace);
9479495266
}
9479595267
#endif
9479695268
if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
9479795269
sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
9479895270
}
@@ -94801,10 +95273,13 @@
9480195273
testcase( sqlite3GlobalConfig.xLog!=0 );
9480295274
sqlite3_log(rc, "statement aborts at %d: [%s] %s",
9480395275
(int)(pOp - aOp), p->zSql, p->zErrMsg);
9480495276
sqlite3VdbeHalt(p);
9480595277
if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
95278
+ if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
95279
+ db->flags |= SQLITE_CorruptRdOnly;
95280
+ }
9480695281
rc = SQLITE_ERROR;
9480795282
if( resetSchemaOnFault>0 ){
9480895283
sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
9480995284
}
9481095285
@@ -94932,11 +95407,14 @@
9493295407
}else{
9493395408
rc = sqlite3_step(p->pStmt);
9493495409
}
9493595410
if( rc==SQLITE_ROW ){
9493695411
VdbeCursor *pC = v->apCsr[0];
94937
- u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
95412
+ u32 type;
95413
+ assert( pC!=0 );
95414
+ assert( pC->eCurType==CURTYPE_BTREE );
95415
+ type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
9493895416
testcase( pC->nHdrParsed==p->iCol );
9493995417
testcase( pC->nHdrParsed==p->iCol+1 );
9494095418
if( type<12 ){
9494195419
zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
9494295420
type==0?"null": type==7?"real": "integer"
@@ -95069,11 +95547,11 @@
9506995547
/* Check that the column is not part of an FK child key definition. It
9507095548
** is not necessary to check if it is part of a parent key, as parent
9507195549
** key columns must be indexed. The check below will pick up this
9507295550
** case. */
9507395551
FKey *pFKey;
95074
- assert( !IsVirtual(pTab) );
95552
+ assert( IsOrdinaryTable(pTab) );
9507595553
for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
9507695554
int j;
9507795555
for(j=0; j<pFKey->nCol; j++){
9507895556
if( pFKey->aCol[j].iFrom==iCol ){
9507995557
zFault = "foreign key";
@@ -95277,10 +95755,12 @@
9527795755
** using the incremental-blob API, this works. For the sessions module
9527895756
** anyhow.
9527995757
*/
9528095758
sqlite3_int64 iKey;
9528195759
iKey = sqlite3BtreeIntegerKey(p->pCsr);
95760
+ assert( v->apCsr[0]!=0 );
95761
+ assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
9528295762
sqlite3VdbePreUpdateHook(
9528395763
v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
9528495764
);
9528595765
}
9528695766
#endif
@@ -96659,11 +97139,11 @@
9665997139
void *p = 0;
9666097140
int chunksize = 4*1024;
9666197141
sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
9666297142
sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
9666397143
sqlite3OsFetch(pFd, 0, (int)nByte, &p);
96664
- sqlite3OsUnfetch(pFd, 0, p);
97144
+ if( p ) sqlite3OsUnfetch(pFd, 0, p);
9666597145
}
9666697146
}
9666797147
#else
9666897148
# define vdbeSorterExtendFile(x,y,z)
9666997149
#endif
@@ -97377,10 +97857,11 @@
9737797857
pTask->file2.iEof += pIncr->mxSz;
9737897858
}else{
9737997859
vdbeMergeEngineFree(pMerger);
9738097860
rc = SQLITE_NOMEM_BKPT;
9738197861
}
97862
+ assert( *ppOut!=0 || rc!=SQLITE_OK );
9738297863
return rc;
9738397864
}
9738497865
9738597866
#if SQLITE_MAX_WORKER_THREADS>0
9738697867
/*
@@ -99078,11 +99559,11 @@
9907899559
if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
9907999560
if( pExpr->pRight ){
9908099561
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
9908199562
pExpr = pExpr->pRight;
9908299563
continue;
99083
- }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
99564
+ }else if( ExprUseXSelect(pExpr) ){
9908499565
assert( !ExprHasProperty(pExpr, EP_WinFunc) );
9908599566
if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
9908699567
}else{
9908799568
if( pExpr->x.pList ){
9908899569
if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
@@ -99350,10 +99831,11 @@
9935099831
sqlite3ExprDelete(db, pDup);
9935199832
pDup = 0;
9935299833
}else{
9935399834
incrAggFunctionDepth(pDup, nSubquery);
9935499835
if( pExpr->op==TK_COLLATE ){
99836
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
9935599837
pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
9935699838
}
9935799839
9935899840
/* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
9935999841
** prevents ExprDelete() from deleting the Expr structure itself,
@@ -99453,10 +99935,11 @@
9945399935
SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){
9945499936
int n;
9945599937
Table *pExTab;
9945699938
9945799939
n = pExpr->iColumn;
99940
+ assert( ExprUseYTab(pExpr) );
9945899941
pExTab = pExpr->y.pTab;
9945999942
assert( pExTab!=0 );
9946099943
if( (pExTab->tabFlags & TF_HasGenerated)!=0
9946199944
&& (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
9946299945
){
@@ -99590,10 +100073,11 @@
99590100073
const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
99591100074
assert( zTabName!=0 );
99592100075
if( sqlite3StrICmp(zTabName, zTab)!=0 ){
99593100076
continue;
99594100077
}
100078
+ assert( ExprUseYTab(pExpr) );
99595100079
if( IN_RENAME_OBJECT && pItem->zAlias ){
99596100080
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
99597100081
}
99598100082
}
99599100083
hCol = sqlite3StrIHash(zCol);
@@ -99621,10 +100105,11 @@
99621100105
pMatch = pItem;
99622100106
}
99623100107
}
99624100108
if( pMatch ){
99625100109
pExpr->iTable = pMatch->iCursor;
100110
+ assert( ExprUseYTab(pExpr) );
99626100111
pExpr->y.pTab = pMatch->pTab;
99627100112
/* RIGHT JOIN not (yet) supported */
99628100113
assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
99629100114
if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
99630100115
ExprSetProperty(pExpr, EP_CanBeNull);
@@ -99694,10 +100179,11 @@
99694100179
cnt++;
99695100180
pMatch = 0;
99696100181
#ifndef SQLITE_OMIT_UPSERT
99697100182
if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
99698100183
testcase( iCol==(-1) );
100184
+ assert( ExprUseYTab(pExpr) );
99699100185
if( IN_RENAME_OBJECT ){
99700100186
pExpr->iColumn = iCol;
99701100187
pExpr->y.pTab = pTab;
99702100188
eNewExprOp = TK_COLUMN;
99703100189
}else{
@@ -99706,10 +100192,11 @@
99706100192
eNewExprOp = TK_REGISTER;
99707100193
}
99708100194
}else
99709100195
#endif /* SQLITE_OMIT_UPSERT */
99710100196
{
100197
+ assert( ExprUseYTab(pExpr) );
99711100198
pExpr->y.pTab = pTab;
99712100199
if( pParse->bReturning ){
99713100200
eNewExprOp = TK_REGISTER;
99714100201
pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
99715100202
sqlite3TableColumnToStorage(pTab, iCol) + 1;
@@ -99780,12 +100267,12 @@
99780100267
if( pEList->a[j].eEName==ENAME_NAME
99781100268
&& sqlite3_stricmp(zAs, zCol)==0
99782100269
){
99783100270
Expr *pOrig;
99784100271
assert( pExpr->pLeft==0 && pExpr->pRight==0 );
99785
- assert( pExpr->x.pList==0 );
99786
- assert( pExpr->x.pSelect==0 );
100272
+ assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 );
100273
+ assert( ExprUseXSelect(pExpr)==0 || pExpr->x.pSelect==0 );
99787100274
pOrig = pEList->a[j].pExpr;
99788100275
if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
99789100276
sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
99790100277
return WRC_Abort;
99791100278
}
@@ -99853,11 +100340,11 @@
99853100340
"double-quoted string literal: \"%w\"", zCol);
99854100341
#ifdef SQLITE_ENABLE_NORMALIZE
99855100342
sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
99856100343
#endif
99857100344
pExpr->op = TK_STRING;
99858
- pExpr->y.pTab = 0;
100345
+ memset(&pExpr->y, 0, sizeof(pExpr->y));
99859100346
return WRC_Prune;
99860100347
}
99861100348
if( sqlite3ExprIdToTrueFalse(pExpr) ){
99862100349
return WRC_Prune;
99863100350
}
@@ -99939,11 +100426,13 @@
99939100426
*/
99940100427
SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
99941100428
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
99942100429
if( p ){
99943100430
SrcItem *pItem = &pSrc->a[iSrc];
99944
- Table *pTab = p->y.pTab = pItem->pTab;
100431
+ Table *pTab;
100432
+ assert( ExprUseYTab(p) );
100433
+ pTab = p->y.pTab = pItem->pTab;
99945100434
p->iTable = pItem->iCursor;
99946100435
if( p->y.pTab->iPKey==iCol ){
99947100436
p->iColumn = -1;
99948100437
}else{
99949100438
p->iColumn = (ynVar)iCol;
@@ -100006,10 +100495,11 @@
100006100495
** value between 1.0 and 0.0.
100007100496
*/
100008100497
static int exprProbability(Expr *p){
100009100498
double r = -1.0;
100010100499
if( p->op!=TK_FLOAT ) return -1;
100500
+ assert( !ExprHasProperty(p, EP_IntValue) );
100011100501
sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
100012100502
assert( r>=0.0 );
100013100503
if( r>1.0 ) return -1;
100014100504
return (int)(r*134217728.0);
100015100505
}
@@ -100054,10 +100544,11 @@
100054100544
SrcList *pSrcList = pNC->pSrcList;
100055100545
SrcItem *pItem;
100056100546
assert( pSrcList && pSrcList->nSrc>=1 );
100057100547
pItem = pSrcList->a;
100058100548
pExpr->op = TK_COLUMN;
100549
+ assert( ExprUseYTab(pExpr) );
100059100550
pExpr->y.pTab = pItem->pTab;
100060100551
pExpr->iTable = pItem->iCursor;
100061100552
pExpr->iColumn--;
100062100553
pExpr->affExpr = SQLITE_AFF_INTEGER;
100063100554
break;
@@ -100086,10 +100577,11 @@
100086100577
anRef[i] = p->nRef;
100087100578
}
100088100579
sqlite3WalkExpr(pWalker, pExpr->pLeft);
100089100580
if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
100090100581
testcase( ExprHasProperty(pExpr, EP_FromJoin) );
100582
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
100091100583
if( pExpr->op==TK_NOTNULL ){
100092100584
pExpr->u.zToken = "true";
100093100585
ExprSetProperty(pExpr, EP_IsTrue);
100094100586
}else{
100095100587
pExpr->u.zToken = "false";
@@ -100121,10 +100613,11 @@
100121100613
Expr *pRight;
100122100614
100123100615
if( pExpr->op==TK_ID ){
100124100616
zDb = 0;
100125100617
zTable = 0;
100618
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
100126100619
zColumn = pExpr->u.zToken;
100127100620
}else{
100128100621
Expr *pLeft = pExpr->pLeft;
100129100622
testcase( pNC->ncFlags & NC_IdxExpr );
100130100623
testcase( pNC->ncFlags & NC_GenCol );
@@ -100133,16 +100626,19 @@
100133100626
pRight = pExpr->pRight;
100134100627
if( pRight->op==TK_ID ){
100135100628
zDb = 0;
100136100629
}else{
100137100630
assert( pRight->op==TK_DOT );
100631
+ assert( !ExprHasProperty(pRight, EP_IntValue) );
100138100632
zDb = pLeft->u.zToken;
100139100633
pLeft = pRight->pLeft;
100140100634
pRight = pRight->pRight;
100141100635
}
100636
+ assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) );
100142100637
zTable = pLeft->u.zToken;
100143100638
zColumn = pRight->u.zToken;
100639
+ assert( ExprUseYTab(pExpr) );
100144100640
if( IN_RENAME_OBJECT ){
100145100641
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
100146100642
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
100147100643
}
100148100644
}
@@ -100163,11 +100659,11 @@
100163100659
u8 enc = ENC(pParse->db); /* The database encoding */
100164100660
int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100165100661
#ifndef SQLITE_OMIT_WINDOWFUNC
100166100662
Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100167100663
#endif
100168
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
100664
+ assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
100169100665
zId = pExpr->u.zToken;
100170100666
nId = sqlite3Strlen30(zId);
100171100667
pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100172100668
if( pDef==0 ){
100173100669
pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
@@ -100327,11 +100823,11 @@
100327100823
sqlite3WalkExprList(pWalker, pList);
100328100824
if( is_agg ){
100329100825
#ifndef SQLITE_OMIT_WINDOWFUNC
100330100826
if( pWin ){
100331100827
Select *pSel = pNC->pWinSelect;
100332
- assert( pWin==pExpr->y.pWin );
100828
+ assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
100333100829
if( IN_RENAME_OBJECT==0 ){
100334100830
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
100335100831
if( pParse->db->mallocFailed ) break;
100336100832
}
100337100833
sqlite3WalkExprList(pWalker, pWin->pPartition);
@@ -100340,19 +100836,22 @@
100340100836
sqlite3WindowLink(pSel, pWin);
100341100837
pNC->ncFlags |= NC_HasWin;
100342100838
}else
100343100839
#endif /* SQLITE_OMIT_WINDOWFUNC */
100344100840
{
100345
- NameContext *pNC2 = pNC;
100841
+ NameContext *pNC2; /* For looping up thru outer contexts */
100346100842
pExpr->op = TK_AGG_FUNCTION;
100347100843
pExpr->op2 = 0;
100348100844
#ifndef SQLITE_OMIT_WINDOWFUNC
100349100845
if( ExprHasProperty(pExpr, EP_WinFunc) ){
100350100846
sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100351100847
}
100352100848
#endif
100353
- while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
100849
+ pNC2 = pNC;
100850
+ while( pNC2
100851
+ && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
100852
+ ){
100354100853
pExpr->op2++;
100355100854
pNC2 = pNC2->pNext;
100356100855
}
100357100856
assert( pDef!=0 || IN_RENAME_OBJECT );
100358100857
if( pNC2 && pDef ){
@@ -100376,11 +100875,11 @@
100376100875
case TK_SELECT:
100377100876
case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
100378100877
#endif
100379100878
case TK_IN: {
100380100879
testcase( pExpr->op==TK_IN );
100381
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
100880
+ if( ExprUseXSelect(pExpr) ){
100382100881
int nRef = pNC->nRef;
100383100882
testcase( pNC->ncFlags & NC_IsCheck );
100384100883
testcase( pNC->ncFlags & NC_PartIdx );
100385100884
testcase( pNC->ncFlags & NC_IdxExpr );
100386100885
testcase( pNC->ncFlags & NC_GenCol );
@@ -100433,10 +100932,11 @@
100433100932
int nLeft, nRight;
100434100933
if( pParse->db->mallocFailed ) break;
100435100934
assert( pExpr->pLeft!=0 );
100436100935
nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
100437100936
if( pExpr->op==TK_BETWEEN ){
100937
+ assert( ExprUseXList(pExpr) );
100438100938
nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
100439100939
if( nRight==nLeft ){
100440100940
nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
100441100941
}
100442100942
}else{
@@ -100481,11 +100981,13 @@
100481100981
int i; /* Loop counter */
100482100982
100483100983
UNUSED_PARAMETER(pParse);
100484100984
100485100985
if( pE->op==TK_ID ){
100486
- char *zCol = pE->u.zToken;
100986
+ const char *zCol;
100987
+ assert( !ExprHasProperty(pE, EP_IntValue) );
100988
+ zCol = pE->u.zToken;
100487100989
for(i=0; i<pEList->nExpr; i++){
100488100990
if( pEList->a[i].eEName==ENAME_NAME
100489100991
&& sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
100490100992
){
100491100993
return i+1;
@@ -101315,12 +101817,12 @@
101315101817
101316101818
/*
101317101819
** Return the affinity character for a single column of a table.
101318101820
*/
101319101821
SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101320
- assert( iCol<pTab->nCol );
101321
- return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
101822
+ if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER;
101823
+ return pTab->aCol[iCol].affinity;
101322101824
}
101323101825
101324101826
/*
101325101827
** Return the 'affinity' of the expression pExpr if any.
101326101828
**
@@ -101346,15 +101848,18 @@
101346101848
pExpr = pExpr->pLeft;
101347101849
assert( pExpr!=0 );
101348101850
}
101349101851
op = pExpr->op;
101350101852
if( op==TK_REGISTER ) op = pExpr->op2;
101351
- if( (op==TK_COLUMN || op==TK_AGG_COLUMN) && pExpr->y.pTab ){
101352
- return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
101853
+ if( op==TK_COLUMN || op==TK_AGG_COLUMN ){
101854
+ assert( ExprUseYTab(pExpr) );
101855
+ if( pExpr->y.pTab ){
101856
+ return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
101857
+ }
101353101858
}
101354101859
if( op==TK_SELECT ){
101355
- assert( pExpr->flags&EP_xIsSelect );
101860
+ assert( ExprUseXSelect(pExpr) );
101356101861
assert( pExpr->x.pSelect!=0 );
101357101862
assert( pExpr->x.pSelect->pEList!=0 );
101358101863
assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
101359101864
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
101360101865
}
@@ -101363,18 +101868,19 @@
101363101868
assert( !ExprHasProperty(pExpr, EP_IntValue) );
101364101869
return sqlite3AffinityType(pExpr->u.zToken, 0);
101365101870
}
101366101871
#endif
101367101872
if( op==TK_SELECT_COLUMN ){
101368
- assert( pExpr->pLeft->flags&EP_xIsSelect );
101873
+ assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
101369101874
assert( pExpr->iColumn < pExpr->iTable );
101370101875
assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
101371101876
return sqlite3ExprAffinity(
101372101877
pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
101373101878
);
101374101879
}
101375101880
if( op==TK_VECTOR ){
101881
+ assert( ExprUseXList(pExpr) );
101376101882
return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
101377101883
}
101378101884
return pExpr->affExpr;
101379101885
}
101380101886
@@ -101430,11 +101936,11 @@
101430101936
** expression.
101431101937
*/
101432101938
SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
101433101939
while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
101434101940
if( ExprHasProperty(pExpr, EP_Unlikely) ){
101435
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
101941
+ assert( ExprUseXList(pExpr) );
101436101942
assert( pExpr->x.pList->nExpr>0 );
101437101943
assert( pExpr->op==TK_FUNCTION );
101438101944
pExpr = pExpr->x.pList->a[0].pExpr;
101439101945
}else{
101440101946
assert( pExpr->op==TK_COLLATE );
@@ -101463,45 +101969,46 @@
101463101969
CollSeq *pColl = 0;
101464101970
const Expr *p = pExpr;
101465101971
while( p ){
101466101972
int op = p->op;
101467101973
if( op==TK_REGISTER ) op = p->op2;
101468
- if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
101469
- && p->y.pTab!=0
101470
- ){
101471
- /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
101472
- ** a TK_COLUMN but was previously evaluated and cached in a register */
101473
- int j = p->iColumn;
101474
- if( j>=0 ){
101475
- const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]);
101476
- pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
101477
- }
101478
- break;
101974
+ if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){
101975
+ assert( ExprUseYTab(p) );
101976
+ if( p->y.pTab!=0 ){
101977
+ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
101978
+ ** a TK_COLUMN but was previously evaluated and cached in a register */
101979
+ int j = p->iColumn;
101980
+ if( j>=0 ){
101981
+ const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]);
101982
+ pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
101983
+ }
101984
+ break;
101985
+ }
101479101986
}
101480101987
if( op==TK_CAST || op==TK_UPLUS ){
101481101988
p = p->pLeft;
101482101989
continue;
101483101990
}
101484101991
if( op==TK_VECTOR ){
101992
+ assert( ExprUseXList(p) );
101485101993
p = p->x.pList->a[0].pExpr;
101486101994
continue;
101487101995
}
101488101996
if( op==TK_COLLATE ){
101997
+ assert( !ExprHasProperty(p, EP_IntValue) );
101489101998
pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
101490101999
break;
101491102000
}
101492102001
if( p->flags & EP_Collate ){
101493102002
if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
101494102003
p = p->pLeft;
101495102004
}else{
101496102005
Expr *pNext = p->pRight;
101497102006
/* The Expr.x union is never used at the same time as Expr.pRight */
102007
+ assert( ExprUseXList(p) );
101498102008
assert( p->x.pList==0 || p->pRight==0 );
101499
- if( p->x.pList!=0
101500
- && !db->mallocFailed
101501
- && ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
101502
- ){
102009
+ if( p->x.pList!=0 && !db->mallocFailed ){
101503102010
int i;
101504102011
for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
101505102012
if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
101506102013
pNext = p->x.pList->a[i].pExpr;
101507102014
break;
@@ -101580,11 +102087,11 @@
101580102087
pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
101581102088
assert( pExpr->pLeft );
101582102089
aff = sqlite3ExprAffinity(pExpr->pLeft);
101583102090
if( pExpr->pRight ){
101584102091
aff = sqlite3CompareAffinity(pExpr->pRight, aff);
101585
- }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
102092
+ }else if( ExprUseXSelect(pExpr) ){
101586102093
aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
101587102094
}else if( aff==0 ){
101588102095
aff = SQLITE_AFF_BLOB;
101589102096
}
101590102097
return aff;
@@ -101720,12 +102227,14 @@
101720102227
*/
101721102228
SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){
101722102229
u8 op = pExpr->op;
101723102230
if( op==TK_REGISTER ) op = pExpr->op2;
101724102231
if( op==TK_VECTOR ){
102232
+ assert( ExprUseXList(pExpr) );
101725102233
return pExpr->x.pList->nExpr;
101726102234
}else if( op==TK_SELECT ){
102235
+ assert( ExprUseXSelect(pExpr) );
101727102236
return pExpr->x.pSelect->pEList->nExpr;
101728102237
}else{
101729102238
return 1;
101730102239
}
101731102240
}
@@ -101748,12 +102257,14 @@
101748102257
SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
101749102258
assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
101750102259
if( sqlite3ExprIsVector(pVector) ){
101751102260
assert( pVector->op2==0 || pVector->op==TK_REGISTER );
101752102261
if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
102262
+ assert( ExprUseXSelect(pVector) );
101753102263
return pVector->x.pSelect->pEList->a[i].pExpr;
101754102264
}else{
102265
+ assert( ExprUseXList(pVector) );
101755102266
return pVector->x.pList->a[i].pExpr;
101756102267
}
101757102268
}
101758102269
return pVector;
101759102270
}
@@ -101785,11 +102296,11 @@
101785102296
int iField, /* Which column of the vector to return */
101786102297
int nField /* Total number of columns in the vector */
101787102298
){
101788102299
Expr *pRet;
101789102300
if( pVector->op==TK_SELECT ){
101790
- assert( pVector->flags & EP_xIsSelect );
102301
+ assert( ExprUseXSelect(pVector) );
101791102302
/* The TK_SELECT_COLUMN Expr node:
101792102303
**
101793102304
** pLeft: pVector containing TK_SELECT. Not deleted.
101794102305
** pRight: not used. But recursively deleted.
101795102306
** iColumn: Index of a column in pVector
@@ -101810,11 +102321,13 @@
101810102321
pRet->iColumn = iField;
101811102322
pRet->pLeft = pVector;
101812102323
}
101813102324
}else{
101814102325
if( pVector->op==TK_VECTOR ){
101815
- Expr **ppVector = &pVector->x.pList->a[iField].pExpr;
102326
+ Expr **ppVector;
102327
+ assert( ExprUseXList(pVector) );
102328
+ ppVector = &pVector->x.pList->a[iField].pExpr;
101816102329
pVector = *ppVector;
101817102330
if( IN_RENAME_OBJECT ){
101818102331
/* This must be a vector UPDATE inside a trigger */
101819102332
*ppVector = 0;
101820102333
return pVector;
@@ -101874,14 +102387,16 @@
101874102387
if( op==TK_REGISTER ){
101875102388
*ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
101876102389
return pVector->iTable+iField;
101877102390
}
101878102391
if( op==TK_SELECT ){
102392
+ assert( ExprUseXSelect(pVector) );
101879102393
*ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
101880102394
return regSelect+iField;
101881102395
}
101882102396
if( op==TK_VECTOR ){
102397
+ assert( ExprUseXList(pVector) );
101883102398
*ppExpr = pVector->x.pList->a[iField].pExpr;
101884102399
return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
101885102400
}
101886102401
return 0;
101887102402
}
@@ -102052,11 +102567,11 @@
102052102567
*/
102053102568
static void exprSetHeight(Expr *p){
102054102569
int nHeight = 0;
102055102570
heightOfExpr(p->pLeft, &nHeight);
102056102571
heightOfExpr(p->pRight, &nHeight);
102057
- if( ExprHasProperty(p, EP_xIsSelect) ){
102572
+ if( ExprUseXSelect(p) ){
102058102573
heightOfSelect(p->x.pSelect, &nHeight);
102059102574
}else if( p->x.pList ){
102060102575
heightOfExprList(p->x.pList, &nHeight);
102061102576
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
102062102577
}
@@ -102091,11 +102606,11 @@
102091102606
** Propagate all EP_Propagate flags from the Expr.x.pList into
102092102607
** Expr.flags.
102093102608
*/
102094102609
SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
102095102610
if( pParse->nErr ) return;
102096
- if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
102611
+ if( p && ExprUseXList(p) && p->x.pList ){
102097102612
p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
102098102613
}
102099102614
}
102100102615
#define exprSetHeight(y)
102101102616
#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
@@ -102275,17 +102790,24 @@
102275102790
Select *pRet = 0;
102276102791
assert( nElem>1 );
102277102792
for(ii=0; ii<pEList->nExpr; ii++){
102278102793
Select *pSel;
102279102794
Expr *pExpr = pEList->a[ii].pExpr;
102280
- int nExprElem = (pExpr->op==TK_VECTOR ? pExpr->x.pList->nExpr : 1);
102795
+ int nExprElem;
102796
+ if( pExpr->op==TK_VECTOR ){
102797
+ assert( ExprUseXList(pExpr) );
102798
+ nExprElem = pExpr->x.pList->nExpr;
102799
+ }else{
102800
+ nExprElem = 1;
102801
+ }
102281102802
if( nExprElem!=nElem ){
102282102803
sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d",
102283102804
nExprElem, nExprElem>1?"s":"", nElem
102284102805
);
102285102806
break;
102286102807
}
102808
+ assert( ExprUseXList(pExpr) );
102287102809
pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0);
102288102810
pExpr->x.pList = 0;
102289102811
if( pSel ){
102290102812
if( pRet ){
102291102813
pSel->op = TK_ALL;
@@ -102351,11 +102873,11 @@
102351102873
){
102352102874
sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
102353102875
}
102354102876
pNew->x.pList = pList;
102355102877
ExprSetProperty(pNew, EP_HasFunc);
102356
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
102878
+ assert( ExprUseXList(pNew) );
102357102879
sqlite3ExprSetHeightAndFlags(pParse, pNew);
102358102880
if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
102359102881
return pNew;
102360102882
}
102361102883
@@ -102477,31 +102999,30 @@
102477102999
/*
102478103000
** Recursively delete an expression tree.
102479103001
*/
102480103002
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
102481103003
assert( p!=0 );
102482
- /* Sanity check: Assert that the IntValue is non-negative if it exists */
102483
- assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
102484
-
102485
- assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
102486
- assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
102487
- || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
103004
+ assert( !ExprUseUValue(p) || p->u.iValue>=0 );
103005
+ assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
103006
+ assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
103007
+ assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) );
102488103008
#ifdef SQLITE_DEBUG
102489103009
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
102490103010
assert( p->pLeft==0 );
102491103011
assert( p->pRight==0 );
102492
- assert( p->x.pSelect==0 );
103012
+ assert( !ExprUseXSelect(p) || p->x.pSelect==0 );
103013
+ assert( !ExprUseXList(p) || p->x.pList==0 );
102493103014
}
102494103015
#endif
102495103016
if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
102496103017
/* The Expr.x union is never used at the same time as Expr.pRight */
102497
- assert( p->x.pList==0 || p->pRight==0 );
103018
+ assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
102498103019
if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
102499103020
if( p->pRight ){
102500103021
assert( !ExprHasProperty(p, EP_WinFunc) );
102501103022
sqlite3ExprDeleteNN(db, p->pRight);
102502
- }else if( ExprHasProperty(p, EP_xIsSelect) ){
103023
+ }else if( ExprUseXSelect(p) ){
102503103024
assert( !ExprHasProperty(p, EP_WinFunc) );
102504103025
sqlite3SelectDelete(db, p->x.pSelect);
102505103026
}else{
102506103027
sqlite3ExprListDelete(db, p->x.pList);
102507103028
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -102509,11 +103030,14 @@
102509103030
sqlite3WindowDelete(db, p->y.pWin);
102510103031
}
102511103032
#endif
102512103033
}
102513103034
}
102514
- if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
103035
+ if( ExprHasProperty(p, EP_MemToken) ){
103036
+ assert( !ExprHasProperty(p, EP_IntValue) );
103037
+ sqlite3DbFree(db, p->u.zToken);
103038
+ }
102515103039
if( !ExprHasProperty(p, EP_Static) ){
102516103040
sqlite3DbFreeNN(db, p);
102517103041
}
102518103042
}
102519103043
SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -102725,11 +103249,11 @@
102725103249
memcpy(zToken, p->u.zToken, nToken);
102726103250
}
102727103251
102728103252
if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
102729103253
/* Fill in the pNew->x.pSelect or pNew->x.pList member. */
102730
- if( ExprHasProperty(p, EP_xIsSelect) ){
103254
+ if( ExprUseXSelect(p) ){
102731103255
pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
102732103256
}else{
102733103257
pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
102734103258
}
102735103259
}
@@ -103019,11 +103543,11 @@
103019103543
}
103020103544
103021103545
return pRet;
103022103546
}
103023103547
#else
103024
-SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
103548
+SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
103025103549
assert( p==0 );
103026103550
return 0;
103027103551
}
103028103552
#endif
103029103553
@@ -103352,11 +103876,11 @@
103352103876
** the conversion happened, and zero if the expression is unaltered.
103353103877
*/
103354103878
SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
103355103879
u32 v;
103356103880
assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
103357
- if( !ExprHasProperty(pExpr, EP_Quoted)
103881
+ if( !ExprHasProperty(pExpr, EP_Quoted|EP_IntValue)
103358103882
&& (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
103359103883
){
103360103884
pExpr->op = TK_TRUEFALSE;
103361103885
ExprSetProperty(pExpr, v);
103362103886
return 1;
@@ -103369,10 +103893,11 @@
103369103893
** and 0 if it is FALSE.
103370103894
*/
103371103895
SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
103372103896
pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
103373103897
assert( pExpr->op==TK_TRUEFALSE );
103898
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
103374103899
assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
103375103900
|| sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
103376103901
return pExpr->u.zToken[4]==0;
103377103902
}
103378103903
@@ -103573,11 +104098,11 @@
103573104098
}
103574104099
}
103575104100
}
103576104101
103577104102
/* Check if pExpr is a sub-select. If so, consider it variable. */
103578
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104103
+ if( ExprUseXSelect(pExpr) ){
103579104104
pWalker->eCode = 0;
103580104105
return WRC_Abort;
103581104106
}
103582104107
103583104108
return exprNodeIsConstant(pWalker, pExpr);
@@ -103680,13 +104205,13 @@
103680104205
case TK_UPLUS: {
103681104206
rc = sqlite3ExprIsInteger(p->pLeft, pValue);
103682104207
break;
103683104208
}
103684104209
case TK_UMINUS: {
103685
- int v;
104210
+ int v = 0;
103686104211
if( sqlite3ExprIsInteger(p->pLeft, &v) ){
103687
- assert( v!=(-2147483647-1) );
104212
+ assert( ((unsigned int)v)!=0x80000000 );
103688104213
*pValue = -v;
103689104214
rc = 1;
103690104215
}
103691104216
break;
103692104217
}
@@ -103723,14 +104248,15 @@
103723104248
case TK_STRING:
103724104249
case TK_FLOAT:
103725104250
case TK_BLOB:
103726104251
return 0;
103727104252
case TK_COLUMN:
104253
+ assert( ExprUseYTab(p) );
103728104254
return ExprHasProperty(p, EP_CanBeNull) ||
103729104255
p->y.pTab==0 || /* Reference to column of index on expression */
103730104256
(p->iColumn>=0
103731
- && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */
104257
+ && p->y.pTab->aCol!=0 /* Possible due to prior error */
103732104258
&& p->y.pTab->aCol[p->iColumn].notNull==0);
103733104259
default:
103734104260
return 1;
103735104261
}
103736104262
}
@@ -103800,11 +104326,11 @@
103800104326
Select *p;
103801104327
SrcList *pSrc;
103802104328
ExprList *pEList;
103803104329
Table *pTab;
103804104330
int i;
103805
- if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */
104331
+ if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
103806104332
if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
103807104333
p = pX->x.pSelect;
103808104334
if( p->pPrior ) return 0; /* Not a compound SELECT */
103809104335
if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
103810104336
testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -103971,11 +104497,11 @@
103971104497
/* If the RHS of this IN(...) operator is a SELECT, and if it matters
103972104498
** whether or not the SELECT result contains NULL values, check whether
103973104499
** or not NULL is actually possible (it may not be, for example, due
103974104500
** to NOT NULL constraints in the schema). If no NULL values are possible,
103975104501
** set prRhsHasNull to 0 before continuing. */
103976
- if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){
104502
+ if( prRhsHasNull && ExprUseXSelect(pX) ){
103977104503
int i;
103978104504
ExprList *pEList = pX->x.pSelect->pEList;
103979104505
for(i=0; i<pEList->nExpr; i++){
103980104506
if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
103981104507
}
@@ -104072,11 +104598,12 @@
104072104598
Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104073104599
Expr *pRhs = pEList->a[i].pExpr;
104074104600
CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104075104601
int j;
104076104602
104077
- assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
104603
+ assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104604
+ || pParse->nErr || db->mallocFailed );
104078104605
for(j=0; j<nExpr; j++){
104079104606
if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104080104607
assert( pIdx->azColl[j] );
104081104608
if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104082104609
continue;
@@ -104127,11 +104654,11 @@
104127104654
** then it is not worth creating an ephemeral table to evaluate
104128104655
** the IN operator so return IN_INDEX_NOOP.
104129104656
*/
104130104657
if( eType==0
104131104658
&& (inFlags & IN_INDEX_NOOP_OK)
104132
- && !ExprHasProperty(pX, EP_xIsSelect)
104659
+ && ExprUseXList(pX)
104133104660
&& (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
104134104661
){
104135104662
eType = IN_INDEX_NOOP;
104136104663
}
104137104664
@@ -104175,11 +104702,11 @@
104175104702
** string is eventually freed using sqlite3DbFree().
104176104703
*/
104177104704
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
104178104705
Expr *pLeft = pExpr->pLeft;
104179104706
int nVal = sqlite3ExprVectorSize(pLeft);
104180
- Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
104707
+ Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
104181104708
char *zRet;
104182104709
104183104710
assert( pExpr->op==TK_IN );
104184104711
zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
104185104712
if( zRet ){
@@ -104225,11 +104752,11 @@
104225104752
**
104226104753
** "row value misused"
104227104754
*/
104228104755
SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
104229104756
#ifndef SQLITE_OMIT_SUBQUERY
104230
- if( pExpr->flags & EP_xIsSelect ){
104757
+ if( ExprUseXSelect(pExpr) ){
104231104758
sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
104232104759
}else
104233104760
#endif
104234104761
{
104235104762
sqlite3ErrorMsg(pParse, "row value misused");
@@ -104289,22 +104816,24 @@
104289104816
/* If this routine has already been coded, but the previous code
104290104817
** might not have been invoked yet, so invoke it now as a subroutine.
104291104818
*/
104292104819
if( ExprHasProperty(pExpr, EP_Subrtn) ){
104293104820
addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
104294
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104821
+ if( ExprUseXSelect(pExpr) ){
104295104822
ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
104296104823
pExpr->x.pSelect->selId));
104297104824
}
104825
+ assert( ExprUseYSub(pExpr) );
104298104826
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
104299104827
pExpr->y.sub.iAddr);
104300104828
sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
104301104829
sqlite3VdbeJumpHere(v, addrOnce);
104302104830
return;
104303104831
}
104304104832
104305104833
/* Begin coding the subroutine */
104834
+ assert( !ExprUseYWin(pExpr) );
104306104835
ExprSetProperty(pExpr, EP_Subrtn);
104307104836
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
104308104837
pExpr->y.sub.regReturn = ++pParse->nMem;
104309104838
pExpr->y.sub.iAddr =
104310104839
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
@@ -104321,19 +104850,19 @@
104321104850
** RHS of the IN operator.
104322104851
*/
104323104852
pExpr->iTable = iTab;
104324104853
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
104325104854
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
104326
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104855
+ if( ExprUseXSelect(pExpr) ){
104327104856
VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
104328104857
}else{
104329104858
VdbeComment((v, "RHS of IN operator"));
104330104859
}
104331104860
#endif
104332104861
pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
104333104862
104334
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104863
+ if( ExprUseXSelect(pExpr) ){
104335104864
/* Case 1: expr IN (SELECT ...)
104336104865
**
104337104866
** Generate code to write the results of the select into the temporary
104338104867
** table allocated and opened above.
104339104868
*/
@@ -104427,10 +104956,11 @@
104427104956
sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
104428104957
}
104429104958
if( addrOnce ){
104430104959
sqlite3VdbeJumpHere(v, addrOnce);
104431104960
/* Subroutine return */
104961
+ assert( ExprUseYSub(pExpr) );
104432104962
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
104433104963
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
104434104964
sqlite3ClearTempRegCache(pParse);
104435104965
}
104436104966
}
@@ -104463,23 +104993,26 @@
104463104993
assert( v!=0 );
104464104994
if( pParse->nErr ) return 0;
104465104995
testcase( pExpr->op==TK_EXISTS );
104466104996
testcase( pExpr->op==TK_SELECT );
104467104997
assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
104468
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
104998
+ assert( ExprUseXSelect(pExpr) );
104469104999
pSel = pExpr->x.pSelect;
104470105000
104471105001
/* If this routine has already been coded, then invoke it as a
104472105002
** subroutine. */
104473105003
if( ExprHasProperty(pExpr, EP_Subrtn) ){
104474105004
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
105005
+ assert( ExprUseYSub(pExpr) );
104475105006
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
104476105007
pExpr->y.sub.iAddr);
104477105008
return pExpr->iTable;
104478105009
}
104479105010
104480105011
/* Begin coding the subroutine */
105012
+ assert( !ExprUseYWin(pExpr) );
105013
+ assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
104481105014
ExprSetProperty(pExpr, EP_Subrtn);
104482105015
pExpr->y.sub.regReturn = ++pParse->nMem;
104483105016
pExpr->y.sub.iAddr =
104484105017
sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
104485105018
VdbeComment((v, "return address"));
@@ -104555,10 +105088,11 @@
104555105088
if( addrOnce ){
104556105089
sqlite3VdbeJumpHere(v, addrOnce);
104557105090
}
104558105091
104559105092
/* Subroutine return */
105093
+ assert( ExprUseYSub(pExpr) );
104560105094
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
104561105095
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
104562105096
sqlite3ClearTempRegCache(pParse);
104563105097
return rReg;
104564105098
}
@@ -104571,11 +105105,11 @@
104571105105
** columns as the vector on the LHS. Or, if the RHS of the IN() is not
104572105106
** a sub-query, that the LHS is a vector of size 1.
104573105107
*/
104574105108
SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
104575105109
int nVector = sqlite3ExprVectorSize(pIn->pLeft);
104576
- if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){
105110
+ if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){
104577105111
if( nVector!=pIn->x.pSelect->pEList->nExpr ){
104578105112
sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
104579105113
return 1;
104580105114
}
104581105115
}else if( nVector!=1 ){
@@ -104705,17 +105239,19 @@
104705105239
** sequence of comparisons.
104706105240
**
104707105241
** This is step (1) in the in-operator.md optimized algorithm.
104708105242
*/
104709105243
if( eType==IN_INDEX_NOOP ){
104710
- ExprList *pList = pExpr->x.pList;
104711
- CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
105244
+ ExprList *pList;
105245
+ CollSeq *pColl;
104712105246
int labelOk = sqlite3VdbeMakeLabel(pParse);
104713105247
int r2, regToFree;
104714105248
int regCkNull = 0;
104715105249
int ii;
104716
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
105250
+ assert( ExprUseXList(pExpr) );
105251
+ pList = pExpr->x.pList;
105252
+ pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
104717105253
if( destIfNull!=destIfFalse ){
104718105254
regCkNull = sqlite3GetTempReg(pParse);
104719105255
sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
104720105256
}
104721105257
for(ii=0; ii<pList->nExpr; ii++){
@@ -105097,10 +105633,11 @@
105097105633
#endif
105098105634
}else{
105099105635
int i;
105100105636
iResult = pParse->nMem+1;
105101105637
pParse->nMem += nResult;
105638
+ assert( ExprUseXList(p) );
105102105639
for(i=0; i<nResult; i++){
105103105640
sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
105104105641
}
105105105642
}
105106105643
}
@@ -105295,10 +105832,11 @@
105295105832
** datatype by applying the Affinity of the table column to the
105296105833
** constant.
105297105834
*/
105298105835
int aff;
105299105836
iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
105837
+ assert( ExprUseYTab(pExpr) );
105300105838
if( pExpr->y.pTab ){
105301105839
aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
105302105840
}else{
105303105841
aff = pExpr->affExpr;
105304105842
}
@@ -105318,13 +105856,15 @@
105318105856
** The row is unpacked into registers beginning at
105319105857
** 0-(pParse->iSelfTab). The rowid (if any) is in a register
105320105858
** immediately prior to the first column.
105321105859
*/
105322105860
Column *pCol;
105323
- Table *pTab = pExpr->y.pTab;
105861
+ Table *pTab;
105324105862
int iSrc;
105325105863
int iCol = pExpr->iColumn;
105864
+ assert( ExprUseYTab(pExpr) );
105865
+ pTab = pExpr->y.pTab;
105326105866
assert( pTab!=0 );
105327105867
assert( iCol>=XN_ROWID );
105328105868
assert( iCol<pTab->nCol );
105329105869
if( iCol<0 ){
105330105870
return -1-pParse->iSelfTab;
@@ -105358,10 +105898,11 @@
105358105898
/* Coding an expression that is part of an index where column names
105359105899
** in the index refer to the table to which the index belongs */
105360105900
iTab = pParse->iSelfTab - 1;
105361105901
}
105362105902
}
105903
+ assert( ExprUseYTab(pExpr) );
105363105904
iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
105364105905
pExpr->iColumn, iTab, target,
105365105906
pExpr->op2);
105366105907
if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){
105367105908
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
@@ -105435,10 +105976,11 @@
105435105976
inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
105436105977
if( inReg!=target ){
105437105978
sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
105438105979
inReg = target;
105439105980
}
105981
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
105440105982
sqlite3VdbeAddOp2(v, OP_Cast, target,
105441105983
sqlite3AffinityType(pExpr->u.zToken, 0));
105442105984
return inReg;
105443105985
}
105444105986
#endif /* SQLITE_OMIT_CAST */
@@ -105602,12 +106144,12 @@
105602106144
if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
105603106145
/* SQL functions can be expensive. So try to avoid running them
105604106146
** multiple times if we know they always give the same result */
105605106147
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
105606106148
}
105607
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
105608106149
assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
106150
+ assert( ExprUseXList(pExpr) );
105609106151
pFarg = pExpr->x.pList;
105610106152
nFarg = pFarg ? pFarg->nExpr : 0;
105611106153
assert( !ExprHasProperty(pExpr, EP_IntValue) );
105612106154
zId = pExpr->u.zToken;
105613106155
pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
@@ -105692,11 +106234,11 @@
105692106234
if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
105693106235
if( !pColl ) pColl = db->pDfltColl;
105694106236
sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
105695106237
}
105696106238
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
105697
- if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){
106239
+ if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){
105698106240
Expr *pArg = pFarg->a[0].pExpr;
105699106241
if( pArg->op==TK_COLUMN ){
105700106242
sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
105701106243
}else{
105702106244
sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -105722,11 +106264,14 @@
105722106264
int nCol;
105723106265
testcase( op==TK_EXISTS );
105724106266
testcase( op==TK_SELECT );
105725106267
if( pParse->db->mallocFailed ){
105726106268
return 0;
105727
- }else if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
106269
+ }else if( op==TK_SELECT
106270
+ && ALWAYS( ExprUseXSelect(pExpr) )
106271
+ && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1
106272
+ ){
105728106273
sqlite3SubselectError(pParse, nCol, 1);
105729106274
}else{
105730106275
return sqlite3CodeSubselect(pParse, pExpr);
105731106276
}
105732106277
break;
@@ -105804,13 +106349,18 @@
105804106349
**
105805106350
** p1==0 -> old.rowid p1==3 -> new.rowid
105806106351
** p1==1 -> old.a p1==4 -> new.a
105807106352
** p1==2 -> old.b p1==5 -> new.b
105808106353
*/
105809
- Table *pTab = pExpr->y.pTab;
105810
- int iCol = pExpr->iColumn;
105811
- int p1 = pExpr->iTable * (pTab->nCol+1) + 1
106354
+ Table *pTab;
106355
+ int iCol;
106356
+ int p1;
106357
+
106358
+ assert( ExprUseYTab(pExpr) );
106359
+ pTab = pExpr->y.pTab;
106360
+ iCol = pExpr->iColumn;
106361
+ p1 = pExpr->iTable * (pTab->nCol+1) + 1
105812106362
+ sqlite3TableColumnToStorage(pTab, iCol);
105813106363
105814106364
assert( pExpr->iTable==0 || pExpr->iTable==1 );
105815106365
assert( iCol>=-1 && iCol<pTab->nCol );
105816106366
assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
@@ -105894,11 +106444,11 @@
105894106444
Expr *pX; /* The X expression */
105895106445
Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
105896106446
Expr *pDel = 0;
105897106447
sqlite3 *db = pParse->db;
105898106448
105899
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
106449
+ assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 );
105900106450
assert(pExpr->x.pList->nExpr > 0);
105901106451
pEList = pExpr->x.pList;
105902106452
aListelem = pEList->a;
105903106453
nExpr = pEList->nExpr;
105904106454
endLabel = sqlite3VdbeMakeLabel(pParse);
@@ -106239,11 +106789,11 @@
106239106789
106240106790
memset(&compLeft, 0, sizeof(Expr));
106241106791
memset(&compRight, 0, sizeof(Expr));
106242106792
memset(&exprAnd, 0, sizeof(Expr));
106243106793
106244
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
106794
+ assert( ExprUseXList(pExpr) );
106245106795
pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
106246106796
if( db->mallocFailed==0 ){
106247106797
exprAnd.op = TK_AND;
106248106798
exprAnd.pLeft = &compLeft;
106249106799
exprAnd.pRight = &compRight;
@@ -106714,11 +107264,13 @@
106714107264
if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
106715107265
return 1;
106716107266
}
106717107267
return 2;
106718107268
}
106719
- if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
107269
+ assert( !ExprHasProperty(pA, EP_IntValue) );
107270
+ assert( !ExprHasProperty(pB, EP_IntValue) );
107271
+ if( pA->u.zToken ){
106720107272
if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
106721107273
if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
106722107274
#ifndef SQLITE_OMIT_WINDOWFUNC
106723107275
assert( pA->op==pB->op );
106724107276
if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
@@ -106732,11 +107284,16 @@
106732107284
#endif
106733107285
}else if( pA->op==TK_NULL ){
106734107286
return 0;
106735107287
}else if( pA->op==TK_COLLATE ){
106736107288
if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
106737
- }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
107289
+ }else
107290
+ if( pB->u.zToken!=0
107291
+ && pA->op!=TK_COLUMN
107292
+ && pA->op!=TK_AGG_COLUMN
107293
+ && strcmp(pA->u.zToken,pB->u.zToken)!=0
107294
+ ){
106738107295
return 2;
106739107296
}
106740107297
}
106741107298
if( (pA->flags & (EP_Distinct|EP_Commuted))
106742107299
!= (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
@@ -106821,16 +107378,17 @@
106821107378
return pNN->op!=TK_NULL;
106822107379
}
106823107380
switch( p->op ){
106824107381
case TK_IN: {
106825107382
if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
106826
- assert( ExprHasProperty(p,EP_xIsSelect)
106827
- || (p->x.pList!=0 && p->x.pList->nExpr>0) );
107383
+ assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) );
106828107384
return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
106829107385
}
106830107386
case TK_BETWEEN: {
106831
- ExprList *pList = p->x.pList;
107387
+ ExprList *pList;
107388
+ assert( ExprUseXList(p) );
107389
+ pList = p->x.pList;
106832107390
assert( pList!=0 );
106833107391
assert( pList->nExpr==2 );
106834107392
if( seenNot ) return 0;
106835107393
if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
106836107394
|| exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
@@ -107003,14 +107561,18 @@
107003107561
testcase( pExpr->op==TK_LE );
107004107562
testcase( pExpr->op==TK_GT );
107005107563
testcase( pExpr->op==TK_GE );
107006107564
/* The y.pTab=0 assignment in wherecode.c always happens after the
107007107565
** impliesNotNullRow() test */
107008
- if( (pLeft->op==TK_COLUMN && pLeft->y.pTab!=0
107009
- && IsVirtual(pLeft->y.pTab))
107010
- || (pRight->op==TK_COLUMN && pRight->y.pTab!=0
107011
- && IsVirtual(pRight->y.pTab))
107566
+ assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
107567
+ assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
107568
+ if( (pLeft->op==TK_COLUMN
107569
+ && pLeft->y.pTab!=0
107570
+ && IsVirtual(pLeft->y.pTab))
107571
+ || (pRight->op==TK_COLUMN
107572
+ && pRight->y.pTab!=0
107573
+ && IsVirtual(pRight->y.pTab))
107012107574
){
107013107575
return WRC_Prune;
107014107576
}
107015107577
/* no break */ deliberate_fall_through
107016107578
}
@@ -107115,92 +107677,129 @@
107115107677
sqlite3WalkExpr(&w, pExpr);
107116107678
return !w.eCode;
107117107679
}
107118107680
107119107681
107120
-/*
107121
-** An instance of the following structure is used by the tree walker
107122
-** to count references to table columns in the arguments of an
107123
-** aggregate function, in order to implement the
107124
-** sqlite3FunctionThisSrc() routine.
107682
+/* Structure used to pass information throught the Walker in order to
107683
+** implement sqlite3ReferencesSrcList().
107125107684
*/
107126
-struct SrcCount {
107127
- SrcList *pSrc; /* One particular FROM clause in a nested query */
107128
- int iSrcInner; /* Smallest cursor number in this context */
107129
- int nThis; /* Number of references to columns in pSrcList */
107130
- int nOther; /* Number of references to columns in other FROM clauses */
107685
+struct RefSrcList {
107686
+ sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */
107687
+ SrcList *pRef; /* Looking for references to these tables */
107688
+ i64 nExclude; /* Number of tables to exclude from the search */
107689
+ int *aiExclude; /* Cursor IDs for tables to exclude from the search */
107131107690
};
107132107691
107133107692
/*
107134
-** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
107135
-** SELECT with a FROM clause encountered during this iteration, set
107136
-** SrcCount.iSrcInner to the cursor number of the leftmost object in
107137
-** the FROM cause.
107693
+** Walker SELECT callbacks for sqlite3ReferencesSrcList().
107694
+**
107695
+** When entering a new subquery on the pExpr argument, add all FROM clause
107696
+** entries for that subquery to the exclude list.
107697
+**
107698
+** When leaving the subquery, remove those entries from the exclude list.
107138107699
*/
107139
-static int selectSrcCount(Walker *pWalker, Select *pSel){
107140
- struct SrcCount *p = pWalker->u.pSrcCount;
107141
- if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
107142
- pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
107700
+static int selectRefEnter(Walker *pWalker, Select *pSelect){
107701
+ struct RefSrcList *p = pWalker->u.pRefSrcList;
107702
+ SrcList *pSrc = pSelect->pSrc;
107703
+ i64 i, j;
107704
+ int *piNew;
107705
+ if( pSrc->nSrc==0 ) return WRC_Continue;
107706
+ j = p->nExclude;
107707
+ p->nExclude += pSrc->nSrc;
107708
+ piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int));
107709
+ if( piNew==0 ){
107710
+ p->nExclude = 0;
107711
+ return WRC_Abort;
107712
+ }else{
107713
+ p->aiExclude = piNew;
107714
+ }
107715
+ for(i=0; i<pSrc->nSrc; i++, j++){
107716
+ p->aiExclude[j] = pSrc->a[i].iCursor;
107143107717
}
107144107718
return WRC_Continue;
107145107719
}
107146
-
107147
-/*
107148
-** Count the number of references to columns.
107149
-*/
107150
-static int exprSrcCount(Walker *pWalker, Expr *pExpr){
107151
- /* There was once a NEVER() on the second term on the grounds that
107152
- ** sqlite3FunctionUsesThisSrc() was always called before
107153
- ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
107154
- ** been converted into TK_AGG_COLUMN. But this is no longer true due
107155
- ** to window functions - sqlite3WindowRewrite() may now indirectly call
107156
- ** FunctionUsesThisSrc() when creating a new sub-select. */
107157
- if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
107158
- int i;
107159
- struct SrcCount *p = pWalker->u.pSrcCount;
107160
- SrcList *pSrc = p->pSrc;
107720
+static void selectRefLeave(Walker *pWalker, Select *pSelect){
107721
+ struct RefSrcList *p = pWalker->u.pRefSrcList;
107722
+ SrcList *pSrc = pSelect->pSrc;
107723
+ if( p->nExclude ){
107724
+ assert( p->nExclude>=pSrc->nSrc );
107725
+ p->nExclude -= pSrc->nSrc;
107726
+ }
107727
+}
107728
+
107729
+/* This is the Walker EXPR callback for sqlite3ReferencesSrcList().
107730
+**
107731
+** Set the 0x01 bit of pWalker->eCode if there is a reference to any
107732
+** of the tables shown in RefSrcList.pRef.
107733
+**
107734
+** Set the 0x02 bit of pWalker->eCode if there is a reference to a
107735
+** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude.
107736
+*/
107737
+static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){
107738
+ if( pExpr->op==TK_COLUMN
107739
+ || pExpr->op==TK_AGG_COLUMN
107740
+ ){
107741
+ int i;
107742
+ struct RefSrcList *p = pWalker->u.pRefSrcList;
107743
+ SrcList *pSrc = p->pRef;
107161107744
int nSrc = pSrc ? pSrc->nSrc : 0;
107162107745
for(i=0; i<nSrc; i++){
107163
- if( pExpr->iTable==pSrc->a[i].iCursor ) break;
107164
- }
107165
- if( i<nSrc ){
107166
- p->nThis++;
107167
- }else if( pExpr->iTable<p->iSrcInner ){
107168
- /* In a well-formed parse tree (no name resolution errors),
107169
- ** TK_COLUMN nodes with smaller Expr.iTable values are in an
107170
- ** outer context. Those are the only ones to count as "other" */
107171
- p->nOther++;
107746
+ if( pExpr->iTable==pSrc->a[i].iCursor ){
107747
+ pWalker->eCode |= 1;
107748
+ return WRC_Continue;
107749
+ }
107750
+ }
107751
+ for(i=0; i<p->nExclude && p->aiExclude[i]!=pExpr->iTable; i++){}
107752
+ if( i>=p->nExclude ){
107753
+ pWalker->eCode |= 2;
107172107754
}
107173107755
}
107174107756
return WRC_Continue;
107175107757
}
107176107758
107177107759
/*
107178
-** Determine if any of the arguments to the pExpr Function reference
107179
-** pSrcList. Return true if they do. Also return true if the function
107180
-** has no arguments or has only constant arguments. Return false if pExpr
107181
-** references columns but not columns of tables found in pSrcList.
107760
+** Check to see if pExpr references any tables in pSrcList.
107761
+** Possible return values:
107762
+**
107763
+** 1 pExpr does references a table in pSrcList.
107764
+**
107765
+** 0 pExpr references some table that is not defined in either
107766
+** pSrcList or in subqueries of pExpr itself.
107767
+**
107768
+** -1 pExpr only references no tables at all, or it only
107769
+** references tables defined in subqueries of pExpr itself.
107770
+**
107771
+** As currently used, pExpr is always an aggregate function call. That
107772
+** fact is exploited for efficiency.
107182107773
*/
107183
-SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
107774
+SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
107184107775
Walker w;
107185
- struct SrcCount cnt;
107776
+ struct RefSrcList x;
107777
+ memset(&w, 0, sizeof(w));
107778
+ memset(&x, 0, sizeof(x));
107779
+ w.xExprCallback = exprRefToSrcList;
107780
+ w.xSelectCallback = selectRefEnter;
107781
+ w.xSelectCallback2 = selectRefLeave;
107782
+ w.u.pRefSrcList = &x;
107783
+ x.db = pParse->db;
107784
+ x.pRef = pSrcList;
107186107785
assert( pExpr->op==TK_AGG_FUNCTION );
107187
- memset(&w, 0, sizeof(w));
107188
- w.xExprCallback = exprSrcCount;
107189
- w.xSelectCallback = selectSrcCount;
107190
- w.u.pSrcCount = &cnt;
107191
- cnt.pSrc = pSrcList;
107192
- cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
107193
- cnt.nThis = 0;
107194
- cnt.nOther = 0;
107786
+ assert( ExprUseXList(pExpr) );
107195107787
sqlite3WalkExprList(&w, pExpr->x.pList);
107196107788
#ifndef SQLITE_OMIT_WINDOWFUNC
107197107789
if( ExprHasProperty(pExpr, EP_WinFunc) ){
107198107790
sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107199107791
}
107200107792
#endif
107201
- return cnt.nThis>0 || cnt.nOther==0;
107793
+ sqlite3DbFree(pParse->db, x.aiExclude);
107794
+ if( w.eCode & 0x01 ){
107795
+ return 1;
107796
+ }else if( w.eCode ){
107797
+ return 0;
107798
+ }else{
107799
+ return -1;
107800
+ }
107202107801
}
107203107802
107204107803
/*
107205107804
** This is a Walker expression node callback.
107206107805
**
@@ -107331,10 +107930,11 @@
107331107930
}
107332107931
if( (k>=pAggInfo->nColumn)
107333107932
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
107334107933
){
107335107934
pCol = &pAggInfo->aCol[k];
107935
+ assert( ExprUseYTab(pExpr) );
107336107936
pCol->pTab = pExpr->y.pTab;
107337107937
pCol->iTable = pExpr->iTable;
107338107938
pCol->iColumn = pExpr->iColumn;
107339107939
pCol->iMem = ++pParse->nMem;
107340107940
pCol->iSorterColumn = -1;
@@ -107394,11 +107994,11 @@
107394107994
if( i>=0 ){
107395107995
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
107396107996
pItem = &pAggInfo->aFunc[i];
107397107997
pItem->pFExpr = pExpr;
107398107998
pItem->iMem = ++pParse->nMem;
107399
- assert( !ExprHasProperty(pExpr, EP_IntValue) );
107999
+ assert( ExprUseUToken(pExpr) );
107400108000
pItem->pFunc = sqlite3FindFunction(pParse->db,
107401108001
pExpr->u.zToken,
107402108002
pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
107403108003
if( pExpr->flags & EP_Distinct ){
107404108004
pItem->iDistinct = pParse->nTab++;
@@ -107609,11 +108209,11 @@
107609108209
int bNoDQS /* Do not allow DQS in the schema */
107610108210
){
107611108211
pParse->colNamesSet = 1;
107612108212
sqlite3NestedParse(pParse,
107613108213
"SELECT 1 "
107614
- "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
108214
+ "FROM \"%w\"." LEGACY_SCHEMA_TABLE " "
107615108215
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107616108216
" AND sql NOT LIKE 'create virtual%%'"
107617108217
" AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
107618108218
zDb,
107619108219
zDb, bTemp, zWhen, bNoDQS
@@ -107620,11 +108220,11 @@
107620108220
);
107621108221
107622108222
if( bTemp==0 ){
107623108223
sqlite3NestedParse(pParse,
107624108224
"SELECT 1 "
107625
- "FROM temp." DFLT_SCHEMA_TABLE " "
108225
+ "FROM temp." LEGACY_SCHEMA_TABLE " "
107626108226
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107627108227
" AND sql NOT LIKE 'create virtual%%'"
107628108228
" AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
107629108229
zDb, zWhen, bNoDQS
107630108230
);
@@ -107638,18 +108238,18 @@
107638108238
** not true, similarly update all SQL statements in the sqlite_schema table
107639108239
** of the temp db.
107640108240
*/
107641108241
static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
107642108242
sqlite3NestedParse(pParse,
107643
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE
108243
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE
107644108244
" SET sql = sqlite_rename_quotefix(%Q, sql)"
107645108245
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107646108246
" AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
107647108247
);
107648108248
if( bTemp==0 ){
107649108249
sqlite3NestedParse(pParse,
107650
- "UPDATE temp." DFLT_SCHEMA_TABLE
108250
+ "UPDATE temp." LEGACY_SCHEMA_TABLE
107651108251
" SET sql = sqlite_rename_quotefix('temp', sql)"
107652108252
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107653108253
" AND sql NOT LIKE 'create virtual%%'"
107654108254
);
107655108255
}
@@ -107763,21 +108363,21 @@
107763108363
nTabName = sqlite3Utf8CharLen(zTabName, -1);
107764108364
107765108365
/* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
107766108366
** the schema to use the new table name. */
107767108367
sqlite3NestedParse(pParse,
107768
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108368
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
107769108369
"sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
107770108370
"WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
107771108371
"AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107772108372
, zDb, zDb, zTabName, zName, (iDb==1), zTabName
107773108373
);
107774108374
107775108375
/* Update the tbl_name and name columns of the sqlite_schema table
107776108376
** as required. */
107777108377
sqlite3NestedParse(pParse,
107778
- "UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
108378
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET "
107779108379
"tbl_name = %Q, "
107780108380
"name = CASE "
107781108381
"WHEN type='table' THEN %Q "
107782108382
"WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
107783108383
" AND type='index' THEN "
@@ -107916,10 +108516,11 @@
107916108516
*/
107917108517
assert( pDflt==0 || pDflt->op==TK_SPAN );
107918108518
if( pDflt && pDflt->pLeft->op==TK_NULL ){
107919108519
pDflt = 0;
107920108520
}
108521
+ assert( IsOrdinaryTable(pNew) );
107921108522
if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){
107922108523
sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
107923108524
"Cannot add a REFERENCES column with non-NULL default value");
107924108525
}
107925108526
if( pCol->notNull && !pDflt ){
@@ -107958,13 +108559,14 @@
107958108559
while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
107959108560
*zEnd-- = '\0';
107960108561
}
107961108562
/* substr() operations on characters, but addColOffset is in bytes. So we
107962108563
** have to use printf() to translate between these units: */
107963
- assert( !IsVirtual(pTab) );
108564
+ assert( IsOrdinaryTable(pTab) );
108565
+ assert( IsOrdinaryTable(pNew) );
107964108566
sqlite3NestedParse(pParse,
107965
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108567
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
107966108568
"sql = printf('%%.%ds, ',sql) || %Q"
107967108569
" || substr(sql,1+length(printf('%%.%ds',sql))) "
107968108570
"WHERE type = 'table' AND name = %Q",
107969108571
zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,
107970108572
zTab
@@ -107986,11 +108588,11 @@
107986108588
VdbeCoverage(v);
107987108589
sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
107988108590
sqlite3ReleaseTempReg(pParse, r1);
107989108591
107990108592
/* Reload the table definition */
107991
- renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
108593
+ renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd);
107992108594
107993108595
/* Verify that constraints are still satisfied */
107994108596
if( pNew->pCheck!=0
107995108597
|| (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
107996108598
){
@@ -108052,10 +108654,11 @@
108052108654
if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
108053108655
goto exit_begin_add_column;
108054108656
}
108055108657
108056108658
sqlite3MayAbort(pParse);
108659
+ assert( IsOrdinaryTable(pTab) );
108057108660
assert( pTab->u.tab.addColOffset>0 );
108058108661
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
108059108662
108060108663
/* Put a copy of the Table struct in Parse.pNewTable for the
108061108664
** sqlite3AddColumn() function and friends to modify. But modify
@@ -108082,11 +108685,11 @@
108082108685
for(i=0; i<pNew->nCol; i++){
108083108686
Column *pCol = &pNew->aCol[i];
108084108687
pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName);
108085108688
pCol->hName = sqlite3StrIHash(pCol->zCnName);
108086108689
}
108087
- assert( !IsVirtual(pNew) );
108690
+ assert( IsOrdinaryTable(pNew) );
108088108691
pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0);
108089108692
pNew->pSchema = db->aDb[iDb].pSchema;
108090108693
pNew->u.tab.addColOffset = pTab->u.tab.addColOffset;
108091108694
pNew->nTabRef = 1;
108092108695
@@ -108193,21 +108796,21 @@
108193108796
zNew = sqlite3NameFromToken(db, pNew);
108194108797
if( !zNew ) goto exit_rename_column;
108195108798
assert( pNew->n>0 );
108196108799
bQuote = sqlite3Isquote(pNew->z[0]);
108197108800
sqlite3NestedParse(pParse,
108198
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108801
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108199108802
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
108200108803
"WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
108201108804
" AND (type != 'index' OR tbl_name = %Q)",
108202108805
zDb,
108203108806
zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
108204108807
pTab->zName
108205108808
);
108206108809
108207108810
sqlite3NestedParse(pParse,
108208
- "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
108811
+ "UPDATE temp." LEGACY_SCHEMA_TABLE " SET "
108209108812
"sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
108210108813
"WHERE type IN ('trigger', 'view')",
108211108814
zDb, pTab->zName, iCol, zNew, bQuote
108212108815
);
108213108816
@@ -108351,11 +108954,13 @@
108351108954
** Walker callback used by sqlite3RenameExprUnmap().
108352108955
*/
108353108956
static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
108354108957
Parse *pParse = pWalker->pParse;
108355108958
sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr);
108356
- sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);
108959
+ if( ExprUseYTab(pExpr) ){
108960
+ sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);
108961
+ }
108357108962
return WRC_Continue;
108358108963
}
108359108964
108360108965
/*
108361108966
** Iterate through the Select objects that are part of WITH clauses attached
@@ -108413,11 +109018,13 @@
108413109018
*/
108414109019
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
108415109020
Parse *pParse = pWalker->pParse;
108416109021
int i;
108417109022
if( pParse->nErr ) return WRC_Abort;
108418
- if( NEVER(p->selFlags & (SF_View|SF_CopyCte)) ){
109023
+ testcase( p->selFlags & SF_View );
109024
+ testcase( p->selFlags & SF_CopyCte );
109025
+ if( p->selFlags & (SF_View|SF_CopyCte) ){
108419109026
return WRC_Prune;
108420109027
}
108421109028
if( ALWAYS(p->pEList) ){
108422109029
ExprList *pList = p->pEList;
108423109030
for(i=0; i<pList->nExpr; i++){
@@ -108550,10 +109157,11 @@
108550109157
&& pWalker->pParse->pTriggerTab==p->pTab
108551109158
){
108552109159
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
108553109160
}else if( pExpr->op==TK_COLUMN
108554109161
&& pExpr->iColumn==p->iCol
109162
+ && ALWAYS(ExprUseYTab(pExpr))
108555109163
&& p->pTab==pExpr->y.pTab
108556109164
){
108557109165
renameTokenFind(pWalker->pParse, p, (void*)pExpr);
108558109166
}
108559109167
return WRC_Continue;
@@ -108874,10 +109482,13 @@
108874109482
p->pTab->nTabRef++;
108875109483
rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
108876109484
}
108877109485
}
108878109486
}
109487
+ if( rc==SQLITE_OK && db->mallocFailed ){
109488
+ rc = SQLITE_NOMEM;
109489
+ }
108879109490
sNC.pSrcList = pSrc;
108880109491
if( rc==SQLITE_OK && pStep->pWhere ){
108881109492
rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
108882109493
}
108883109494
if( rc==SQLITE_OK ){
@@ -109080,11 +109691,11 @@
109080109691
sqlite3WalkExpr(&sWalker, pExpr);
109081109692
}
109082109693
#endif
109083109694
}
109084109695
109085
- assert( !IsVirtual(sParse.pNewTable) );
109696
+ assert( IsOrdinaryTable(sParse.pNewTable) );
109086109697
for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
109087109698
for(i=0; i<pFKey->nCol; i++){
109088109699
if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
109089109700
renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
109090109701
}
@@ -109152,11 +109763,14 @@
109152109763
/*
109153109764
** Walker expression callback used by "RENAME TABLE".
109154109765
*/
109155109766
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
109156109767
RenameCtx *p = pWalker->u.pRename;
109157
- if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
109768
+ if( pExpr->op==TK_COLUMN
109769
+ && ALWAYS(ExprUseYTab(pExpr))
109770
+ && p->pTab==pExpr->y.pTab
109771
+ ){
109158109772
renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
109159109773
}
109160109774
return WRC_Continue;
109161109775
}
109162109776
@@ -109270,11 +109884,11 @@
109270109884
#ifndef SQLITE_OMIT_FOREIGN_KEY
109271109885
if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys))
109272109886
&& !IsVirtual(pTab)
109273109887
){
109274109888
FKey *pFKey;
109275
- assert( !IsVirtual(pTab) );
109889
+ assert( IsOrdinaryTable(pTab) );
109276109890
for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
109277109891
if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
109278109892
renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
109279109893
}
109280109894
}
@@ -109591,11 +110205,11 @@
109591110205
if( iCol<pTab->nCol-1 ){
109592110206
RenameToken *pEnd;
109593110207
pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName);
109594110208
zEnd = (const char*)pEnd->t.z;
109595110209
}else{
109596
- assert( !IsVirtual(pTab) );
110210
+ assert( IsOrdinaryTable(pTab) );
109597110211
zEnd = (const char*)&zSql[pTab->u.tab.addColOffset];
109598110212
while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--;
109599110213
}
109600110214
109601110215
zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd);
@@ -109673,11 +110287,11 @@
109673110287
assert( iDb>=0 );
109674110288
zDb = db->aDb[iDb].zDbSName;
109675110289
renameTestSchema(pParse, zDb, iDb==1, "", 0);
109676110290
renameFixQuotes(pParse, zDb, iDb==1);
109677110291
sqlite3NestedParse(pParse,
109678
- "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
110292
+ "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
109679110293
"sql = sqlite_drop_column(%d, sql, %d) "
109680110294
"WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
109681110295
, zDb, iDb, iCol, pTab->zName
109682110296
);
109683110297
@@ -110766,11 +111380,11 @@
110766111380
pParse->nMem = MAX(pParse->nMem, iMem);
110767111381
v = sqlite3GetVdbe(pParse);
110768111382
if( v==0 || NEVER(pTab==0) ){
110769111383
return;
110770111384
}
110771
- if( pTab->tnum==0 ){
111385
+ if( !IsOrdinaryTable(pTab) ){
110772111386
/* Do not gather statistics on views or virtual tables */
110773111387
return;
110774111388
}
110775111389
if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
110776111390
/* Do not gather statistics on system tables */
@@ -112049,21 +112663,22 @@
112049112663
if( pParse->nErr ) goto attach_end;
112050112664
memset(&sName, 0, sizeof(NameContext));
112051112665
sName.pParse = pParse;
112052112666
112053112667
if(
112054
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
112055
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
112056
- SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
112668
+ SQLITE_OK!=resolveAttachExpr(&sName, pFilename) ||
112669
+ SQLITE_OK!=resolveAttachExpr(&sName, pDbname) ||
112670
+ SQLITE_OK!=resolveAttachExpr(&sName, pKey)
112057112671
){
112058112672
goto attach_end;
112059112673
}
112060112674
112061112675
#ifndef SQLITE_OMIT_AUTHORIZATION
112062112676
if( pAuthArg ){
112063112677
char *zAuthArg;
112064112678
if( pAuthArg->op==TK_STRING ){
112679
+ assert( !ExprHasProperty(pAuthArg, EP_IntValue) );
112065112680
zAuthArg = pAuthArg->u.zToken;
112066112681
}else{
112067112682
zAuthArg = 0;
112068112683
}
112069112684
rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
@@ -112744,21 +113359,26 @@
112744113359
Returning *pReturning = pParse->u1.pReturning;
112745113360
int addrRewind;
112746113361
int i;
112747113362
int reg;
112748113363
112749
- addrRewind =
112750
- sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
112751
- VdbeCoverage(v);
112752
- reg = pReturning->iRetReg;
112753
- for(i=0; i<pReturning->nRetCol; i++){
112754
- sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i);
112755
- }
112756
- sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i);
112757
- sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1);
112758
- VdbeCoverage(v);
112759
- sqlite3VdbeJumpHere(v, addrRewind);
113364
+ if( pReturning->nRetCol==0 ){
113365
+ assert( CORRUPT_DB );
113366
+ }else{
113367
+ sqlite3VdbeAddOp0(v, OP_FkCheck);
113368
+ addrRewind =
113369
+ sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
113370
+ VdbeCoverage(v);
113371
+ reg = pReturning->iRetReg;
113372
+ for(i=0; i<pReturning->nRetCol; i++){
113373
+ sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i);
113374
+ }
113375
+ sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i);
113376
+ sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1);
113377
+ VdbeCoverage(v);
113378
+ sqlite3VdbeJumpHere(v, addrRewind);
113379
+ }
112760113380
}
112761113381
sqlite3VdbeAddOp0(v, OP_Halt);
112762113382
112763113383
#if SQLITE_USER_AUTHENTICATION
112764113384
if( pParse->nTableLock>0 && db->init.busy==0 ){
@@ -112835,11 +113455,15 @@
112835113455
}
112836113456
}
112837113457
112838113458
if( pParse->bReturning ){
112839113459
Returning *pRet = pParse->u1.pReturning;
112840
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
113460
+ if( pRet->nRetCol==0 ){
113461
+ assert( CORRUPT_DB );
113462
+ }else{
113463
+ sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
113464
+ }
112841113465
}
112842113466
112843113467
/* Finally, jump back to the beginning of the executable code. */
112844113468
sqlite3VdbeGoto(v, 1);
112845113469
}
@@ -112953,21 +113577,21 @@
112953113577
}
112954113578
}
112955113579
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
112956113580
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
112957113581
if( i==1 ){
112958
- if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0
112959
- || sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0
112960
- || sqlite3StrICmp(zName+7, &DFLT_SCHEMA_TABLE[7])==0
113582
+ if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0
113583
+ || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0
113584
+ || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0
112961113585
){
112962113586
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
112963
- DFLT_TEMP_SCHEMA_TABLE);
113587
+ LEGACY_TEMP_SCHEMA_TABLE);
112964113588
}
112965113589
}else{
112966
- if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
113590
+ if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
112967113591
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
112968
- DFLT_SCHEMA_TABLE);
113592
+ LEGACY_SCHEMA_TABLE);
112969113593
}
112970113594
}
112971113595
}
112972113596
}else{
112973113597
/* Match against TEMP first */
@@ -112981,15 +113605,15 @@
112981113605
assert( sqlite3SchemaMutexHeld(db, i, 0) );
112982113606
p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
112983113607
if( p ) break;
112984113608
}
112985113609
if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
112986
- if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
112987
- p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE);
112988
- }else if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 ){
113610
+ if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113611
+ p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE);
113612
+ }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
112989113613
p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
112990
- DFLT_TEMP_SCHEMA_TABLE);
113614
+ LEGACY_TEMP_SCHEMA_TABLE);
112991113615
}
112992113616
}
112993113617
}
112994113618
return p;
112995113619
}
@@ -113080,10 +113704,26 @@
113080113704
}else{
113081113705
zDb = p->zDatabase;
113082113706
}
113083113707
return sqlite3LocateTable(pParse, flags, p->zName, zDb);
113084113708
}
113709
+
113710
+/*
113711
+** Return the preferred table name for system tables. Translate legacy
113712
+** names into the new preferred names, as appropriate.
113713
+*/
113714
+SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){
113715
+ if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113716
+ if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){
113717
+ return PREFERRED_SCHEMA_TABLE;
113718
+ }
113719
+ if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){
113720
+ return PREFERRED_TEMP_SCHEMA_TABLE;
113721
+ }
113722
+ }
113723
+ return zName;
113724
+}
113085113725
113086113726
/*
113087113727
** Locate the in-memory structure that describes
113088113728
** a particular index given the name of that index
113089113729
** and the name of the database that contains the index.
@@ -113257,11 +113897,11 @@
113257113897
Table *pTab, /* The table containing the column */
113258113898
Column *pCol, /* The column to receive the new DEFAULT expression */
113259113899
Expr *pExpr /* The new default expression */
113260113900
){
113261113901
ExprList *pList;
113262
- assert( !IsVirtual(pTab) );
113902
+ assert( IsOrdinaryTable(pTab) );
113263113903
pList = pTab->u.tab.pDfltList;
113264113904
if( pCol->iDflt==0
113265113905
|| NEVER(pList==0)
113266113906
|| NEVER(pList->nExpr<pCol->iDflt)
113267113907
){
@@ -113278,11 +113918,11 @@
113278113918
** the DEFAULT clause or the AS clause of a generated column.
113279113919
** Return NULL if the column has no associated expression.
113280113920
*/
113281113921
SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
113282113922
if( pCol->iDflt==0 ) return 0;
113283
- if( NEVER(IsVirtual(pTab)) ) return 0;
113923
+ if( NEVER(!IsOrdinaryTable(pTab)) ) return 0;
113284113924
if( NEVER(pTab->u.tab.pDfltList==0) ) return 0;
113285113925
if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0;
113286113926
return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
113287113927
}
113288113928
@@ -113292,12 +113932,12 @@
113292113932
SQLITE_PRIVATE void sqlite3ColumnSetColl(
113293113933
sqlite3 *db,
113294113934
Column *pCol,
113295113935
const char *zColl
113296113936
){
113297
- int nColl;
113298
- int n;
113937
+ i64 nColl;
113938
+ i64 n;
113299113939
char *zNew;
113300113940
assert( zColl!=0 );
113301113941
n = sqlite3Strlen30(pCol->zCnName) + 1;
113302113942
if( pCol->colFlags & COLFLAG_HASTYPE ){
113303113943
n += sqlite3Strlen30(pCol->zCnName+n) + 1;
@@ -113337,17 +113977,17 @@
113337113977
for(i=0; i<pTable->nCol; i++, pCol++){
113338113978
assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) );
113339113979
sqlite3DbFree(db, pCol->zCnName);
113340113980
}
113341113981
sqlite3DbFree(db, pTable->aCol);
113342
- if( !IsVirtual(pTable) ){
113982
+ if( IsOrdinaryTable(pTable) ){
113343113983
sqlite3ExprListDelete(db, pTable->u.tab.pDfltList);
113344113984
}
113345113985
if( db==0 || db->pnBytesFreed==0 ){
113346113986
pTable->aCol = 0;
113347113987
pTable->nCol = 0;
113348
- if( !IsVirtual(pTable) ){
113988
+ if( IsOrdinaryTable(pTable) ){
113349113989
pTable->u.tab.pDfltList = 0;
113350113990
}
113351113991
}
113352113992
}
113353113993
}
@@ -113479,11 +114119,11 @@
113479114119
** Open the sqlite_schema table stored in database number iDb for
113480114120
** writing. The table is opened using cursor 0.
113481114121
*/
113482114122
SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){
113483114123
Vdbe *v = sqlite3GetVdbe(p);
113484
- sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
114124
+ sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE);
113485114125
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
113486114126
if( p->nTab==0 ){
113487114127
p->nTab = 1;
113488114128
}
113489114129
}
@@ -114098,11 +114738,11 @@
114098114738
break;
114099114739
}
114100114740
}
114101114741
}
114102114742
114103
- z = sqlite3DbMallocRaw(db, sName.n + 1 + sType.n + (sType.n>0) );
114743
+ z = sqlite3DbMallocRaw(db, (i64)sName.n + 1 + (i64)sType.n + (sType.n>0) );
114104114744
if( z==0 ) return;
114105114745
if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName);
114106114746
memcpy(z, sName.z, sName.n);
114107114747
z[sName.n] = 0;
114108114748
sqlite3Dequote(z);
@@ -114112,11 +114752,11 @@
114112114752
sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
114113114753
sqlite3DbFree(db, z);
114114114754
return;
114115114755
}
114116114756
}
114117
- aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+1)*sizeof(p->aCol[0]));
114757
+ aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0]));
114118114758
if( aNew==0 ){
114119114759
sqlite3DbFree(db, z);
114120114760
return;
114121114761
}
114122114762
p->aCol = aNew;
@@ -114410,11 +115050,13 @@
114410115050
for(i=0; i<nTerm; i++){
114411115051
Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
114412115052
assert( pCExpr!=0 );
114413115053
sqlite3StringToId(pCExpr);
114414115054
if( pCExpr->op==TK_ID ){
114415
- const char *zCName = pCExpr->u.zToken;
115055
+ const char *zCName;
115056
+ assert( !ExprHasProperty(pCExpr, EP_IntValue) );
115057
+ zCName = pCExpr->u.zToken;
114416115058
for(iCol=0; iCol<pTab->nCol; iCol++){
114417115059
if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){
114418115060
pCol = &pTab->aCol[iCol];
114419115061
makeColumnPartOfPrimaryKey(pParse, pCol);
114420115062
break;
@@ -114782,11 +115424,10 @@
114782115424
** This is used to determine if the column number x appears in any of the
114783115425
** first nCol entries of an index.
114784115426
*/
114785115427
static int hasColumn(const i16 *aiCol, int nCol, int x){
114786115428
while( nCol-- > 0 ){
114787
- assert( aiCol[0]>=0 );
114788115429
if( x==*(aiCol++) ){
114789115430
return 1;
114790115431
}
114791115432
}
114792115433
return 0;
@@ -115057,10 +115698,45 @@
115057115698
if( pMod->pModule->xShadowName==0 ) return 0;
115058115699
return pMod->pModule->xShadowName(zName+nName+1);
115059115700
}
115060115701
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115061115702
115703
+#ifndef SQLITE_OMIT_VIRTUALTABLE
115704
+/*
115705
+** Table pTab is a virtual table. If it the virtual table implementation
115706
+** exists and has an xShadowName method, then loop over all other ordinary
115707
+** tables within the same schema looking for shadow tables of pTab, and mark
115708
+** any shadow tables seen using the TF_Shadow flag.
115709
+*/
115710
+SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){
115711
+ int nName; /* Length of pTab->zName */
115712
+ Module *pMod; /* Module for the virtual table */
115713
+ HashElem *k; /* For looping through the symbol table */
115714
+
115715
+ assert( IsVirtual(pTab) );
115716
+ pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]);
115717
+ if( pMod==0 ) return;
115718
+ if( NEVER(pMod->pModule==0) ) return;
115719
+ if( pMod->pModule->iVersion<3 ) return;
115720
+ if( pMod->pModule->xShadowName==0 ) return;
115721
+ assert( pTab->zName!=0 );
115722
+ nName = sqlite3Strlen30(pTab->zName);
115723
+ for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){
115724
+ Table *pOther = sqliteHashData(k);
115725
+ assert( pOther->zName!=0 );
115726
+ if( !IsOrdinaryTable(pOther) ) continue;
115727
+ if( pOther->tabFlags & TF_Shadow ) continue;
115728
+ if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0
115729
+ && pOther->zName[nName]=='_'
115730
+ && pMod->pModule->xShadowName(pOther->zName+nName+1)
115731
+ ){
115732
+ pOther->tabFlags |= TF_Shadow;
115733
+ }
115734
+ }
115735
+}
115736
+#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115737
+
115062115738
#ifndef SQLITE_OMIT_VIRTUALTABLE
115063115739
/*
115064115740
** Return true if zName is a shadow table name in the current database
115065115741
** connection.
115066115742
**
@@ -115158,11 +115834,11 @@
115158115834
**
115159115835
** If the root page number is 1, that means this is the sqlite_schema
115160115836
** table itself. So mark it read-only.
115161115837
*/
115162115838
if( db->init.busy ){
115163
- if( pSelect ){
115839
+ if( pSelect || (!IsOrdinaryTable(p) && db->init.newTnum) ){
115164115840
sqlite3ErrorMsg(pParse, "");
115165115841
return;
115166115842
}
115167115843
p->tnum = db->init.newTnum;
115168115844
if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
@@ -115385,11 +116061,11 @@
115385116061
/* A slot for the record has already been allocated in the
115386116062
** schema table. We just need to update that slot with all
115387116063
** the information we've collected.
115388116064
*/
115389116065
sqlite3NestedParse(pParse,
115390
- "UPDATE %Q." DFLT_SCHEMA_TABLE
116066
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE
115391116067
" SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
115392116068
" WHERE rowid=#%d",
115393116069
db->aDb[iDb].zDbSName,
115394116070
zType,
115395116071
p->zName,
@@ -115571,17 +116247,16 @@
115571116247
#endif
115572116248
115573116249
assert( pTable );
115574116250
115575116251
#ifndef SQLITE_OMIT_VIRTUALTABLE
115576
- db->nSchemaLock++;
115577
- rc = sqlite3VtabCallConnect(pParse, pTable);
115578
- db->nSchemaLock--;
115579
- if( rc ){
115580
- return 1;
116252
+ if( IsVirtual(pTable) ){
116253
+ db->nSchemaLock++;
116254
+ rc = sqlite3VtabCallConnect(pParse, pTable);
116255
+ db->nSchemaLock--;
116256
+ return rc;
115581116257
}
115582
- if( IsVirtual(pTable) ) return 0;
115583116258
#endif
115584116259
115585116260
#ifndef SQLITE_OMIT_VIEW
115586116261
/* A positive nCol means the columns names for this view are
115587116262
** already known.
@@ -115765,11 +116440,11 @@
115765116440
** The "#NNN" in the SQL is a special constant that means whatever value
115766116441
** is in register NNN. See grammar rules associated with the TK_REGISTER
115767116442
** token for additional information.
115768116443
*/
115769116444
sqlite3NestedParse(pParse,
115770
- "UPDATE %Q." DFLT_SCHEMA_TABLE
116445
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE
115771116446
" SET rootpage=%d WHERE #%d AND rootpage=#%d",
115772116447
pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
115773116448
#endif
115774116449
sqlite3ReleaseTempReg(pParse, r1);
115775116450
}
@@ -115900,11 +116575,11 @@
115900116575
** dropped. Triggers are handled separately because a trigger can be
115901116576
** created in the temp database that refers to a table in another
115902116577
** database.
115903116578
*/
115904116579
sqlite3NestedParse(pParse,
115905
- "DELETE FROM %Q." DFLT_SCHEMA_TABLE
116580
+ "DELETE FROM %Q." LEGACY_SCHEMA_TABLE
115906116581
" WHERE tbl_name=%Q and type!='trigger'",
115907116582
pDb->zDbSName, pTab->zName);
115908116583
if( !isView && !IsVirtual(pTab) ){
115909116584
destroyTable(pParse, pTab);
115910116585
}
@@ -115947,10 +116622,13 @@
115947116622
if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
115948116623
return 1;
115949116624
}
115950116625
if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
115951116626
return 1;
116627
+ }
116628
+ if( pTab->tabFlags & TF_Eponymous ){
116629
+ return 1;
115952116630
}
115953116631
return 0;
115954116632
}
115955116633
115956116634
/*
@@ -116087,11 +116765,11 @@
116087116765
sqlite3 *db = pParse->db;
116088116766
#ifndef SQLITE_OMIT_FOREIGN_KEY
116089116767
FKey *pFKey = 0;
116090116768
FKey *pNextTo;
116091116769
Table *p = pParse->pNewTable;
116092
- int nByte;
116770
+ i64 nByte;
116093116771
int i;
116094116772
int nCol;
116095116773
char *z;
116096116774
116097116775
assert( pTo!=0 );
@@ -116123,10 +116801,11 @@
116123116801
pFKey = sqlite3DbMallocZero(db, nByte );
116124116802
if( pFKey==0 ){
116125116803
goto fk_end;
116126116804
}
116127116805
pFKey->pFrom = p;
116806
+ assert( IsOrdinaryTable(p) );
116128116807
pFKey->pNextFrom = p->u.tab.pFKey;
116129116808
z = (char*)&pFKey->aCol[nCol];
116130116809
pFKey->zTo = z;
116131116810
if( IN_RENAME_OBJECT ){
116132116811
sqlite3RenameTokenMap(pParse, (void*)z, pTo);
@@ -116188,11 +116867,11 @@
116188116867
pNextTo->pPrevTo = pFKey;
116189116868
}
116190116869
116191116870
/* Link the foreign key to the table as the last step.
116192116871
*/
116193
- assert( !IsVirtual(p) );
116872
+ assert( IsOrdinaryTable(p) );
116194116873
p->u.tab.pFKey = pFKey;
116195116874
pFKey = 0;
116196116875
116197116876
fk_end:
116198116877
sqlite3DbFree(db, pFKey);
@@ -116211,11 +116890,11 @@
116211116890
SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
116212116891
#ifndef SQLITE_OMIT_FOREIGN_KEY
116213116892
Table *pTab;
116214116893
FKey *pFKey;
116215116894
if( (pTab = pParse->pNewTable)==0 ) return;
116216
- if( NEVER(IsVirtual(pTab)) ) return;
116895
+ if( NEVER(!IsOrdinaryTable(pTab)) ) return;
116217116896
if( (pFKey = pTab->u.tab.pFKey)==0 ) return;
116218116897
assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
116219116898
pFKey->isDeferred = (u8)isDeferred;
116220116899
#endif
116221116900
}
@@ -116613,10 +117292,11 @@
116613117292
*/
116614117293
for(i=0; i<pList->nExpr; i++){
116615117294
Expr *pExpr = pList->a[i].pExpr;
116616117295
assert( pExpr!=0 );
116617117296
if( pExpr->op==TK_COLLATE ){
117297
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
116618117298
nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
116619117299
}
116620117300
}
116621117301
116622117302
/*
@@ -116708,10 +117388,11 @@
116708117388
pIndex->aiColumn[i] = (i16)j;
116709117389
}
116710117390
zColl = 0;
116711117391
if( pListItem->pExpr->op==TK_COLLATE ){
116712117392
int nColl;
117393
+ assert( !ExprHasProperty(pListItem->pExpr, EP_IntValue) );
116713117394
zColl = pListItem->pExpr->u.zToken;
116714117395
nColl = sqlite3Strlen30(zColl) + 1;
116715117396
assert( nExtra>=nColl );
116716117397
memcpy(zExtra, zColl, nColl);
116717117398
zColl = zExtra;
@@ -116914,17 +117595,17 @@
116914117595
}
116915117596
116916117597
/* Add an entry in sqlite_schema for this index
116917117598
*/
116918117599
sqlite3NestedParse(pParse,
116919
- "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
116920
- db->aDb[iDb].zDbSName,
116921
- pIndex->zName,
116922
- pTab->zName,
116923
- iMem,
116924
- zStmt
116925
- );
117600
+ "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
117601
+ db->aDb[iDb].zDbSName,
117602
+ pIndex->zName,
117603
+ pTab->zName,
117604
+ iMem,
117605
+ zStmt
117606
+ );
116926117607
sqlite3DbFree(db, zStmt);
116927117608
116928117609
/* Fill the index with data and reparse the schema. Code an OP_Expire
116929117610
** to invalidate all pre-compiled statements.
116930117611
*/
@@ -117100,11 +117781,11 @@
117100117781
/* Generate code to remove the index and from the schema table */
117101117782
v = sqlite3GetVdbe(pParse);
117102117783
if( v ){
117103117784
sqlite3BeginWriteOperation(pParse, 1, iDb);
117104117785
sqlite3NestedParse(pParse,
117105
- "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117786
+ "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117106117787
db->aDb[iDb].zDbSName, pIndex->zName
117107117788
);
117108117789
sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
117109117790
sqlite3ChangeCookie(pParse, iDb);
117110117791
destroyRootPage(pParse, pIndex->tnum, iDb);
@@ -117468,11 +118149,11 @@
117468118149
pItem->pSelect = pSubquery;
117469118150
pItem->pOn = pOn;
117470118151
pItem->pUsing = pUsing;
117471118152
return p;
117472118153
117473
- append_from_error:
118154
+append_from_error:
117474118155
assert( p==0 );
117475118156
sqlite3ExprDelete(db, pOn);
117476118157
sqlite3IdListDelete(db, pUsing);
117477118158
sqlite3SelectDelete(db, pSubquery);
117478118159
return 0;
@@ -117496,10 +118177,11 @@
117496118177
** construct "indexed_opt" for details. */
117497118178
pItem->fg.notIndexed = 1;
117498118179
}else{
117499118180
pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
117500118181
pItem->fg.isIndexedBy = 1;
118182
+ assert( pItem->fg.isCte==0 ); /* No collision on union u2 */
117501118183
}
117502118184
}
117503118185
}
117504118186
117505118187
/*
@@ -118476,10 +119158,11 @@
118476119158
int h, /* Hash of the name */
118477119159
const char *zFunc /* Name of function */
118478119160
){
118479119161
FuncDef *p;
118480119162
for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
119163
+ assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
118481119164
if( sqlite3StrICmp(p->zName, zFunc)==0 ){
118482119165
return p;
118483119166
}
118484119167
}
118485119168
return 0;
@@ -118497,10 +119180,11 @@
118497119180
FuncDef *pOther;
118498119181
const char *zName = aDef[i].zName;
118499119182
int nName = sqlite3Strlen30(zName);
118500119183
int h = SQLITE_FUNC_HASH(zName[0], nName);
118501119184
assert( zName[0]>='a' && zName[0]<='z' );
119185
+ assert( aDef[i].funcFlags & SQLITE_FUNC_BUILTIN );
118502119186
pOther = sqlite3FunctionSearch(h, zName);
118503119187
if( pOther ){
118504119188
assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
118505119189
aDef[i].pNext = pOther->pNext;
118506119190
pOther->pNext = &aDef[i];
@@ -118721,10 +119405,20 @@
118721119405
pTab = 0;
118722119406
}
118723119407
}
118724119408
return pTab;
118725119409
}
119410
+
119411
+/* Generate byte-code that will report the number of rows modified
119412
+** by a DELETE, INSERT, or UPDATE statement.
119413
+*/
119414
+SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){
119415
+ sqlite3VdbeAddOp0(v, OP_FkCheck);
119416
+ sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1);
119417
+ sqlite3VdbeSetNumCols(v, 1);
119418
+ sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC);
119419
+}
118726119420
118727119421
/* Return true if table pTab is read-only.
118728119422
**
118729119423
** A table is read-only if any of the following are true:
118730119424
**
@@ -118888,10 +119582,11 @@
118888119582
** and the SELECT subtree. */
118889119583
pSrc->a[0].pTab = 0;
118890119584
pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
118891119585
pSrc->a[0].pTab = pTab;
118892119586
if( pSrc->a[0].fg.isIndexedBy ){
119587
+ assert( pSrc->a[0].fg.isCte==0 );
118893119588
pSrc->a[0].u2.pIBIndex = 0;
118894119589
pSrc->a[0].fg.isIndexedBy = 0;
118895119590
sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
118896119591
}else if( pSrc->a[0].fg.isCte ){
118897119592
pSrc->a[0].u2.pCteUse->nUse++;
@@ -119296,13 +119991,11 @@
119296119991
/* Return the number of rows that were deleted. If this routine is
119297119992
** generating code because of a call to sqlite3NestedParse(), do not
119298119993
** invoke the callback function.
119299119994
*/
119300119995
if( memCnt ){
119301
- sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1);
119302
- sqlite3VdbeSetNumCols(v, 1);
119303
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
119996
+ sqlite3CodeChangeCount(v, memCnt, "rows deleted");
119304119997
}
119305119998
119306119999
delete_from_cleanup:
119307120000
sqlite3AuthContextPop(&sContext);
119308120001
sqlite3SrcListDelete(db, pTabList);
@@ -121472,11 +122165,15 @@
121472122165
if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
121473122166
pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
121474122167
/* pGCC is always non-NULL since groupConcatStep() will have always
121475122168
** run frist to initialize it */
121476122169
if( ALWAYS(pGCC) ){
121477
- int nVS = sqlite3_value_bytes(argv[0]);
122170
+ int nVS;
122171
+ /* Must call sqlite3_value_text() to convert the argument into text prior
122172
+ ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
122173
+ (void)sqlite3_value_text(argv[0]);
122174
+ nVS = sqlite3_value_bytes(argv[0]);
121478122175
pGCC->nAccum -= 1;
121479122176
if( pGCC->pnSepLengths!=0 ){
121480122177
assert(pGCC->nAccum >= 0);
121481122178
if( pGCC->nAccum>0 ){
121482122179
nVS += *pGCC->pnSepLengths;
@@ -121587,15 +122284,16 @@
121587122284
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
121588122285
FuncDef *pDef;
121589122286
int nExpr;
121590122287
assert( pExpr!=0 );
121591122288
assert( pExpr->op==TK_FUNCTION );
122289
+ assert( ExprUseXList(pExpr) );
121592122290
if( !pExpr->x.pList ){
121593122291
return 0;
121594122292
}
121595
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
121596122293
nExpr = pExpr->x.pList->nExpr;
122294
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
121597122295
pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
121598122296
#ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
121599122297
if( pDef==0 ) return 0;
121600122298
#endif
121601122299
if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
@@ -121615,10 +122313,11 @@
121615122313
aWc[3] = 0;
121616122314
}else{
121617122315
Expr *pEscape = pExpr->x.pList->a[2].pExpr;
121618122316
char *zEscape;
121619122317
if( pEscape->op!=TK_STRING ) return 0;
122318
+ assert( !ExprHasProperty(pEscape, EP_IntValue) );
121620122319
zEscape = pEscape->u.zToken;
121621122320
if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
121622122321
if( zEscape[0]==aWc[0] ) return 0;
121623122322
if( zEscape[0]==aWc[1] ) return 0;
121624122323
aWc[3] = zEscape[0];
@@ -121996,10 +122695,11 @@
121996122695
for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
121997122696
printf("FUNC-HASH %02d:", i);
121998122697
for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
121999122698
int n = sqlite3Strlen30(p->zName);
122000122699
int h = p->zName[0] + n;
122700
+ assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
122001122701
printf(" %s(%d)", p->zName, h);
122002122702
}
122003122703
printf("\n");
122004122704
}
122005122705
}
@@ -122518,10 +123218,11 @@
122518123218
int iCursor, /* The open cursor on the table */
122519123219
i16 iCol /* The column that is wanted */
122520123220
){
122521123221
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
122522123222
if( pExpr ){
123223
+ assert( ExprUseYTab(pExpr) );
122523123224
pExpr->y.pTab = pTab;
122524123225
pExpr->iTable = iCursor;
122525123226
pExpr->iColumn = iCol;
122526123227
}
122527123228
return pExpr;
@@ -122728,17 +123429,16 @@
122728123429
** the table from the database. Triggers are disabled while running this
122729123430
** DELETE, but foreign key actions are not.
122730123431
*/
122731123432
SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
122732123433
sqlite3 *db = pParse->db;
122733
- if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){
123434
+ if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){
122734123435
int iSkip = 0;
122735123436
Vdbe *v = sqlite3GetVdbe(pParse);
122736123437
122737123438
assert( v ); /* VDBE has already been allocated */
122738
- assert( !IsView(pTab) ); /* Not a view */
122739
- assert( !IsVirtual(pTab) );
123439
+ assert( IsOrdinaryTable(pTab) );
122740123440
if( sqlite3FkReferences(pTab)==0 ){
122741123441
/* Search for a deferred foreign key constraint for which this table
122742123442
** is the child table. If one cannot be found, return without
122743123443
** generating any VDBE code. If one can be found, then jump over
122744123444
** the entire DELETE if there are no outstanding deferred constraints
@@ -122898,17 +123598,17 @@
122898123598
/* Exactly one of regOld and regNew should be non-zero. */
122899123599
assert( (regOld==0)!=(regNew==0) );
122900123600
122901123601
/* If foreign-keys are disabled, this function is a no-op. */
122902123602
if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
123603
+ if( !IsOrdinaryTable(pTab) ) return;
122903123604
122904123605
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
122905123606
zDb = db->aDb[iDb].zDbSName;
122906123607
122907123608
/* Loop through all the foreign key constraints for which pTab is the
122908123609
** child table (the table that the foreign key definition is part of). */
122909
- assert( !IsVirtual(pTab) );
122910123610
for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
122911123611
Table *pTo; /* Parent table of foreign key pFKey */
122912123612
Index *pIdx = 0; /* Index on key columns in pTo */
122913123613
int *aiFree = 0;
122914123614
int *aiCol;
@@ -123087,14 +123787,13 @@
123087123787
SQLITE_PRIVATE u32 sqlite3FkOldmask(
123088123788
Parse *pParse, /* Parse context */
123089123789
Table *pTab /* Table being modified */
123090123790
){
123091123791
u32 mask = 0;
123092
- if( pParse->db->flags&SQLITE_ForeignKeys ){
123792
+ if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){
123093123793
FKey *p;
123094123794
int i;
123095
- assert( !IsVirtual(pTab) );
123096123795
for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){
123097123796
for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
123098123797
}
123099123798
for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
123100123799
Index *pIdx = 0;
@@ -123141,11 +123840,11 @@
123141123840
int *aChange, /* Non-NULL for UPDATE operations */
123142123841
int chngRowid /* True for UPDATE that affects rowid */
123143123842
){
123144123843
int eRet = 1; /* Value to return if bHaveFK is true */
123145123844
int bHaveFK = 0; /* If FK processing is required */
123146
- if( pParse->db->flags&SQLITE_ForeignKeys && !IsVirtual(pTab) ){
123845
+ if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){
123147123846
if( !aChange ){
123148123847
/* A DELETE operation. Foreign key processing is required if the
123149123848
** table in question is either the child or parent table for any
123150123849
** foreign key constraint. */
123151123850
bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey);
@@ -123429,11 +124128,11 @@
123429124128
*/
123430124129
SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
123431124130
FKey *pFKey; /* Iterator variable */
123432124131
FKey *pNext; /* Copy of pFKey->pNextFrom */
123433124132
123434
- assert( !IsVirtual(pTab) );
124133
+ assert( IsOrdinaryTable(pTab) );
123435124134
for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){
123436124135
assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
123437124136
123438124137
/* Remove the FK from the fkeyHash hash table. */
123439124138
if( !db || db->pnBytesFreed==0 ){
@@ -123750,28 +124449,34 @@
123750124449
123751124450
/* Before computing generated columns, first go through and make sure
123752124451
** that appropriate affinity has been applied to the regular columns
123753124452
*/
123754124453
sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
123755
- if( (pTab->tabFlags & TF_HasStored)!=0
123756
- && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity
123757
- ){
123758
- /* Change the OP_Affinity argument to '@' (NONE) for all stored
123759
- ** columns. '@' is the no-op affinity and those columns have not
123760
- ** yet been computed. */
123761
- int ii, jj;
123762
- char *zP4 = pOp->p4.z;
123763
- assert( zP4!=0 );
123764
- assert( pOp->p4type==P4_DYNAMIC );
123765
- for(ii=jj=0; zP4[jj]; ii++){
123766
- if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
123767
- continue;
123768
- }
123769
- if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
123770
- zP4[jj] = SQLITE_AFF_NONE;
123771
- }
123772
- jj++;
124454
+ if( (pTab->tabFlags & TF_HasStored)!=0 ){
124455
+ pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
124456
+ if( pOp->opcode==OP_Affinity ){
124457
+ /* Change the OP_Affinity argument to '@' (NONE) for all stored
124458
+ ** columns. '@' is the no-op affinity and those columns have not
124459
+ ** yet been computed. */
124460
+ int ii, jj;
124461
+ char *zP4 = pOp->p4.z;
124462
+ assert( zP4!=0 );
124463
+ assert( pOp->p4type==P4_DYNAMIC );
124464
+ for(ii=jj=0; zP4[jj]; ii++){
124465
+ if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
124466
+ continue;
124467
+ }
124468
+ if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
124469
+ zP4[jj] = SQLITE_AFF_NONE;
124470
+ }
124471
+ jj++;
124472
+ }
124473
+ }else if( pOp->opcode==OP_TypeCheck ){
124474
+ /* If an OP_TypeCheck was generated because the table is STRICT,
124475
+ ** then set the P3 operand to indicate that generated columns should
124476
+ ** not be checked */
124477
+ pOp->p3 = 1;
123773124478
}
123774124479
}
123775124480
123776124481
/* Because there can be multiple generated columns that refer to one another,
123777124482
** this is a two-pass algorithm. On the first pass, mark all generated
@@ -124844,13 +125549,11 @@
124844125549
** Return the number of rows inserted. If this routine is
124845125550
** generating code because of a call to sqlite3NestedParse(), do not
124846125551
** invoke the callback function.
124847125552
*/
124848125553
if( regRowCount ){
124849
- sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
124850
- sqlite3VdbeSetNumCols(v, 1);
124851
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
125554
+ sqlite3CodeChangeCount(v, regRowCount, "rows inserted");
124852125555
}
124853125556
124854125557
insert_cleanup:
124855125558
sqlite3SrcListDelete(db, pTabList);
124856125559
sqlite3ExprListDelete(db, pList);
@@ -125688,10 +126391,11 @@
125688126391
** (5) No FK constraint counters need to be updated if a conflict occurs.
125689126392
**
125690126393
** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
125691126394
** must be explicitly deleted in order to ensure any pre-update hook
125692126395
** is invoked. */
126396
+ assert( IsOrdinaryTable(pTab) );
125693126397
#ifndef SQLITE_ENABLE_PREUPDATE_HOOK
125694126398
if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
125695126399
&& pPk==pIdx /* Condition 2 */
125696126400
&& onError==OE_Replace /* Condition 1 */
125697126401
&& ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
@@ -125794,11 +126498,12 @@
125794126498
default: {
125795126499
int nConflictCk; /* Number of opcodes in conflict check logic */
125796126500
125797126501
assert( onError==OE_Replace );
125798126502
nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
125799
- assert( nConflictCk>0 );
126503
+ assert( nConflictCk>0 || db->mallocFailed );
126504
+ testcase( nConflictCk<=0 );
125800126505
testcase( nConflictCk>1 );
125801126506
if( regTrigCnt ){
125802126507
sqlite3MultiWrite(pParse);
125803126508
nReplaceTrig++;
125804126509
}
@@ -126080,12 +126785,13 @@
126080126785
126081126786
assert( op==OP_OpenRead || op==OP_OpenWrite );
126082126787
assert( op==OP_OpenWrite || p5==0 );
126083126788
if( IsVirtual(pTab) ){
126084126789
/* This routine is a no-op for virtual tables. Leave the output
126085
- ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
126086
- ** can detect if they are used by mistake in the caller. */
126790
+ ** variables *piDataCur and *piIdxCur set to illegal cursor numbers
126791
+ ** for improved error detection. */
126792
+ *piDataCur = *piIdxCur = -999;
126087126793
return 0;
126088126794
}
126089126795
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
126090126796
v = pParse->pVdbe;
126091126797
assert( v!=0 );
@@ -126368,11 +127074,13 @@
126368127074
/* Default values for second and subsequent columns need to match. */
126369127075
if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){
126370127076
Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol);
126371127077
Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol);
126372127078
assert( pDestExpr==0 || pDestExpr->op==TK_SPAN );
127079
+ assert( pDestExpr==0 || !ExprHasProperty(pDestExpr, EP_IntValue) );
126373127080
assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN );
127081
+ assert( pSrcExpr==0 || !ExprHasProperty(pSrcExpr, EP_IntValue) );
126374127082
if( (pDestExpr==0)!=(pSrcExpr==0)
126375127083
|| (pDestExpr!=0 && strcmp(pDestExpr->u.zToken,
126376127084
pSrcExpr->u.zToken)!=0)
126377127085
){
126378127086
return 0; /* Default values must be the same for all columns */
@@ -126408,10 +127116,11 @@
126408127116
** But the main beneficiary of the transfer optimization is the VACUUM
126409127117
** command, and the VACUUM command disables foreign key constraints. So
126410127118
** the extra complication to make this rule less restrictive is probably
126411127119
** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
126412127120
*/
127121
+ assert( IsOrdinaryTable(pDest) );
126413127122
if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){
126414127123
return 0;
126415127124
}
126416127125
#endif
126417127126
if( (db->flags & SQLITE_CountRows)!=0 ){
@@ -127089,10 +127798,14 @@
127089127798
/* Version 3.34.0 and later */
127090127799
int (*txn_state)(sqlite3*,const char*);
127091127800
/* Version 3.36.1 and later */
127092127801
sqlite3_int64 (*changes64)(sqlite3*);
127093127802
sqlite3_int64 (*total_changes64)(sqlite3*);
127803
+ /* Version 3.37.0 and later */
127804
+ int (*autovacuum_pages)(sqlite3*,
127805
+ unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
127806
+ void*, void(*)(void*));
127094127807
};
127095127808
127096127809
/*
127097127810
** This is the function signature used for all extension entry points. It
127098127811
** is also defined in the file "loadext.c".
@@ -127395,10 +128108,15 @@
127395128108
#define sqlite3_create_filename sqlite3_api->create_filename
127396128109
#define sqlite3_free_filename sqlite3_api->free_filename
127397128110
#define sqlite3_database_file_object sqlite3_api->database_file_object
127398128111
/* Version 3.34.0 and later */
127399128112
#define sqlite3_txn_state sqlite3_api->txn_state
128113
+/* Version 3.36.1 and later */
128114
+#define sqlite3_changes64 sqlite3_api->changes64
128115
+#define sqlite3_total_changes64 sqlite3_api->total_changes64
128116
+/* Version 3.37.0 and later */
128117
+#define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
127400128118
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127401128119
127402128120
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127403128121
/* This case when the file really is being compiled as a loadable
127404128122
** extension */
@@ -127882,10 +128600,12 @@
127882128600
/* Version 3.34.0 and later */
127883128601
sqlite3_txn_state,
127884128602
/* Version 3.36.1 and later */
127885128603
sqlite3_changes64,
127886128604
sqlite3_total_changes64,
128605
+ /* Version 3.37.0 and later */
128606
+ sqlite3_autovacuum_pages,
127887128607
};
127888128608
127889128609
/* True if x is the directory separator character
127890128610
*/
127891128611
#if SQLITE_OS_WIN
@@ -128871,11 +129591,11 @@
128871129591
/* iArg: */ 0 },
128872129592
{/* zName: */ "table_list",
128873129593
/* ePragTyp: */ PragTyp_TABLE_LIST,
128874129594
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1,
128875129595
/* ColNames: */ 15, 6,
128876
- /* iArg: */ 1 },
129596
+ /* iArg: */ 0 },
128877129597
{/* zName: */ "table_xinfo",
128878129598
/* ePragTyp: */ PragTyp_TABLE_INFO,
128879129599
/* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
128880129600
/* ColNames: */ 8, 7,
128881129601
/* iArg: */ 1 },
@@ -129400,11 +130120,15 @@
129400130120
goto pragma_out;
129401130121
}
129402130122
129403130123
/* Locate the pragma in the lookup table */
129404130124
pPragma = pragmaLocate(zLeft);
129405
- if( pPragma==0 ) goto pragma_out;
130125
+ if( pPragma==0 ){
130126
+ /* IMP: R-43042-22504 No error messages are generated if an
130127
+ ** unknown pragma is issued. */
130128
+ goto pragma_out;
130129
+ }
129406130130
129407130131
/* Make sure the database schema is loaded if the pragma requires that */
129408130132
if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
129409130133
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
129410130134
}
@@ -130050,10 +130774,18 @@
130050130774
if( sqlite3GetBoolean(zRight, 0) ){
130051130775
db->flags |= mask;
130052130776
}else{
130053130777
db->flags &= ~mask;
130054130778
if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
130779
+ if( (mask & SQLITE_WriteSchema)!=0
130780
+ && sqlite3_stricmp(zRight, "reset")==0
130781
+ ){
130782
+ /* IMP: R-60817-01178 If the argument is "RESET" then schema
130783
+ ** writing is disabled (as with "PRAGMA writable_schema=OFF") and,
130784
+ ** in addition, the schema is reloaded. */
130785
+ sqlite3ResetAllSchemasOfConnection(db);
130786
+ }
130055130787
}
130056130788
130057130789
/* Many of the flag-pragmas modify the code generated by the SQL
130058130790
** compiler (eg. count_changes). So add an opcode to expire all
130059130791
** compiled SQL statements after modifying a pragma value.
@@ -130090,10 +130822,11 @@
130090130822
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
130091130823
pParse->nMem = 7;
130092130824
sqlite3ViewGetColumnNames(pParse, pTab);
130093130825
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
130094130826
int isHidden = 0;
130827
+ const Expr *pColExpr;
130095130828
if( pCol->colFlags & COLFLAG_NOINSERT ){
130096130829
if( pPragma->iArg==0 ){
130097130830
nHidden++;
130098130831
continue;
130099130832
}
@@ -130110,20 +130843,20 @@
130110130843
}else if( pPk==0 ){
130111130844
k = 1;
130112130845
}else{
130113130846
for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
130114130847
}
130115
- assert( sqlite3ColumnExpr(pTab,pCol)==0
130116
- || sqlite3ColumnExpr(pTab,pCol)->op==TK_SPAN
130117
- || isHidden>=2 );
130848
+ pColExpr = sqlite3ColumnExpr(pTab,pCol);
130849
+ assert( pColExpr==0 || pColExpr->op==TK_SPAN || isHidden>=2 );
130850
+ assert( pColExpr==0 || !ExprHasProperty(pColExpr, EP_IntValue)
130851
+ || isHidden>=2 );
130118130852
sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
130119130853
i-nHidden,
130120130854
pCol->zCnName,
130121130855
sqlite3ColumnType(pCol,""),
130122130856
pCol->notNull ? 1 : 0,
130123
- isHidden>=2 || sqlite3ColumnExpr(pTab,pCol)==0 ? 0 :
130124
- sqlite3ColumnExpr(pTab,pCol)->u.zToken,
130857
+ (isHidden>=2 || pColExpr==0) ? 0 : pColExpr->u.zToken,
130125130858
k,
130126130859
isHidden);
130127130860
}
130128130861
}
130129130862
}
@@ -130147,12 +130880,39 @@
130147130880
pParse->nMem = 6;
130148130881
sqlite3CodeVerifyNamedSchema(pParse, zDb);
130149130882
for(ii=0; ii<db->nDb; ii++){
130150130883
HashElem *k;
130151130884
Hash *pHash;
130885
+ int initNCol;
130152130886
if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue;
130887
+
130888
+ /* Ensure that the Table.nCol field is initialized for all views
130889
+ ** and virtual tables. Each time we initialize a Table.nCol value
130890
+ ** for a table, that can potentially disrupt the hash table, so restart
130891
+ ** the initialization scan.
130892
+ */
130153130893
pHash = &db->aDb[ii].pSchema->tblHash;
130894
+ initNCol = sqliteHashCount(pHash);
130895
+ while( initNCol-- ){
130896
+ for(k=sqliteHashFirst(pHash); 1; k=sqliteHashNext(k) ){
130897
+ Table *pTab;
130898
+ if( k==0 ){ initNCol = 0; break; }
130899
+ pTab = sqliteHashData(k);
130900
+ if( pTab->nCol==0 ){
130901
+ char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName);
130902
+ if( zSql ){
130903
+ sqlite3_stmt *pDummy = 0;
130904
+ (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
130905
+ (void)sqlite3_finalize(pDummy);
130906
+ sqlite3DbFree(db, zSql);
130907
+ }
130908
+ pHash = &db->aDb[ii].pSchema->tblHash;
130909
+ break;
130910
+ }
130911
+ }
130912
+ }
130913
+
130154130914
for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){
130155130915
Table *pTab = sqliteHashData(k);
130156130916
const char *zType;
130157130917
if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue;
130158130918
if( IsView(pTab) ){
@@ -130164,11 +130924,11 @@
130164130924
}else{
130165130925
zType = "table";
130166130926
}
130167130927
sqlite3VdbeMultiLoad(v, 1, "sssiii",
130168130928
db->aDb[ii].zDbSName,
130169
- pTab->zName,
130929
+ sqlite3PreferredTableName(pTab->zName),
130170130930
zType,
130171130931
pTab->nCol,
130172130932
(pTab->tabFlags & TF_WithoutRowid)!=0,
130173130933
(pTab->tabFlags & TF_Strict)!=0
130174130934
);
@@ -130184,11 +130944,11 @@
130184130944
pParse->nMem = 5;
130185130945
sqlite3CodeVerifySchema(pParse, iDb);
130186130946
for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
130187130947
Table *pTab = sqliteHashData(i);
130188130948
sqlite3VdbeMultiLoad(v, 1, "ssiii",
130189
- pTab->zName,
130949
+ sqlite3PreferredTableName(pTab->zName),
130190130950
0,
130191130951
pTab->szTabRow,
130192130952
pTab->nRowLogEst,
130193130953
pTab->tabFlags);
130194130954
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -130303,15 +131063,17 @@
130303131063
FuncDef *p;
130304131064
int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0;
130305131065
pParse->nMem = 6;
130306131066
for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
130307131067
for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
131068
+ assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
130308131069
pragmaFunclistLine(v, p, 1, showInternFunc);
130309131070
}
130310131071
}
130311131072
for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
130312131073
p = (FuncDef*)sqliteHashData(j);
131074
+ assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 );
130313131075
pragmaFunclistLine(v, p, 0, showInternFunc);
130314131076
}
130315131077
}
130316131078
break;
130317131079
@@ -130341,11 +131103,11 @@
130341131103
#ifndef SQLITE_OMIT_FOREIGN_KEY
130342131104
case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
130343131105
FKey *pFK;
130344131106
Table *pTab;
130345131107
pTab = sqlite3FindTable(db, zRight, zDb);
130346
- if( pTab && !IsVirtual(pTab) ){
131108
+ if( pTab && IsOrdinaryTable(pTab) ){
130347131109
pFK = pTab->u.tab.pFKey;
130348131110
if( pFK ){
130349131111
int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
130350131112
int i = 0;
130351131113
pParse->nMem = 8;
@@ -130401,19 +131163,19 @@
130401131163
k = 0;
130402131164
}else{
130403131165
pTab = (Table*)sqliteHashData(k);
130404131166
k = sqliteHashNext(k);
130405131167
}
130406
- if( pTab==0 || IsVirtual(pTab) || pTab->u.tab.pFKey==0 ) continue;
131168
+ if( pTab==0 || !IsOrdinaryTable(pTab) || pTab->u.tab.pFKey==0 ) continue;
130407131169
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
130408131170
zDb = db->aDb[iDb].zDbSName;
130409131171
sqlite3CodeVerifySchema(pParse, iDb);
130410131172
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
130411131173
if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
130412131174
sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
130413131175
sqlite3VdbeLoadString(v, regResult, pTab->zName);
130414
- assert( !IsVirtual(pTab) );
131176
+ assert( IsOrdinaryTable(pTab) );
130415131177
for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
130416131178
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
130417131179
if( pParent==0 ) continue;
130418131180
pIdx = 0;
130419131181
sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
@@ -130432,11 +131194,11 @@
130432131194
}
130433131195
assert( pParse->nErr>0 || pFK==0 );
130434131196
if( pFK ) break;
130435131197
if( pParse->nTab<i ) pParse->nTab = i;
130436131198
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
130437
- assert( !IsVirtual(pTab) );
131199
+ assert( IsOrdinaryTable(pTab) );
130438131200
for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
130439131201
pParent = sqlite3FindTable(db, pFK->zTo, zDb);
130440131202
pIdx = 0;
130441131203
aiCols = 0;
130442131204
if( pParent ){
@@ -130636,11 +131398,11 @@
130636131398
int loopTop;
130637131399
int iDataCur, iIdxCur;
130638131400
int r1 = -1;
130639131401
int bStrict;
130640131402
130641
- if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
131403
+ if( !IsOrdinaryTable(pTab) ) continue;
130642131404
if( pObjTab && pObjTab!=pTab ) continue;
130643131405
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
130644131406
sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
130645131407
1, 0, &iDataCur, &iIdxCur);
130646131408
/* reg[7] counts the number of entries in the table.
@@ -130677,11 +131439,11 @@
130677131439
if( pCol->notNull ){
130678131440
jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
130679131441
zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
130680131442
pCol->zCnName);
130681131443
sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
130682
- if( bStrict ){
131444
+ if( bStrict && pCol->eCType!=COLTYPE_ANY ){
130683131445
sqlite3VdbeGoto(v, doError);
130684131446
}else{
130685131447
integrityCheckResultRow(v);
130686131448
}
130687131449
sqlite3VdbeJumpHere(v, jmp2);
@@ -131231,16 +131993,16 @@
131231131993
** in each index that it looks at. Return the new limit.
131232131994
*/
131233131995
case PragTyp_ANALYSIS_LIMIT: {
131234131996
sqlite3_int64 N;
131235131997
if( zRight
131236
- && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
131998
+ && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK /* IMP: R-40975-20399 */
131237131999
&& N>=0
131238132000
){
131239132001
db->nAnalysisLimit = (int)(N&0x7fffffff);
131240132002
}
131241
- returnSingleInt(v, db->nAnalysisLimit);
132003
+ returnSingleInt(v, db->nAnalysisLimit); /* IMP: R-57594-65522 */
131242132004
break;
131243132005
}
131244132006
131245132007
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
131246132008
/*
@@ -131638,14 +132400,19 @@
131638132400
sqlite3 *db = pData->db;
131639132401
if( db->mallocFailed ){
131640132402
pData->rc = SQLITE_NOMEM_BKPT;
131641132403
}else if( pData->pzErrMsg[0]!=0 ){
131642132404
/* A error message has already been generated. Do not overwrite it */
131643
- }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){
132405
+ }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
132406
+ static const char *azAlterType[] = {
132407
+ "rename",
132408
+ "drop column",
132409
+ "add column"
132410
+ };
131644132411
*pData->pzErrMsg = sqlite3MPrintf(db,
131645132412
"error in %s %s after %s: %s", azObj[0], azObj[1],
131646
- (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column",
132413
+ azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1],
131647132414
zExtra
131648132415
);
131649132416
pData->rc = SQLITE_ERROR;
131650132417
}else if( db->flags & SQLITE_WriteSchema ){
131651132418
pData->rc = SQLITE_CORRUPT_BKPT;
@@ -132412,10 +133179,11 @@
132412133179
/* Make multiple attempts to compile the SQL, until it either succeeds
132413133180
** or encounters a permanent error. A schema problem after one schema
132414133181
** reset is considered a permanent error. */
132415133182
rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
132416133183
assert( rc==SQLITE_OK || *ppStmt==0 );
133184
+ if( rc==SQLITE_OK || db->mallocFailed ) break;
132417133185
}while( rc==SQLITE_ERROR_RETRY
132418133186
|| (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
132419133187
sqlite3BtreeLeaveAll(db);
132420133188
rc = sqlite3ApiExit(db, rc);
132421133189
assert( (rc&db->errMask)==rc );
@@ -133023,14 +133791,17 @@
133023133791
while( p ){
133024133792
ExprSetProperty(p, EP_FromJoin);
133025133793
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
133026133794
ExprSetVVAProperty(p, EP_NoReduce);
133027133795
p->iRightJoinTable = iTable;
133028
- if( p->op==TK_FUNCTION && p->x.pList ){
133029
- int i;
133030
- for(i=0; i<p->x.pList->nExpr; i++){
133031
- sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
133796
+ if( p->op==TK_FUNCTION ){
133797
+ assert( ExprUseXList(p) );
133798
+ if( p->x.pList ){
133799
+ int i;
133800
+ for(i=0; i<p->x.pList->nExpr; i++){
133801
+ sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
133802
+ }
133032133803
}
133033133804
}
133034133805
sqlite3SetJoinExpr(p->pLeft, iTable);
133035133806
p = p->pRight;
133036133807
}
@@ -133049,14 +133820,17 @@
133049133820
ExprClearProperty(p, EP_FromJoin);
133050133821
}
133051133822
if( p->op==TK_COLUMN && p->iTable==iTable ){
133052133823
ExprClearProperty(p, EP_CanBeNull);
133053133824
}
133054
- if( p->op==TK_FUNCTION && p->x.pList ){
133055
- int i;
133056
- for(i=0; i<p->x.pList->nExpr; i++){
133057
- unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
133825
+ if( p->op==TK_FUNCTION ){
133826
+ assert( ExprUseXList(p) );
133827
+ if( p->x.pList ){
133828
+ int i;
133829
+ for(i=0; i<p->x.pList->nExpr; i++){
133830
+ unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
133831
+ }
133058133832
}
133059133833
}
133060133834
unsetJoinExpr(p->pLeft, iTable);
133061133835
p = p->pRight;
133062133836
}
@@ -133567,13 +134341,17 @@
133567134341
ExprList *pExtra = 0;
133568134342
for(i=0; i<pEList->nExpr; i++){
133569134343
struct ExprList_item *pItem = &pEList->a[i];
133570134344
if( pItem->u.x.iOrderByCol==0 ){
133571134345
Expr *pExpr = pItem->pExpr;
133572
- Table *pTab = pExpr->y.pTab;
133573
- if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
133574
- && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
134346
+ Table *pTab;
134347
+ if( pExpr->op==TK_COLUMN
134348
+ && pExpr->iColumn>=0
134349
+ && ALWAYS( ExprUseYTab(pExpr) )
134350
+ && (pTab = pExpr->y.pTab)!=0
134351
+ && IsOrdinaryTable(pTab)
134352
+ && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)!=0
133575134353
){
133576134354
int j;
133577134355
for(j=0; j<nDefer; j++){
133578134356
if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
133579134357
}
@@ -133590,10 +134368,11 @@
133590134368
}
133591134369
for(k=0; k<nKey; k++){
133592134370
Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
133593134371
if( pNew ){
133594134372
pNew->iTable = pExpr->iTable;
134373
+ assert( ExprUseYTab(pNew) );
133595134374
pNew->y.pTab = pExpr->y.pTab;
133596134375
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
133597134376
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
133598134377
}
133599134378
}
@@ -134438,11 +135217,11 @@
134438135217
** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
134439135218
** branch below. */
134440135219
break;
134441135220
}
134442135221
134443
- assert( pTab && pExpr->y.pTab==pTab );
135222
+ assert( pTab && ExprUseYTab(pExpr) && pExpr->y.pTab==pTab );
134444135223
if( pS ){
134445135224
/* The "table" is actually a sub-select or a view in the FROM clause
134446135225
** of the SELECT statement. Return the declaration type and origin
134447135226
** data for the result-set column of the sub-select.
134448135227
*/
@@ -134498,13 +135277,15 @@
134498135277
/* The expression is a sub-select. Return the declaration type and
134499135278
** origin info for the single column in the result set of the SELECT
134500135279
** statement.
134501135280
*/
134502135281
NameContext sNC;
134503
- Select *pS = pExpr->x.pSelect;
134504
- Expr *p = pS->pEList->a[0].pExpr;
134505
- assert( ExprHasProperty(pExpr, EP_xIsSelect) );
135282
+ Select *pS;
135283
+ Expr *p;
135284
+ assert( ExprUseXSelect(pExpr) );
135285
+ pS = pExpr->x.pSelect;
135286
+ p = pS->pEList->a[0].pExpr;
134506135287
sNC.pSrcList = pS->pSrc;
134507135288
sNC.pNext = pNC;
134508135289
sNC.pParse = pNC->pParse;
134509135290
zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
134510135291
break;
@@ -134629,11 +135410,12 @@
134629135410
for(i=0; i<pEList->nExpr; i++){
134630135411
Expr *p = pEList->a[i].pExpr;
134631135412
134632135413
assert( p!=0 );
134633135414
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
134634
- assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
135415
+ assert( p->op!=TK_COLUMN
135416
+ || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */
134635135417
if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
134636135418
/* An AS clause always takes first priority */
134637135419
char *zName = pEList->a[i].zEName;
134638135420
sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
134639135421
}else if( srcName && p->op==TK_COLUMN ){
@@ -134725,11 +135507,14 @@
134725135507
Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
134726135508
while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
134727135509
pColExpr = pColExpr->pRight;
134728135510
assert( pColExpr!=0 );
134729135511
}
134730
- if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->y.pTab)!=0 ){
135512
+ if( pColExpr->op==TK_COLUMN
135513
+ && ALWAYS( ExprUseYTab(pColExpr) )
135514
+ && (pTab = pColExpr->y.pTab)!=0
135515
+ ){
134731135516
/* For columns use the column name name */
134732135517
int iCol = pColExpr->iColumn;
134733135518
if( iCol<0 ) iCol = pTab->iPKey;
134734135519
zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
134735135520
}else if( pColExpr->op==TK_ID ){
@@ -134811,11 +135596,11 @@
134811135596
memset(&sNC, 0, sizeof(sNC));
134812135597
sNC.pSrcList = pSelect->pSrc;
134813135598
a = pSelect->pEList->a;
134814135599
for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
134815135600
const char *zType;
134816
- int n, m;
135601
+ i64 n, m;
134817135602
pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
134818135603
p = a[i].pExpr;
134819135604
zType = columnType(&sNC, p, 0, 0, 0);
134820135605
/* pCol->szEst = ... // Column size est for SELECT tables never used */
134821135606
pCol->affinity = sqlite3ExprAffinity(p);
@@ -134824,10 +135609,13 @@
134824135609
n = sqlite3Strlen30(pCol->zCnName);
134825135610
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
134826135611
if( pCol->zCnName ){
134827135612
memcpy(&pCol->zCnName[n+1], zType, m+1);
134828135613
pCol->colFlags |= COLFLAG_HASTYPE;
135614
+ }else{
135615
+ testcase( pCol->colFlags & COLFLAG_HASTYPE );
135616
+ pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
134829135617
}
134830135618
}
134831135619
if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
134832135620
pColl = sqlite3ExprCollSeq(pParse, p);
134833135621
if( pColl ){
@@ -134994,11 +135782,11 @@
134994135782
** function is responsible for ensuring that this structure is eventually
134995135783
** freed.
134996135784
*/
134997135785
static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
134998135786
ExprList *pOrderBy = p->pOrderBy;
134999
- int nOrderBy = p->pOrderBy->nExpr;
135787
+ int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0;
135000135788
sqlite3 *db = pParse->db;
135001135789
KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
135002135790
if( pRet ){
135003135791
int i;
135004135792
for(i=0; i<nOrderBy; i++){
@@ -135615,10 +136403,11 @@
135615136403
Select *pLoop; /* For looping through SELECT statements */
135616136404
CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
135617136405
int nCol; /* Number of columns in result set */
135618136406
135619136407
assert( p->pNext==0 );
136408
+ assert( p->pEList!=0 );
135620136409
nCol = p->pEList->nExpr;
135621136410
pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
135622136411
if( !pKeyInfo ){
135623136412
rc = SQLITE_NOMEM_BKPT;
135624136413
goto multi_select_end;
@@ -135966,10 +136755,11 @@
135966136755
*/
135967136756
if( op!=TK_ALL ){
135968136757
for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
135969136758
struct ExprList_item *pItem;
135970136759
for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
136760
+ assert( pItem!=0 );
135971136761
assert( pItem->u.x.iOrderByCol>0 );
135972136762
if( pItem->u.x.iOrderByCol==i ) break;
135973136763
}
135974136764
if( j==nOrderBy ){
135975136765
Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
@@ -135992,10 +136782,11 @@
135992136782
aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1));
135993136783
if( aPermute ){
135994136784
struct ExprList_item *pItem;
135995136785
aPermute[0] = nOrderBy;
135996136786
for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
136787
+ assert( pItem!=0 );
135997136788
assert( pItem->u.x.iOrderByCol>0 );
135998136789
assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
135999136790
aPermute[i] = pItem->u.x.iOrderByCol - 1;
136000136791
}
136001136792
pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -136304,11 +137095,11 @@
136304137095
if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
136305137096
pExpr->iTable = pSubst->iNewTable;
136306137097
}
136307137098
pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
136308137099
pExpr->pRight = substExpr(pSubst, pExpr->pRight);
136309
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
137100
+ if( ExprUseXSelect(pExpr) ){
136310137101
substSelect(pSubst, pExpr->x.pSelect, 1);
136311137102
}else{
136312137103
substExprList(pSubst, pExpr->x.pList);
136313137104
}
136314137105
#ifndef SQLITE_OMIT_WINDOWFUNC
@@ -136791,11 +137582,11 @@
136791137582
/* Restriction (23) */
136792137583
if( (p->selFlags & SF_Recursive) ) return 0;
136793137584
136794137585
if( pSrc->nSrc>1 ){
136795137586
if( pParse->nSelect>500 ) return 0;
136796
- aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+1)*sizeof(int));
137587
+ aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int));
136797137588
if( aCsrMap ) aCsrMap[0] = pParse->nTab;
136798137589
}
136799137590
}
136800137591
136801137592
/***** If we reach this point, flattening is permitted. *****/
@@ -137515,25 +138306,28 @@
137515138306
** located but before their arguments have been subjected to aggregate
137516138307
** analysis.
137517138308
*/
137518138309
static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
137519138310
int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
137520
- ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
138311
+ ExprList *pEList; /* Arguments to agg function */
137521138312
const char *zFunc; /* Name of aggregate function pFunc */
137522138313
ExprList *pOrderBy;
137523138314
u8 sortFlags = 0;
137524138315
137525138316
assert( *ppMinMax==0 );
137526138317
assert( pFunc->op==TK_AGG_FUNCTION );
137527138318
assert( !IsWindowFunc(pFunc) );
138319
+ assert( ExprUseXList(pFunc) );
138320
+ pEList = pFunc->x.pList;
137528138321
if( pEList==0
137529138322
|| pEList->nExpr!=1
137530138323
|| ExprHasProperty(pFunc, EP_WinFunc)
137531138324
|| OptimizationDisabled(db, SQLITE_MinMaxOpt)
137532138325
){
137533138326
return eRet;
137534138327
}
138328
+ assert( !ExprHasProperty(pFunc, EP_IntValue) );
137535138329
zFunc = pFunc->u.zToken;
137536138330
if( sqlite3StrICmp(zFunc, "min")==0 ){
137537138331
eRet = WHERE_ORDERBY_MIN;
137538138332
if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
137539138333
sortFlags = KEYINFO_ORDER_BIGNULL;
@@ -137557,31 +138351,44 @@
137557138351
**
137558138352
** SELECT count(*) FROM <tbl>
137559138353
**
137560138354
** where table is a database table, not a sub-select or view. If the query
137561138355
** does match this pattern, then a pointer to the Table object representing
137562
-** <tbl> is returned. Otherwise, 0 is returned.
138356
+** <tbl> is returned. Otherwise, NULL is returned.
138357
+**
138358
+** This routine checks to see if it is safe to use the count optimization.
138359
+** A correct answer is still obtained (though perhaps more slowly) if
138360
+** this routine returns NULL when it could have returned a table pointer.
138361
+** But returning the pointer when NULL should have been returned can
138362
+** result in incorrect answers and/or crashes. So, when in doubt, return NULL.
137563138363
*/
137564138364
static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
137565138365
Table *pTab;
137566138366
Expr *pExpr;
137567138367
137568138368
assert( !p->pGroupBy );
137569138369
137570
- if( p->pWhere || p->pEList->nExpr!=1
137571
- || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
138370
+ if( p->pWhere
138371
+ || p->pEList->nExpr!=1
138372
+ || p->pSrc->nSrc!=1
138373
+ || p->pSrc->a[0].pSelect
138374
+ || pAggInfo->nFunc!=1
137572138375
){
137573138376
return 0;
137574138377
}
137575138378
pTab = p->pSrc->a[0].pTab;
138379
+ assert( pTab!=0 );
138380
+ assert( !IsView(pTab) );
138381
+ if( !IsOrdinaryTable(pTab) ) return 0;
137576138382
pExpr = p->pEList->a[0].pExpr;
137577
- assert( pTab && !IsView(pTab) && pExpr );
137578
-
137579
- if( IsVirtual(pTab) ) return 0;
138383
+ assert( pExpr!=0 );
137580138384
if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
137581
- if( NEVER(pAggInfo->nFunc==0) ) return 0;
138385
+ if( pExpr->pAggInfo!=pAggInfo ) return 0;
137582138386
if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
138387
+ assert( pAggInfo->aFunc[0].pFExpr==pExpr );
138388
+ testcase( ExprHasProperty(pExpr, EP_Distinct) );
138389
+ testcase( ExprHasProperty(pExpr, EP_WinFunc) );
137583138390
if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
137584138391
137585138392
return pTab;
137586138393
}
137587138394
@@ -137606,10 +138413,11 @@
137606138413
if( !pIdx ){
137607138414
sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
137608138415
pParse->checkSchema = 1;
137609138416
return SQLITE_ERROR;
137610138417
}
138418
+ assert( pFrom->fg.isCte==0 );
137611138419
pFrom->u2.pIBIndex = pIdx;
137612138420
return SQLITE_OK;
137613138421
}
137614138422
137615138423
/*
@@ -137863,10 +138671,14 @@
137863138671
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
137864138672
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
137865138673
if( db->mallocFailed ) return 2;
137866138674
pFrom->pSelect->selFlags |= SF_CopyCte;
137867138675
assert( pFrom->pSelect );
138676
+ if( pFrom->fg.isIndexedBy ){
138677
+ sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy);
138678
+ return 2;
138679
+ }
137868138680
pFrom->fg.isCte = 1;
137869138681
pFrom->u2.pCteUse = pCteUse;
137870138682
pCteUse->nUse++;
137871138683
if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
137872138684
pCteUse->eM10d = M10d_Yes;
@@ -138498,11 +139310,11 @@
138498139310
#endif
138499139311
sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
138500139312
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
138501139313
if( pFunc->iDistinct>=0 ){
138502139314
Expr *pE = pFunc->pFExpr;
138503
- assert( !ExprHasProperty(pE, EP_xIsSelect) );
139315
+ assert( ExprUseXList(pE) );
138504139316
if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
138505139317
sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
138506139318
"argument");
138507139319
pFunc->iDistinct = -1;
138508139320
}else{
@@ -138523,12 +139335,13 @@
138523139335
static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
138524139336
Vdbe *v = pParse->pVdbe;
138525139337
int i;
138526139338
struct AggInfo_func *pF;
138527139339
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
138528
- ExprList *pList = pF->pFExpr->x.pList;
138529
- assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
139340
+ ExprList *pList;
139341
+ assert( ExprUseXList(pF->pFExpr) );
139342
+ pList = pF->pFExpr->x.pList;
138530139343
sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
138531139344
sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
138532139345
}
138533139346
}
138534139347
@@ -138558,13 +139371,14 @@
138558139371
pAggInfo->directMode = 1;
138559139372
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
138560139373
int nArg;
138561139374
int addrNext = 0;
138562139375
int regAgg;
138563
- ExprList *pList = pF->pFExpr->x.pList;
138564
- assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
139376
+ ExprList *pList;
139377
+ assert( ExprUseXList(pF->pFExpr) );
138565139378
assert( !IsWindowFunc(pF->pFExpr) );
139379
+ pList = pF->pFExpr->x.pList;
138566139380
if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
138567139381
Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
138568139382
if( pAggInfo->nAccumulator
138569139383
&& (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
138570139384
&& regAcc
@@ -138806,11 +139620,13 @@
138806139620
if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
138807139621
if( p->pWhere ) return 0;
138808139622
if( p->pGroupBy ) return 0;
138809139623
pExpr = p->pEList->a[0].pExpr;
138810139624
if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
139625
+ assert( ExprUseUToken(pExpr) );
138811139626
if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
139627
+ assert( ExprUseXList(pExpr) );
138812139628
if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
138813139629
if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
138814139630
pSub = p->pSrc->a[0].pSelect;
138815139631
if( pSub==0 ) return 0; /* The FROM is a subquery */
138816139632
if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
@@ -139621,11 +140437,11 @@
139621140437
}else{
139622140438
minMaxFlag = WHERE_ORDERBY_NORMAL;
139623140439
}
139624140440
for(i=0; i<pAggInfo->nFunc; i++){
139625140441
Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
139626
- assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
140442
+ assert( ExprUseXList(pExpr) );
139627140443
sNC.ncFlags |= NC_InAggFunc;
139628140444
sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
139629140445
#ifndef SQLITE_OMIT_WINDOWFUNC
139630140446
assert( !IsWindowFunc(pExpr) );
139631140447
if( ExprHasProperty(pExpr, EP_WinFunc) ){
@@ -139676,11 +140492,13 @@
139676140492
u16 distFlag = 0;
139677140493
int eDist = WHERE_DISTINCT_NOOP;
139678140494
139679140495
if( pAggInfo->nFunc==1
139680140496
&& pAggInfo->aFunc[0].iDistinct>=0
139681
- && pAggInfo->aFunc[0].pFExpr->x.pList
140497
+ && ALWAYS(pAggInfo->aFunc[0].pFExpr!=0)
140498
+ && ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr))
140499
+ && pAggInfo->aFunc[0].pFExpr->x.pList!=0
139682140500
){
139683140501
Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr;
139684140502
pExpr = sqlite3ExprDup(db, pExpr, 0);
139685140503
pDistinct = sqlite3ExprListDup(db, pGroupBy, 0);
139686140504
pDistinct = sqlite3ExprListAppend(pParse, pDistinct, pExpr);
@@ -139997,10 +140815,11 @@
139997140815
if( i==pAggInfo->nFunc ){
139998140816
regAcc = ++pParse->nMem;
139999140817
sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
140000140818
}
140001140819
}else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){
140820
+ assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) );
140002140821
pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList;
140003140822
distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0;
140004140823
}
140005140824
140006140825
/* This case runs if the aggregate has no GROUP BY clause. The
@@ -140670,11 +141489,11 @@
140670141489
if( v==0 ) goto triggerfinish_cleanup;
140671141490
sqlite3BeginWriteOperation(pParse, 0, iDb);
140672141491
z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
140673141492
testcase( z==0 );
140674141493
sqlite3NestedParse(pParse,
140675
- "INSERT INTO %Q." DFLT_SCHEMA_TABLE
141494
+ "INSERT INTO %Q." LEGACY_SCHEMA_TABLE
140676141495
" VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
140677141496
db->aDb[iDb].zDbSName, zName,
140678141497
pTrig->table, z);
140679141498
sqlite3DbFree(db, z);
140680141499
sqlite3ChangeCookie(pParse, iDb);
@@ -140984,11 +141803,11 @@
140984141803
140985141804
/* Generate code to destroy the database record of the trigger.
140986141805
*/
140987141806
if( (v = sqlite3GetVdbe(pParse))!=0 ){
140988141807
sqlite3NestedParse(pParse,
140989
- "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
141808
+ "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
140990141809
db->aDb[iDb].zDbSName, pTrigger->zName
140991141810
);
140992141811
sqlite3ChangeCookie(pParse, iDb);
140993141812
sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
140994141813
}
@@ -142852,13 +143671,11 @@
142852143671
/*
142853143672
** Return the number of rows that were changed, if we are tracking
142854143673
** that information.
142855143674
*/
142856143675
if( regRowCount ){
142857
- sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
142858
- sqlite3VdbeSetNumCols(v, 1);
142859
- sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
143676
+ sqlite3CodeChangeCount(v, regRowCount, "rows updated");
142860143677
}
142861143678
142862143679
update_cleanup:
142863143680
sqlite3AuthContextPop(&sContext);
142864143681
sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
@@ -143637,11 +144454,13 @@
143637144454
rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
143638144455
if( rc!=SQLITE_OK ) goto end_of_vacuum;
143639144456
143640144457
/* Do not attempt to change the page size for a WAL database */
143641144458
if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
143642
- ==PAGER_JOURNALMODE_WAL ){
144459
+ ==PAGER_JOURNALMODE_WAL
144460
+ && pOut==0
144461
+ ){
143643144462
db->nextPagesize = 0;
143644144463
}
143645144464
143646144465
if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
143647144466
|| (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
@@ -144022,11 +144841,14 @@
144022144841
** Except, if argument db is not NULL, then the entry associated with
144023144842
** connection db is left in the p->u.vtab.p list.
144024144843
*/
144025144844
static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
144026144845
VTable *pRet = 0;
144027
- VTable *pVTable = p->u.vtab.p;
144846
+ VTable *pVTable;
144847
+
144848
+ assert( IsVirtual(p) );
144849
+ pVTable = p->u.vtab.p;
144028144850
p->u.vtab.p = 0;
144029144851
144030144852
/* Assert that the mutex (if any) associated with the BtShared database
144031144853
** that contains table p is held by the caller. See header comments
144032144854
** above function sqlite3VtabUnlockList() for an explanation of why
@@ -144130,10 +144952,11 @@
144130144952
** structure being xDisconnected and free). Any other VTable structures
144131144953
** in the list are moved to the sqlite3.pDisconnect list of the associated
144132144954
** database connection.
144133144955
*/
144134144956
SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
144957
+ assert( IsVirtual(p) );
144135144958
if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
144136144959
if( p->u.vtab.azArg ){
144137144960
int i;
144138144961
for(i=0; i<p->u.vtab.nArg; i++){
144139144962
if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]);
@@ -144147,13 +144970,16 @@
144147144970
** The string is not copied - the pointer is stored. The
144148144971
** string will be freed automatically when the table is
144149144972
** deleted.
144150144973
*/
144151144974
static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
144152
- sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg);
144975
+ sqlite3_int64 nBytes;
144153144976
char **azModuleArg;
144154144977
sqlite3 *db = pParse->db;
144978
+
144979
+ assert( IsVirtual(pTable) );
144980
+ nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg);
144155144981
if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
144156144982
sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
144157144983
}
144158144984
azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes);
144159144985
if( azModuleArg==0 ){
@@ -144236,10 +145062,11 @@
144236145062
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
144237145063
Table *pTab = pParse->pNewTable; /* The table being constructed */
144238145064
sqlite3 *db = pParse->db; /* The database connection */
144239145065
144240145066
if( pTab==0 ) return;
145067
+ assert( IsVirtual(pTab) );
144241145068
addArgumentToVtab(pParse);
144242145069
pParse->sArg.z = 0;
144243145070
if( pTab->u.vtab.nArg<1 ) return;
144244145071
144245145072
/* If the CREATE VIRTUAL TABLE statement is being entered for the
@@ -144271,11 +145098,11 @@
144271145098
** entry in the sqlite_schema table tht was created for this vtab
144272145099
** by sqlite3StartTable().
144273145100
*/
144274145101
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
144275145102
sqlite3NestedParse(pParse,
144276
- "UPDATE %Q." DFLT_SCHEMA_TABLE " "
145103
+ "UPDATE %Q." LEGACY_SCHEMA_TABLE " "
144277145104
"SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
144278145105
"WHERE rowid=#%d",
144279145106
db->aDb[iDb].zDbSName,
144280145107
pTab->zName,
144281145108
pTab->zName,
@@ -144291,22 +145118,18 @@
144291145118
sqlite3DbFree(db, zStmt);
144292145119
144293145120
iReg = ++pParse->nMem;
144294145121
sqlite3VdbeLoadString(v, iReg, pTab->zName);
144295145122
sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
144296
- }
144297
-
144298
- /* If we are rereading the sqlite_schema table create the in-memory
144299
- ** record of the table. The xConnect() method is not called until
144300
- ** the first time the virtual table is used in an SQL statement. This
144301
- ** allows a schema that contains virtual tables to be loaded before
144302
- ** the required virtual table implementations are registered. */
144303
- else {
145123
+ }else{
145124
+ /* If we are rereading the sqlite_schema table create the in-memory
145125
+ ** record of the table. */
144304145126
Table *pOld;
144305145127
Schema *pSchema = pTab->pSchema;
144306145128
const char *zName = pTab->zName;
144307
- assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
145129
+ assert( zName!=0 );
145130
+ sqlite3MarkAllShadowTablesOf(db, pTab);
144308145131
pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
144309145132
if( pOld ){
144310145133
sqlite3OomFault(db);
144311145134
assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
144312145135
return;
@@ -144353,17 +145176,20 @@
144353145176
char **pzErr
144354145177
){
144355145178
VtabCtx sCtx;
144356145179
VTable *pVTable;
144357145180
int rc;
144358
- const char *const*azArg = (const char *const*)pTab->u.vtab.azArg;
145181
+ const char *const*azArg;
144359145182
int nArg = pTab->u.vtab.nArg;
144360145183
char *zErr = 0;
144361145184
char *zModuleName;
144362145185
int iDb;
144363145186
VtabCtx *pCtx;
144364145187
145188
+ assert( IsVirtual(pTab) );
145189
+ azArg = (const char *const*)pTab->u.vtab.azArg;
145190
+
144365145191
/* Check that the virtual-table is not already being initialized */
144366145192
for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
144367145193
if( pCtx->pTab==pTab ){
144368145194
*pzErr = sqlite3MPrintf(db,
144369145195
"vtable constructor called recursively: %s", pTab->zName
@@ -144483,11 +145309,12 @@
144483145309
const char *zMod;
144484145310
Module *pMod;
144485145311
int rc;
144486145312
144487145313
assert( pTab );
144488
- if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
145314
+ assert( IsVirtual(pTab) );
145315
+ if( sqlite3GetVTable(db, pTab) ){
144489145316
return SQLITE_OK;
144490145317
}
144491145318
144492145319
/* Locate the required virtual table module */
144493145320
zMod = pTab->u.vtab.azArg[0];
@@ -144687,11 +145514,14 @@
144687145514
SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
144688145515
int rc = SQLITE_OK;
144689145516
Table *pTab;
144690145517
144691145518
pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
144692
- if( pTab!=0 && ALWAYS(pTab->u.vtab.p!=0) ){
145519
+ if( ALWAYS(pTab!=0)
145520
+ && ALWAYS(IsVirtual(pTab))
145521
+ && ALWAYS(pTab->u.vtab.p!=0)
145522
+ ){
144693145523
VTable *p;
144694145524
int (*xDestroy)(sqlite3_vtab *);
144695145525
for(p=pTab->u.vtab.p; p; p=p->pNext){
144696145526
assert( p->pVtab );
144697145527
if( p->pVtab->nRef>0 ){
@@ -144920,10 +145750,11 @@
144920145750
int rc = 0;
144921145751
144922145752
/* Check to see the left operand is a column in a virtual table */
144923145753
if( NEVER(pExpr==0) ) return pDef;
144924145754
if( pExpr->op!=TK_COLUMN ) return pDef;
145755
+ assert( ExprUseYTab(pExpr) );
144925145756
pTab = pExpr->y.pTab;
144926145757
if( pTab==0 ) return pDef;
144927145758
if( !IsVirtual(pTab) ) return pDef;
144928145759
pVtab = sqlite3GetVTable(db, pTab)->pVtab;
144929145760
assert( pVtab!=0 );
@@ -145214,10 +146045,11 @@
145214146045
int addrBignull; /* Jump here for next part of big-null scan */
145215146046
#ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
145216146047
u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
145217146048
int addrLikeRep; /* LIKE range processing address */
145218146049
#endif
146050
+ int regFilter; /* Bloom filter */
145219146051
u8 iFrom; /* Which entry in the FROM clause */
145220146052
u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
145221146053
int p1, p2; /* Operands of the opcode used to end the loop */
145222146054
union { /* Information that depends on pWLoop->wsFlags */
145223146055
struct {
@@ -145228,11 +146060,11 @@
145228146060
int iBase; /* Base register of multi-key index record */
145229146061
int nPrefix; /* Number of prior entires in the key */
145230146062
u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
145231146063
} *aInLoop; /* Information about each nested IN operator */
145232146064
} in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
145233
- Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
146065
+ Index *pCoveringIdx; /* Possible covering index for WHERE_MULTI_OR */
145234146066
} u;
145235146067
struct WhereLoop *pWLoop; /* The selected WhereLoop object */
145236146068
Bitmask notReady; /* FROM entries not usable at this level */
145237146069
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
145238146070
int addrVisit; /* Address at which row is visited */
@@ -145442,15 +146274,15 @@
145442146274
struct WhereScan {
145443146275
WhereClause *pOrigWC; /* Original, innermost WhereClause */
145444146276
WhereClause *pWC; /* WhereClause currently being scanned */
145445146277
const char *zCollName; /* Required collating sequence, if not NULL */
145446146278
Expr *pIdxExpr; /* Search for this index expression */
145447
- char idxaff; /* Must match this affinity, if zCollName!=NULL */
145448
- unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
145449
- unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */
146279
+ int k; /* Resume scanning at this->pWC->a[this->k] */
145450146280
u32 opMask; /* Acceptable operators */
145451
- int k; /* Resume scanning at this->pWC->a[this->k] */
146281
+ char idxaff; /* Must match this affinity, if zCollName!=NULL */
146282
+ unsigned char iEquiv; /* Current slot in aiCur[] and aiColumn[] */
146283
+ unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
145452146284
int aiCur[11]; /* Cursors in the equivalence class */
145453146285
i16 aiColumn[11]; /* Corresponding column number in the eq-class */
145454146286
};
145455146287
145456146288
/*
@@ -145470,10 +146302,11 @@
145470146302
WhereClause *pOuter; /* Outer conjunction */
145471146303
u8 op; /* Split operator. TK_AND or TK_OR */
145472146304
u8 hasOr; /* True if any a[].eOperator is WO_OR */
145473146305
int nTerm; /* Number of terms */
145474146306
int nSlot; /* Number of entries in a[] */
146307
+ int nBase; /* Number of terms through the last non-Virtual */
145475146308
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
145476146309
#if defined(SQLITE_SMALL_STACK)
145477146310
WhereTerm aStatic[1]; /* Initial static space for a[] */
145478146311
#else
145479146312
WhereTerm aStatic[8]; /* Initial static space for a[] */
@@ -145527,15 +146360,10 @@
145527146360
int bVarSelect; /* Used by sqlite3WhereExprUsage() */
145528146361
int n; /* Number of assigned cursor values */
145529146362
int ix[BMS]; /* Cursor assigned to each bit */
145530146363
};
145531146364
145532
-/*
145533
-** Initialize a WhereMaskSet object
145534
-*/
145535
-#define initMaskSet(P) (P)->n=0
145536
-
145537146365
/*
145538146366
** This object is a convenience wrapper holding all information needed
145539146367
** to construct WhereLoop objects for a particular query.
145540146368
*/
145541146369
struct WhereLoopBuilder {
@@ -145660,12 +146488,18 @@
145660146488
Parse *pParse, /* Parse context */
145661146489
SrcList *pTabList, /* Table list this loop refers to */
145662146490
WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
145663146491
u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
145664146492
);
146493
+SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter(
146494
+ const Parse *pParse, /* Parse context */
146495
+ const WhereInfo *pWInfo, /* WHERE clause */
146496
+ const WhereLevel *pLevel /* Bloom filter on this level */
146497
+);
145665146498
#else
145666146499
# define sqlite3WhereExplainOneScan(u,v,w,x) 0
146500
+# define sqlite3WhereExplainBloomFilter(u,v,w) 0
145667146501
#endif /* SQLITE_OMIT_EXPLAIN */
145668146502
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
145669146503
SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
145670146504
Vdbe *v, /* Vdbe to add scanstatus entry to */
145671146505
SrcList *pSrclist, /* FROM clause pLvl reads data from */
@@ -145754,10 +146588,12 @@
145754146588
#define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
145755146589
#define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
145756146590
#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
145757146591
#define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
145758146592
#define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
146593
+#define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
146594
+#define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
145759146595
145760146596
#endif /* !defined(SQLITE_WHEREINT_H) */
145761146597
145762146598
/************** End of whereInt.h ********************************************/
145763146599
/************** Continuing where we left off in wherecode.c ******************/
@@ -145916,23 +146752,31 @@
145916146752
sqlite3_str_append(&str, " USING ", 7);
145917146753
sqlite3_str_appendf(&str, zFmt, pIdx->zName);
145918146754
explainIndexRange(&str, pLoop);
145919146755
}
145920146756
}else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
145921
- const char *zRangeOp;
146757
+ char cRangeOp;
146758
+#if 0 /* Better output, but breaks many tests */
146759
+ const Table *pTab = pItem->pTab;
146760
+ const char *zRowid = pTab->iPKey>=0 ? pTab->aCol[pTab->iPKey].zCnName:
146761
+ "rowid";
146762
+#else
146763
+ const char *zRowid = "rowid";
146764
+#endif
146765
+ sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (%s", zRowid);
145922146766
if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
145923
- zRangeOp = "=";
146767
+ cRangeOp = '=';
145924146768
}else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
145925
- zRangeOp = ">? AND rowid<";
146769
+ sqlite3_str_appendf(&str, ">? AND %s", zRowid);
146770
+ cRangeOp = '<';
145926146771
}else if( flags&WHERE_BTM_LIMIT ){
145927
- zRangeOp = ">";
146772
+ cRangeOp = '>';
145928146773
}else{
145929146774
assert( flags&WHERE_TOP_LIMIT);
145930
- zRangeOp = "<";
146775
+ cRangeOp = '<';
145931146776
}
145932
- sqlite3_str_appendf(&str,
145933
- " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
146777
+ sqlite3_str_appendf(&str, "%c?)", cRangeOp);
145934146778
}
145935146779
#ifndef SQLITE_OMIT_VIRTUALTABLE
145936146780
else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
145937146781
sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
145938146782
pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
@@ -145951,10 +146795,60 @@
145951146795
ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
145952146796
pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
145953146797
}
145954146798
return ret;
145955146799
}
146800
+
146801
+/*
146802
+** Add a single OP_Explain opcode that describes a Bloom filter.
146803
+**
146804
+** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or
146805
+** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not
146806
+** required and this routine is a no-op.
146807
+**
146808
+** If an OP_Explain opcode is added to the VM, its address is returned.
146809
+** Otherwise, if no OP_Explain is coded, zero is returned.
146810
+*/
146811
+SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter(
146812
+ const Parse *pParse, /* Parse context */
146813
+ const WhereInfo *pWInfo, /* WHERE clause */
146814
+ const WhereLevel *pLevel /* Bloom filter on this level */
146815
+){
146816
+ int ret = 0;
146817
+ SrcItem *pItem = &pWInfo->pTabList->a[pLevel->iFrom];
146818
+ Vdbe *v = pParse->pVdbe; /* VM being constructed */
146819
+ sqlite3 *db = pParse->db; /* Database handle */
146820
+ char *zMsg; /* Text to add to EQP output */
146821
+ int i; /* Loop counter */
146822
+ WhereLoop *pLoop; /* The where loop */
146823
+ StrAccum str; /* EQP output string */
146824
+ char zBuf[100]; /* Initial space for EQP output string */
146825
+
146826
+ sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
146827
+ str.printfFlags = SQLITE_PRINTF_INTERNAL;
146828
+ sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem);
146829
+ pLoop = pLevel->pWLoop;
146830
+ if( pLoop->wsFlags & WHERE_IPK ){
146831
+ const Table *pTab = pItem->pTab;
146832
+ if( pTab->iPKey>=0 ){
146833
+ sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName);
146834
+ }else{
146835
+ sqlite3_str_appendf(&str, "rowid=?");
146836
+ }
146837
+ }else{
146838
+ for(i=pLoop->nSkip; i<pLoop->u.btree.nEq; i++){
146839
+ const char *z = explainIndexColumnName(pLoop->u.btree.pIndex, i);
146840
+ if( i>pLoop->nSkip ) sqlite3_str_append(&str, " AND ", 5);
146841
+ sqlite3_str_appendf(&str, "%s=?", z);
146842
+ }
146843
+ }
146844
+ sqlite3_str_append(&str, ")", 1);
146845
+ zMsg = sqlite3StrAccumFinish(&str);
146846
+ ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
146847
+ pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
146848
+ return ret;
146849
+}
145956146850
#endif /* SQLITE_OMIT_EXPLAIN */
145957146851
145958146852
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
145959146853
/*
145960146854
** Configure the VM passed as the first argument with an
@@ -146156,20 +147050,27 @@
146156147050
){
146157147051
sqlite3 *db = pParse->db;
146158147052
Expr *pNew;
146159147053
pNew = sqlite3ExprDup(db, pX, 0);
146160147054
if( db->mallocFailed==0 ){
146161
- ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */
146162
- ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */
147055
+ ExprList *pOrigRhs; /* Original unmodified RHS */
147056
+ ExprList *pOrigLhs; /* Original unmodified LHS */
146163147057
ExprList *pRhs = 0; /* New RHS after modifications */
146164147058
ExprList *pLhs = 0; /* New LHS after mods */
146165147059
int i; /* Loop counter */
146166147060
Select *pSelect; /* Pointer to the SELECT on the RHS */
146167147061
147062
+ assert( ExprUseXSelect(pNew) );
147063
+ pOrigRhs = pNew->x.pSelect->pEList;
147064
+ assert( pNew->pLeft!=0 );
147065
+ assert( ExprUseXList(pNew->pLeft) );
147066
+ pOrigLhs = pNew->pLeft->x.pList;
146168147067
for(i=iEq; i<pLoop->nLTerm; i++){
146169147068
if( pLoop->aLTerm[i]->pExpr==pX ){
146170
- int iField = pLoop->aLTerm[i]->u.x.iField - 1;
147069
+ int iField;
147070
+ assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
147071
+ iField = pLoop->aLTerm[i]->u.x.iField - 1;
146171147072
if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
146172147073
pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
146173147074
pOrigRhs->a[iField].pExpr = 0;
146174147075
assert( pOrigLhs->a[iField].pExpr!=0 );
146175147076
pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
@@ -146280,11 +147181,11 @@
146280147181
assert( pLoop->aLTerm[i]!=0 );
146281147182
if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
146282147183
}
146283147184
146284147185
iTab = 0;
146285
- if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
147186
+ if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
146286147187
eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
146287147188
}else{
146288147189
sqlite3 *db = pParse->db;
146289147190
pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
146290147191
@@ -146302,12 +147203,12 @@
146302147203
bRev = !bRev;
146303147204
}
146304147205
sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
146305147206
VdbeCoverageIf(v, bRev);
146306147207
VdbeCoverageIf(v, !bRev);
147208
+
146307147209
assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
146308
-
146309147210
pLoop->wsFlags |= WHERE_IN_ABLE;
146310147211
if( pLevel->u.in.nIn==0 ){
146311147212
pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
146312147213
}
146313147214
if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
@@ -146703,11 +147604,11 @@
146703147604
sHint.pIdx = pLoop->u.btree.pIndex;
146704147605
memset(&sWalker, 0, sizeof(sWalker));
146705147606
sWalker.pParse = pParse;
146706147607
sWalker.u.pCCurHint = &sHint;
146707147608
pWC = &pWInfo->sWC;
146708
- for(i=0; i<pWC->nTerm; i++){
147609
+ for(i=0; i<pWC->nBase; i++){
146709147610
pTerm = &pWC->a[i];
146710147611
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
146711147612
if( pTerm->prereqAll & pLevel->notReady ) continue;
146712147613
146713147614
/* Any terms specified as part of the ON(...) clause for any LEFT
@@ -146845,21 +147746,23 @@
146845147746
*/
146846147747
static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
146847147748
assert( nReg>0 );
146848147749
if( p && sqlite3ExprIsVector(p) ){
146849147750
#ifndef SQLITE_OMIT_SUBQUERY
146850
- if( (p->flags & EP_xIsSelect) ){
147751
+ if( ExprUseXSelect(p) ){
146851147752
Vdbe *v = pParse->pVdbe;
146852147753
int iSelect;
146853147754
assert( p->op==TK_SELECT );
146854147755
iSelect = sqlite3CodeSubselect(pParse, p);
146855147756
sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
146856147757
}else
146857147758
#endif
146858147759
{
146859147760
int i;
146860
- ExprList *pList = p->x.pList;
147761
+ const ExprList *pList;
147762
+ assert( ExprUseXList(p) );
147763
+ pList = p->x.pList;
146861147764
assert( nReg<=pList->nExpr );
146862147765
for(i=0; i<nReg; i++){
146863147766
sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
146864147767
}
146865147768
}
@@ -146908,14 +147811,14 @@
146908147811
preserveExpr(pX, pExpr);
146909147812
pExpr->affExpr = sqlite3ExprAffinity(pExpr);
146910147813
pExpr->op = TK_COLUMN;
146911147814
pExpr->iTable = pX->iIdxCur;
146912147815
pExpr->iColumn = pX->iIdxCol;
146913
- pExpr->y.pTab = 0;
146914147816
testcase( ExprHasProperty(pExpr, EP_Skip) );
146915147817
testcase( ExprHasProperty(pExpr, EP_Unlikely) );
146916
- ExprClearProperty(pExpr, EP_Skip|EP_Unlikely);
147818
+ ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn);
147819
+ pExpr->y.pTab = 0;
146917147820
return WRC_Prune;
146918147821
}else{
146919147822
return WRC_Continue;
146920147823
}
146921147824
}
@@ -146926,11 +147829,11 @@
146926147829
*/
146927147830
static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){
146928147831
if( pExpr->op==TK_COLUMN ){
146929147832
IdxExprTrans *pX = p->u.pIdxTrans;
146930147833
if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){
146931
- assert( pExpr->y.pTab!=0 );
147834
+ assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 );
146932147835
preserveExpr(pX, pExpr);
146933147836
pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn);
146934147837
pExpr->iTable = pX->iIdxCur;
146935147838
pExpr->iColumn = pX->iIdxCol;
146936147839
pExpr->y.pTab = 0;
@@ -146974,11 +147877,11 @@
146974147877
x.pWInfo = pWInfo;
146975147878
x.db = pWInfo->pParse->db;
146976147879
for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){
146977147880
i16 iRef = pIdx->aiColumn[iIdxCol];
146978147881
if( iRef==XN_EXPR ){
146979
- assert( aColExpr->a[iIdxCol].pExpr!=0 );
147882
+ assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 );
146980147883
x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
146981147884
if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue;
146982147885
w.xExprCallback = whereIndexExprTransNode;
146983147886
#ifndef SQLITE_OMIT_GENERATED_COLUMNS
146984147887
}else if( iRef>=0
@@ -147031,10 +147934,67 @@
147031147934
if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){
147032147935
pTerm->wtFlags |= TERM_CODED;
147033147936
}
147034147937
}
147035147938
}
147939
+
147940
+/*
147941
+** This routine is called right after An OP_Filter has been generated and
147942
+** before the corresponding index search has been performed. This routine
147943
+** checks to see if there are additional Bloom filters in inner loops that
147944
+** can be checked prior to doing the index lookup. If there are available
147945
+** inner-loop Bloom filters, then evaluate those filters now, before the
147946
+** index lookup. The idea is that a Bloom filter check is way faster than
147947
+** an index lookup, and the Bloom filter might return false, meaning that
147948
+** the index lookup can be skipped.
147949
+**
147950
+** We know that an inner loop uses a Bloom filter because it has the
147951
+** WhereLevel.regFilter set. If an inner-loop Bloom filter is checked,
147952
+** then clear the WhereLevel.regFilter value to prevent the Bloom filter
147953
+** from being checked a second time when the inner loop is evaluated.
147954
+*/
147955
+static SQLITE_NOINLINE void filterPullDown(
147956
+ Parse *pParse, /* Parsing context */
147957
+ WhereInfo *pWInfo, /* Complete information about the WHERE clause */
147958
+ int iLevel, /* Which level of pWInfo->a[] should be coded */
147959
+ int addrNxt, /* Jump here to bypass inner loops */
147960
+ Bitmask notReady /* Loops that are not ready */
147961
+){
147962
+ while( ++iLevel < pWInfo->nLevel ){
147963
+ WhereLevel *pLevel = &pWInfo->a[iLevel];
147964
+ WhereLoop *pLoop = pLevel->pWLoop;
147965
+ if( pLevel->regFilter==0 ) continue;
147966
+ /* ,--- Because constructBloomFilter() has will not have set
147967
+ ** vvvvv--' pLevel->regFilter if this were true. */
147968
+ if( NEVER(pLoop->prereq & notReady) ) continue;
147969
+ if( pLoop->wsFlags & WHERE_IPK ){
147970
+ WhereTerm *pTerm = pLoop->aLTerm[0];
147971
+ int regRowid;
147972
+ assert( pTerm!=0 );
147973
+ assert( pTerm->pExpr!=0 );
147974
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
147975
+ regRowid = sqlite3GetTempReg(pParse);
147976
+ regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid);
147977
+ sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
147978
+ addrNxt, regRowid, 1);
147979
+ VdbeCoverage(pParse->pVdbe);
147980
+ }else{
147981
+ u16 nEq = pLoop->u.btree.nEq;
147982
+ int r1;
147983
+ char *zStartAff;
147984
+
147985
+ assert( pLoop->wsFlags & WHERE_INDEXED );
147986
+ r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff);
147987
+ codeApplyAffinity(pParse, r1, nEq, zStartAff);
147988
+ sqlite3DbFree(pParse->db, zStartAff);
147989
+ sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
147990
+ addrNxt, r1, nEq);
147991
+ VdbeCoverage(pParse->pVdbe);
147992
+ }
147993
+ pLevel->regFilter = 0;
147994
+ }
147995
+}
147036147996
147037147997
/*
147038147998
** Generate code for the start of the iLevel-th loop in the WHERE clause
147039147999
** implementation described by pWInfo.
147040148000
*/
@@ -147163,11 +148123,16 @@
147163148123
** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
147164148124
if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
147165148125
pLevel->p1 = iCur;
147166148126
pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
147167148127
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
147168
- iIn = pLevel->u.in.nIn;
148128
+ assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
148129
+ if( pLoop->wsFlags & WHERE_IN_ABLE ){
148130
+ iIn = pLevel->u.in.nIn;
148131
+ }else{
148132
+ iIn = 0;
148133
+ }
147169148134
for(j=nConstraint-1; j>=0; j--){
147170148135
pTerm = pLoop->aLTerm[j];
147171148136
if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
147172148137
if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
147173148138
disableTerm(pLevel, pTerm);
@@ -147237,10 +148202,16 @@
147237148202
testcase( pTerm->wtFlags & TERM_VIRTUAL );
147238148203
iReleaseReg = ++pParse->nMem;
147239148204
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
147240148205
if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
147241148206
addrNxt = pLevel->addrNxt;
148207
+ if( pLevel->regFilter ){
148208
+ sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt,
148209
+ iRowidReg, 1);
148210
+ VdbeCoverage(v);
148211
+ filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady);
148212
+ }
147242148213
sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
147243148214
VdbeCoverage(v);
147244148215
pLevel->op = OP_Noop;
147245148216
}else if( (pLoop->wsFlags & WHERE_IPK)!=0
147246148217
&& (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
@@ -147562,10 +148533,16 @@
147562148533
}else{
147563148534
if( regBignull ){
147564148535
sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
147565148536
VdbeComment((v, "NULL-scan pass ctr"));
147566148537
}
148538
+ if( pLevel->regFilter ){
148539
+ sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt,
148540
+ regBase, nEq);
148541
+ VdbeCoverage(v);
148542
+ filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady);
148543
+ }
147567148544
147568148545
op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
147569148546
assert( op!=0 );
147570148547
if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
147571148548
assert( regBignull==0 );
@@ -147610,12 +148587,23 @@
147610148587
147611148588
/* Load the value for the inequality constraint at the end of the
147612148589
** range (if any).
147613148590
*/
147614148591
nConstraint = nEq;
148592
+ assert( pLevel->p2==0 );
147615148593
if( pRangeEnd ){
147616148594
Expr *pRight = pRangeEnd->pExpr->pRight;
148595
+ if( addrSeekScan ){
148596
+ /* For a seek-scan that has a range on the lowest term of the index,
148597
+ ** we have to make the top of the loop be code that sets the end
148598
+ ** condition of the range. Otherwise, the OP_SeekScan might jump
148599
+ ** over that initialization, leaving the range-end value set to the
148600
+ ** range-start value, resulting in a wrong answer.
148601
+ ** See ticket 5981a8c041a3c2f3 (2021-11-02).
148602
+ */
148603
+ pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148604
+ }
147617148605
codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
147618148606
whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
147619148607
if( (pRangeEnd->wtFlags & TERM_VNULL)==0
147620148608
&& sqlite3ExprCanBeNull(pRight)
147621148609
){
@@ -147645,11 +148633,11 @@
147645148633
}
147646148634
sqlite3DbFree(db, zStartAff);
147647148635
sqlite3DbFree(db, zEndAff);
147648148636
147649148637
/* Top of the loop body */
147650
- pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148638
+ if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
147651148639
147652148640
/* Check if the index cursor is past the end of the range. */
147653148641
if( nConstraint ){
147654148642
if( regBignull ){
147655148643
/* Except, skip the end-of-range check while doing the NULL-scan */
@@ -148052,11 +149040,14 @@
148052149040
}
148053149041
sqlite3ExprDelete(db, pDelete);
148054149042
}
148055149043
}
148056149044
ExplainQueryPlanPop(pParse);
148057
- pLevel->u.pCovidx = pCov;
149045
+ assert( pLevel->pWLoop==pLoop );
149046
+ assert( (pLoop->wsFlags & WHERE_MULTI_OR)!=0 );
149047
+ assert( (pLoop->wsFlags & WHERE_IN_ABLE)==0 );
149048
+ pLevel->u.pCoveringIdx = pCov;
148058149049
if( pCov ) pLevel->iIdxCur = iCovCur;
148059149050
if( pAndExpr ){
148060149051
pAndExpr->pLeft = 0;
148061149052
sqlite3ExprDelete(db, pAndExpr);
148062149053
}
@@ -148179,11 +149170,11 @@
148179149170
** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
148180149171
** and we are coding the t1 loop and the t2 loop has not yet coded,
148181149172
** then we cannot use the "t1.a=t2.b" constraint, but we can code
148182149173
** the implied "t1.a=123" constraint.
148183149174
*/
148184
- for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
149175
+ for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){
148185149176
Expr *pE, sEAlt;
148186149177
WhereTerm *pAlt;
148187149178
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
148188149179
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
148189149180
if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
@@ -148196,16 +149187,17 @@
148196149187
sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
148197149188
}
148198149189
#endif
148199149190
assert( !ExprHasProperty(pE, EP_FromJoin) );
148200149191
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
149192
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
148201149193
pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
148202149194
WO_EQ|WO_IN|WO_IS, 0);
148203149195
if( pAlt==0 ) continue;
148204149196
if( pAlt->wtFlags & (TERM_CODED) ) continue;
148205149197
if( (pAlt->eOperator & WO_IN)
148206
- && (pAlt->pExpr->flags & EP_xIsSelect)
149198
+ && ExprUseXSelect(pAlt->pExpr)
148207149199
&& (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
148208149200
){
148209149201
continue;
148210149202
}
148211149203
testcase( pAlt->eOperator & WO_EQ );
@@ -148223,11 +149215,11 @@
148223149215
*/
148224149216
if( pLevel->iLeftJoin ){
148225149217
pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
148226149218
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
148227149219
VdbeComment((v, "record LEFT JOIN hit"));
148228
- for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
149220
+ for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
148229149221
testcase( pTerm->wtFlags & TERM_VIRTUAL );
148230149222
testcase( pTerm->wtFlags & TERM_CODED );
148231149223
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
148232149224
if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
148233149225
assert( pWInfo->untestedTerms );
@@ -148334,10 +149326,11 @@
148334149326
sqlite3DbFree(db, pOld);
148335149327
}
148336149328
pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
148337149329
}
148338149330
pTerm = &pWC->a[idx = pWC->nTerm++];
149331
+ if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
148339149332
if( p && ExprHasProperty(p, EP_Unlikely) ){
148340149333
pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
148341149334
}else{
148342149335
pTerm->truthProb = 1;
148343149336
}
@@ -148450,10 +149443,11 @@
148450149443
return 0;
148451149444
}
148452149445
#ifdef SQLITE_EBCDIC
148453149446
if( *pnoCase ) return 0;
148454149447
#endif
149448
+ assert( ExprUseXList(pExpr) );
148455149449
pList = pExpr->x.pList;
148456149450
pLeft = pList->a[1].pExpr;
148457149451
148458149452
pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
148459149453
op = pRight->op;
@@ -148465,11 +149459,12 @@
148465149459
z = sqlite3_value_text(pVal);
148466149460
}
148467149461
sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
148468149462
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
148469149463
}else if( op==TK_STRING ){
148470
- z = (u8*)pRight->u.zToken;
149464
+ assert( !ExprHasProperty(pRight, EP_IntValue) );
149465
+ z = (u8*)pRight->u.zToken;
148471149466
}
148472149467
if( z ){
148473149468
148474149469
/* Count the number of prefix characters prior to the first wildcard */
148475149470
cnt = 0;
@@ -148494,11 +149489,13 @@
148494149489
148495149490
/* Get the pattern prefix. Remove all escapes from the prefix. */
148496149491
pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
148497149492
if( pPrefix ){
148498149493
int iFrom, iTo;
148499
- char *zNew = pPrefix->u.zToken;
149494
+ char *zNew;
149495
+ assert( !ExprHasProperty(pPrefix, EP_IntValue) );
149496
+ zNew = pPrefix->u.zToken;
148500149497
zNew[cnt] = 0;
148501149498
for(iFrom=iTo=0; iFrom<cnt; iFrom++){
148502149499
if( zNew[iFrom]==wc[3] ) iFrom++;
148503149500
zNew[iTo++] = zNew[iFrom];
148504149501
}
@@ -148518,11 +149515,13 @@
148518149515
** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
148519149516
** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
148520149517
*/
148521149518
if( pLeft->op!=TK_COLUMN
148522149519
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
148523
- || (pLeft->y.pTab && IsVirtual(pLeft->y.pTab)) /* Might be numeric */
149520
+ || (ALWAYS( ExprUseYTab(pLeft) )
149521
+ && pLeft->y.pTab
149522
+ && IsVirtual(pLeft->y.pTab)) /* Might be numeric */
148524149523
){
148525149524
int isNum;
148526149525
double rDummy;
148527149526
isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
148528149527
if( isNum<=0 ){
@@ -148546,10 +149545,11 @@
148546149545
/* If the RHS pattern is a bound parameter, make arrangements to
148547149546
** reprepare the statement when that parameter is rebound */
148548149547
if( op==TK_VARIABLE ){
148549149548
Vdbe *v = pParse->pVdbe;
148550149549
sqlite3VdbeSetVarmask(v, pRight->iColumn);
149550
+ assert( !ExprHasProperty(pRight, EP_IntValue) );
148551149551
if( *pisComplete && pRight->u.zToken[1] ){
148552149552
/* If the rhs of the LIKE expression is a variable, and the current
148553149553
** value of the variable means there is no need to invoke the LIKE
148554149554
** function, then no OP_Variable will be added to the program.
148555149555
** This causes problems for the sqlite3_bind_parameter_name()
@@ -148619,10 +149619,11 @@
148619149619
};
148620149620
ExprList *pList;
148621149621
Expr *pCol; /* Column reference */
148622149622
int i;
148623149623
149624
+ assert( ExprUseXList(pExpr) );
148624149625
pList = pExpr->x.pList;
148625149626
if( pList==0 || pList->nExpr!=2 ){
148626149627
return 0;
148627149628
}
148628149629
@@ -148632,13 +149633,15 @@
148632149633
**
148633149634
** vtab_column MATCH expression
148634149635
** MATCH(expression,vtab_column)
148635149636
*/
148636149637
pCol = pList->a[1].pExpr;
149638
+ assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
148637149639
testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
148638149640
if( ExprIsVtab(pCol) ){
148639149641
for(i=0; i<ArraySize(aOp); i++){
149642
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
148640149643
if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
148641149644
*peOp2 = aOp[i].eOp2;
148642149645
*ppRight = pList->a[0].pExpr;
148643149646
*ppLeft = pCol;
148644149647
return 1;
@@ -148655,20 +149658,22 @@
148655149658
** Historically, xFindFunction expected to see lower-case function
148656149659
** names. But for this use case, xFindFunction is expected to deal
148657149660
** with function names in an arbitrary case.
148658149661
*/
148659149662
pCol = pList->a[0].pExpr;
149663
+ assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
148660149664
testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
148661149665
if( ExprIsVtab(pCol) ){
148662149666
sqlite3_vtab *pVtab;
148663149667
sqlite3_module *pMod;
148664149668
void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
148665149669
void *pNotUsed;
148666149670
pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
148667149671
assert( pVtab!=0 );
148668149672
assert( pVtab->pModule!=0 );
148669
- pMod = (sqlite3_module *)pVtab->pModule;
149673
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
149674
+ pMod = (sqlite3_module *)pVtab->pModule;
148670149675
if( pMod->xFindFunction!=0 ){
148671149676
i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
148672149677
if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
148673149678
*peOp2 = i;
148674149679
*ppRight = pList->a[1].pExpr;
@@ -148679,14 +149684,16 @@
148679149684
}
148680149685
}else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
148681149686
int res = 0;
148682149687
Expr *pLeft = pExpr->pLeft;
148683149688
Expr *pRight = pExpr->pRight;
149689
+ assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
148684149690
testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
148685149691
if( ExprIsVtab(pLeft) ){
148686149692
res++;
148687149693
}
149694
+ assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
148688149695
testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
148689149696
if( pRight && ExprIsVtab(pRight) ){
148690149697
res++;
148691149698
SWAP(Expr*, pLeft, pRight);
148692149699
}
@@ -148935,10 +149942,11 @@
148935149942
int j;
148936149943
Bitmask b = 0;
148937149944
pOrTerm->u.pAndInfo = pAndInfo;
148938149945
pOrTerm->wtFlags |= TERM_ANDINFO;
148939149946
pOrTerm->eOperator = WO_AND;
149947
+ pOrTerm->leftCursor = -1;
148940149948
pAndWC = &pAndInfo->wc;
148941149949
memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
148942149950
sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
148943149951
sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
148944149952
sqlite3WhereExprAnalyze(pSrc, pAndWC);
@@ -148977,15 +149985,14 @@
148977149985
/*
148978149986
** Record the set of tables that satisfy case 3. The set might be
148979149987
** empty.
148980149988
*/
148981149989
pOrInfo->indexable = indexable;
149990
+ pTerm->eOperator = WO_OR;
149991
+ pTerm->leftCursor = -1;
148982149992
if( indexable ){
148983
- pTerm->eOperator = WO_OR;
148984149993
pWC->hasOr = 1;
148985
- }else{
148986
- pTerm->eOperator = WO_OR;
148987149994
}
148988149995
148989149996
/* For a two-way OR, attempt to implementation case 2.
148990149997
*/
148991149998
if( indexable && pOrWc->nTerm==2 ){
@@ -149054,10 +150061,11 @@
149054150061
testcase( pOrTerm->wtFlags & TERM_COPIED );
149055150062
testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
149056150063
assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
149057150064
continue;
149058150065
}
150066
+ assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
149059150067
iColumn = pOrTerm->u.x.leftColumn;
149060150068
iCursor = pOrTerm->leftCursor;
149061150069
pLeft = pOrTerm->pExpr->pLeft;
149062150070
break;
149063150071
}
@@ -149074,10 +150082,11 @@
149074150082
/* We have found a candidate table and column. Check to see if that
149075150083
** table and column is common to every term in the OR clause */
149076150084
okToChngToIN = 1;
149077150085
for(; i>=0 && okToChngToIN; i--, pOrTerm++){
149078150086
assert( pOrTerm->eOperator & WO_EQ );
150087
+ assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
149079150088
if( pOrTerm->leftCursor!=iCursor ){
149080150089
pOrTerm->wtFlags &= ~TERM_OR_OK;
149081150090
}else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR
149082150091
&& sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
149083150092
)){
@@ -149110,10 +150119,11 @@
149110150119
Expr *pNew; /* The complete IN operator */
149111150120
149112150121
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
149113150122
if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
149114150123
assert( pOrTerm->eOperator & WO_EQ );
150124
+ assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
149115150125
assert( pOrTerm->leftCursor==iCursor );
149116150126
assert( pOrTerm->u.x.leftColumn==iColumn );
149117150127
pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
149118150128
pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
149119150129
pLeft = pOrTerm->pExpr->pLeft;
@@ -149122,11 +150132,11 @@
149122150132
pDup = sqlite3ExprDup(db, pLeft, 0);
149123150133
pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
149124150134
if( pNew ){
149125150135
int idxNew;
149126150136
transferJoinMarkings(pNew, pExpr);
149127
- assert( !ExprHasProperty(pNew, EP_xIsSelect) );
150137
+ assert( ExprUseXList(pNew) );
149128150138
pNew->x.pList = pList;
149129150139
idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
149130150140
testcase( idxNew==0 );
149131150141
exprAnalyze(pSrc, pWC, idxNew);
149132150142
/* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */
@@ -149250,10 +150260,11 @@
149250150260
** on the first element of the vector. */
149251150261
assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
149252150262
assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
149253150263
assert( op<=TK_GE );
149254150264
if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
150265
+ assert( ExprUseXList(pExpr) );
149255150266
pExpr = pExpr->x.pList->a[0].pExpr;
149256150267
149257150268
}
149258150269
149259150270
if( pExpr->op==TK_COLUMN ){
@@ -149307,32 +150318,49 @@
149307150318
int nLeft; /* Number of elements on left side vector */
149308150319
149309150320
if( db->mallocFailed ){
149310150321
return;
149311150322
}
150323
+ assert( pWC->nTerm > idxTerm );
149312150324
pTerm = &pWC->a[idxTerm];
149313150325
pMaskSet = &pWInfo->sMaskSet;
149314150326
pExpr = pTerm->pExpr;
150327
+ assert( pExpr!=0 ); /* Because malloc() has not failed */
149315150328
assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
150329
+ pMaskSet->bVarSelect = 0;
149316150330
prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
149317150331
op = pExpr->op;
149318150332
if( op==TK_IN ){
149319150333
assert( pExpr->pRight==0 );
149320150334
if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
149321
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
150335
+ if( ExprUseXSelect(pExpr) ){
149322150336
pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
149323150337
}else{
149324150338
pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList);
149325150339
}
149326
- }else if( op==TK_ISNULL ){
149327
- pTerm->prereqRight = 0;
150340
+ prereqAll = prereqLeft | pTerm->prereqRight;
149328150341
}else{
149329150342
pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
150343
+ if( pExpr->pLeft==0
150344
+ || ExprHasProperty(pExpr, EP_xIsSelect|EP_IfNullRow)
150345
+ || pExpr->x.pList!=0
150346
+ ){
150347
+ prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
150348
+ }else{
150349
+ prereqAll = prereqLeft | pTerm->prereqRight;
150350
+ }
149330150351
}
149331
- pMaskSet->bVarSelect = 0;
149332
- prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
149333150352
if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
150353
+
150354
+#ifdef SQLITE_DEBUG
150355
+ if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){
150356
+ printf("\n*** Incorrect prereqAll computed for:\n");
150357
+ sqlite3TreeViewExpr(0,pExpr,0);
150358
+ abort();
150359
+ }
150360
+#endif
150361
+
149334150362
if( ExprHasProperty(pExpr, EP_FromJoin) ){
149335150363
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
149336150364
prereqAll |= x;
149337150365
extraRight = x-1; /* ON clause terms may not be used with an index
149338150366
** on left table of a LEFT JOIN. Ticket #3015 */
@@ -149352,15 +150380,17 @@
149352150380
u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
149353150381
149354150382
if( pTerm->u.x.iField>0 ){
149355150383
assert( op==TK_IN );
149356150384
assert( pLeft->op==TK_VECTOR );
150385
+ assert( ExprUseXList(pLeft) );
149357150386
pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
149358150387
}
149359150388
149360150389
if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
149361150390
pTerm->leftCursor = aiCurCol[0];
150391
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
149362150392
pTerm->u.x.leftColumn = aiCurCol[1];
149363150393
pTerm->eOperator = operatorMask(op) & opMask;
149364150394
}
149365150395
if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
149366150396
if( pRight
@@ -149394,10 +150424,11 @@
149394150424
pDup = pExpr;
149395150425
pNew = pTerm;
149396150426
}
149397150427
pNew->wtFlags |= exprCommute(pParse, pDup);
149398150428
pNew->leftCursor = aiCurCol[0];
150429
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
149399150430
pNew->u.x.leftColumn = aiCurCol[1];
149400150431
testcase( (prereqLeft | extraRight) != prereqLeft );
149401150432
pNew->prereqRight = prereqLeft | extraRight;
149402150433
pNew->prereqAll = prereqAll;
149403150434
pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
@@ -149404,10 +150435,11 @@
149404150435
}else
149405150436
if( op==TK_ISNULL
149406150437
&& !ExprHasProperty(pExpr,EP_FromJoin)
149407150438
&& 0==sqlite3ExprCanBeNull(pLeft)
149408150439
){
150440
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
149409150441
pExpr->op = TK_TRUEFALSE;
149410150442
pExpr->u.zToken = "false";
149411150443
ExprSetProperty(pExpr, EP_IsFalse);
149412150444
pTerm->prereqAll = 0;
149413150445
pTerm->eOperator = 0;
@@ -149429,13 +150461,15 @@
149429150461
** term. That means that if the BETWEEN term is coded, the children are
149430150462
** skipped. Or, if the children are satisfied by an index, the original
149431150463
** BETWEEN term is skipped.
149432150464
*/
149433150465
else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
149434
- ExprList *pList = pExpr->x.pList;
150466
+ ExprList *pList;
149435150467
int i;
149436150468
static const u8 ops[] = {TK_GE, TK_LE};
150469
+ assert( ExprUseXList(pExpr) );
150470
+ pList = pExpr->x.pList;
149437150471
assert( pList!=0 );
149438150472
assert( pList->nExpr==2 );
149439150473
for(i=0; i<2; i++){
149440150474
Expr *pNewExpr;
149441150475
int idxNew;
@@ -149524,12 +150558,16 @@
149524150558
int idxNew1;
149525150559
int idxNew2;
149526150560
const char *zCollSeqName; /* Name of collating sequence */
149527150561
const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
149528150562
150563
+ assert( ExprUseXList(pExpr) );
149529150564
pLeft = pExpr->x.pList->a[1].pExpr;
149530150565
pStr2 = sqlite3ExprDup(db, pStr1, 0);
150566
+ assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) );
150567
+ assert( pStr2==0 || !ExprHasProperty(pStr2, EP_IntValue) );
150568
+
149531150569
149532150570
/* Convert the lower bound to upper-case and the upper bound to
149533150571
** lower-case (upper-case is less than lower-case in ASCII) so that
149534150572
** the range constraints also work for BLOBs
149535150573
*/
@@ -149625,10 +150663,11 @@
149625150663
** not use window functions.
149626150664
*/
149627150665
else if( pExpr->op==TK_IN
149628150666
&& pTerm->u.x.iField==0
149629150667
&& pExpr->pLeft->op==TK_VECTOR
150668
+ && ALWAYS( ExprUseXSelect(pExpr) )
149630150669
&& pExpr->x.pSelect->pPrior==0
149631150670
#ifndef SQLITE_OMIT_WINDOWFUNC
149632150671
&& pExpr->x.pSelect->pWin==0
149633150672
#endif
149634150673
&& pWC->op==TK_AND
@@ -149741,10 +150780,11 @@
149741150780
){
149742150781
pWC->pWInfo = pWInfo;
149743150782
pWC->hasOr = 0;
149744150783
pWC->pOuter = 0;
149745150784
pWC->nTerm = 0;
150785
+ pWC->nBase = 0;
149746150786
pWC->nSlot = ArraySize(pWC->aStatic);
149747150787
pWC->a = pWC->aStatic;
149748150788
}
149749150789
149750150790
/*
@@ -149751,21 +150791,37 @@
149751150791
** Deallocate a WhereClause structure. The WhereClause structure
149752150792
** itself is not freed. This routine is the inverse of
149753150793
** sqlite3WhereClauseInit().
149754150794
*/
149755150795
SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
149756
- int i;
149757
- WhereTerm *a;
149758150796
sqlite3 *db = pWC->pWInfo->pParse->db;
149759
- for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
149760
- if( a->wtFlags & TERM_DYNAMIC ){
149761
- sqlite3ExprDelete(db, a->pExpr);
149762
- }
149763
- if( a->wtFlags & TERM_ORINFO ){
149764
- whereOrInfoDelete(db, a->u.pOrInfo);
149765
- }else if( a->wtFlags & TERM_ANDINFO ){
149766
- whereAndInfoDelete(db, a->u.pAndInfo);
150797
+ assert( pWC->nTerm>=pWC->nBase );
150798
+ if( pWC->nTerm>0 ){
150799
+ WhereTerm *a = pWC->a;
150800
+ WhereTerm *aLast = &pWC->a[pWC->nTerm-1];
150801
+#ifdef SQLITE_DEBUG
150802
+ int i;
150803
+ /* Verify that every term past pWC->nBase is virtual */
150804
+ for(i=pWC->nBase; i<pWC->nTerm; i++){
150805
+ assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
150806
+ }
150807
+#endif
150808
+ while(1){
150809
+ if( a->wtFlags & TERM_DYNAMIC ){
150810
+ sqlite3ExprDelete(db, a->pExpr);
150811
+ }
150812
+ if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
150813
+ if( a->wtFlags & TERM_ORINFO ){
150814
+ assert( (a->wtFlags & TERM_ANDINFO)==0 );
150815
+ whereOrInfoDelete(db, a->u.pOrInfo);
150816
+ }else{
150817
+ assert( (a->wtFlags & TERM_ANDINFO)!=0 );
150818
+ whereAndInfoDelete(db, a->u.pAndInfo);
150819
+ }
150820
+ }
150821
+ if( a==aLast ) break;
150822
+ a++;
149767150823
}
149768150824
}
149769150825
if( pWC->a!=pWC->aStatic ){
149770150826
sqlite3DbFree(db, pWC->a);
149771150827
}
@@ -149774,38 +150830,71 @@
149774150830
149775150831
/*
149776150832
** These routines walk (recursively) an expression tree and generate
149777150833
** a bitmask indicating which tables are used in that expression
149778150834
** tree.
150835
+**
150836
+** sqlite3WhereExprUsage(MaskSet, Expr) ->
150837
+**
150838
+** Return a Bitmask of all tables referenced by Expr. Expr can be
150839
+** be NULL, in which case 0 is returned.
150840
+**
150841
+** sqlite3WhereExprUsageNN(MaskSet, Expr) ->
150842
+**
150843
+** Same as sqlite3WhereExprUsage() except that Expr must not be
150844
+** NULL. The "NN" suffix on the name stands for "Not Null".
150845
+**
150846
+** sqlite3WhereExprListUsage(MaskSet, ExprList) ->
150847
+**
150848
+** Return a Bitmask of all tables referenced by every expression
150849
+** in the expression list ExprList. ExprList can be NULL, in which
150850
+** case 0 is returned.
150851
+**
150852
+** sqlite3WhereExprUsageFull(MaskSet, ExprList) ->
150853
+**
150854
+** Internal use only. Called only by sqlite3WhereExprUsageNN() for
150855
+** complex expressions that require pushing register values onto
150856
+** the stack. Many calls to sqlite3WhereExprUsageNN() do not need
150857
+** the more complex analysis done by this routine. Hence, the
150858
+** computations done by this routine are broken out into a separate
150859
+** "no-inline" function to avoid the stack push overhead in the
150860
+** common case where it is not needed.
149779150861
*/
149780
-SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
150862
+static SQLITE_NOINLINE Bitmask sqlite3WhereExprUsageFull(
150863
+ WhereMaskSet *pMaskSet,
150864
+ Expr *p
150865
+){
149781150866
Bitmask mask;
149782
- if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
149783
- return sqlite3WhereGetMask(pMaskSet, p->iTable);
149784
- }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
149785
- assert( p->op!=TK_IF_NULL_ROW );
149786
- return 0;
149787
- }
149788150867
mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
149789150868
if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
149790150869
if( p->pRight ){
149791150870
mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
149792150871
assert( p->x.pList==0 );
149793
- }else if( ExprHasProperty(p, EP_xIsSelect) ){
150872
+ }else if( ExprUseXSelect(p) ){
149794150873
if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
149795150874
mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
149796150875
}else if( p->x.pList ){
149797150876
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
149798150877
}
149799150878
#ifndef SQLITE_OMIT_WINDOWFUNC
149800
- if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){
150879
+ if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && ExprUseYWin(p) ){
150880
+ assert( p->y.pWin!=0 );
149801150881
mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
149802150882
mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
149803150883
mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter);
149804150884
}
149805150885
#endif
149806150886
return mask;
150887
+}
150888
+SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
150889
+ if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
150890
+ return sqlite3WhereGetMask(pMaskSet, p->iTable);
150891
+ }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
150892
+ assert( p->op!=TK_IF_NULL_ROW );
150893
+ return 0;
150894
+ }
150895
+ return sqlite3WhereExprUsageFull(pMaskSet, p);
149807150896
}
149808150897
SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
149809150898
return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
149810150899
}
149811150900
SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
@@ -149870,10 +150959,11 @@
149870150959
}
149871150960
pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
149872150961
if( pColRef==0 ) return;
149873150962
pColRef->iTable = pItem->iCursor;
149874150963
pColRef->iColumn = k++;
150964
+ assert( ExprUseYTab(pColRef) );
149875150965
pColRef->y.pTab = pTab;
149876150966
pRhs = sqlite3PExpr(pParse, TK_UPLUS,
149877150967
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
149878150968
pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
149879150969
if( pItem->fg.jointype & JT_LEFT ){
@@ -150119,11 +151209,16 @@
150119151209
** iCursor is not in the set.
150120151210
*/
150121151211
SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){
150122151212
int i;
150123151213
assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
150124
- for(i=0; i<pMaskSet->n; i++){
151214
+ assert( pMaskSet->n>0 || pMaskSet->ix[0]<0 );
151215
+ assert( iCursor>=-1 );
151216
+ if( pMaskSet->ix[0]==iCursor ){
151217
+ return 1;
151218
+ }
151219
+ for(i=1; i<pMaskSet->n; i++){
150125151220
if( pMaskSet->ix[i]==iCursor ){
150126151221
return MASKBIT(i);
150127151222
}
150128151223
}
150129151224
return 0;
@@ -150171,12 +151266,14 @@
150171151266
pWC = pScan->pWC;
150172151267
while(1){
150173151268
iColumn = pScan->aiColumn[pScan->iEquiv-1];
150174151269
iCur = pScan->aiCur[pScan->iEquiv-1];
150175151270
assert( pWC!=0 );
151271
+ assert( iCur>=0 );
150176151272
do{
150177151273
for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
151274
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 || pTerm->leftCursor<0 );
150178151275
if( pTerm->leftCursor==iCur
150179151276
&& pTerm->u.x.leftColumn==iColumn
150180151277
&& (iColumn!=XN_EXPR
150181151278
|| sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
150182151279
pScan->pIdxExpr,iCur)==0)
@@ -150214,11 +151311,12 @@
150214151311
if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
150215151312
continue;
150216151313
}
150217151314
}
150218151315
if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
150219
- && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
151316
+ && (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0))
151317
+ && pX->op==TK_COLUMN
150220151318
&& pX->iTable==pScan->aiCur[0]
150221151319
&& pX->iColumn==pScan->aiColumn[0]
150222151320
){
150223151321
testcase( pTerm->eOperator & WO_IS );
150224151322
continue;
@@ -150301,20 +151399,20 @@
150301151399
pScan->nEquiv = 1;
150302151400
pScan->iEquiv = 1;
150303151401
if( pIdx ){
150304151402
int j = iColumn;
150305151403
iColumn = pIdx->aiColumn[j];
150306
- if( iColumn==XN_EXPR ){
151404
+ if( iColumn==pIdx->pTable->iPKey ){
151405
+ iColumn = XN_ROWID;
151406
+ }else if( iColumn>=0 ){
151407
+ pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
151408
+ pScan->zCollName = pIdx->azColl[j];
151409
+ }else if( iColumn==XN_EXPR ){
150307151410
pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
150308151411
pScan->zCollName = pIdx->azColl[j];
150309151412
pScan->aiColumn[0] = XN_EXPR;
150310151413
return whereScanInitIndexExpr(pScan);
150311
- }else if( iColumn==pIdx->pTable->iPKey ){
150312
- iColumn = XN_ROWID;
150313
- }else if( iColumn>=0 ){
150314
- pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
150315
- pScan->zCollName = pIdx->azColl[j];
150316151414
}
150317151415
}else if( iColumn==XN_EXPR ){
150318151416
return 0;
150319151417
}
150320151418
pScan->aiColumn[0] = iColumn;
@@ -150594,13 +151692,13 @@
150594151692
** Return TRUE if the WHERE clause term pTerm is of a form where it
150595151693
** could be used with an index to access pSrc, assuming an appropriate
150596151694
** index existed.
150597151695
*/
150598151696
static int termCanDriveIndex(
150599
- WhereTerm *pTerm, /* WHERE clause term to check */
150600
- SrcItem *pSrc, /* Table we are trying to access */
150601
- Bitmask notReady /* Tables in outer loops of the join */
151697
+ const WhereTerm *pTerm, /* WHERE clause term to check */
151698
+ const SrcItem *pSrc, /* Table we are trying to access */
151699
+ const Bitmask notReady /* Tables in outer loops of the join */
150602151700
){
150603151701
char aff;
150604151702
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
150605151703
if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
150606151704
if( (pSrc->fg.jointype & JT_LEFT)
@@ -150611,10 +151709,11 @@
150611151709
** the RHS of a LEFT JOIN. Such a term can only be used if it is from
150612151710
** the ON clause. */
150613151711
return 0;
150614151712
}
150615151713
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
151714
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
150616151715
if( pTerm->u.x.leftColumn<0 ) return 0;
150617151716
aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
150618151717
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
150619151718
testcase( pTerm->pExpr->op==TK_IS );
150620151719
return 1;
@@ -150626,15 +151725,15 @@
150626151725
/*
150627151726
** Generate code to construct the Index object for an automatic index
150628151727
** and to set up the WhereLevel object pLevel so that the code generator
150629151728
** makes use of the automatic index.
150630151729
*/
150631
-static void constructAutomaticIndex(
151730
+static SQLITE_NOINLINE void constructAutomaticIndex(
150632151731
Parse *pParse, /* The parsing context */
150633
- WhereClause *pWC, /* The WHERE clause */
150634
- SrcItem *pSrc, /* The FROM clause term to get the next index */
150635
- Bitmask notReady, /* Mask of cursors that are not available */
151732
+ const WhereClause *pWC, /* The WHERE clause */
151733
+ const SrcItem *pSrc, /* The FROM clause term to get the next index */
151734
+ const Bitmask notReady, /* Mask of cursors that are not available */
150636151735
WhereLevel *pLevel /* Write new index here */
150637151736
){
150638151737
int nKeyCol; /* Number of columns in the constructed index */
150639151738
WhereTerm *pTerm; /* A single term of the WHERE clause */
150640151739
WhereTerm *pWCEnd; /* End of pWC->a[] */
@@ -150672,23 +151771,26 @@
150672151771
pWCEnd = &pWC->a[pWC->nTerm];
150673151772
pLoop = pLevel->pWLoop;
150674151773
idxCols = 0;
150675151774
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
150676151775
Expr *pExpr = pTerm->pExpr;
150677
- assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */
150678
- || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */
150679
- || pLoop->prereq!=0 ); /* table of a LEFT JOIN */
150680
- if( pLoop->prereq==0
150681
- && (pTerm->wtFlags & TERM_VIRTUAL)==0
150682
- && !ExprHasProperty(pExpr, EP_FromJoin)
150683
- && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
151776
+ /* Make the automatic index a partial index if there are terms in the
151777
+ ** WHERE clause (or the ON clause of a LEFT join) that constrain which
151778
+ ** rows of the target table (pSrc) that can be used. */
151779
+ if( (pTerm->wtFlags & TERM_VIRTUAL)==0
151780
+ && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin))
151781
+ && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
151782
+ ){
150684151783
pPartial = sqlite3ExprAnd(pParse, pPartial,
150685151784
sqlite3ExprDup(pParse->db, pExpr, 0));
150686151785
}
150687151786
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
150688
- int iCol = pTerm->u.x.leftColumn;
150689
- Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
151787
+ int iCol;
151788
+ Bitmask cMask;
151789
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151790
+ iCol = pTerm->u.x.leftColumn;
151791
+ cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
150690151792
testcase( iCol==BMS );
150691151793
testcase( iCol==BMS-1 );
150692151794
if( !sentWarning ){
150693151795
sqlite3_log(SQLITE_WARNING_AUTOINDEX,
150694151796
"automatic index on %s(%s)", pTable->zName,
@@ -150736,12 +151838,15 @@
150736151838
pIdx->pTable = pTable;
150737151839
n = 0;
150738151840
idxCols = 0;
150739151841
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
150740151842
if( termCanDriveIndex(pTerm, pSrc, notReady) ){
150741
- int iCol = pTerm->u.x.leftColumn;
150742
- Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
151843
+ int iCol;
151844
+ Bitmask cMask;
151845
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151846
+ iCol = pTerm->u.x.leftColumn;
151847
+ cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
150743151848
testcase( iCol==BMS-1 );
150744151849
testcase( iCol==BMS );
150745151850
if( (idxCols & cMask)==0 ){
150746151851
Expr *pX = pTerm->pExpr;
150747151852
idxCols |= cMask;
@@ -150779,10 +151884,14 @@
150779151884
assert( pLevel->iIdxCur>=0 );
150780151885
pLevel->iIdxCur = pParse->nTab++;
150781151886
sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
150782151887
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
150783151888
VdbeComment((v, "for %s", pTable->zName));
151889
+ if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){
151890
+ pLevel->regFilter = ++pParse->nMem;
151891
+ sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter);
151892
+ }
150784151893
150785151894
/* Fill the automatic index with content */
150786151895
pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
150787151896
if( pTabItem->fg.viaCoroutine ){
150788151897
int regYield = pTabItem->regReturn;
@@ -150801,10 +151910,14 @@
150801151910
}
150802151911
regRecord = sqlite3GetTempReg(pParse);
150803151912
regBase = sqlite3GenerateIndexKey(
150804151913
pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
150805151914
);
151915
+ if( pLevel->regFilter ){
151916
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0,
151917
+ regBase, pLoop->u.btree.nEq);
151918
+ }
150806151919
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
150807151920
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
150808151921
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
150809151922
if( pTabItem->fg.viaCoroutine ){
150810151923
sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
@@ -150826,10 +151939,127 @@
150826151939
150827151940
end_auto_index_create:
150828151941
sqlite3ExprDelete(pParse->db, pPartial);
150829151942
}
150830151943
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
151944
+
151945
+/*
151946
+** Generate bytecode that will initialize a Bloom filter that is appropriate
151947
+** for pLevel.
151948
+**
151949
+** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER
151950
+** flag set, initialize a Bloomfilter for them as well. Except don't do
151951
+** this recursive initialization if the SQLITE_BloomPulldown optimization has
151952
+** been turned off.
151953
+**
151954
+** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared
151955
+** from the loop, but the regFilter value is set to a register that implements
151956
+** the Bloom filter. When regFilter is positive, the
151957
+** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter
151958
+** and skip the subsequence B-Tree seek if the Bloom filter indicates that
151959
+** no matching rows exist.
151960
+**
151961
+** This routine may only be called if it has previously been determined that
151962
+** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit
151963
+** is set.
151964
+*/
151965
+static SQLITE_NOINLINE void constructBloomFilter(
151966
+ WhereInfo *pWInfo, /* The WHERE clause */
151967
+ int iLevel, /* Index in pWInfo->a[] that is pLevel */
151968
+ WhereLevel *pLevel, /* Make a Bloom filter for this FROM term */
151969
+ Bitmask notReady /* Loops that are not ready */
151970
+){
151971
+ int addrOnce; /* Address of opening OP_Once */
151972
+ int addrTop; /* Address of OP_Rewind */
151973
+ int addrCont; /* Jump here to skip a row */
151974
+ const WhereTerm *pTerm; /* For looping over WHERE clause terms */
151975
+ const WhereTerm *pWCEnd; /* Last WHERE clause term */
151976
+ Parse *pParse = pWInfo->pParse; /* Parsing context */
151977
+ Vdbe *v = pParse->pVdbe; /* VDBE under construction */
151978
+ WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */
151979
+ int iCur; /* Cursor for table getting the filter */
151980
+
151981
+ assert( pLoop!=0 );
151982
+ assert( v!=0 );
151983
+ assert( pLoop->wsFlags & WHERE_BLOOMFILTER );
151984
+
151985
+ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
151986
+ do{
151987
+ const SrcItem *pItem;
151988
+ const Table *pTab;
151989
+ u64 sz;
151990
+ sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel);
151991
+ addrCont = sqlite3VdbeMakeLabel(pParse);
151992
+ iCur = pLevel->iTabCur;
151993
+ pLevel->regFilter = ++pParse->nMem;
151994
+
151995
+ /* The Bloom filter is a Blob held in a register. Initialize it
151996
+ ** to zero-filled blob of at least 80K bits, but maybe more if the
151997
+ ** estimated size of the table is larger. We could actually
151998
+ ** measure the size of the table at run-time using OP_Count with
151999
+ ** P3==1 and use that value to initialize the blob. But that makes
152000
+ ** testing complicated. By basing the blob size on the value in the
152001
+ ** sqlite_stat1 table, testing is much easier.
152002
+ */
152003
+ pItem = &pWInfo->pTabList->a[pLevel->iFrom];
152004
+ assert( pItem!=0 );
152005
+ pTab = pItem->pTab;
152006
+ assert( pTab!=0 );
152007
+ sz = sqlite3LogEstToInt(pTab->nRowLogEst);
152008
+ if( sz<10000 ){
152009
+ sz = 10000;
152010
+ }else if( sz>10000000 ){
152011
+ sz = 10000000;
152012
+ }
152013
+ sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter);
152014
+
152015
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
152016
+ pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm];
152017
+ for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
152018
+ Expr *pExpr = pTerm->pExpr;
152019
+ if( (pTerm->wtFlags & TERM_VIRTUAL)==0
152020
+ && sqlite3ExprIsTableConstant(pExpr, iCur)
152021
+ ){
152022
+ sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
152023
+ }
152024
+ }
152025
+ if( pLoop->wsFlags & WHERE_IPK ){
152026
+ int r1 = sqlite3GetTempReg(pParse);
152027
+ sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1);
152028
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, 1);
152029
+ sqlite3ReleaseTempReg(pParse, r1);
152030
+ }else{
152031
+ Index *pIdx = pLoop->u.btree.pIndex;
152032
+ int n = pLoop->u.btree.nEq;
152033
+ int r1 = sqlite3GetTempRange(pParse, n);
152034
+ int jj;
152035
+ for(jj=0; jj<n; jj++){
152036
+ int iCol = pIdx->aiColumn[jj];
152037
+ assert( pIdx->pTable==pItem->pTab );
152038
+ sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj);
152039
+ }
152040
+ sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
152041
+ sqlite3ReleaseTempRange(pParse, r1, n);
152042
+ }
152043
+ sqlite3VdbeResolveLabel(v, addrCont);
152044
+ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
152045
+ VdbeCoverage(v);
152046
+ sqlite3VdbeJumpHere(v, addrTop);
152047
+ pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
152048
+ if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
152049
+ while( iLevel < pWInfo->nLevel ){
152050
+ iLevel++;
152051
+ pLevel = &pWInfo->a[iLevel];
152052
+ pLoop = pLevel->pWLoop;
152053
+ if( pLoop==0 ) continue;
152054
+ if( pLoop->prereq & notReady ) continue;
152055
+ if( pLoop->wsFlags & WHERE_BLOOMFILTER ) break;
152056
+ }
152057
+ }while( iLevel < pWInfo->nLevel );
152058
+ sqlite3VdbeJumpHere(v, addrOnce);
152059
+}
152060
+
150831152061
150832152062
#ifndef SQLITE_OMIT_VIRTUALTABLE
150833152063
/*
150834152064
** Allocate and populate an sqlite3_index_info structure. It is the
150835152065
** responsibility of the caller to eventually release the structure
@@ -150864,10 +152094,11 @@
150864152094
testcase( pTerm->eOperator & WO_ISNULL );
150865152095
testcase( pTerm->eOperator & WO_IS );
150866152096
testcase( pTerm->eOperator & WO_ALL );
150867152097
if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
150868152098
if( pTerm->wtFlags & TERM_VNULL ) continue;
152099
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
150869152100
assert( pTerm->u.x.leftColumn>=(-1) );
150870152101
nTerm++;
150871152102
}
150872152103
150873152104
/* If the ORDER BY clause contains only columns in the current
@@ -150924,10 +152155,11 @@
150924152155
if( (pSrc->fg.jointype & JT_LEFT)!=0
150925152156
&& !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
150926152157
){
150927152158
continue;
150928152159
}
152160
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
150929152161
assert( pTerm->u.x.leftColumn>=(-1) );
150930152162
pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
150931152163
pIdxCons[j].iTermOffset = i;
150932152164
op = pTerm->eOperator & WO_ALL;
150933152165
if( op==WO_IN ) op = WO_EQ;
@@ -151687,10 +152919,11 @@
151687152919
if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
151688152920
if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
151689152921
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
151690152922
if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
151691152923
if( pTerm->eOperator & WO_SINGLE ){
152924
+ assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151692152925
sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
151693152926
pTerm->leftCursor, pTerm->u.x.leftColumn);
151694152927
}else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
151695152928
sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
151696152929
pTerm->u.pOrInfo->indexable);
@@ -151704,11 +152937,11 @@
151704152937
** shown about each Term */
151705152938
if( sqlite3WhereTrace & 0x10000 ){
151706152939
sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
151707152940
pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
151708152941
}
151709
- if( pTerm->u.x.iField ){
152942
+ if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){
151710152943
sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
151711152944
}
151712152945
if( pTerm->iParent>=0 ){
151713152946
sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
151714152947
}
@@ -151766,13 +152999,13 @@
151766152999
}
151767153000
sqlite3DebugPrintf(" %-19s", z);
151768153001
sqlite3_free(z);
151769153002
}
151770153003
if( p->wsFlags & WHERE_SKIPSCAN ){
151771
- sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
153004
+ sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
151772153005
}else{
151773
- sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
153006
+ sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
151774153007
}
151775153008
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
151776153009
if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
151777153010
int i;
151778153011
for(i=0; i<p->nLTerm; i++){
@@ -151868,11 +153101,12 @@
151868153101
static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
151869153102
int i;
151870153103
assert( pWInfo!=0 );
151871153104
for(i=0; i<pWInfo->nLevel; i++){
151872153105
WhereLevel *pLevel = &pWInfo->a[i];
151873
- if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
153106
+ if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){
153107
+ assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 );
151874153108
sqlite3DbFree(db, pLevel->u.in.aInLoop);
151875153109
}
151876153110
}
151877153111
sqlite3WhereClauseClear(&pWInfo->sWC);
151878153112
while( pWInfo->pLoops ){
@@ -152227,22 +153461,29 @@
152227153461
Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
152228153462
int i, j;
152229153463
LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
152230153464
152231153465
assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
152232
- for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
153466
+ for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){
152233153467
assert( pTerm!=0 );
152234
- if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
153468
+ if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
152235153469
if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
152236
- if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
153470
+ if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue;
152237153471
for(j=pLoop->nLTerm-1; j>=0; j--){
152238153472
pX = pLoop->aLTerm[j];
152239153473
if( pX==0 ) continue;
152240153474
if( pX==pTerm ) break;
152241153475
if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
152242153476
}
152243153477
if( j<0 ){
153478
+ if( pLoop->maskSelf==pTerm->prereqAll ){
153479
+ /* If there are extra terms in the WHERE clause not used by an index
153480
+ ** that depend only on the table being scanned, and that will tend to
153481
+ ** cause many rows to be omitted, then mark that table as
153482
+ ** "self-culling". */
153483
+ pLoop->wsFlags |= WHERE_SELFCULL;
153484
+ }
152244153485
if( pTerm->truthProb<=0 ){
152245153486
/* If a truth probability is specified using the likelihood() hints,
152246153487
** then use the probability provided by the application. */
152247153488
pLoop->nOut += pTerm->truthProb;
152248153489
}else{
@@ -152266,11 +153507,13 @@
152266153507
}
152267153508
}
152268153509
}
152269153510
}
152270153511
}
152271
- if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce;
153512
+ if( pLoop->nOut > nRow-iReduce ){
153513
+ pLoop->nOut = nRow - iReduce;
153514
+ }
152272153515
}
152273153516
152274153517
/*
152275153518
** Term pTerm is a vector range comparison operation. The first comparison
152276153519
** in the vector can be optimized using column nEq of the index. This
@@ -152303,13 +153546,16 @@
152303153546
/* Test if comparison i of pTerm is compatible with column (i+nEq)
152304153547
** of the index. If not, exit the loop. */
152305153548
char aff; /* Comparison affinity */
152306153549
char idxaff = 0; /* Indexed columns affinity */
152307153550
CollSeq *pColl; /* Comparison collation sequence */
152308
- Expr *pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
152309
- Expr *pRhs = pTerm->pExpr->pRight;
152310
- if( pRhs->flags & EP_xIsSelect ){
153551
+ Expr *pLhs, *pRhs;
153552
+
153553
+ assert( ExprUseXList(pTerm->pExpr->pLeft) );
153554
+ pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
153555
+ pRhs = pTerm->pExpr->pRight;
153556
+ if( ExprUseXSelect(pRhs) ){
152311153557
pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
152312153558
}else{
152313153559
pRhs = pRhs->x.pList->a[i].pExpr;
152314153560
}
152315153561
@@ -152466,11 +153712,11 @@
152466153712
|| (pNew->wsFlags & WHERE_SKIPSCAN)!=0
152467153713
);
152468153714
152469153715
if( eOp & WO_IN ){
152470153716
Expr *pExpr = pTerm->pExpr;
152471
- if( ExprHasProperty(pExpr, EP_xIsSelect) ){
153717
+ if( ExprUseXSelect(pExpr) ){
152472153718
/* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
152473153719
int i;
152474153720
nIn = 46; assert( 46==sqlite3LogEst(25) );
152475153721
152476153722
/* The expression may actually be of the form (x, y) IN (SELECT...).
@@ -152607,11 +153853,11 @@
152607153853
#ifdef SQLITE_ENABLE_STAT4
152608153854
tRowcnt nOut = 0;
152609153855
if( nInMul==0
152610153856
&& pProbe->nSample
152611153857
&& ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol)
152612
- && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
153858
+ && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr))
152613153859
&& OptimizationEnabled(db, SQLITE_Stat4)
152614153860
){
152615153861
Expr *pExpr = pTerm->pExpr;
152616153862
if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
152617153863
testcase( eOp & WO_EQ );
@@ -152883,10 +154129,11 @@
152883154129
pTab = pSrc->pTab;
152884154130
pWC = pBuilder->pWC;
152885154131
assert( !IsVirtual(pSrc->pTab) );
152886154132
152887154133
if( pSrc->fg.isIndexedBy ){
154134
+ assert( pSrc->fg.isCte==0 );
152888154135
/* An INDEXED BY clause specifies a particular index to use */
152889154136
pProbe = pSrc->u2.pIBIndex;
152890154137
}else if( !HasRowid(pTab) ){
152891154138
pProbe = pTab->pIndex;
152892154139
}else{
@@ -153498,10 +154745,11 @@
153498154745
}else if( pOrTerm->leftCursor==iCur ){
153499154746
tempWC.pWInfo = pWC->pWInfo;
153500154747
tempWC.pOuter = pWC;
153501154748
tempWC.op = TK_AND;
153502154749
tempWC.nTerm = 1;
154750
+ tempWC.nBase = 1;
153503154751
tempWC.a = pOrTerm;
153504154752
sSubBuild.pWC = &tempWC;
153505154753
}else{
153506154754
continue;
153507154755
}
@@ -153969,11 +155217,11 @@
153969155217
}
153970155218
} /* End the loop over all WhereLoops from outer-most down to inner-most */
153971155219
if( obSat==obDone ) return (i8)nOrderBy;
153972155220
if( !isOrderDistinct ){
153973155221
for(i=nOrderBy-1; i>0; i--){
153974
- Bitmask m = MASKBIT(i) - 1;
155222
+ Bitmask m = ALWAYS(i<BMS) ? MASKBIT(i) - 1 : 0;
153975155223
if( (obSat&m)==m ) return i;
153976155224
}
153977155225
return 0;
153978155226
}
153979155227
return -1;
@@ -154494,13 +155742,13 @@
154494155742
pWC = &pWInfo->sWC;
154495155743
pLoop = pBuilder->pNew;
154496155744
pLoop->wsFlags = 0;
154497155745
pLoop->nSkip = 0;
154498155746
pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0);
155747
+ while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan);
154499155748
if( pTerm ){
154500155749
testcase( pTerm->eOperator & WO_IS );
154501
- assert( pTerm->prereqRight==0 );
154502155750
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
154503155751
pLoop->aLTerm[0] = pTerm;
154504155752
pLoop->nLTerm = 1;
154505155753
pLoop->u.btree.nEq = 1;
154506155754
/* TUNING: Cost of a rowid lookup is 10 */
@@ -154604,10 +155852,154 @@
154604155852
}
154605155853
# define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C)
154606155854
#else
154607155855
# define WHERETRACE_ALL_LOOPS(W,C)
154608155856
#endif
155857
+
155858
+/* Attempt to omit tables from a join that do not affect the result.
155859
+** For a table to not affect the result, the following must be true:
155860
+**
155861
+** 1) The query must not be an aggregate.
155862
+** 2) The table must be the RHS of a LEFT JOIN.
155863
+** 3) Either the query must be DISTINCT, or else the ON or USING clause
155864
+** must contain a constraint that limits the scan of the table to
155865
+** at most a single row.
155866
+** 4) The table must not be referenced by any part of the query apart
155867
+** from its own USING or ON clause.
155868
+**
155869
+** For example, given:
155870
+**
155871
+** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
155872
+** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
155873
+** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
155874
+**
155875
+** then table t2 can be omitted from the following:
155876
+**
155877
+** SELECT v1, v3 FROM t1
155878
+** LEFT JOIN t2 ON (t1.ipk=t2.ipk)
155879
+** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
155880
+**
155881
+** or from:
155882
+**
155883
+** SELECT DISTINCT v1, v3 FROM t1
155884
+** LEFT JOIN t2
155885
+** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
155886
+*/
155887
+static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
155888
+ WhereInfo *pWInfo,
155889
+ Bitmask notReady
155890
+){
155891
+ int i;
155892
+ Bitmask tabUsed;
155893
+
155894
+ /* Preconditions checked by the caller */
155895
+ assert( pWInfo->nLevel>=2 );
155896
+ assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_OmitNoopJoin) );
155897
+
155898
+ /* These two preconditions checked by the caller combine to guarantee
155899
+ ** condition (1) of the header comment */
155900
+ assert( pWInfo->pResultSet!=0 );
155901
+ assert( 0==(pWInfo->wctrlFlags & WHERE_AGG_DISTINCT) );
155902
+
155903
+ tabUsed = sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pResultSet);
155904
+ if( pWInfo->pOrderBy ){
155905
+ tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy);
155906
+ }
155907
+ for(i=pWInfo->nLevel-1; i>=1; i--){
155908
+ WhereTerm *pTerm, *pEnd;
155909
+ SrcItem *pItem;
155910
+ WhereLoop *pLoop;
155911
+ pLoop = pWInfo->a[i].pWLoop;
155912
+ pItem = &pWInfo->pTabList->a[pLoop->iTab];
155913
+ if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
155914
+ if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0
155915
+ && (pLoop->wsFlags & WHERE_ONEROW)==0
155916
+ ){
155917
+ continue;
155918
+ }
155919
+ if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
155920
+ pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
155921
+ for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
155922
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155923
+ if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
155924
+ || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
155925
+ ){
155926
+ break;
155927
+ }
155928
+ }
155929
+ }
155930
+ if( pTerm<pEnd ) continue;
155931
+ WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
155932
+ notReady &= ~pLoop->maskSelf;
155933
+ for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
155934
+ if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155935
+ pTerm->wtFlags |= TERM_CODED;
155936
+ }
155937
+ }
155938
+ if( i!=pWInfo->nLevel-1 ){
155939
+ int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
155940
+ memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
155941
+ }
155942
+ pWInfo->nLevel--;
155943
+ assert( pWInfo->nLevel>0 );
155944
+ }
155945
+ return notReady;
155946
+}
155947
+
155948
+/*
155949
+** Check to see if there are any SEARCH loops that might benefit from
155950
+** using a Bloom filter. Consider a Bloom filter if:
155951
+**
155952
+** (1) The SEARCH happens more than N times where N is the number
155953
+** of rows in the table that is being considered for the Bloom
155954
+** filter.
155955
+** (2) Some searches are expected to find zero rows. (This is determined
155956
+** by the WHERE_SELFCULL flag on the term.)
155957
+** (3) Bloom-filter processing is not disabled. (Checked by the
155958
+** caller.)
155959
+** (4) The size of the table being searched is known by ANALYZE.
155960
+**
155961
+** This block of code merely checks to see if a Bloom filter would be
155962
+** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the
155963
+** WhereLoop. The implementation of the Bloom filter comes further
155964
+** down where the code for each WhereLoop is generated.
155965
+*/
155966
+static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
155967
+ const WhereInfo *pWInfo
155968
+){
155969
+ int i;
155970
+ LogEst nSearch;
155971
+
155972
+ assert( pWInfo->nLevel>=2 );
155973
+ assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) );
155974
+ nSearch = pWInfo->a[0].pWLoop->nOut;
155975
+ for(i=1; i<pWInfo->nLevel; i++){
155976
+ WhereLoop *pLoop = pWInfo->a[i].pWLoop;
155977
+ const int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
155978
+ if( (pLoop->wsFlags & reqFlags)==reqFlags
155979
+ /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
155980
+ && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0)
155981
+ ){
155982
+ SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
155983
+ Table *pTab = pItem->pTab;
155984
+ pTab->tabFlags |= TF_StatsUsed;
155985
+ if( nSearch > pTab->nRowLogEst
155986
+ && (pTab->tabFlags & TF_HasStat1)!=0
155987
+ ){
155988
+ testcase( pItem->fg.jointype & JT_LEFT );
155989
+ pLoop->wsFlags |= WHERE_BLOOMFILTER;
155990
+ pLoop->wsFlags &= ~WHERE_IDX_ONLY;
155991
+ WHERETRACE(0xffff, (
155992
+ "-> use Bloom-filter on loop %c because there are ~%.1e "
155993
+ "lookups into %s which has only ~%.1e rows\n",
155994
+ pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
155995
+ (double)sqlite3LogEstToInt(pTab->nRowLogEst)));
155996
+ }
155997
+ }
155998
+ nSearch += pLoop->nOut;
155999
+ }
156000
+}
154609156001
154610156002
/*
154611156003
** Generate the beginning of the loop used for WHERE clause processing.
154612156004
** The return value is a pointer to an opaque structure that contains
154613156005
** information needed to terminate the loop. Later, the calling routine
@@ -154735,16 +156127,10 @@
154735156127
/* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
154736156128
testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
154737156129
if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
154738156130
sWLB.pOrderBy = pOrderBy;
154739156131
154740
- /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
154741
- ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
154742
- if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
154743
- wctrlFlags &= ~WHERE_WANT_DISTINCT;
154744
- }
154745
-
154746156132
/* The number of tables in the FROM clause is limited by the number of
154747156133
** bits in a Bitmask
154748156134
*/
154749156135
testcase( pTabList->nSrc==BMS );
154750156136
if( pTabList->nSrc>BMS ){
@@ -154787,10 +156173,14 @@
154787156173
memset(&pWInfo->nOBSat, 0,
154788156174
offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
154789156175
memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
154790156176
assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
154791156177
pMaskSet = &pWInfo->sMaskSet;
156178
+ pMaskSet->n = 0;
156179
+ pMaskSet->ix[0] = -99; /* Initialize ix[0] to a value that can never be
156180
+ ** a valid cursor number, to avoid an initial
156181
+ ** test for pMaskSet->n==0 in sqlite3WhereGetMask() */
154792156182
sWLB.pWInfo = pWInfo;
154793156183
sWLB.pWC = &pWInfo->sWC;
154794156184
sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
154795156185
assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
154796156186
whereLoopInit(sWLB.pNew);
@@ -154799,19 +156189,20 @@
154799156189
#endif
154800156190
154801156191
/* Split the WHERE clause into separate subexpressions where each
154802156192
** subexpression is separated by an AND operator.
154803156193
*/
154804
- initMaskSet(pMaskSet);
154805156194
sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo);
154806156195
sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND);
154807156196
154808156197
/* Special case: No FROM clause
154809156198
*/
154810156199
if( nTabList==0 ){
154811156200
if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr;
154812
- if( wctrlFlags & WHERE_WANT_DISTINCT ){
156201
+ if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0
156202
+ && OptimizationEnabled(db, SQLITE_DistinctOpt)
156203
+ ){
154813156204
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
154814156205
}
154815156206
ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
154816156207
}else{
154817156208
/* Assign a bit from the bitmask to every term in the FROM clause.
@@ -154858,21 +156249,26 @@
154858156249
** preserves SQLite's legacy behaviour in the following two cases:
154859156250
**
154860156251
** FROM ... WHERE random()>0; -- eval random() once per row
154861156252
** FROM ... WHERE (SELECT random())>0; -- eval random() once overall
154862156253
*/
154863
- for(ii=0; ii<sWLB.pWC->nTerm; ii++){
156254
+ for(ii=0; ii<sWLB.pWC->nBase; ii++){
154864156255
WhereTerm *pT = &sWLB.pWC->a[ii];
154865156256
if( pT->wtFlags & TERM_VIRTUAL ) continue;
154866156257
if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
154867156258
sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
154868156259
pT->wtFlags |= TERM_CODED;
154869156260
}
154870156261
}
154871156262
154872156263
if( wctrlFlags & WHERE_WANT_DISTINCT ){
154873
- if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
156264
+ if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
156265
+ /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
156266
+ ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
156267
+ wctrlFlags &= ~WHERE_WANT_DISTINCT;
156268
+ pWInfo->wctrlFlags &= ~WHERE_WANT_DISTINCT;
156269
+ }else if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
154874156270
/* The DISTINCT marking is pointless. Ignore it. */
154875156271
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
154876156272
}else if( pOrderBy==0 ){
154877156273
/* Try to ORDER BY the result set to make distinct processing easier */
154878156274
pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
@@ -154969,88 +156365,40 @@
154969156365
sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
154970156366
}
154971156367
}
154972156368
#endif
154973156369
154974
- /* Attempt to omit tables from the join that do not affect the result.
154975
- ** For a table to not affect the result, the following must be true:
154976
- **
154977
- ** 1) The query must not be an aggregate.
154978
- ** 2) The table must be the RHS of a LEFT JOIN.
154979
- ** 3) Either the query must be DISTINCT, or else the ON or USING clause
154980
- ** must contain a constraint that limits the scan of the table to
154981
- ** at most a single row.
154982
- ** 4) The table must not be referenced by any part of the query apart
154983
- ** from its own USING or ON clause.
154984
- **
154985
- ** For example, given:
154986
- **
154987
- ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
154988
- ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
154989
- ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
154990
- **
154991
- ** then table t2 can be omitted from the following:
154992
- **
154993
- ** SELECT v1, v3 FROM t1
154994
- ** LEFT JOIN t2 ON (t1.ipk=t2.ipk)
154995
- ** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
154996
- **
154997
- ** or from:
154998
- **
154999
- ** SELECT DISTINCT v1, v3 FROM t1
155000
- ** LEFT JOIN t2
155001
- ** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
156370
+ /* Attempt to omit tables from a join that do not affect the result.
156371
+ ** See the comment on whereOmitNoopJoin() for further information.
156372
+ **
156373
+ ** This query optimization is factored out into a separate "no-inline"
156374
+ ** procedure to keep the sqlite3WhereBegin() procedure from becoming
156375
+ ** too large. If sqlite3WhereBegin() becomes too large, that prevents
156376
+ ** some C-compiler optimizers from in-lining the
156377
+ ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to
156378
+ ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons.
155002156379
*/
155003156380
notReady = ~(Bitmask)0;
155004156381
if( pWInfo->nLevel>=2
155005156382
&& pResultSet!=0 /* these two combine to guarantee */
155006156383
&& 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */
155007156384
&& OptimizationEnabled(db, SQLITE_OmitNoopJoin)
155008156385
){
155009
- int i;
155010
- Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
155011
- if( sWLB.pOrderBy ){
155012
- tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
155013
- }
155014
- for(i=pWInfo->nLevel-1; i>=1; i--){
155015
- WhereTerm *pTerm, *pEnd;
155016
- SrcItem *pItem;
155017
- pLoop = pWInfo->a[i].pWLoop;
155018
- pItem = &pWInfo->pTabList->a[pLoop->iTab];
155019
- if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
155020
- if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
155021
- && (pLoop->wsFlags & WHERE_ONEROW)==0
155022
- ){
155023
- continue;
155024
- }
155025
- if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
155026
- pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
155027
- for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
155028
- if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155029
- if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
155030
- || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
155031
- ){
155032
- break;
155033
- }
155034
- }
155035
- }
155036
- if( pTerm<pEnd ) continue;
155037
- WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
155038
- notReady &= ~pLoop->maskSelf;
155039
- for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
155040
- if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155041
- pTerm->wtFlags |= TERM_CODED;
155042
- }
155043
- }
155044
- if( i!=pWInfo->nLevel-1 ){
155045
- int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
155046
- memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
155047
- }
155048
- pWInfo->nLevel--;
155049
- nTabList--;
155050
- }
155051
- }
156386
+ notReady = whereOmitNoopJoin(pWInfo, notReady);
156387
+ nTabList = pWInfo->nLevel;
156388
+ assert( nTabList>0 );
156389
+ }
156390
+
156391
+ /* Check to see if there are any SEARCH loops that might benefit from
156392
+ ** using a Bloom filter.
156393
+ */
156394
+ if( pWInfo->nLevel>=2
156395
+ && OptimizationEnabled(db, SQLITE_BloomFilter)
156396
+ ){
156397
+ whereCheckIfBloomFilterIsUseful(pWInfo);
156398
+ }
156399
+
155052156400
#if defined(WHERETRACE_ENABLED)
155053156401
if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
155054156402
sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n");
155055156403
sqlite3WhereClausePrint(sWLB.pWC);
155056156404
}
@@ -155232,19 +156580,24 @@
155232156580
** program.
155233156581
*/
155234156582
for(ii=0; ii<nTabList; ii++){
155235156583
int addrExplain;
155236156584
int wsFlags;
156585
+ if( pParse->nErr ) goto whereBeginError;
155237156586
pLevel = &pWInfo->a[ii];
155238156587
wsFlags = pLevel->pWLoop->wsFlags;
156588
+ if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
156589
+ if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
155239156590
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155240
- if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155241
- constructAutomaticIndex(pParse, &pWInfo->sWC,
155242
- &pTabList->a[pLevel->iFrom], notReady, pLevel);
156591
+ constructAutomaticIndex(pParse, &pWInfo->sWC,
156592
+ &pTabList->a[pLevel->iFrom], notReady, pLevel);
156593
+#endif
156594
+ }else{
156595
+ constructBloomFilter(pWInfo, ii, pLevel, notReady);
156596
+ }
155243156597
if( db->mallocFailed ) goto whereBeginError;
155244156598
}
155245
-#endif
155246156599
addrExplain = sqlite3WhereExplainOneScan(
155247156600
pParse, pTabList, pLevel, wctrlFlags
155248156601
);
155249156602
pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
155250156603
notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
@@ -155353,11 +156706,11 @@
155353156706
if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
155354156707
#endif
155355156708
}else{
155356156709
sqlite3VdbeResolveLabel(v, pLevel->addrCont);
155357156710
}
155358
- if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
156711
+ if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
155359156712
struct InLoop *pIn;
155360156713
int j;
155361156714
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
155362156715
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
155363156716
assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull
@@ -155422,14 +156775,14 @@
155422156775
if( (ws & WHERE_IDX_ONLY)==0 ){
155423156776
assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
155424156777
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
155425156778
}
155426156779
if( (ws & WHERE_INDEXED)
155427
- || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
156780
+ || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx)
155428156781
){
155429156782
if( ws & WHERE_MULTI_OR ){
155430
- Index *pIx = pLevel->u.pCovidx;
156783
+ Index *pIx = pLevel->u.pCoveringIdx;
155431156784
int iDb = sqlite3SchemaToIndex(db, pIx->pSchema);
155432156785
sqlite3VdbeAddOp3(v, OP_ReopenIdx, pLevel->iIdxCur, pIx->tnum, iDb);
155433156786
sqlite3VdbeSetP4KeyInfo(pParse, pIx);
155434156787
}
155435156788
sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
@@ -155506,11 +156859,11 @@
155506156859
** reference the index.
155507156860
*/
155508156861
if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
155509156862
pIdx = pLoop->u.btree.pIndex;
155510156863
}else if( pLoop->wsFlags & WHERE_MULTI_OR ){
155511
- pIdx = pLevel->u.pCovidx;
156864
+ pIdx = pLevel->u.pCoveringIdx;
155512156865
}
155513156866
if( pIdx
155514156867
&& !db->mallocFailed
155515156868
){
155516156869
if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){
@@ -156167,28 +157520,28 @@
156167157520
static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
156168157521
156169157522
/* Window functions that use all window interfaces: xStep, xFinal,
156170157523
** xValue, and xInverse */
156171157524
#define WINDOWFUNCALL(name,nArg,extra) { \
156172
- nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
157525
+ nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
156173157526
name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
156174157527
name ## InvFunc, name ## Name, {0} \
156175157528
}
156176157529
156177157530
/* Window functions that are implemented using bytecode and thus have
156178157531
** no-op routines for their methods */
156179157532
#define WINDOWFUNCNOOP(name,nArg,extra) { \
156180
- nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
157533
+ nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
156181157534
noopStepFunc, noopValueFunc, noopValueFunc, \
156182157535
noopStepFunc, name ## Name, {0} \
156183157536
}
156184157537
156185157538
/* Window functions that use all window interfaces: xStep, the
156186157539
** same routine for xFinalize and xValue and which never call
156187157540
** xInverse. */
156188157541
#define WINDOWFUNCX(name,nArg,extra) { \
156189
- nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
157542
+ nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
156190157543
name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
156191157544
noopStepFunc, name ## Name, {0} \
156192157545
}
156193157546
156194157547
@@ -156527,11 +157880,12 @@
156527157880
return WRC_Continue;
156528157881
}
156529157882
156530157883
static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
156531157884
if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
156532
- sqlite3ErrorMsg(pWalker->pParse,
157885
+ assert( !ExprHasProperty(pExpr, EP_IntValue) );
157886
+ sqlite3ErrorMsg(pWalker->pParse,
156533157887
"misuse of aggregate: %s()", pExpr->u.zToken);
156534157888
}
156535157889
return WRC_Continue;
156536157890
}
156537157891
@@ -156615,11 +157969,13 @@
156615157969
/* Append the arguments passed to each window function to the
156616157970
** sub-select expression list. Also allocate two registers for each
156617157971
** window function - one for the accumulator, another for interim
156618157972
** results. */
156619157973
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
156620
- ExprList *pArgs = pWin->pOwner->x.pList;
157974
+ ExprList *pArgs;
157975
+ assert( ExprUseXList(pWin->pOwner) );
157976
+ pArgs = pWin->pOwner->x.pList;
156621157977
if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
156622157978
selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
156623157979
pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
156624157980
pWin->bExprArgs = 1;
156625157981
}else{
@@ -156682,11 +158038,15 @@
156682158038
}
156683158039
}else{
156684158040
sqlite3SelectDelete(db, pSub);
156685158041
}
156686158042
if( db->mallocFailed ) rc = SQLITE_NOMEM;
156687
- sqlite3DbFree(db, pTab);
158043
+
158044
+ /* Defer deleting the temporary table pTab because if an error occurred,
158045
+ ** there could still be references to that table embedded in the
158046
+ ** result-set or ORDER BY clause of the SELECT statement p. */
158047
+ sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
156688158048
}
156689158049
156690158050
if( rc ){
156691158051
if( pParse->nErr==0 ){
156692158052
assert( pParse->db->mallocFailed );
@@ -157008,12 +158368,15 @@
157008158368
**
157009158369
** regApp+0: slot to copy min()/max() argument to for MakeRecord
157010158370
** regApp+1: integer value used to ensure keys are unique
157011158371
** regApp+2: output of MakeRecord
157012158372
*/
157013
- ExprList *pList = pWin->pOwner->x.pList;
157014
- KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
158373
+ ExprList *pList;
158374
+ KeyInfo *pKeyInfo;
158375
+ assert( ExprUseXList(pWin->pOwner) );
158376
+ pList = pWin->pOwner->x.pList;
158377
+ pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
157015158378
pWin->csrApp = pParse->nTab++;
157016158379
pWin->regApp = pParse->nMem+1;
157017158380
pParse->nMem += 3;
157018158381
if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
157019158382
assert( pKeyInfo->aSortFlags[0]==0 );
@@ -157097,11 +158460,13 @@
157097158460
/*
157098158461
** Return the number of arguments passed to the window-function associated
157099158462
** with the object passed as the only argument to this function.
157100158463
*/
157101158464
static int windowArgCount(Window *pWin){
157102
- ExprList *pList = pWin->pOwner->x.pList;
158465
+ const ExprList *pList;
158466
+ assert( ExprUseXList(pWin->pOwner) );
158467
+ pList = pWin->pOwner->x.pList;
157103158468
return (pList ? pList->nExpr : 0);
157104158469
}
157105158470
157106158471
typedef struct WindowCodeArg WindowCodeArg;
157107158472
typedef struct WindowCsrAndReg WindowCsrAndReg;
@@ -157282,10 +158647,11 @@
157282158647
sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
157283158648
}else if( pFunc->xSFunc!=noopStepFunc ){
157284158649
int addrIf = 0;
157285158650
if( pWin->pFilter ){
157286158651
int regTmp;
158652
+ assert( ExprUseXList(pWin->pOwner) );
157287158653
assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
157288158654
assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
157289158655
regTmp = sqlite3GetTempReg(pParse);
157290158656
sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
157291158657
addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
@@ -157295,10 +158661,11 @@
157295158661
157296158662
if( pWin->bExprArgs ){
157297158663
int iOp = sqlite3VdbeCurrentAddr(v);
157298158664
int iEnd;
157299158665
158666
+ assert( ExprUseXList(pWin->pOwner) );
157300158667
nArg = pWin->pOwner->x.pList->nExpr;
157301158668
regArg = sqlite3GetTempRange(pParse, nArg);
157302158669
sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
157303158670
157304158671
for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
@@ -157309,10 +158676,11 @@
157309158676
}
157310158677
}
157311158678
if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
157312158679
CollSeq *pColl;
157313158680
assert( nArg>0 );
158681
+ assert( ExprUseXList(pWin->pOwner) );
157314158682
pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
157315158683
sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
157316158684
}
157317158685
sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
157318158686
bInverse, regArg, pWin->regAccum);
@@ -157494,10 +158862,11 @@
157494158862
Parse *pParse = p->pParse;
157495158863
Window *pWin;
157496158864
157497158865
for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
157498158866
FuncDef *pFunc = pWin->pFunc;
158867
+ assert( ExprUseXList(pWin->pOwner) );
157499158868
if( pFunc->zName==nth_valueName
157500158869
|| pFunc->zName==first_valueName
157501158870
){
157502158871
int csr = pWin->csrApp;
157503158872
int lbl = sqlite3VdbeMakeLabel(pParse);
@@ -158843,13 +160212,13 @@
158843160212
p->affExpr = 0;
158844160213
p->flags = EP_Leaf;
158845160214
ExprClearVVAProperties(p);
158846160215
p->iAgg = -1;
158847160216
p->pLeft = p->pRight = 0;
158848
- p->x.pList = 0;
158849160217
p->pAggInfo = 0;
158850
- p->y.pTab = 0;
160218
+ memset(&p->x, 0, sizeof(p->x));
160219
+ memset(&p->y, 0, sizeof(p->y));
158851160220
p->op2 = 0;
158852160221
p->iTable = 0;
158853160222
p->iColumn = 0;
158854160223
p->u.zToken = (char*)&p[1];
158855160224
memcpy(p->u.zToken, t.z, t.n);
@@ -158951,14 +160320,14 @@
158951160320
#define TK_DETACH 40
158952160321
#define TK_EACH 41
158953160322
#define TK_FAIL 42
158954160323
#define TK_OR 43
158955160324
#define TK_AND 44
158956
-#define TK_IS 45
158957
-#define TK_MATCH 46
158958
-#define TK_LIKE_KW 47
158959
-#define TK_BETWEEN 48
160325
+#define TK_MATCH 45
160326
+#define TK_LIKE_KW 46
160327
+#define TK_BETWEEN 47
160328
+#define TK_IS 48
158960160329
#define TK_IN 49
158961160330
#define TK_ISNULL 50
158962160331
#define TK_NOTNULL 51
158963160332
#define TK_NE 52
158964160333
#define TK_EQ 53
@@ -159266,216 +160635,215 @@
159266160635
** yy_reduce_ofst[] For each state, the offset into yy_action for
159267160636
** shifting non-terminals after a reduce.
159268160637
** yy_default[] Default action for each state.
159269160638
**
159270160639
*********** Begin parsing tables **********************************************/
159271
-#define YY_ACTTAB_COUNT (2037)
160640
+#define YY_ACTTAB_COUNT (2022)
159272160641
static const YYACTIONTYPE yy_action[] = {
159273160642
/* 0 */ 564, 115, 112, 220, 169, 199, 115, 112, 220, 564,
159274160643
/* 10 */ 375, 1266, 564, 376, 564, 270, 1309, 1309, 406, 407,
159275160644
/* 20 */ 1084, 199, 1513, 41, 41, 515, 489, 521, 558, 558,
159276160645
/* 30 */ 558, 965, 41, 41, 395, 41, 41, 51, 51, 966,
159277
- /* 40 */ 296, 1269, 296, 122, 123, 113, 1207, 1207, 1041, 1044,
160646
+ /* 40 */ 296, 1269, 296, 122, 123, 1207, 1207, 1041, 113, 1044,
159278160647
/* 50 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 564, 407,
159279160648
/* 60 */ 275, 275, 275, 275, 1268, 115, 112, 220, 115, 112,
159280160649
/* 70 */ 220, 1512, 846, 561, 516, 561, 115, 112, 220, 250,
159281
- /* 80 */ 217, 71, 71, 122, 123, 113, 1207, 1207, 1041, 1044,
160650
+ /* 80 */ 217, 71, 71, 122, 123, 1207, 1207, 1041, 113, 1044,
159282160651
/* 90 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 440, 440,
159283160652
/* 100 */ 440, 1149, 119, 119, 119, 119, 118, 118, 117, 117,
159284160653
/* 110 */ 117, 116, 442, 1183, 1149, 116, 442, 1149, 546, 513,
159285
- /* 120 */ 1548, 1554, 374, 442, 6, 1183, 1154, 522, 1154, 407,
160654
+ /* 120 */ 1548, 1554, 374, 213, 6, 169, 1154, 522, 1154, 407,
159286160655
/* 130 */ 1556, 461, 373, 1554, 535, 99, 463, 332, 121, 121,
159287160656
/* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117,
159288
- /* 150 */ 117, 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044,
160657
+ /* 150 */ 117, 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044,
159289160658
/* 160 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 1257, 1183,
159290160659
/* 170 */ 1184, 1185, 243, 1064, 564, 502, 499, 498, 567, 124,
159291
- /* 180 */ 567, 1183, 1184, 1185, 474, 497, 119, 119, 119, 119,
160660
+ /* 180 */ 567, 1128, 1627, 344, 1627, 497, 119, 119, 119, 119,
159292160661
/* 190 */ 118, 118, 117, 117, 117, 116, 442, 70, 70, 407,
159293160662
/* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 442,
159294
- /* 210 */ 1409, 1469, 119, 119, 119, 119, 118, 118, 117, 117,
159295
- /* 220 */ 117, 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044,
159296
- /* 230 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 407, 1031,
159297
- /* 240 */ 1031, 1042, 1045, 81, 382, 541, 378, 80, 119, 119,
160663
+ /* 210 */ 474, 1469, 119, 119, 119, 119, 118, 118, 117, 117,
160664
+ /* 220 */ 117, 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044,
160665
+ /* 230 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 407, 208,
160666
+ /* 240 */ 539, 1548, 1424, 81, 339, 6, 342, 80, 119, 119,
159298160667
/* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 381,
159299
- /* 260 */ 463, 332, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159300
- /* 270 */ 1034, 120, 120, 121, 121, 121, 121, 262, 215, 512,
159301
- /* 280 */ 1424, 422, 119, 119, 119, 119, 118, 118, 117, 117,
160668
+ /* 260 */ 1126, 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160669
+ /* 270 */ 1034, 120, 120, 121, 121, 121, 121, 262, 463, 332,
160670
+ /* 280 */ 359, 1567, 119, 119, 119, 119, 118, 118, 117, 117,
159302160671
/* 290 */ 117, 116, 442, 1231, 1, 1, 571, 2, 1235, 1573,
159303
- /* 300 */ 571, 2, 1235, 307, 1149, 141, 1600, 307, 407, 141,
159304
- /* 310 */ 1183, 361, 1317, 1035, 866, 531, 1317, 1149, 359, 1567,
160672
+ /* 300 */ 571, 2, 1235, 307, 1149, 141, 417, 307, 407, 141,
160673
+ /* 310 */ 1183, 98, 1317, 489, 866, 531, 1317, 1149, 215, 512,
159305160674
/* 320 */ 1149, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159306
- /* 330 */ 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
160675
+ /* 330 */ 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
159307160676
/* 340 */ 1034, 120, 120, 121, 121, 121, 121, 275, 275, 1001,
159308
- /* 350 */ 426, 275, 275, 1128, 1627, 1021, 1627, 137, 542, 1541,
159309
- /* 360 */ 561, 272, 950, 950, 561, 1423, 1183, 1184, 1185, 1594,
159310
- /* 370 */ 866, 1012, 530, 315, 231, 1011, 468, 1276, 231, 119,
160677
+ /* 350 */ 1257, 275, 275, 1128, 1628, 1021, 1628, 137, 415, 1600,
160678
+ /* 360 */ 561, 272, 1255, 950, 561, 1423, 1183, 1184, 1185, 1594,
160679
+ /* 370 */ 866, 1012, 530, 315, 231, 1011, 317, 1276, 231, 119,
159311160680
/* 380 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
159312160681
/* 390 */ 1570, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159313160682
/* 400 */ 116, 442, 330, 359, 1567, 564, 446, 1011, 1011, 1013,
159314
- /* 410 */ 446, 207, 564, 306, 555, 407, 363, 1021, 363, 346,
160683
+ /* 410 */ 446, 877, 564, 306, 555, 407, 447, 1021, 563, 346,
159315160684
/* 420 */ 184, 118, 118, 117, 117, 117, 116, 442, 71, 71,
159316160685
/* 430 */ 439, 438, 1126, 1012, 472, 71, 71, 1011, 205, 122,
159317
- /* 440 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120,
159318
- /* 450 */ 121, 121, 121, 121, 219, 219, 472, 1183, 407, 570,
159319
- /* 460 */ 1183, 1235, 503, 1477, 149, 546, 307, 489, 141, 1011,
159320
- /* 470 */ 1011, 1013, 546, 140, 545, 1317, 1214, 191, 1214, 950,
159321
- /* 480 */ 950, 514, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159322
- /* 490 */ 1034, 120, 120, 121, 121, 121, 121, 563, 119, 119,
160686
+ /* 440 */ 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120,
160687
+ /* 450 */ 121, 121, 121, 121, 1304, 219, 1283, 1183, 407, 570,
160688
+ /* 460 */ 1183, 1235, 503, 1477, 1304, 546, 307, 489, 141, 1011,
160689
+ /* 470 */ 1011, 1013, 546, 140, 545, 1317, 1214, 382, 1214, 378,
160690
+ /* 480 */ 950, 514, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160691
+ /* 490 */ 1034, 120, 120, 121, 121, 121, 121, 472, 119, 119,
159323160692
/* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 283,
159324
- /* 510 */ 275, 275, 415, 1183, 1184, 1185, 1183, 1184, 1185, 372,
159325
- /* 520 */ 1183, 243, 344, 561, 502, 499, 498, 1539, 407, 1540,
159326
- /* 530 */ 1183, 288, 870, 143, 497, 1549, 185, 231, 9, 6,
160693
+ /* 510 */ 275, 275, 1476, 1183, 1184, 1185, 1183, 1184, 1185, 417,
160694
+ /* 520 */ 1183, 243, 541, 561, 502, 499, 498, 1001, 407, 478,
160695
+ /* 530 */ 1183, 472, 870, 143, 497, 1549, 185, 231, 9, 6,
159327160696
/* 540 */ 253, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159328
- /* 550 */ 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159329
- /* 560 */ 1034, 120, 120, 121, 121, 121, 121, 407, 137, 446,
159330
- /* 570 */ 447, 863, 169, 1183, 397, 1204, 1183, 1184, 1185, 931,
159331
- /* 580 */ 526, 1001, 98, 339, 564, 342, 1183, 1184, 1185, 306,
159332
- /* 590 */ 555, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034,
159333
- /* 600 */ 120, 120, 121, 121, 121, 121, 452, 71, 71, 275,
160697
+ /* 550 */ 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160698
+ /* 560 */ 1034, 120, 120, 121, 121, 121, 121, 407, 372, 446,
160699
+ /* 570 */ 363, 863, 288, 1183, 397, 1204, 1183, 1184, 1185, 931,
160700
+ /* 580 */ 330, 458, 318, 526, 564, 541, 1183, 1184, 1185, 284,
160701
+ /* 590 */ 1183, 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034,
160702
+ /* 600 */ 120, 120, 121, 121, 121, 121, 291, 71, 71, 275,
159334160703
/* 610 */ 275, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159335
- /* 620 */ 116, 442, 561, 417, 306, 555, 1183, 1307, 1307, 1183,
159336
- /* 630 */ 1184, 1185, 1204, 1149, 330, 458, 318, 407, 363, 470,
159337
- /* 640 */ 431, 1167, 32, 541, 527, 350, 1149, 1629, 393, 1149,
160704
+ /* 620 */ 116, 442, 561, 1031, 1031, 1042, 1183, 1045, 287, 1183,
160705
+ /* 630 */ 1184, 1185, 1204, 137, 218, 542, 1541, 407, 363, 470,
160706
+ /* 640 */ 431, 1167, 32, 363, 527, 350, 1183, 1184, 1185, 380,
159338160707
/* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
159339
- /* 660 */ 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034,
159340
- /* 670 */ 120, 120, 121, 121, 121, 121, 407, 199, 472, 1183,
159341
- /* 680 */ 1022, 472, 1183, 1184, 1185, 386, 151, 539, 1548, 277,
159342
- /* 690 */ 400, 137, 6, 317, 5, 564, 562, 3, 920, 920,
159343
- /* 700 */ 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120,
160708
+ /* 660 */ 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034,
160709
+ /* 670 */ 120, 120, 121, 121, 121, 121, 407, 392, 1227, 1183,
160710
+ /* 680 */ 1022, 1540, 1183, 1184, 1185, 1523, 149, 1307, 1307, 306,
160711
+ /* 690 */ 555, 151, 1546, 361, 5, 564, 6, 3, 1035, 1542,
160712
+ /* 700 */ 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120,
159344160713
/* 710 */ 120, 121, 121, 121, 121, 411, 505, 83, 71, 71,
159345160714
/* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
159346
- /* 730 */ 442, 1183, 218, 428, 1183, 1183, 1184, 1185, 363, 261,
159347
- /* 740 */ 278, 358, 508, 353, 507, 248, 407, 306, 555, 1539,
159348
- /* 750 */ 1006, 349, 363, 291, 489, 302, 293, 1542, 281, 119,
160715
+ /* 730 */ 442, 1183, 426, 428, 1183, 1183, 1184, 1185, 191, 261,
160716
+ /* 740 */ 278, 358, 508, 353, 507, 248, 407, 455, 137, 1539,
160717
+ /* 750 */ 1006, 349, 363, 472, 1539, 302, 1228, 405, 281, 119,
159349160718
/* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
159350
- /* 770 */ 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120,
159351
- /* 780 */ 120, 121, 121, 121, 121, 407, 148, 1183, 1184, 1185,
159352
- /* 790 */ 1183, 1184, 1185, 275, 275, 1304, 1257, 1283, 483, 1476,
159353
- /* 800 */ 150, 489, 480, 564, 1187, 1304, 561, 1587, 1255, 122,
159354
- /* 810 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120,
159355
- /* 820 */ 121, 121, 121, 121, 564, 886, 13, 13, 520, 119,
160719
+ /* 770 */ 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120,
160720
+ /* 780 */ 120, 121, 121, 121, 121, 407, 452, 1183, 1184, 1185,
160721
+ /* 790 */ 1183, 1184, 1185, 275, 275, 269, 269, 489, 483, 1525,
160722
+ /* 800 */ 148, 363, 480, 564, 306, 555, 561, 489, 561, 122,
160723
+ /* 810 */ 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120,
160724
+ /* 820 */ 121, 121, 121, 121, 564, 886, 13, 13, 293, 119,
159356160725
/* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
159357
- /* 840 */ 1183, 420, 417, 564, 269, 269, 1316, 13, 13, 1539,
159358
- /* 850 */ 1546, 16, 16, 322, 6, 407, 506, 561, 1089, 1089,
159359
- /* 860 */ 486, 1187, 425, 1539, 887, 292, 71, 71, 119, 119,
160726
+ /* 840 */ 1183, 420, 1316, 564, 98, 417, 199, 13, 13, 150,
160727
+ /* 850 */ 306, 555, 1312, 322, 386, 407, 506, 478, 562, 400,
160728
+ /* 860 */ 920, 920, 425, 1539, 887, 292, 71, 71, 119, 119,
159360160729
/* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 122,
159361
- /* 880 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120,
159362
- /* 890 */ 121, 121, 121, 121, 564, 12, 1183, 1184, 1185, 407,
159363
- /* 900 */ 275, 275, 451, 303, 834, 835, 836, 417, 489, 276,
159364
- /* 910 */ 276, 1547, 284, 561, 319, 6, 321, 71, 71, 429,
159365
- /* 920 */ 451, 450, 561, 952, 101, 113, 1207, 1207, 1041, 1044,
160730
+ /* 880 */ 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120,
160731
+ /* 890 */ 121, 121, 121, 121, 564, 1149, 1183, 1184, 1185, 407,
160732
+ /* 900 */ 275, 275, 451, 303, 1089, 1089, 486, 448, 1149, 276,
160733
+ /* 910 */ 276, 1149, 1539, 561, 319, 286, 321, 71, 71, 429,
160734
+ /* 920 */ 451, 450, 561, 952, 101, 1207, 1207, 1041, 113, 1044,
159366160735
/* 930 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 119, 119,
159367160736
/* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 1105,
159368
- /* 950 */ 1183, 489, 564, 1312, 437, 455, 478, 564, 246, 245,
159369
- /* 960 */ 244, 1409, 1545, 547, 1106, 405, 6, 1544, 196, 1258,
159370
- /* 970 */ 413, 6, 105, 462, 103, 71, 71, 286, 564, 1107,
160737
+ /* 950 */ 1183, 1547, 564, 12, 437, 6, 329, 564, 834, 835,
160738
+ /* 960 */ 836, 1629, 393, 547, 1106, 246, 245, 244, 1545, 1258,
160739
+ /* 970 */ 413, 1521, 6, 1086, 310, 71, 71, 1086, 564, 1107,
159371160740
/* 980 */ 13, 13, 119, 119, 119, 119, 118, 118, 117, 117,
159372
- /* 990 */ 117, 116, 442, 451, 104, 427, 337, 320, 275, 275,
159373
- /* 1000 */ 906, 13, 13, 564, 1482, 1105, 1183, 1184, 1185, 126,
159374
- /* 1010 */ 907, 561, 546, 564, 407, 478, 295, 1321, 253, 200,
159375
- /* 1020 */ 1106, 548, 1482, 1484, 280, 1409, 55, 55, 1287, 561,
159376
- /* 1030 */ 478, 380, 423, 951, 407, 1107, 71, 71, 122, 123,
159377
- /* 1040 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121,
159378
- /* 1050 */ 121, 121, 121, 1204, 407, 287, 552, 309, 122, 123,
159379
- /* 1060 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121,
159380
- /* 1070 */ 121, 121, 121, 441, 1128, 1628, 146, 1628, 122, 111,
159381
- /* 1080 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121,
159382
- /* 1090 */ 121, 121, 121, 404, 403, 1482, 424, 119, 119, 119,
160741
+ /* 990 */ 117, 116, 442, 451, 104, 427, 537, 320, 275, 275,
160742
+ /* 1000 */ 906, 13, 13, 520, 1482, 1105, 1183, 1184, 1185, 484,
160743
+ /* 1010 */ 907, 561, 546, 564, 407, 536, 295, 478, 253, 200,
160744
+ /* 1020 */ 1106, 548, 1482, 1484, 1160, 1409, 16, 16, 126, 557,
160745
+ /* 1030 */ 413, 479, 311, 951, 407, 1107, 71, 71, 122, 123,
160746
+ /* 1040 */ 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120, 121,
160747
+ /* 1050 */ 121, 121, 121, 1204, 407, 544, 552, 314, 122, 123,
160748
+ /* 1060 */ 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120, 121,
160749
+ /* 1070 */ 121, 121, 121, 441, 144, 1160, 468, 146, 122, 111,
160750
+ /* 1080 */ 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120, 121,
160751
+ /* 1090 */ 121, 121, 121, 247, 12, 1482, 422, 119, 119, 119,
159383160752
/* 1100 */ 119, 118, 118, 117, 117, 117, 116, 442, 1183, 564,
159384
- /* 1110 */ 1204, 544, 1086, 858, 329, 361, 1086, 119, 119, 119,
159385
- /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 442, 564, 294,
159386
- /* 1130 */ 144, 523, 56, 56, 224, 564, 510, 119, 119, 119,
159387
- /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 442, 484, 1409,
159388
- /* 1150 */ 537, 15, 15, 1126, 434, 439, 438, 407, 13, 13,
159389
- /* 1160 */ 1523, 12, 926, 1211, 1183, 1184, 1185, 925, 1213, 536,
159390
- /* 1170 */ 858, 557, 413, 193, 1525, 494, 1212, 448, 1160, 1222,
159391
- /* 1180 */ 1183, 564, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034,
159392
- /* 1190 */ 120, 120, 121, 121, 121, 121, 1521, 1149, 564, 965,
159393
- /* 1200 */ 564, 1214, 247, 1214, 13, 13, 1409, 966, 538, 564,
159394
- /* 1210 */ 1149, 108, 556, 1149, 4, 310, 392, 1227, 17, 194,
159395
- /* 1220 */ 485, 43, 43, 57, 57, 306, 555, 524, 559, 1160,
159396
- /* 1230 */ 464, 564, 44, 44, 392, 1127, 1183, 1184, 1185, 479,
160753
+ /* 1110 */ 1204, 207, 404, 403, 858, 950, 294, 119, 119, 119,
160754
+ /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 442, 564, 30,
160755
+ /* 1130 */ 564, 1409, 55, 55, 1599, 564, 895, 119, 119, 119,
160756
+ /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 442, 510, 1409,
160757
+ /* 1150 */ 1409, 56, 56, 15, 15, 439, 438, 407, 13, 13,
160758
+ /* 1160 */ 31, 1187, 412, 1211, 1183, 1184, 1185, 196, 1213, 306,
160759
+ /* 1170 */ 555, 858, 462, 193, 926, 564, 1212, 489, 361, 925,
160760
+ /* 1180 */ 1183, 564, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034,
160761
+ /* 1190 */ 120, 120, 121, 121, 121, 121, 1544, 1149, 43, 43,
160762
+ /* 1200 */ 6, 1214, 423, 1214, 13, 13, 564, 219, 538, 494,
160763
+ /* 1210 */ 1149, 108, 556, 1149, 4, 392, 1127, 434, 1187, 194,
160764
+ /* 1220 */ 424, 485, 337, 1315, 414, 171, 1253, 1321, 559, 57,
160765
+ /* 1230 */ 57, 564, 950, 564, 224, 247, 1183, 1184, 1185, 561,
159397160766
/* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
159398
- /* 1250 */ 442, 443, 564, 327, 13, 13, 564, 418, 1315, 414,
159399
- /* 1260 */ 171, 564, 311, 553, 213, 529, 1253, 564, 517, 543,
159400
- /* 1270 */ 412, 108, 556, 137, 4, 58, 58, 435, 314, 59,
159401
- /* 1280 */ 59, 274, 217, 549, 60, 60, 349, 476, 559, 1353,
159402
- /* 1290 */ 61, 61, 1021, 275, 275, 1228, 213, 564, 106, 106,
159403
- /* 1300 */ 8, 275, 275, 275, 275, 107, 561, 443, 566, 565,
159404
- /* 1310 */ 564, 443, 1011, 1228, 561, 564, 561, 564, 275, 275,
159405
- /* 1320 */ 62, 62, 1352, 553, 247, 456, 564, 98, 110, 306,
159406
- /* 1330 */ 555, 561, 564, 45, 45, 405, 1203, 533, 46, 46,
159407
- /* 1340 */ 47, 47, 532, 465, 1011, 1011, 1013, 1014, 27, 49,
159408
- /* 1350 */ 49, 564, 1021, 405, 469, 50, 50, 564, 106, 106,
159409
- /* 1360 */ 305, 564, 84, 204, 405, 107, 564, 443, 566, 565,
159410
- /* 1370 */ 405, 564, 1011, 564, 63, 63, 564, 1599, 564, 895,
159411
- /* 1380 */ 64, 64, 457, 477, 65, 65, 147, 96, 38, 14,
159412
- /* 1390 */ 14, 1528, 412, 564, 66, 66, 128, 128, 926, 67,
159413
- /* 1400 */ 67, 52, 52, 925, 1011, 1011, 1013, 1014, 27, 1572,
159414
- /* 1410 */ 1171, 445, 208, 1123, 279, 394, 68, 68, 228, 390,
159415
- /* 1420 */ 390, 389, 264, 387, 1171, 445, 843, 877, 279, 108,
159416
- /* 1430 */ 556, 453, 4, 390, 390, 389, 264, 387, 564, 225,
159417
- /* 1440 */ 843, 313, 328, 1003, 98, 252, 559, 544, 471, 312,
159418
- /* 1450 */ 252, 564, 208, 225, 564, 313, 473, 30, 252, 279,
159419
- /* 1460 */ 466, 69, 69, 312, 390, 390, 389, 264, 387, 443,
159420
- /* 1470 */ 333, 843, 98, 564, 53, 53, 323, 157, 157, 227,
159421
- /* 1480 */ 495, 553, 249, 289, 225, 564, 313, 162, 31, 1501,
159422
- /* 1490 */ 135, 564, 1500, 227, 312, 533, 158, 158, 885, 884,
159423
- /* 1500 */ 534, 162, 873, 301, 135, 564, 481, 226, 76, 76,
159424
- /* 1510 */ 1021, 347, 1071, 98, 54, 54, 106, 106, 1067, 564,
159425
- /* 1520 */ 249, 226, 519, 107, 227, 443, 566, 565, 72, 72,
159426
- /* 1530 */ 1011, 334, 162, 564, 230, 135, 108, 556, 959, 4,
159427
- /* 1540 */ 252, 408, 129, 129, 564, 1349, 306, 555, 564, 923,
159428
- /* 1550 */ 564, 110, 226, 559, 564, 408, 73, 73, 564, 873,
159429
- /* 1560 */ 306, 555, 1011, 1011, 1013, 1014, 27, 130, 130, 1071,
159430
- /* 1570 */ 449, 131, 131, 127, 127, 357, 443, 156, 156, 892,
159431
- /* 1580 */ 893, 155, 155, 338, 449, 356, 408, 564, 553, 968,
159432
- /* 1590 */ 969, 306, 555, 1015, 341, 564, 108, 556, 564, 4,
159433
- /* 1600 */ 1132, 1286, 533, 564, 856, 343, 145, 532, 345, 1300,
159434
- /* 1610 */ 136, 136, 1083, 559, 1083, 449, 564, 1021, 134, 134,
159435
- /* 1620 */ 1284, 132, 132, 106, 106, 1285, 133, 133, 564, 352,
159436
- /* 1630 */ 107, 564, 443, 566, 565, 1340, 443, 1011, 362, 75,
159437
- /* 1640 */ 75, 1082, 564, 1082, 564, 924, 1561, 110, 553, 551,
159438
- /* 1650 */ 1015, 77, 77, 1361, 74, 74, 1408, 1336, 1347, 550,
159439
- /* 1660 */ 1414, 1265, 1256, 1244, 1243, 42, 42, 48, 48, 1011,
159440
- /* 1670 */ 1011, 1013, 1014, 27, 1245, 1580, 490, 1021, 267, 202,
159441
- /* 1680 */ 1333, 365, 11, 106, 106, 930, 367, 210, 369, 391,
159442
- /* 1690 */ 107, 1395, 443, 566, 565, 223, 1390, 1011, 500, 454,
159443
- /* 1700 */ 282, 1400, 285, 108, 556, 214, 4, 325, 1383, 1283,
159444
- /* 1710 */ 475, 355, 1473, 1583, 1472, 1399, 371, 1222, 326, 398,
159445
- /* 1720 */ 559, 290, 331, 197, 100, 556, 209, 4, 198, 1011,
159446
- /* 1730 */ 1011, 1013, 1014, 27, 385, 256, 1520, 1518, 554, 1219,
159447
- /* 1740 */ 416, 559, 83, 443, 173, 206, 182, 221, 459, 167,
159448
- /* 1750 */ 177, 460, 175, 493, 233, 553, 79, 178, 1396, 179,
159449
- /* 1760 */ 35, 180, 96, 1402, 443, 396, 36, 467, 1478, 1401,
159450
- /* 1770 */ 482, 237, 1404, 399, 82, 186, 553, 1467, 89, 488,
159451
- /* 1780 */ 190, 268, 239, 491, 1021, 340, 240, 401, 1246, 1489,
159452
- /* 1790 */ 106, 106, 336, 509, 1294, 241, 1303, 107, 430, 443,
159453
- /* 1800 */ 566, 565, 1302, 91, 1011, 1021, 1598, 1301, 1273, 215,
159454
- /* 1810 */ 1597, 106, 106, 402, 877, 432, 354, 1272, 107, 1271,
159455
- /* 1820 */ 443, 566, 565, 1596, 1566, 1011, 1293, 433, 518, 299,
159456
- /* 1830 */ 300, 360, 95, 525, 1344, 364, 1011, 1011, 1013, 1014,
159457
- /* 1840 */ 27, 254, 255, 1552, 436, 1551, 125, 544, 10, 379,
159458
- /* 1850 */ 1326, 1453, 102, 97, 1345, 528, 304, 1011, 1011, 1013,
159459
- /* 1860 */ 1014, 27, 366, 377, 1343, 1342, 368, 370, 1325, 384,
159460
- /* 1870 */ 201, 383, 34, 1368, 1367, 568, 1177, 266, 263, 265,
159461
- /* 1880 */ 1505, 159, 569, 1241, 1236, 1506, 160, 142, 1504, 1503,
159462
- /* 1890 */ 297, 211, 830, 161, 212, 78, 444, 203, 308, 222,
159463
- /* 1900 */ 1081, 139, 1079, 316, 174, 163, 1203, 229, 176, 909,
159464
- /* 1910 */ 324, 232, 1095, 181, 409, 410, 172, 164, 165, 419,
159465
- /* 1920 */ 183, 85, 86, 421, 166, 87, 88, 1098, 1094, 234,
159466
- /* 1930 */ 235, 152, 18, 236, 335, 1087, 1216, 252, 187, 487,
159467
- /* 1940 */ 238, 188, 37, 845, 492, 356, 242, 496, 351, 501,
159468
- /* 1950 */ 189, 90, 19, 504, 348, 20, 875, 92, 298, 168,
159469
- /* 1960 */ 888, 153, 93, 511, 94, 1165, 154, 1047, 1134, 39,
159470
- /* 1970 */ 216, 1133, 271, 273, 958, 192, 953, 110, 1151, 1155,
159471
- /* 1980 */ 251, 7, 21, 1159, 1139, 22, 1153, 33, 23, 24,
159472
- /* 1990 */ 25, 540, 1158, 195, 98, 1062, 26, 1048, 1046, 1050,
159473
- /* 2000 */ 1104, 1051, 1103, 257, 258, 28, 40, 1173, 1016, 857,
159474
- /* 2010 */ 109, 29, 560, 388, 138, 1172, 259, 170, 260, 1232,
159475
- /* 2020 */ 1232, 919, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
159476
- /* 2030 */ 1232, 1232, 1589, 1232, 1232, 1232, 1588,
160767
+ /* 1250 */ 442, 443, 564, 517, 13, 13, 44, 44, 275, 275,
160768
+ /* 1260 */ 1409, 275, 275, 553, 1353, 529, 213, 549, 456, 543,
160769
+ /* 1270 */ 465, 561, 564, 137, 561, 58, 58, 469, 405, 1222,
160770
+ /* 1280 */ 405, 274, 217, 108, 556, 110, 4, 405, 275, 275,
160771
+ /* 1290 */ 564, 1352, 1021, 564, 1228, 59, 59, 523, 106, 106,
160772
+ /* 1300 */ 559, 561, 275, 275, 412, 107, 457, 443, 566, 565,
160773
+ /* 1310 */ 564, 8, 1011, 60, 60, 561, 61, 61, 564, 965,
160774
+ /* 1320 */ 349, 926, 305, 443, 84, 204, 925, 966, 564, 306,
160775
+ /* 1330 */ 555, 435, 405, 62, 62, 553, 476, 105, 564, 103,
160776
+ /* 1340 */ 464, 45, 45, 1203, 1011, 1011, 1013, 1014, 27, 533,
160777
+ /* 1350 */ 564, 46, 46, 453, 532, 1572, 1171, 445, 1528, 564,
160778
+ /* 1360 */ 279, 47, 47, 327, 1021, 390, 390, 389, 264, 387,
160779
+ /* 1370 */ 106, 106, 843, 49, 49, 108, 556, 107, 4, 443,
160780
+ /* 1380 */ 566, 565, 50, 50, 1011, 225, 564, 313, 564, 96,
160781
+ /* 1390 */ 564, 228, 559, 524, 147, 312, 38, 1123, 564, 394,
160782
+ /* 1400 */ 466, 328, 280, 98, 544, 564, 17, 564, 323, 63,
160783
+ /* 1410 */ 63, 64, 64, 65, 65, 443, 1011, 1011, 1013, 1014,
160784
+ /* 1420 */ 27, 14, 14, 289, 564, 227, 564, 553, 66, 66,
160785
+ /* 1430 */ 128, 128, 477, 162, 564, 309, 135, 564, 1003, 277,
160786
+ /* 1440 */ 252, 533, 564, 1501, 564, 418, 534, 67, 67, 52,
160787
+ /* 1450 */ 52, 564, 1287, 226, 564, 1500, 1021, 68, 68, 208,
160788
+ /* 1460 */ 69, 69, 106, 106, 1286, 53, 53, 157, 157, 107,
160789
+ /* 1470 */ 873, 443, 566, 565, 158, 158, 1011, 76, 76, 564,
160790
+ /* 1480 */ 357, 564, 108, 556, 471, 4, 252, 408, 885, 884,
160791
+ /* 1490 */ 356, 564, 306, 555, 564, 473, 564, 252, 481, 559,
160792
+ /* 1500 */ 564, 334, 54, 54, 72, 72, 564, 230, 1011, 1011,
160793
+ /* 1510 */ 1013, 1014, 27, 564, 129, 129, 449, 73, 73, 130,
160794
+ /* 1520 */ 130, 564, 443, 131, 131, 519, 564, 873, 564, 127,
160795
+ /* 1530 */ 127, 333, 1071, 98, 553, 1349, 156, 156, 564, 495,
160796
+ /* 1540 */ 347, 249, 98, 338, 155, 155, 892, 893, 533, 136,
160797
+ /* 1550 */ 136, 134, 134, 532, 341, 1171, 445, 1587, 564, 279,
160798
+ /* 1560 */ 343, 132, 132, 1021, 390, 390, 389, 264, 387, 106,
160799
+ /* 1570 */ 106, 843, 564, 1067, 564, 249, 107, 564, 443, 566,
160800
+ /* 1580 */ 565, 133, 133, 1011, 225, 1015, 313, 108, 556, 1071,
160801
+ /* 1590 */ 4, 345, 968, 969, 312, 75, 75, 77, 77, 1300,
160802
+ /* 1600 */ 74, 74, 564, 1132, 559, 564, 108, 556, 959, 4,
160803
+ /* 1610 */ 252, 923, 1083, 110, 1083, 1011, 1011, 1013, 1014, 27,
160804
+ /* 1620 */ 1082, 1285, 1082, 559, 227, 42, 42, 443, 48, 48,
160805
+ /* 1630 */ 1284, 856, 162, 145, 924, 135, 110, 352, 362, 553,
160806
+ /* 1640 */ 1340, 1361, 1015, 1408, 1336, 301, 443, 1561, 1347, 550,
160807
+ /* 1650 */ 1414, 551, 226, 202, 1265, 1333, 1256, 1244, 553, 1243,
160808
+ /* 1660 */ 490, 1245, 1580, 267, 11, 391, 210, 223, 1021, 1390,
160809
+ /* 1670 */ 1395, 282, 365, 367, 106, 106, 930, 369, 454, 285,
160810
+ /* 1680 */ 1383, 107, 325, 443, 566, 565, 408, 1021, 1011, 326,
160811
+ /* 1690 */ 475, 306, 555, 106, 106, 100, 556, 500, 4, 1400,
160812
+ /* 1700 */ 107, 1399, 443, 566, 565, 398, 1283, 1011, 214, 355,
160813
+ /* 1710 */ 1473, 290, 559, 1472, 1583, 449, 554, 371, 331, 197,
160814
+ /* 1720 */ 1011, 1011, 1013, 1014, 27, 198, 209, 385, 1222, 173,
160815
+ /* 1730 */ 221, 256, 1520, 1518, 1219, 443, 79, 416, 206, 1011,
160816
+ /* 1740 */ 1011, 1013, 1014, 27, 83, 279, 182, 553, 82, 167,
160817
+ /* 1750 */ 390, 390, 389, 264, 387, 35, 1396, 843, 1478, 459,
160818
+ /* 1760 */ 175, 177, 460, 493, 178, 179, 180, 233, 96, 396,
160819
+ /* 1770 */ 225, 1402, 313, 1401, 36, 1404, 1021, 467, 186, 482,
160820
+ /* 1780 */ 312, 399, 106, 106, 237, 1467, 89, 1489, 488, 107,
160821
+ /* 1790 */ 239, 443, 566, 565, 268, 336, 1011, 190, 491, 340,
160822
+ /* 1800 */ 240, 401, 1246, 241, 509, 1294, 430, 1303, 91, 877,
160823
+ /* 1810 */ 227, 215, 1566, 1302, 1301, 1273, 1598, 432, 162, 518,
160824
+ /* 1820 */ 1272, 135, 1597, 354, 402, 433, 1271, 1596, 1011, 1011,
160825
+ /* 1830 */ 1013, 1014, 27, 1293, 299, 360, 300, 525, 226, 95,
160826
+ /* 1840 */ 254, 255, 1344, 364, 436, 125, 544, 1552, 10, 1453,
160827
+ /* 1850 */ 379, 1551, 102, 304, 97, 528, 34, 568, 1177, 263,
160828
+ /* 1860 */ 265, 266, 569, 1241, 1236, 172, 409, 410, 159, 383,
160829
+ /* 1870 */ 377, 366, 408, 1345, 1343, 368, 370, 306, 555, 1342,
160830
+ /* 1880 */ 1326, 1325, 1368, 201, 384, 1367, 1505, 1506, 160, 1504,
160831
+ /* 1890 */ 1503, 142, 161, 211, 212, 78, 830, 444, 203, 308,
160832
+ /* 1900 */ 297, 449, 222, 1081, 139, 1079, 316, 174, 163, 1203,
160833
+ /* 1910 */ 229, 176, 232, 909, 324, 1095, 164, 181, 165, 419,
160834
+ /* 1920 */ 421, 183, 85, 86, 87, 88, 166, 1098, 235, 234,
160835
+ /* 1930 */ 1094, 152, 18, 236, 335, 1087, 252, 1216, 487, 238,
160836
+ /* 1940 */ 37, 187, 188, 845, 492, 356, 242, 348, 496, 189,
160837
+ /* 1950 */ 90, 93, 19, 20, 168, 875, 501, 351, 92, 504,
160838
+ /* 1960 */ 888, 153, 511, 1133, 1165, 154, 298, 1047, 94, 1134,
160839
+ /* 1970 */ 39, 958, 216, 271, 273, 192, 953, 110, 1151, 251,
160840
+ /* 1980 */ 1155, 21, 1159, 22, 1158, 1139, 1153, 33, 23, 24,
160841
+ /* 1990 */ 540, 25, 195, 98, 26, 1062, 1048, 1046, 1050, 1104,
160842
+ /* 2000 */ 7, 1103, 257, 258, 1051, 28, 40, 560, 1016, 857,
160843
+ /* 2010 */ 109, 29, 919, 138, 259, 260, 170, 1589, 388, 1588,
160844
+ /* 2020 */ 1173, 1172,
159477160845
};
159478160846
static const YYCODETYPE yy_lookahead[] = {
159479160847
/* 0 */ 192, 273, 274, 275, 192, 192, 273, 274, 275, 192,
159480160848
/* 10 */ 218, 215, 192, 218, 192, 212, 234, 235, 205, 19,
159481160849
/* 20 */ 11, 192, 294, 215, 216, 203, 192, 203, 209, 210,
@@ -159486,202 +160854,202 @@
159486160854
/* 70 */ 275, 237, 21, 251, 252, 251, 273, 274, 275, 255,
159487160855
/* 80 */ 256, 215, 216, 43, 44, 45, 46, 47, 48, 49,
159488160856
/* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 209, 210,
159489160857
/* 100 */ 211, 76, 102, 103, 104, 105, 106, 107, 108, 109,
159490160858
/* 110 */ 110, 111, 112, 59, 89, 111, 112, 92, 252, 307,
159491
- /* 120 */ 308, 313, 314, 112, 312, 59, 86, 261, 88, 19,
160859
+ /* 120 */ 308, 313, 314, 25, 312, 192, 86, 261, 88, 19,
159492160860
/* 130 */ 313, 80, 315, 313, 314, 25, 127, 128, 54, 55,
159493160861
/* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109,
159494160862
/* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49,
159495160863
/* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 192, 115,
159496160864
/* 170 */ 116, 117, 118, 122, 192, 121, 122, 123, 202, 69,
159497
- /* 180 */ 204, 115, 116, 117, 192, 131, 102, 103, 104, 105,
160865
+ /* 180 */ 204, 22, 23, 16, 25, 131, 102, 103, 104, 105,
159498160866
/* 190 */ 106, 107, 108, 109, 110, 111, 112, 215, 216, 19,
159499160867
/* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112,
159500160868
/* 210 */ 192, 160, 102, 103, 104, 105, 106, 107, 108, 109,
159501160869
/* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49,
159502
- /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 46,
159503
- /* 240 */ 47, 48, 49, 24, 248, 192, 250, 67, 102, 103,
160870
+ /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 141,
160871
+ /* 240 */ 307, 308, 272, 24, 77, 312, 79, 67, 102, 103,
159504160872
/* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 277,
159505
- /* 260 */ 127, 128, 43, 44, 45, 46, 47, 48, 49, 50,
159506
- /* 270 */ 51, 52, 53, 54, 55, 56, 57, 26, 164, 165,
159507
- /* 280 */ 272, 263, 102, 103, 104, 105, 106, 107, 108, 109,
160873
+ /* 260 */ 101, 112, 43, 44, 45, 46, 47, 48, 49, 50,
160874
+ /* 270 */ 51, 52, 53, 54, 55, 56, 57, 26, 127, 128,
160875
+ /* 280 */ 310, 311, 102, 103, 104, 105, 106, 107, 108, 109,
159508160876
/* 290 */ 110, 111, 112, 184, 185, 186, 187, 188, 189, 186,
159509
- /* 300 */ 187, 188, 189, 194, 76, 196, 229, 194, 19, 196,
159510
- /* 310 */ 59, 192, 203, 120, 59, 87, 203, 89, 310, 311,
160877
+ /* 300 */ 187, 188, 189, 194, 76, 196, 192, 194, 19, 196,
160878
+ /* 310 */ 59, 25, 203, 192, 59, 87, 203, 89, 164, 165,
159511160879
/* 320 */ 92, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159512160880
/* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50,
159513160881
/* 340 */ 51, 52, 53, 54, 55, 56, 57, 238, 239, 73,
159514
- /* 350 */ 231, 238, 239, 22, 23, 100, 25, 81, 305, 306,
159515
- /* 360 */ 251, 23, 25, 25, 251, 272, 115, 116, 117, 214,
159516
- /* 370 */ 115, 116, 144, 192, 265, 120, 114, 222, 265, 102,
160882
+ /* 350 */ 192, 238, 239, 22, 23, 100, 25, 81, 237, 229,
160883
+ /* 360 */ 251, 23, 204, 25, 251, 272, 115, 116, 117, 214,
160884
+ /* 370 */ 115, 116, 144, 192, 265, 120, 262, 222, 265, 102,
159517160885
/* 380 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
159518160886
/* 390 */ 192, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159519160887
/* 400 */ 111, 112, 126, 310, 311, 192, 297, 152, 153, 154,
159520
- /* 410 */ 297, 149, 192, 137, 138, 19, 192, 100, 192, 23,
160888
+ /* 410 */ 297, 125, 192, 137, 138, 19, 295, 100, 192, 23,
159521160889
/* 420 */ 22, 106, 107, 108, 109, 110, 111, 112, 215, 216,
159522160890
/* 430 */ 106, 107, 101, 116, 192, 215, 216, 120, 149, 43,
159523160891
/* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
159524
- /* 450 */ 54, 55, 56, 57, 117, 117, 192, 59, 19, 187,
159525
- /* 460 */ 59, 189, 23, 282, 240, 252, 194, 192, 196, 152,
159526
- /* 470 */ 153, 154, 252, 72, 261, 203, 152, 25, 154, 142,
160892
+ /* 450 */ 54, 55, 56, 57, 222, 117, 224, 59, 19, 187,
160893
+ /* 460 */ 59, 189, 23, 282, 232, 252, 194, 192, 196, 152,
160894
+ /* 470 */ 153, 154, 252, 72, 261, 203, 152, 248, 154, 250,
159527160895
/* 480 */ 142, 261, 43, 44, 45, 46, 47, 48, 49, 50,
159528160896
/* 490 */ 51, 52, 53, 54, 55, 56, 57, 192, 102, 103,
159529160897
/* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 267,
159530160898
/* 510 */ 238, 239, 237, 115, 116, 117, 115, 116, 117, 192,
159531
- /* 520 */ 59, 118, 16, 251, 121, 122, 123, 303, 19, 303,
159532
- /* 530 */ 59, 267, 23, 72, 131, 308, 22, 265, 22, 312,
160899
+ /* 520 */ 59, 118, 192, 251, 121, 122, 123, 73, 19, 192,
160900
+ /* 530 */ 59, 192, 23, 72, 131, 308, 22, 265, 22, 312,
159533160901
/* 540 */ 24, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159534160902
/* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50,
159535
- /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 81, 297,
159536
- /* 570 */ 295, 23, 192, 59, 203, 59, 115, 116, 117, 108,
159537
- /* 580 */ 192, 73, 25, 77, 192, 79, 115, 116, 117, 137,
159538
- /* 590 */ 138, 43, 44, 45, 46, 47, 48, 49, 50, 51,
159539
- /* 600 */ 52, 53, 54, 55, 56, 57, 119, 215, 216, 238,
160903
+ /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 192, 297,
160904
+ /* 570 */ 192, 23, 267, 59, 203, 59, 115, 116, 117, 108,
160905
+ /* 580 */ 126, 127, 128, 192, 192, 192, 115, 116, 117, 262,
160906
+ /* 590 */ 59, 43, 44, 45, 46, 47, 48, 49, 50, 51,
160907
+ /* 600 */ 52, 53, 54, 55, 56, 57, 267, 215, 216, 238,
159540160908
/* 610 */ 239, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159541
- /* 620 */ 111, 112, 251, 192, 137, 138, 59, 234, 235, 115,
159542
- /* 630 */ 116, 117, 116, 76, 126, 127, 128, 19, 192, 268,
159543
- /* 640 */ 19, 23, 22, 192, 252, 24, 89, 300, 301, 92,
160909
+ /* 620 */ 111, 112, 251, 45, 46, 47, 59, 49, 291, 115,
160910
+ /* 630 */ 116, 117, 116, 81, 192, 305, 306, 19, 192, 268,
160911
+ /* 640 */ 19, 23, 22, 192, 252, 24, 115, 116, 117, 192,
159544160912
/* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
159545160913
/* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51,
159546
- /* 670 */ 52, 53, 54, 55, 56, 57, 19, 192, 192, 59,
159547
- /* 680 */ 23, 192, 115, 116, 117, 200, 240, 307, 308, 22,
159548
- /* 690 */ 205, 81, 312, 262, 22, 192, 133, 22, 135, 136,
160914
+ /* 670 */ 52, 53, 54, 55, 56, 57, 19, 22, 23, 59,
160915
+ /* 680 */ 23, 303, 115, 116, 117, 192, 240, 234, 235, 137,
160916
+ /* 690 */ 138, 240, 308, 192, 22, 192, 312, 22, 120, 306,
159549160917
/* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
159550160918
/* 710 */ 53, 54, 55, 56, 57, 197, 95, 150, 215, 216,
159551160919
/* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
159552
- /* 730 */ 112, 59, 192, 112, 59, 115, 116, 117, 192, 118,
159553
- /* 740 */ 119, 120, 121, 122, 123, 124, 19, 137, 138, 303,
159554
- /* 750 */ 23, 130, 192, 267, 192, 252, 267, 306, 203, 102,
160920
+ /* 730 */ 112, 59, 231, 112, 59, 115, 116, 117, 25, 118,
160921
+ /* 740 */ 119, 120, 121, 122, 123, 124, 19, 243, 81, 303,
160922
+ /* 750 */ 23, 130, 192, 192, 303, 252, 101, 253, 203, 102,
159555160923
/* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
159556160924
/* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
159557
- /* 780 */ 53, 54, 55, 56, 57, 19, 240, 115, 116, 117,
159558
- /* 790 */ 115, 116, 117, 238, 239, 222, 192, 224, 280, 237,
159559
- /* 800 */ 240, 192, 284, 192, 59, 232, 251, 140, 204, 43,
160925
+ /* 780 */ 53, 54, 55, 56, 57, 19, 119, 115, 116, 117,
160926
+ /* 790 */ 115, 116, 117, 238, 239, 238, 239, 192, 280, 192,
160927
+ /* 800 */ 240, 192, 284, 192, 137, 138, 251, 192, 251, 43,
159560160928
/* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
159561
- /* 820 */ 54, 55, 56, 57, 192, 35, 215, 216, 192, 102,
160929
+ /* 820 */ 54, 55, 56, 57, 192, 35, 215, 216, 267, 102,
159562160930
/* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
159563
- /* 840 */ 59, 230, 192, 192, 238, 239, 237, 215, 216, 303,
159564
- /* 850 */ 308, 215, 216, 16, 312, 19, 66, 251, 126, 127,
159565
- /* 860 */ 128, 116, 230, 303, 74, 203, 215, 216, 102, 103,
160931
+ /* 840 */ 59, 230, 237, 192, 25, 192, 192, 215, 216, 240,
160932
+ /* 850 */ 137, 138, 237, 16, 200, 19, 66, 192, 133, 205,
160933
+ /* 860 */ 135, 136, 230, 303, 74, 203, 215, 216, 102, 103,
159566160934
/* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43,
159567160935
/* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
159568
- /* 890 */ 54, 55, 56, 57, 192, 212, 115, 116, 117, 19,
159569
- /* 900 */ 238, 239, 192, 252, 7, 8, 9, 192, 192, 238,
159570
- /* 910 */ 239, 308, 262, 251, 77, 312, 79, 215, 216, 129,
160936
+ /* 890 */ 54, 55, 56, 57, 192, 76, 115, 116, 117, 19,
160937
+ /* 900 */ 238, 239, 192, 252, 126, 127, 128, 192, 89, 238,
160938
+ /* 910 */ 239, 92, 303, 251, 77, 262, 79, 215, 216, 129,
159571160939
/* 920 */ 210, 211, 251, 142, 158, 45, 46, 47, 48, 49,
159572160940
/* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103,
159573160941
/* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 12,
159574
- /* 950 */ 59, 192, 192, 237, 252, 243, 192, 192, 126, 127,
159575
- /* 960 */ 128, 192, 308, 203, 27, 253, 312, 308, 285, 207,
159576
- /* 970 */ 208, 312, 157, 290, 159, 215, 216, 262, 192, 42,
160942
+ /* 950 */ 59, 308, 192, 212, 252, 312, 291, 192, 7, 8,
160943
+ /* 960 */ 9, 300, 301, 203, 27, 126, 127, 128, 308, 207,
160944
+ /* 970 */ 208, 192, 312, 29, 192, 215, 216, 33, 192, 42,
159577160945
/* 980 */ 215, 216, 102, 103, 104, 105, 106, 107, 108, 109,
159578
- /* 990 */ 110, 111, 112, 283, 158, 230, 237, 160, 238, 239,
159579
- /* 1000 */ 63, 215, 216, 192, 192, 12, 115, 116, 117, 22,
159580
- /* 1010 */ 73, 251, 252, 192, 19, 192, 230, 239, 24, 24,
159581
- /* 1020 */ 27, 261, 210, 211, 99, 192, 215, 216, 225, 251,
159582
- /* 1030 */ 192, 192, 263, 142, 19, 42, 215, 216, 43, 44,
160946
+ /* 990 */ 110, 111, 112, 283, 158, 230, 66, 160, 238, 239,
160947
+ /* 1000 */ 63, 215, 216, 192, 192, 12, 115, 116, 117, 65,
160948
+ /* 1010 */ 73, 251, 252, 192, 19, 85, 230, 192, 24, 24,
160949
+ /* 1020 */ 27, 261, 210, 211, 94, 192, 215, 216, 22, 207,
160950
+ /* 1030 */ 208, 290, 192, 142, 19, 42, 215, 216, 43, 44,
159583160951
/* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
159584
- /* 1050 */ 55, 56, 57, 59, 19, 291, 63, 132, 43, 44,
160952
+ /* 1050 */ 55, 56, 57, 59, 19, 144, 63, 192, 43, 44,
159585160953
/* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
159586
- /* 1070 */ 55, 56, 57, 252, 22, 23, 22, 25, 43, 44,
160954
+ /* 1070 */ 55, 56, 57, 252, 163, 145, 114, 22, 43, 44,
159587160955
/* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
159588
- /* 1090 */ 55, 56, 57, 106, 107, 283, 263, 102, 103, 104,
160956
+ /* 1090 */ 55, 56, 57, 45, 212, 283, 263, 102, 103, 104,
159589160957
/* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 192,
159590
- /* 1110 */ 116, 144, 29, 59, 291, 192, 33, 102, 103, 104,
159591
- /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 192, 291,
159592
- /* 1130 */ 163, 19, 215, 216, 15, 192, 108, 102, 103, 104,
159593
- /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 65, 192,
159594
- /* 1150 */ 66, 215, 216, 101, 231, 106, 107, 19, 215, 216,
159595
- /* 1160 */ 192, 212, 134, 114, 115, 116, 117, 139, 119, 85,
159596
- /* 1170 */ 116, 207, 208, 230, 192, 19, 127, 192, 94, 60,
160958
+ /* 1110 */ 116, 149, 106, 107, 59, 25, 291, 102, 103, 104,
160959
+ /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 192, 22,
160960
+ /* 1130 */ 192, 192, 215, 216, 23, 192, 25, 102, 103, 104,
160961
+ /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 108, 192,
160962
+ /* 1150 */ 192, 215, 216, 215, 216, 106, 107, 19, 215, 216,
160963
+ /* 1160 */ 53, 59, 114, 114, 115, 116, 117, 285, 119, 137,
160964
+ /* 1170 */ 138, 116, 290, 230, 134, 192, 127, 192, 192, 139,
159597160965
/* 1180 */ 59, 192, 44, 45, 46, 47, 48, 49, 50, 51,
159598
- /* 1190 */ 52, 53, 54, 55, 56, 57, 192, 76, 192, 31,
159599
- /* 1200 */ 192, 152, 46, 154, 215, 216, 192, 39, 87, 192,
159600
- /* 1210 */ 89, 19, 20, 92, 22, 192, 22, 23, 22, 230,
159601
- /* 1220 */ 263, 215, 216, 215, 216, 137, 138, 115, 36, 145,
159602
- /* 1230 */ 128, 192, 215, 216, 22, 23, 115, 116, 117, 290,
160966
+ /* 1190 */ 52, 53, 54, 55, 56, 57, 308, 76, 215, 216,
160967
+ /* 1200 */ 312, 152, 263, 154, 215, 216, 192, 117, 87, 19,
160968
+ /* 1210 */ 89, 19, 20, 92, 22, 22, 23, 231, 116, 230,
160969
+ /* 1220 */ 263, 263, 237, 203, 298, 299, 203, 239, 36, 215,
160970
+ /* 1230 */ 216, 192, 142, 192, 15, 45, 115, 116, 117, 251,
159603160971
/* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
159604
- /* 1250 */ 112, 59, 192, 151, 215, 216, 192, 61, 203, 298,
159605
- /* 1260 */ 299, 192, 192, 71, 25, 144, 203, 192, 203, 230,
159606
- /* 1270 */ 114, 19, 20, 81, 22, 215, 216, 263, 192, 215,
159607
- /* 1280 */ 216, 255, 256, 203, 215, 216, 130, 19, 36, 192,
159608
- /* 1290 */ 215, 216, 100, 238, 239, 101, 25, 192, 106, 107,
159609
- /* 1300 */ 48, 238, 239, 238, 239, 113, 251, 115, 116, 117,
159610
- /* 1310 */ 192, 59, 120, 101, 251, 192, 251, 192, 238, 239,
159611
- /* 1320 */ 215, 216, 192, 71, 46, 243, 192, 25, 25, 137,
159612
- /* 1330 */ 138, 251, 192, 215, 216, 253, 25, 85, 215, 216,
159613
- /* 1340 */ 215, 216, 90, 243, 152, 153, 154, 155, 156, 215,
159614
- /* 1350 */ 216, 192, 100, 253, 243, 215, 216, 192, 106, 107,
159615
- /* 1360 */ 243, 192, 148, 149, 253, 113, 192, 115, 116, 117,
159616
- /* 1370 */ 253, 192, 120, 192, 215, 216, 192, 23, 192, 25,
159617
- /* 1380 */ 215, 216, 192, 115, 215, 216, 22, 148, 24, 215,
159618
- /* 1390 */ 216, 192, 114, 192, 215, 216, 215, 216, 134, 215,
159619
- /* 1400 */ 216, 215, 216, 139, 152, 153, 154, 155, 156, 0,
159620
- /* 1410 */ 1, 2, 141, 23, 5, 25, 215, 216, 24, 10,
159621
- /* 1420 */ 11, 12, 13, 14, 1, 2, 17, 125, 5, 19,
159622
- /* 1430 */ 20, 268, 22, 10, 11, 12, 13, 14, 192, 30,
159623
- /* 1440 */ 17, 32, 23, 23, 25, 25, 36, 144, 23, 40,
159624
- /* 1450 */ 25, 192, 141, 30, 192, 32, 23, 22, 25, 5,
159625
- /* 1460 */ 128, 215, 216, 40, 10, 11, 12, 13, 14, 59,
159626
- /* 1470 */ 23, 17, 25, 192, 215, 216, 192, 215, 216, 70,
159627
- /* 1480 */ 23, 71, 25, 151, 30, 192, 32, 78, 53, 192,
159628
- /* 1490 */ 81, 192, 192, 70, 40, 85, 215, 216, 119, 120,
159629
- /* 1500 */ 90, 78, 59, 254, 81, 192, 192, 98, 215, 216,
159630
- /* 1510 */ 100, 23, 59, 25, 215, 216, 106, 107, 23, 192,
159631
- /* 1520 */ 25, 98, 19, 113, 70, 115, 116, 117, 215, 216,
159632
- /* 1530 */ 120, 192, 78, 192, 140, 81, 19, 20, 23, 22,
159633
- /* 1540 */ 25, 132, 215, 216, 192, 192, 137, 138, 192, 23,
159634
- /* 1550 */ 192, 25, 98, 36, 192, 132, 215, 216, 192, 116,
159635
- /* 1560 */ 137, 138, 152, 153, 154, 155, 156, 215, 216, 116,
159636
- /* 1570 */ 161, 215, 216, 215, 216, 120, 59, 215, 216, 7,
159637
- /* 1580 */ 8, 215, 216, 192, 161, 130, 132, 192, 71, 83,
159638
- /* 1590 */ 84, 137, 138, 59, 192, 192, 19, 20, 192, 22,
159639
- /* 1600 */ 97, 225, 85, 192, 23, 192, 25, 90, 192, 192,
159640
- /* 1610 */ 215, 216, 152, 36, 154, 161, 192, 100, 215, 216,
159641
- /* 1620 */ 192, 215, 216, 106, 107, 225, 215, 216, 192, 192,
159642
- /* 1630 */ 113, 192, 115, 116, 117, 257, 59, 120, 192, 215,
159643
- /* 1640 */ 216, 152, 192, 154, 192, 23, 317, 25, 71, 235,
159644
- /* 1650 */ 116, 215, 216, 192, 215, 216, 192, 192, 192, 192,
159645
- /* 1660 */ 192, 192, 192, 192, 192, 215, 216, 215, 216, 152,
159646
- /* 1670 */ 153, 154, 155, 156, 192, 192, 287, 100, 286, 241,
159647
- /* 1680 */ 254, 254, 242, 106, 107, 108, 254, 213, 254, 190,
159648
- /* 1690 */ 113, 270, 115, 116, 117, 296, 266, 120, 219, 258,
159649
- /* 1700 */ 244, 270, 258, 19, 20, 228, 22, 292, 266, 224,
159650
- /* 1710 */ 292, 218, 218, 195, 218, 270, 258, 60, 245, 270,
159651
- /* 1720 */ 36, 245, 244, 248, 19, 20, 242, 22, 248, 152,
159652
- /* 1730 */ 153, 154, 155, 156, 244, 140, 199, 199, 279, 38,
159653
- /* 1740 */ 199, 36, 150, 59, 296, 149, 22, 296, 18, 43,
159654
- /* 1750 */ 236, 199, 233, 18, 198, 71, 293, 236, 271, 236,
159655
- /* 1760 */ 269, 236, 148, 271, 59, 245, 269, 245, 282, 271,
159656
- /* 1770 */ 199, 198, 233, 245, 293, 233, 71, 245, 157, 62,
159657
- /* 1780 */ 22, 199, 198, 220, 100, 199, 198, 220, 199, 289,
159658
- /* 1790 */ 106, 107, 288, 114, 226, 198, 217, 113, 64, 115,
159659
- /* 1800 */ 116, 117, 217, 22, 120, 100, 223, 217, 217, 164,
159660
- /* 1810 */ 223, 106, 107, 220, 125, 24, 217, 219, 113, 217,
159661
- /* 1820 */ 115, 116, 117, 217, 311, 120, 226, 112, 304, 281,
159662
- /* 1830 */ 281, 220, 114, 143, 260, 259, 152, 153, 154, 155,
159663
- /* 1840 */ 156, 199, 91, 316, 82, 316, 147, 144, 22, 199,
159664
- /* 1850 */ 249, 276, 157, 146, 260, 145, 278, 152, 153, 154,
159665
- /* 1860 */ 155, 156, 259, 248, 260, 260, 259, 259, 249, 245,
159666
- /* 1870 */ 247, 246, 25, 264, 264, 201, 13, 6, 193, 193,
159667
- /* 1880 */ 212, 206, 191, 191, 191, 212, 206, 221, 212, 212,
159668
- /* 1890 */ 221, 213, 4, 206, 213, 212, 3, 22, 162, 15,
159669
- /* 1900 */ 23, 16, 23, 138, 150, 129, 25, 24, 141, 20,
159670
- /* 1910 */ 16, 143, 1, 141, 302, 302, 299, 129, 129, 61,
159671
- /* 1920 */ 150, 53, 53, 37, 129, 53, 53, 115, 1, 34,
159672
- /* 1930 */ 140, 5, 22, 114, 160, 68, 75, 25, 68, 41,
159673
- /* 1940 */ 140, 114, 24, 20, 19, 130, 124, 67, 24, 67,
159674
- /* 1950 */ 22, 22, 22, 96, 23, 22, 59, 22, 67, 37,
159675
- /* 1960 */ 28, 23, 148, 22, 25, 23, 23, 23, 23, 22,
159676
- /* 1970 */ 140, 97, 23, 23, 115, 22, 142, 25, 88, 75,
159677
- /* 1980 */ 34, 44, 34, 75, 23, 34, 86, 22, 34, 34,
159678
- /* 1990 */ 34, 24, 93, 25, 25, 23, 34, 23, 23, 23,
159679
- /* 2000 */ 23, 11, 23, 25, 22, 22, 22, 1, 23, 23,
159680
- /* 2010 */ 22, 22, 25, 15, 23, 1, 140, 25, 140, 318,
159681
- /* 2020 */ 318, 134, 318, 318, 318, 318, 318, 318, 318, 318,
159682
- /* 2030 */ 318, 318, 140, 318, 318, 318, 140, 318, 318, 318,
160972
+ /* 1250 */ 112, 59, 192, 203, 215, 216, 215, 216, 238, 239,
160973
+ /* 1260 */ 192, 238, 239, 71, 192, 144, 25, 203, 243, 230,
160974
+ /* 1270 */ 243, 251, 192, 81, 251, 215, 216, 243, 253, 60,
160975
+ /* 1280 */ 253, 255, 256, 19, 20, 25, 22, 253, 238, 239,
160976
+ /* 1290 */ 192, 192, 100, 192, 101, 215, 216, 19, 106, 107,
160977
+ /* 1300 */ 36, 251, 238, 239, 114, 113, 192, 115, 116, 117,
160978
+ /* 1310 */ 192, 47, 120, 215, 216, 251, 215, 216, 192, 31,
160979
+ /* 1320 */ 130, 134, 243, 59, 148, 149, 139, 39, 192, 137,
160980
+ /* 1330 */ 138, 263, 253, 215, 216, 71, 19, 157, 192, 159,
160981
+ /* 1340 */ 128, 215, 216, 25, 152, 153, 154, 155, 156, 85,
160982
+ /* 1350 */ 192, 215, 216, 268, 90, 0, 1, 2, 192, 192,
160983
+ /* 1360 */ 5, 215, 216, 151, 100, 10, 11, 12, 13, 14,
160984
+ /* 1370 */ 106, 107, 17, 215, 216, 19, 20, 113, 22, 115,
160985
+ /* 1380 */ 116, 117, 215, 216, 120, 30, 192, 32, 192, 148,
160986
+ /* 1390 */ 192, 24, 36, 115, 22, 40, 24, 23, 192, 25,
160987
+ /* 1400 */ 128, 23, 99, 25, 144, 192, 22, 192, 192, 215,
160988
+ /* 1410 */ 216, 215, 216, 215, 216, 59, 152, 153, 154, 155,
160989
+ /* 1420 */ 156, 215, 216, 151, 192, 70, 192, 71, 215, 216,
160990
+ /* 1430 */ 215, 216, 115, 78, 192, 132, 81, 192, 23, 22,
160991
+ /* 1440 */ 25, 85, 192, 192, 192, 61, 90, 215, 216, 215,
160992
+ /* 1450 */ 216, 192, 225, 98, 192, 192, 100, 215, 216, 141,
160993
+ /* 1460 */ 215, 216, 106, 107, 225, 215, 216, 215, 216, 113,
160994
+ /* 1470 */ 59, 115, 116, 117, 215, 216, 120, 215, 216, 192,
160995
+ /* 1480 */ 120, 192, 19, 20, 23, 22, 25, 132, 119, 120,
160996
+ /* 1490 */ 130, 192, 137, 138, 192, 23, 192, 25, 192, 36,
160997
+ /* 1500 */ 192, 192, 215, 216, 215, 216, 192, 140, 152, 153,
160998
+ /* 1510 */ 154, 155, 156, 192, 215, 216, 161, 215, 216, 215,
160999
+ /* 1520 */ 216, 192, 59, 215, 216, 19, 192, 116, 192, 215,
161000
+ /* 1530 */ 216, 23, 59, 25, 71, 192, 215, 216, 192, 23,
161001
+ /* 1540 */ 23, 25, 25, 192, 215, 216, 7, 8, 85, 215,
161002
+ /* 1550 */ 216, 215, 216, 90, 192, 1, 2, 140, 192, 5,
161003
+ /* 1560 */ 192, 215, 216, 100, 10, 11, 12, 13, 14, 106,
161004
+ /* 1570 */ 107, 17, 192, 23, 192, 25, 113, 192, 115, 116,
161005
+ /* 1580 */ 117, 215, 216, 120, 30, 59, 32, 19, 20, 116,
161006
+ /* 1590 */ 22, 192, 83, 84, 40, 215, 216, 215, 216, 192,
161007
+ /* 1600 */ 215, 216, 192, 97, 36, 192, 19, 20, 23, 22,
161008
+ /* 1610 */ 25, 23, 152, 25, 154, 152, 153, 154, 155, 156,
161009
+ /* 1620 */ 152, 225, 154, 36, 70, 215, 216, 59, 215, 216,
161010
+ /* 1630 */ 192, 23, 78, 25, 23, 81, 25, 192, 192, 71,
161011
+ /* 1640 */ 257, 192, 116, 192, 192, 254, 59, 317, 192, 192,
161012
+ /* 1650 */ 192, 235, 98, 241, 192, 254, 192, 192, 71, 192,
161013
+ /* 1660 */ 287, 192, 192, 286, 242, 190, 213, 296, 100, 266,
161014
+ /* 1670 */ 270, 244, 254, 254, 106, 107, 108, 254, 258, 258,
161015
+ /* 1680 */ 266, 113, 292, 115, 116, 117, 132, 100, 120, 245,
161016
+ /* 1690 */ 292, 137, 138, 106, 107, 19, 20, 219, 22, 270,
161017
+ /* 1700 */ 113, 270, 115, 116, 117, 270, 224, 120, 228, 218,
161018
+ /* 1710 */ 218, 245, 36, 218, 195, 161, 279, 258, 244, 248,
161019
+ /* 1720 */ 152, 153, 154, 155, 156, 248, 242, 244, 60, 296,
161020
+ /* 1730 */ 296, 140, 199, 199, 38, 59, 293, 199, 149, 152,
161021
+ /* 1740 */ 153, 154, 155, 156, 150, 5, 22, 71, 293, 43,
161022
+ /* 1750 */ 10, 11, 12, 13, 14, 269, 271, 17, 282, 18,
161023
+ /* 1760 */ 233, 236, 199, 18, 236, 236, 236, 198, 148, 245,
161024
+ /* 1770 */ 30, 271, 32, 271, 269, 233, 100, 245, 233, 199,
161025
+ /* 1780 */ 40, 245, 106, 107, 198, 245, 157, 289, 62, 113,
161026
+ /* 1790 */ 198, 115, 116, 117, 199, 288, 120, 22, 220, 199,
161027
+ /* 1800 */ 198, 220, 199, 198, 114, 226, 64, 217, 22, 125,
161028
+ /* 1810 */ 70, 164, 311, 217, 217, 217, 223, 24, 78, 304,
161029
+ /* 1820 */ 219, 81, 223, 217, 220, 112, 217, 217, 152, 153,
161030
+ /* 1830 */ 154, 155, 156, 226, 281, 220, 281, 143, 98, 114,
161031
+ /* 1840 */ 199, 91, 260, 259, 82, 147, 144, 316, 22, 276,
161032
+ /* 1850 */ 199, 316, 157, 278, 146, 145, 25, 201, 13, 193,
161033
+ /* 1860 */ 193, 6, 191, 191, 191, 299, 302, 302, 206, 246,
161034
+ /* 1870 */ 248, 259, 132, 260, 260, 259, 259, 137, 138, 260,
161035
+ /* 1880 */ 249, 249, 264, 247, 245, 264, 212, 212, 206, 212,
161036
+ /* 1890 */ 212, 221, 206, 213, 213, 212, 4, 3, 22, 162,
161037
+ /* 1900 */ 221, 161, 15, 23, 16, 23, 138, 150, 129, 25,
161038
+ /* 1910 */ 24, 141, 143, 20, 16, 1, 129, 141, 129, 61,
161039
+ /* 1920 */ 37, 150, 53, 53, 53, 53, 129, 115, 140, 34,
161040
+ /* 1930 */ 1, 5, 22, 114, 160, 68, 25, 75, 41, 140,
161041
+ /* 1940 */ 24, 68, 114, 20, 19, 130, 124, 23, 67, 22,
161042
+ /* 1950 */ 22, 148, 22, 22, 37, 59, 67, 24, 22, 96,
161043
+ /* 1960 */ 28, 23, 22, 97, 23, 23, 67, 23, 25, 23,
161044
+ /* 1970 */ 22, 115, 140, 23, 23, 22, 142, 25, 88, 34,
161045
+ /* 1980 */ 75, 34, 75, 34, 93, 23, 86, 22, 34, 34,
161046
+ /* 1990 */ 24, 34, 25, 25, 34, 23, 23, 23, 23, 23,
161047
+ /* 2000 */ 44, 23, 25, 22, 11, 22, 22, 25, 23, 23,
161048
+ /* 2010 */ 22, 22, 134, 23, 140, 140, 25, 140, 15, 140,
161049
+ /* 2020 */ 1, 1, 318, 318, 318, 318, 318, 318, 318, 318,
161050
+ /* 2030 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159683161051
/* 2040 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159684161052
/* 2050 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159685161053
/* 2060 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159686161054
/* 2070 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159687161055
/* 2080 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
@@ -159694,122 +161062,120 @@
159694161062
/* 2150 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159695161063
/* 2160 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159696161064
/* 2170 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159697161065
/* 2180 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159698161066
/* 2190 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159699
- /* 2200 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159700
- /* 2210 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159701
- /* 2220 */ 318,
161067
+ /* 2200 */ 318, 318, 318, 318, 318, 318,
159702161068
};
159703161069
#define YY_SHIFT_COUNT (571)
159704161070
#define YY_SHIFT_MIN (0)
159705
-#define YY_SHIFT_MAX (2014)
161071
+#define YY_SHIFT_MAX (2020)
159706161072
static const unsigned short int yy_shift_ofst[] = {
159707
- /* 0 */ 1423, 1409, 1454, 1192, 1192, 610, 1252, 1410, 1517, 1684,
159708
- /* 10 */ 1684, 1684, 276, 0, 0, 180, 1015, 1684, 1684, 1684,
159709
- /* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159710
- /* 30 */ 1049, 1049, 1121, 1121, 54, 487, 610, 610, 610, 610,
159711
- /* 40 */ 610, 40, 110, 219, 289, 396, 439, 509, 548, 618,
161073
+ /* 0 */ 1554, 1355, 1740, 1192, 1192, 552, 1264, 1356, 1463, 1587,
161074
+ /* 10 */ 1587, 1587, 276, 0, 0, 180, 1015, 1587, 1587, 1587,
161075
+ /* 20 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161076
+ /* 30 */ 1049, 1049, 1121, 1121, 54, 667, 552, 552, 552, 552,
161077
+ /* 40 */ 552, 40, 110, 219, 289, 396, 439, 509, 548, 618,
159712161078
/* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015,
159713161079
/* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015,
159714
- /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1577, 1684,
159715
- /* 80 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159716
- /* 90 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159717
- /* 100 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159718
- /* 110 */ 1684, 1684, 1684, 1705, 1684, 1684, 1684, 1684, 1684, 1684,
159719
- /* 120 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 146, 84, 84,
159720
- /* 130 */ 84, 84, 84, 277, 315, 401, 97, 461, 251, 66,
159721
- /* 140 */ 66, 51, 1156, 66, 66, 324, 324, 66, 452, 452,
159722
- /* 150 */ 452, 452, 133, 114, 114, 4, 11, 2037, 2037, 621,
161080
+ /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1568, 1587,
161081
+ /* 80 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161082
+ /* 90 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161083
+ /* 100 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161084
+ /* 110 */ 1587, 1587, 1587, 1676, 1587, 1587, 1587, 1587, 1587, 1587,
161085
+ /* 120 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 146, 84, 84,
161086
+ /* 130 */ 84, 84, 84, 277, 315, 401, 97, 461, 251, 531,
161087
+ /* 140 */ 531, 51, 1190, 531, 531, 324, 324, 531, 713, 713,
161088
+ /* 150 */ 713, 713, 151, 154, 154, 4, 149, 2022, 2022, 621,
159723161089
/* 160 */ 621, 621, 567, 398, 398, 398, 398, 937, 937, 228,
159724
- /* 170 */ 251, 331, 1052, 66, 66, 66, 66, 66, 66, 66,
159725
- /* 180 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
159726
- /* 190 */ 66, 66, 66, 557, 557, 66, 9, 25, 25, 745,
159727
- /* 200 */ 745, 967, 1088, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
161090
+ /* 170 */ 251, 159, 331, 531, 531, 531, 531, 531, 531, 531,
161091
+ /* 180 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
161092
+ /* 190 */ 531, 531, 531, 819, 819, 531, 9, 25, 25, 1102,
161093
+ /* 200 */ 1102, 911, 1032, 2022, 2022, 2022, 2022, 2022, 2022, 2022,
159728161094
/* 210 */ 255, 317, 317, 514, 403, 620, 471, 672, 781, 891,
159729
- /* 220 */ 675, 66, 66, 66, 66, 66, 66, 66, 66, 66,
159730
- /* 230 */ 66, 508, 66, 66, 66, 66, 66, 66, 66, 66,
159731
- /* 240 */ 66, 66, 66, 66, 790, 790, 790, 66, 66, 66,
159732
- /* 250 */ 338, 66, 66, 66, 516, 1084, 66, 66, 993, 66,
159733
- /* 260 */ 66, 66, 66, 66, 66, 66, 66, 732, 1083, 563,
159734
- /* 270 */ 994, 994, 994, 994, 337, 563, 563, 1028, 987, 897,
159735
- /* 280 */ 1119, 262, 1214, 1271, 1112, 1214, 1112, 1268, 1239, 262,
159736
- /* 290 */ 262, 1239, 262, 1271, 1268, 1302, 1354, 1278, 1168, 1168,
159737
- /* 300 */ 1168, 1112, 1303, 1303, 815, 1311, 1264, 1364, 1657, 1657,
159738
- /* 310 */ 1595, 1595, 1701, 1701, 1595, 1592, 1596, 1724, 1706, 1730,
159739
- /* 320 */ 1730, 1730, 1730, 1595, 1735, 1614, 1596, 1596, 1614, 1724,
159740
- /* 330 */ 1706, 1614, 1706, 1614, 1595, 1735, 1621, 1717, 1595, 1735,
159741
- /* 340 */ 1758, 1595, 1735, 1595, 1735, 1758, 1679, 1679, 1679, 1734,
159742
- /* 350 */ 1781, 1781, 1758, 1679, 1689, 1679, 1734, 1679, 1679, 1645,
159743
- /* 360 */ 1791, 1715, 1715, 1758, 1690, 1718, 1690, 1718, 1690, 1718,
159744
- /* 370 */ 1690, 1718, 1595, 1751, 1751, 1762, 1762, 1699, 1703, 1826,
159745
- /* 380 */ 1595, 1695, 1699, 1707, 1710, 1614, 1847, 1863, 1863, 1871,
159746
- /* 390 */ 1871, 1871, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
159747
- /* 400 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 193, 837, 1194,
159748
- /* 410 */ 1212, 506, 832, 1054, 1390, 925, 1435, 1394, 1102, 1332,
159749
- /* 420 */ 1419, 1196, 1420, 1425, 1433, 1447, 1457, 1488, 1443, 1379,
159750
- /* 430 */ 1572, 1455, 1503, 1453, 1495, 1515, 1506, 1526, 1460, 1489,
159751
- /* 440 */ 1581, 1622, 1534, 667, 1888, 1893, 1875, 1736, 1884, 1885,
159752
- /* 450 */ 1877, 1879, 1765, 1754, 1776, 1881, 1881, 1883, 1767, 1889,
159753
- /* 460 */ 1768, 1894, 1911, 1772, 1788, 1881, 1789, 1858, 1886, 1881,
159754
- /* 470 */ 1770, 1868, 1869, 1872, 1873, 1795, 1812, 1895, 1790, 1927,
159755
- /* 480 */ 1926, 1910, 1819, 1774, 1867, 1912, 1870, 1861, 1898, 1800,
159756
- /* 490 */ 1827, 1918, 1923, 1925, 1815, 1822, 1928, 1880, 1929, 1930,
159757
- /* 500 */ 1931, 1933, 1882, 1897, 1924, 1857, 1932, 1935, 1891, 1922,
159758
- /* 510 */ 1938, 1814, 1941, 1942, 1943, 1944, 1939, 1945, 1947, 1874,
159759
- /* 520 */ 1830, 1949, 1950, 1859, 1946, 1953, 1834, 1952, 1948, 1951,
159760
- /* 530 */ 1954, 1955, 1890, 1904, 1900, 1937, 1908, 1899, 1956, 1961,
159761
- /* 540 */ 1965, 1967, 1968, 1969, 1962, 1972, 1952, 1974, 1975, 1976,
159762
- /* 550 */ 1977, 1978, 1979, 1982, 1990, 1983, 1984, 1985, 1986, 1988,
159763
- /* 560 */ 1989, 1987, 1887, 1876, 1878, 1892, 1896, 1992, 1991, 1998,
159764
- /* 570 */ 2006, 2014,
161095
+ /* 220 */ 675, 531, 531, 531, 531, 531, 531, 531, 531, 531,
161096
+ /* 230 */ 531, 454, 531, 531, 531, 531, 531, 531, 531, 531,
161097
+ /* 240 */ 531, 531, 531, 531, 790, 790, 790, 531, 531, 531,
161098
+ /* 250 */ 338, 531, 531, 531, 516, 930, 531, 531, 993, 531,
161099
+ /* 260 */ 531, 531, 531, 531, 531, 531, 531, 778, 944, 725,
161100
+ /* 270 */ 994, 994, 994, 994, 1090, 725, 725, 1040, 1006, 951,
161101
+ /* 280 */ 1219, 962, 1176, 98, 1278, 1176, 1278, 1317, 1241, 962,
161102
+ /* 290 */ 962, 1241, 962, 98, 1317, 286, 1111, 1048, 1288, 1288,
161103
+ /* 300 */ 1288, 1278, 1260, 1260, 1180, 1318, 1187, 1372, 1668, 1668,
161104
+ /* 310 */ 1591, 1591, 1696, 1696, 1591, 1594, 1589, 1724, 1706, 1741,
161105
+ /* 320 */ 1741, 1741, 1741, 1591, 1745, 1620, 1589, 1589, 1620, 1724,
161106
+ /* 330 */ 1706, 1620, 1706, 1620, 1591, 1745, 1629, 1726, 1591, 1745,
161107
+ /* 340 */ 1775, 1591, 1745, 1591, 1745, 1775, 1690, 1690, 1690, 1742,
161108
+ /* 350 */ 1786, 1786, 1775, 1690, 1684, 1690, 1742, 1690, 1690, 1647,
161109
+ /* 360 */ 1793, 1713, 1713, 1775, 1694, 1725, 1694, 1725, 1694, 1725,
161110
+ /* 370 */ 1694, 1725, 1591, 1750, 1750, 1762, 1762, 1698, 1702, 1826,
161111
+ /* 380 */ 1591, 1695, 1698, 1708, 1710, 1620, 1831, 1845, 1845, 1855,
161112
+ /* 390 */ 1855, 1855, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022,
161113
+ /* 400 */ 2022, 2022, 2022, 2022, 2022, 2022, 2022, 578, 837, 655,
161114
+ /* 410 */ 1193, 167, 839, 1055, 1374, 1303, 1107, 1367, 1212, 1272,
161115
+ /* 420 */ 1378, 1384, 1415, 1461, 1472, 1508, 1516, 1517, 1411, 1369,
161116
+ /* 430 */ 1539, 1360, 1506, 1473, 1550, 1585, 1509, 1588, 1460, 1468,
161117
+ /* 440 */ 1608, 1611, 1526, 1417, 1892, 1894, 1876, 1737, 1887, 1888,
161118
+ /* 450 */ 1880, 1882, 1768, 1757, 1779, 1884, 1884, 1886, 1770, 1893,
161119
+ /* 460 */ 1769, 1898, 1914, 1776, 1787, 1884, 1789, 1858, 1883, 1884,
161120
+ /* 470 */ 1771, 1869, 1870, 1871, 1872, 1797, 1812, 1895, 1788, 1929,
161121
+ /* 480 */ 1926, 1910, 1819, 1774, 1867, 1911, 1873, 1862, 1897, 1799,
161122
+ /* 490 */ 1828, 1916, 1923, 1925, 1815, 1822, 1927, 1881, 1928, 1930,
161123
+ /* 500 */ 1924, 1931, 1889, 1896, 1933, 1863, 1932, 1936, 1899, 1917,
161124
+ /* 510 */ 1938, 1803, 1940, 1941, 1942, 1944, 1943, 1946, 1948, 1866,
161125
+ /* 520 */ 1832, 1950, 1951, 1856, 1945, 1953, 1834, 1952, 1947, 1949,
161126
+ /* 530 */ 1954, 1955, 1890, 1905, 1900, 1956, 1907, 1891, 1957, 1962,
161127
+ /* 540 */ 1965, 1966, 1967, 1968, 1960, 1972, 1952, 1973, 1974, 1975,
161128
+ /* 550 */ 1976, 1977, 1978, 1981, 1993, 1983, 1984, 1985, 1986, 1988,
161129
+ /* 560 */ 1989, 1982, 1878, 1874, 1875, 1877, 1879, 1991, 1990, 2003,
161130
+ /* 570 */ 2019, 2020,
159765161131
};
159766161132
#define YY_REDUCE_COUNT (406)
159767161133
#define YY_REDUCE_MIN (-272)
159768
-#define YY_REDUCE_MAX (1693)
161134
+#define YY_REDUCE_MAX (1686)
159769161135
static const short yy_reduce_ofst[] = {
159770161136
/* 0 */ 109, 113, 272, 760, -178, -176, -192, -183, -180, -134,
159771161137
/* 10 */ 213, 220, 371, -208, -205, -272, -197, 611, 632, 765,
159772161138
/* 20 */ 786, 392, 943, 989, 503, 651, 1039, -18, 702, 821,
159773
- /* 30 */ 710, 812, -188, 380, -187, 555, 662, 1055, 1063, 1065,
159774
- /* 40 */ 1080, -267, -267, -267, -267, -267, -267, -267, -267, -267,
161139
+ /* 30 */ 710, 812, -188, -67, -187, 555, 662, 1020, 1023, 1050,
161140
+ /* 40 */ 1064, -267, -267, -267, -267, -267, -267, -267, -267, -267,
159775161141
/* 50 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267,
159776161142
/* 60 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267,
159777
- /* 70 */ -267, -267, -267, -267, -267, -267, -267, -267, 636, 811,
159778
- /* 80 */ 917, 936, 1006, 1008, 1017, 1060, 1064, 1069, 1075, 1105,
159779
- /* 90 */ 1118, 1123, 1125, 1134, 1140, 1159, 1165, 1169, 1174, 1179,
159780
- /* 100 */ 1181, 1184, 1186, 1201, 1246, 1259, 1262, 1281, 1293, 1299,
159781
- /* 110 */ 1313, 1327, 1341, 1352, 1356, 1358, 1362, 1366, 1395, 1403,
159782
- /* 120 */ 1406, 1411, 1424, 1436, 1439, 1450, 1452, -267, -267, -267,
159783
- /* 130 */ -267, -267, -267, -267, -267, 224, -267, 446, -24, 275,
159784
- /* 140 */ 546, 518, 573, 560, 53, -181, -111, 485, 606, 671,
159785
- /* 150 */ 606, 671, 683, 8, 93, -267, -267, -267, -267, 155,
159786
- /* 160 */ 155, 155, 181, 242, 264, 486, 489, -218, 393, 227,
159787
- /* 170 */ 604, 347, 347, -171, 431, 650, 715, -166, 562, 609,
159788
- /* 180 */ 716, 764, 18, 823, 769, 833, 838, 957, 759, 119,
159789
- /* 190 */ 923, 226, 1014, 542, 603, 451, 949, 654, 659, 762,
159790
- /* 200 */ 964, -4, 778, 961, 712, 1082, 1100, 1111, 1026, 1117,
159791
- /* 210 */ -204, -174, -151, -8, 77, 198, 305, 327, 388, 540,
159792
- /* 220 */ 839, 968, 982, 985, 1004, 1023, 1070, 1086, 1097, 1130,
159793
- /* 230 */ 1190, 1163, 1199, 1284, 1297, 1300, 1314, 1339, 1353, 1391,
159794
- /* 240 */ 1402, 1413, 1416, 1417, 803, 1376, 1400, 1428, 1437, 1446,
159795
- /* 250 */ 1378, 1461, 1464, 1465, 1249, 1329, 1466, 1467, 1414, 1468,
159796
- /* 260 */ 305, 1469, 1470, 1471, 1472, 1482, 1483, 1389, 1392, 1438,
159797
- /* 270 */ 1426, 1427, 1432, 1434, 1378, 1438, 1438, 1440, 1474, 1499,
159798
- /* 280 */ 1399, 1421, 1430, 1456, 1441, 1442, 1444, 1415, 1473, 1431,
159799
- /* 290 */ 1445, 1476, 1449, 1478, 1418, 1479, 1477, 1485, 1493, 1494,
159800
- /* 300 */ 1496, 1458, 1475, 1480, 1459, 1490, 1484, 1518, 1448, 1451,
159801
- /* 310 */ 1537, 1538, 1463, 1481, 1541, 1486, 1487, 1491, 1519, 1514,
159802
- /* 320 */ 1521, 1523, 1525, 1552, 1556, 1520, 1492, 1498, 1522, 1497,
159803
- /* 330 */ 1539, 1528, 1542, 1532, 1571, 1573, 1500, 1504, 1582, 1584,
159804
- /* 340 */ 1563, 1586, 1588, 1589, 1597, 1567, 1579, 1585, 1590, 1568,
159805
- /* 350 */ 1583, 1587, 1593, 1591, 1598, 1599, 1600, 1602, 1606, 1513,
159806
- /* 360 */ 1524, 1548, 1549, 1611, 1574, 1576, 1594, 1603, 1604, 1607,
159807
- /* 370 */ 1605, 1608, 1642, 1527, 1529, 1609, 1610, 1601, 1615, 1575,
159808
- /* 380 */ 1650, 1578, 1619, 1623, 1625, 1624, 1674, 1685, 1686, 1691,
159809
- /* 390 */ 1692, 1693, 1612, 1613, 1617, 1675, 1668, 1673, 1676, 1677,
159810
- /* 400 */ 1680, 1666, 1669, 1678, 1681, 1683, 1687,
161143
+ /* 70 */ -267, -267, -267, -267, -267, -267, -267, -267, 811, 917,
161144
+ /* 80 */ 936, 938, 983, 1014, 1041, 1060, 1080, 1098, 1101, 1118,
161145
+ /* 90 */ 1126, 1136, 1146, 1158, 1167, 1194, 1196, 1198, 1206, 1213,
161146
+ /* 100 */ 1215, 1232, 1234, 1242, 1245, 1250, 1252, 1259, 1262, 1287,
161147
+ /* 110 */ 1289, 1299, 1302, 1304, 1308, 1314, 1321, 1329, 1334, 1336,
161148
+ /* 120 */ 1346, 1366, 1380, 1382, 1385, 1410, 1413, -267, -267, -267,
161149
+ /* 130 */ -267, -267, -267, -267, -267, 446, -267, 451, -24, 121,
161150
+ /* 140 */ 560, 518, 232, 609, 330, -181, -111, 654, 557, 671,
161151
+ /* 150 */ 557, 671, 882, -30, 93, -267, -267, -267, -267, 155,
161152
+ /* 160 */ 155, 155, 181, 242, 305, 339, 561, -218, 453, 227,
161153
+ /* 170 */ 158, 661, 661, -171, 114, 327, 653, -166, 275, 605,
161154
+ /* 180 */ 615, 337, 833, 665, 939, 957, 825, 958, 985, 501,
161155
+ /* 190 */ 986, 378, 1068, 384, 643, 393, 741, 660, 888, 762,
161156
+ /* 200 */ 822, 229, 988, 926, 504, 1025, 1027, 1034, 1026, 1079,
161157
+ /* 210 */ -204, -174, -151, 18, 130, 198, 226, 376, 391, 442,
161158
+ /* 220 */ 457, 493, 607, 715, 779, 782, 840, 865, 1072, 1099,
161159
+ /* 230 */ 1114, 1085, 1166, 1216, 1251, 1263, 1306, 1309, 1343, 1351,
161160
+ /* 240 */ 1362, 1368, 1399, 1407, 1227, 1239, 1396, 1438, 1445, 1446,
161161
+ /* 250 */ 1383, 1449, 1451, 1452, 1391, 1330, 1456, 1457, 1416, 1458,
161162
+ /* 260 */ 226, 1462, 1464, 1465, 1467, 1469, 1470, 1373, 1377, 1412,
161163
+ /* 270 */ 1401, 1418, 1419, 1423, 1383, 1412, 1412, 1422, 1453, 1475,
161164
+ /* 280 */ 1371, 1400, 1403, 1427, 1420, 1414, 1421, 1390, 1444, 1429,
161165
+ /* 290 */ 1431, 1466, 1435, 1474, 1398, 1478, 1480, 1482, 1491, 1492,
161166
+ /* 300 */ 1495, 1459, 1471, 1477, 1437, 1483, 1484, 1519, 1433, 1434,
161167
+ /* 310 */ 1533, 1534, 1443, 1455, 1538, 1476, 1485, 1486, 1527, 1525,
161168
+ /* 320 */ 1528, 1529, 1530, 1563, 1569, 1524, 1500, 1502, 1532, 1505,
161169
+ /* 330 */ 1542, 1536, 1545, 1540, 1580, 1586, 1498, 1507, 1595, 1592,
161170
+ /* 340 */ 1578, 1600, 1602, 1603, 1605, 1581, 1590, 1596, 1597, 1579,
161171
+ /* 350 */ 1593, 1599, 1604, 1598, 1601, 1606, 1607, 1609, 1610, 1501,
161172
+ /* 360 */ 1515, 1553, 1555, 1615, 1582, 1584, 1613, 1612, 1614, 1616,
161173
+ /* 370 */ 1619, 1617, 1641, 1531, 1535, 1618, 1621, 1631, 1622, 1573,
161174
+ /* 380 */ 1651, 1575, 1632, 1636, 1623, 1639, 1656, 1666, 1667, 1671,
161175
+ /* 390 */ 1672, 1673, 1564, 1565, 1566, 1662, 1674, 1675, 1677, 1678,
161176
+ /* 400 */ 1682, 1670, 1679, 1680, 1681, 1683, 1686,
159811161177
};
159812161178
static const YYACTIONTYPE yy_default[] = {
159813161179
/* 0 */ 1633, 1633, 1633, 1462, 1230, 1341, 1230, 1230, 1230, 1462,
159814161180
/* 10 */ 1462, 1462, 1230, 1371, 1371, 1515, 1263, 1230, 1230, 1230,
159815161181
/* 20 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1461, 1230, 1230,
@@ -159930,14 +161296,14 @@
159930161296
59, /* DETACH => ID */
159931161297
59, /* EACH => ID */
159932161298
59, /* FAIL => ID */
159933161299
0, /* OR => nothing */
159934161300
0, /* AND => nothing */
159935
- 0, /* IS => nothing */
159936161301
59, /* MATCH => ID */
159937161302
59, /* LIKE_KW => ID */
159938161303
0, /* BETWEEN => nothing */
161304
+ 0, /* IS => nothing */
159939161305
0, /* IN => nothing */
159940161306
0, /* ISNULL => nothing */
159941161307
0, /* NOTNULL => nothing */
159942161308
0, /* NE => nothing */
159943161309
0, /* EQ => nothing */
@@ -160120,13 +161486,13 @@
160120161486
yyStackEntry *yystackEnd; /* Last entry in the stack */
160121161487
#endif
160122161488
};
160123161489
typedef struct yyParser yyParser;
160124161490
161491
+/* #include <assert.h> */
160125161492
#ifndef NDEBUG
160126161493
/* #include <stdio.h> */
160127
-/* #include <assert.h> */
160128161494
static FILE *yyTraceFILE = 0;
160129161495
static char *yyTracePrompt = 0;
160130161496
#endif /* NDEBUG */
160131161497
160132161498
#ifndef NDEBUG
@@ -160202,14 +161568,14 @@
160202161568
/* 40 */ "DETACH",
160203161569
/* 41 */ "EACH",
160204161570
/* 42 */ "FAIL",
160205161571
/* 43 */ "OR",
160206161572
/* 44 */ "AND",
160207
- /* 45 */ "IS",
160208
- /* 46 */ "MATCH",
160209
- /* 47 */ "LIKE_KW",
160210
- /* 48 */ "BETWEEN",
161573
+ /* 45 */ "MATCH",
161574
+ /* 46 */ "LIKE_KW",
161575
+ /* 47 */ "BETWEEN",
161576
+ /* 48 */ "IS",
160211161577
/* 49 */ "IN",
160212161578
/* 50 */ "ISNULL",
160213161579
/* 51 */ "NOTNULL",
160214161580
/* 52 */ "NE",
160215161581
/* 53 */ "EQ",
@@ -163871,12 +165237,12 @@
163871165237
assert( yypParser->yytos>=yypParser->yystack );
163872165238
assert( yyact==yypParser->yytos->stateno );
163873165239
yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
163874165240
if( yyact >= YY_MIN_REDUCE ){
163875165241
unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
163876
- assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
163877165242
#ifndef NDEBUG
165243
+ assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
163878165244
if( yyTraceFILE ){
163879165245
int yysize = yyRuleInfoNRhs[yyruleno];
163880165246
if( yysize ){
163881165247
fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
163882165248
yyTracePrompt,
@@ -165119,10 +166485,11 @@
165119166485
int n = 0; /* Length of the next token token */
165120166486
int tokenType; /* type of the next token */
165121166487
int lastTokenParsed = -1; /* type of the previous token */
165122166488
sqlite3 *db = pParse->db; /* The database connection */
165123166489
int mxSqlLen; /* Max length of an SQL string */
166490
+ Parse *pParentParse = 0; /* Outer parse context, if any */
165124166491
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
165125166492
yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
165126166493
#endif
165127166494
VVA_ONLY( u8 startedWithOom = db->mallocFailed );
165128166495
@@ -165154,11 +166521,11 @@
165154166521
#endif
165155166522
assert( pParse->pNewTable==0 );
165156166523
assert( pParse->pNewTrigger==0 );
165157166524
assert( pParse->nVar==0 );
165158166525
assert( pParse->pVList==0 );
165159
- pParse->pParentParse = db->pParse;
166526
+ pParentParse = db->pParse;
165160166527
db->pParse = pParse;
165161166528
while( 1 ){
165162166529
n = sqlite3GetToken((u8*)zSql, &tokenType);
165163166530
mxSqlLen -= n;
165164166531
if( mxSqlLen<0 ){
@@ -165269,12 +166636,11 @@
165269166636
}
165270166637
if( !IN_RENAME_OBJECT ){
165271166638
sqlite3DeleteTrigger(db, pParse->pNewTrigger);
165272166639
}
165273166640
sqlite3DbFree(db, pParse->pVList);
165274
- db->pParse = pParse->pParentParse;
165275
- pParse->pParentParse = 0;
166641
+ db->pParse = pParentParse;
165276166642
assert( nErr==0 || pParse->rc!=SQLITE_OK );
165277166643
return nErr;
165278166644
}
165279166645
165280166646
@@ -166939,11 +168305,13 @@
166939168305
** if this is not the last copy of the function, do not invoke it. Multiple
166940168306
** copies of a single function are created when create_function() is called
166941168307
** with SQLITE_ANY as the encoding.
166942168308
*/
166943168309
static void functionDestroy(sqlite3 *db, FuncDef *p){
166944
- FuncDestructor *pDestructor = p->u.pDestructor;
168310
+ FuncDestructor *pDestructor;
168311
+ assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 );
168312
+ pDestructor = p->u.pDestructor;
166945168313
if( pDestructor ){
166946168314
pDestructor->nRef--;
166947168315
if( pDestructor->nRef==0 ){
166948168316
pDestructor->xDestroy(pDestructor->pUserData);
166949168317
sqlite3DbFree(db, pDestructor);
@@ -167202,10 +168570,13 @@
167202168570
** So it needs to be freed here. Todo: Why not roll the temp schema into
167203168571
** the same sqliteMalloc() as the one that allocates the database
167204168572
** structure?
167205168573
*/
167206168574
sqlite3DbFree(db, db->aDb[1].pSchema);
168575
+ if( db->xAutovacDestr ){
168576
+ db->xAutovacDestr(db->pAutovacPagesArg);
168577
+ }
167207168578
sqlite3_mutex_leave(db->mutex);
167208168579
db->eOpenState = SQLITE_STATE_CLOSED;
167209168580
sqlite3_mutex_free(db->mutex);
167210168581
assert( sqlite3LookasideUsed(db,0)==0 );
167211168582
if( db->lookaside.bMalloced ){
@@ -167256,11 +168627,11 @@
167256168627
sqlite3BtreeLeaveAll(db);
167257168628
167258168629
/* Any deferred constraint violations have now been resolved. */
167259168630
db->nDeferredCons = 0;
167260168631
db->nDeferredImmCons = 0;
167261
- db->flags &= ~(u64)SQLITE_DeferFKs;
168632
+ db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
167262168633
167263168634
/* If one has been configured, invoke the rollback-hook callback */
167264168635
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
167265168636
db->xRollbackCallback(db->pRollbackArg);
167266168637
}
@@ -167620,21 +168991,20 @@
167620168991
void (*xValue)(sqlite3_context*),
167621168992
void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
167622168993
FuncDestructor *pDestructor
167623168994
){
167624168995
FuncDef *p;
167625
- int nName;
167626168996
int extraFlags;
167627168997
167628168998
assert( sqlite3_mutex_held(db->mutex) );
167629168999
assert( xValue==0 || xSFunc==0 );
167630169000
if( zFunctionName==0 /* Must have a valid name */
167631169001
|| (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */
167632169002
|| ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */
167633169003
|| ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */
167634169004
|| (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
167635
- || (255<(nName = sqlite3Strlen30( zFunctionName)))
169005
+ || (255<sqlite3Strlen30(zFunctionName))
167636169006
){
167637169007
return SQLITE_MISUSE_BKPT;
167638169008
}
167639169009
167640169010
assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
@@ -168103,10 +169473,38 @@
168103169473
db->pPreUpdateArg = pArg;
168104169474
sqlite3_mutex_leave(db->mutex);
168105169475
return pRet;
168106169476
}
168107169477
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
169478
+
169479
+/*
169480
+** Register a function to be invoked prior to each autovacuum that
169481
+** determines the number of pages to vacuum.
169482
+*/
169483
+SQLITE_API int sqlite3_autovacuum_pages(
169484
+ sqlite3 *db, /* Attach the hook to this database */
169485
+ unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
169486
+ void *pArg, /* Argument to the function */
169487
+ void (*xDestructor)(void*) /* Destructor for pArg */
169488
+){
169489
+#ifdef SQLITE_ENABLE_API_ARMOR
169490
+ if( !sqlite3SafetyCheckOk(db) ){
169491
+ if( xDestructor ) xDestructor(pArg);
169492
+ return SQLITE_MISUSE_BKPT;
169493
+ }
169494
+#endif
169495
+ sqlite3_mutex_enter(db->mutex);
169496
+ if( db->xAutovacDestr ){
169497
+ db->xAutovacDestr(db->pAutovacPagesArg);
169498
+ }
169499
+ db->xAutovacPages = xCallback;
169500
+ db->pAutovacPagesArg = pArg;
169501
+ db->xAutovacDestr = xDestructor;
169502
+ sqlite3_mutex_leave(db->mutex);
169503
+ return SQLITE_OK;
169504
+}
169505
+
168108169506
168109169507
#ifndef SQLITE_OMIT_WAL
168110169508
/*
168111169509
** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
168112169510
** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
@@ -168626,10 +170024,12 @@
168626170024
}
168627170025
oldLimit = db->aLimit[limitId];
168628170026
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
168629170027
if( newLimit>aHardLimit[limitId] ){
168630170028
newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
170029
+ }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){
170030
+ newLimit = 1;
168631170031
}
168632170032
db->aLimit[limitId] = newLimit;
168633170033
}
168634170034
return oldLimit; /* IMP: R-53341-35419 */
168635170035
}
@@ -168897,11 +170297,11 @@
168897170297
** This routine does the core work of extracting URI parameters from a
168898170298
** database filename for the sqlite3_uri_parameter() interface.
168899170299
*/
168900170300
static const char *uriParameter(const char *zFilename, const char *zParam){
168901170301
zFilename += sqlite3Strlen30(zFilename) + 1;
168902
- while( zFilename[0] ){
170302
+ while( ALWAYS(zFilename!=0) && zFilename[0] ){
168903170303
int x = strcmp(zFilename, zParam);
168904170304
zFilename += sqlite3Strlen30(zFilename) + 1;
168905170305
if( x==0 ) return zFilename;
168906170306
zFilename += sqlite3Strlen30(zFilename) + 1;
168907170307
}
@@ -168957,14 +170357,15 @@
168957170357
**
168958170358
** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
168959170359
** dealt with in the previous code block. Besides these, the only
168960170360
** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
168961170361
** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
168962
- ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
168963
- ** off all other flags.
170362
+ ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
170363
+ ** bits. Silently mask off all other flags.
168964170364
*/
168965170365
flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
170366
+ SQLITE_OPEN_EXCLUSIVE |
168966170367
SQLITE_OPEN_MAIN_DB |
168967170368
SQLITE_OPEN_TEMP_DB |
168968170369
SQLITE_OPEN_TRANSIENT_DB |
168969170370
SQLITE_OPEN_MAIN_JOURNAL |
168970170371
SQLITE_OPEN_TEMP_JOURNAL |
@@ -168992,11 +170393,11 @@
168992170393
if( isThreadsafe==0 ){
168993170394
sqlite3MutexWarnOnContention(db->mutex);
168994170395
}
168995170396
}
168996170397
sqlite3_mutex_enter(db->mutex);
168997
- db->errMask = 0xff;
170398
+ db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
168998170399
db->nDb = 2;
168999170400
db->eOpenState = SQLITE_STATE_BUSY;
169000170401
db->aDb = db->aDbStatic;
169001170402
db->lookaside.bDisable = 1;
169002170403
db->lookaside.sz = 0;
@@ -169224,12 +170625,12 @@
169224170625
assert( db->mutex!=0 || isThreadsafe==0
169225170626
|| sqlite3GlobalConfig.bFullMutex==0 );
169226170627
sqlite3_mutex_leave(db->mutex);
169227170628
}
169228170629
rc = sqlite3_errcode(db);
169229
- assert( db!=0 || rc==SQLITE_NOMEM );
169230
- if( rc==SQLITE_NOMEM ){
170630
+ assert( db!=0 || (rc&0xff)==SQLITE_NOMEM );
170631
+ if( (rc&0xff)==SQLITE_NOMEM ){
169231170632
sqlite3_close(db);
169232170633
db = 0;
169233170634
}else if( rc!=SQLITE_OK ){
169234170635
db->eOpenState = SQLITE_STATE_SICK;
169235170636
}
@@ -169240,11 +170641,11 @@
169240170641
void *pArg = sqlite3GlobalConfig.pSqllogArg;
169241170642
sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
169242170643
}
169243170644
#endif
169244170645
sqlite3_free_filename(zOpen);
169245
- return rc & 0xff;
170646
+ return rc;
169246170647
}
169247170648
169248170649
169249170650
/*
169250170651
** Open a new database handle.
@@ -170028,16 +171429,20 @@
170028171429
** the schema to be reparsed the next time it is needed. This has the
170029171430
** effect of erasing all imposter tables.
170030171431
*/
170031171432
case SQLITE_TESTCTRL_IMPOSTER: {
170032171433
sqlite3 *db = va_arg(ap, sqlite3*);
171434
+ int iDb;
170033171435
sqlite3_mutex_enter(db->mutex);
170034
- db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
170035
- db->init.busy = db->init.imposterTable = va_arg(ap,int);
170036
- db->init.newTnum = va_arg(ap,int);
170037
- if( db->init.busy==0 && db->init.newTnum>0 ){
170038
- sqlite3ResetAllSchemasOfConnection(db);
171436
+ iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
171437
+ if( iDb>=0 ){
171438
+ db->init.iDb = iDb;
171439
+ db->init.busy = db->init.imposterTable = va_arg(ap,int);
171440
+ db->init.newTnum = va_arg(ap,int);
171441
+ if( db->init.busy==0 && db->init.newTnum>0 ){
171442
+ sqlite3ResetAllSchemasOfConnection(db);
171443
+ }
170039171444
}
170040171445
sqlite3_mutex_leave(db->mutex);
170041171446
break;
170042171447
}
170043171448
@@ -170108,10 +171513,30 @@
170108171513
case 2: *ptr = sqlite3WhereTrace; break;
170109171514
case 3: sqlite3WhereTrace = *ptr; break;
170110171515
}
170111171516
break;
170112171517
}
171518
+
171519
+ /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
171520
+ ** double fIn, // Input value
171521
+ ** int *pLogEst, // sqlite3LogEstFromDouble(fIn)
171522
+ ** u64 *pInt, // sqlite3LogEstToInt(*pLogEst)
171523
+ ** int *pLogEst2 // sqlite3LogEst(*pInt)
171524
+ ** );
171525
+ **
171526
+ ** Test access for the LogEst conversion routines.
171527
+ */
171528
+ case SQLITE_TESTCTRL_LOGEST: {
171529
+ double rIn = va_arg(ap, double);
171530
+ LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
171531
+ u64 iInt = sqlite3LogEstToInt(rLogEst);
171532
+ va_arg(ap, int*)[0] = rLogEst;
171533
+ va_arg(ap, u64*)[0] = iInt;
171534
+ va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
171535
+ break;
171536
+ }
171537
+
170113171538
170114171539
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
170115171540
/* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue)
170116171541
**
170117171542
** If "id" is an integer between 1 and SQLITE_NTUNE then set the value
@@ -170245,11 +171670,11 @@
170245171670
*/
170246171671
SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){
170247171672
if( zFilename==0 || N<0 ) return 0;
170248171673
zFilename = databaseName(zFilename);
170249171674
zFilename += sqlite3Strlen30(zFilename) + 1;
170250
- while( zFilename[0] && (N--)>0 ){
171675
+ while( ALWAYS(zFilename) && zFilename[0] && (N--)>0 ){
170251171676
zFilename += sqlite3Strlen30(zFilename) + 1;
170252171677
zFilename += sqlite3Strlen30(zFilename) + 1;
170253171678
}
170254171679
return zFilename[0] ? zFilename : 0;
170255171680
}
@@ -170295,11 +171720,11 @@
170295171720
}
170296171721
SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){
170297171722
if( zFilename==0 ) return 0;
170298171723
zFilename = databaseName(zFilename);
170299171724
zFilename += sqlite3Strlen30(zFilename) + 1;
170300
- while( zFilename[0] ){
171725
+ while( ALWAYS(zFilename) && zFilename[0] ){
170301171726
zFilename += sqlite3Strlen30(zFilename) + 1;
170302171727
zFilename += sqlite3Strlen30(zFilename) + 1;
170303171728
}
170304171729
return zFilename + 1;
170305171730
}
@@ -171599,21 +173024,22 @@
171599173024
#ifndef SQLITE_AMALGAMATION
171600173025
/*
171601173026
** Macros indicating that conditional expressions are always true or
171602173027
** false.
171603173028
*/
171604
-#ifdef SQLITE_COVERAGE_TEST
171605
-# define ALWAYS(x) (1)
171606
-# define NEVER(X) (0)
171607
-#elif defined(SQLITE_DEBUG)
171608
-# define ALWAYS(x) sqlite3Fts3Always((x)!=0)
171609
-# define NEVER(x) sqlite3Fts3Never((x)!=0)
171610
-SQLITE_PRIVATE int sqlite3Fts3Always(int b);
171611
-SQLITE_PRIVATE int sqlite3Fts3Never(int b);
173029
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
173030
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
173031
+#endif
173032
+#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
173033
+# define ALWAYS(X) (1)
173034
+# define NEVER(X) (0)
173035
+#elif !defined(NDEBUG)
173036
+# define ALWAYS(X) ((X)?1:(assert(0),0))
173037
+# define NEVER(X) ((X)?(assert(0),1):0)
171612173038
#else
171613
-# define ALWAYS(x) (x)
171614
-# define NEVER(x) (x)
173039
+# define ALWAYS(X) (X)
173040
+# define NEVER(X) (X)
171615173041
#endif
171616173042
171617173043
/*
171618173044
** Internal types used by SQLite.
171619173045
*/
@@ -172068,10 +173494,11 @@
172068173494
SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
172069173495
#ifdef SQLITE_TEST
172070173496
SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
172071173497
SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
172072173498
#endif
173499
+SQLITE_PRIVATE void *sqlite3Fts3MallocZero(i64 nByte);
172073173500
172074173501
SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
172075173502
sqlite3_tokenizer_cursor **
172076173503
);
172077173504
@@ -172125,17 +173552,10 @@
172125173552
static int fts3EvalNext(Fts3Cursor *pCsr);
172126173553
static int fts3EvalStart(Fts3Cursor *pCsr);
172127173554
static int fts3TermSegReaderCursor(
172128173555
Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
172129173556
172130
-#ifndef SQLITE_AMALGAMATION
172131
-# if defined(SQLITE_DEBUG)
172132
-SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; }
172133
-SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; }
172134
-# endif
172135
-#endif
172136
-
172137173557
/*
172138173558
** This variable is set to false when running tests for which the on disk
172139173559
** structures should not be corrupt. Otherwise, true. If it is false, extra
172140173560
** assert() conditions in the fts3 code are activated - conditions that are
172141173561
** only true if it is guaranteed that the fts3 database is not corrupt.
@@ -177156,12 +178576,12 @@
177156178576
case FTSQUERY_OR: {
177157178577
Fts3Expr *pLeft = pExpr->pLeft;
177158178578
Fts3Expr *pRight = pExpr->pRight;
177159178579
sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
177160178580
177161
- assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
177162
- assert( pRight->bStart || pLeft->iDocid==pRight->iDocid );
178581
+ assert_fts3_nc( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
178582
+ assert_fts3_nc( pRight->bStart || pLeft->iDocid==pRight->iDocid );
177163178583
177164178584
if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
177165178585
fts3EvalNextRow(pCsr, pLeft, pRc);
177166178586
}else if( pLeft->bEof || iCmp>0 ){
177167178587
fts3EvalNextRow(pCsr, pRight, pRc);
@@ -177795,10 +179215,13 @@
177795179215
while( rc==SQLITE_OK && !pNear->bEof ){
177796179216
fts3EvalNextRow(pCsr, pNear, &rc);
177797179217
if( bEofSave==0 && pNear->iDocid==iDocid ) break;
177798179218
}
177799179219
assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
179220
+ if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
179221
+ rc = FTS_CORRUPT_VTAB;
179222
+ }
177800179223
}
177801179224
if( bTreeEof ){
177802179225
while( rc==SQLITE_OK && !pNear->bEof ){
177803179226
fts3EvalNextRow(pCsr, pNear, &rc);
177804179227
}
@@ -178217,10 +179640,11 @@
178217179640
}
178218179641
178219179642
if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM;
178220179643
memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat);
178221179644
iCol = 0;
179645
+ rc = SQLITE_OK;
178222179646
178223179647
while( i<nDoclist ){
178224179648
sqlite3_int64 v = 0;
178225179649
178226179650
i += sqlite3Fts3GetVarint(&aDoclist[i], &v);
@@ -178260,19 +179684,22 @@
178260179684
break;
178261179685
178262179686
/* State 3. The integer just read is a column number. */
178263179687
default: assert( eState==3 );
178264179688
iCol = (int)v;
179689
+ if( iCol<1 ){
179690
+ rc = SQLITE_CORRUPT_VTAB;
179691
+ break;
179692
+ }
178265179693
if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM;
178266179694
pCsr->aStat[iCol+1].nDoc++;
178267179695
eState = 2;
178268179696
break;
178269179697
}
178270179698
}
178271179699
178272179700
pCsr->iCol = 0;
178273
- rc = SQLITE_OK;
178274179701
}else{
178275179702
pCsr->isEof = 1;
178276179703
}
178277179704
return rc;
178278179705
}
@@ -178597,11 +180024,11 @@
178597180024
/*
178598180025
** Allocate nByte bytes of memory using sqlite3_malloc(). If successful,
178599180026
** zero the memory before returning a pointer to it. If unsuccessful,
178600180027
** return NULL.
178601180028
*/
178602
-static void *fts3MallocZero(sqlite3_int64 nByte){
180029
+SQLITE_PRIVATE void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){
178603180030
void *pRet = sqlite3_malloc64(nByte);
178604180031
if( pRet ) memset(pRet, 0, nByte);
178605180032
return pRet;
178606180033
}
178607180034
@@ -178678,11 +180105,11 @@
178678180105
sqlite3_int64 nByte; /* total space to allocate */
178679180106
178680180107
rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
178681180108
if( rc==SQLITE_OK ){
178682180109
nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
178683
- pRet = (Fts3Expr *)fts3MallocZero(nByte);
180110
+ pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
178684180111
if( !pRet ){
178685180112
rc = SQLITE_NOMEM;
178686180113
}else{
178687180114
pRet->eType = FTSQUERY_PHRASE;
178688180115
pRet->pPhrase = (Fts3Phrase *)&pRet[1];
@@ -178933,11 +180360,11 @@
178933180360
*/
178934180361
cNext = zInput[nKey];
178935180362
if( fts3isspace(cNext)
178936180363
|| cNext=='"' || cNext=='(' || cNext==')' || cNext==0
178937180364
){
178938
- pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr));
180365
+ pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr));
178939180366
if( !pRet ){
178940180367
return SQLITE_NOMEM;
178941180368
}
178942180369
pRet->eType = pKey->eType;
178943180370
pRet->nNear = nNear;
@@ -179112,11 +180539,11 @@
179112180539
179113180540
if( !sqlite3_fts3_enable_parentheses
179114180541
&& p->eType==FTSQUERY_PHRASE && pParse->isNot
179115180542
){
179116180543
/* Create an implicit NOT operator. */
179117
- Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
180544
+ Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
179118180545
if( !pNot ){
179119180546
sqlite3Fts3ExprFree(p);
179120180547
rc = SQLITE_NOMEM;
179121180548
goto exprparse_out;
179122180549
}
@@ -179146,11 +180573,11 @@
179146180573
179147180574
if( isPhrase && !isRequirePhrase ){
179148180575
/* Insert an implicit AND operator. */
179149180576
Fts3Expr *pAnd;
179150180577
assert( pRet && pPrev );
179151
- pAnd = fts3MallocZero(sizeof(Fts3Expr));
180578
+ pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
179152180579
if( !pAnd ){
179153180580
sqlite3Fts3ExprFree(p);
179154180581
rc = SQLITE_NOMEM;
179155180582
goto exprparse_out;
179156180583
}
@@ -183376,12 +184803,22 @@
183376184803
pReader->aNode = 0;
183377184804
if( pElem ){
183378184805
char *aCopy;
183379184806
PendingList *pList = (PendingList *)fts3HashData(pElem);
183380184807
int nCopy = pList->nData+1;
183381
- pReader->zTerm = (char *)fts3HashKey(pElem);
183382
- pReader->nTerm = fts3HashKeysize(pElem);
184808
+
184809
+ int nTerm = fts3HashKeysize(pElem);
184810
+ if( (nTerm+1)>pReader->nTermAlloc ){
184811
+ sqlite3_free(pReader->zTerm);
184812
+ pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2);
184813
+ if( !pReader->zTerm ) return SQLITE_NOMEM;
184814
+ pReader->nTermAlloc = (nTerm+1)*2;
184815
+ }
184816
+ memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm);
184817
+ pReader->zTerm[nTerm] = '\0';
184818
+ pReader->nTerm = nTerm;
184819
+
183383184820
aCopy = (char*)sqlite3_malloc(nCopy);
183384184821
if( !aCopy ) return SQLITE_NOMEM;
183385184822
memcpy(aCopy, pList->aData, nCopy);
183386184823
pReader->nNode = pReader->nDoclist = nCopy;
183387184824
pReader->aNode = pReader->aDoclist = aCopy;
@@ -183630,13 +185067,11 @@
183630185067
** Free all allocations associated with the iterator passed as the
183631185068
** second argument.
183632185069
*/
183633185070
SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
183634185071
if( pReader ){
183635
- if( !fts3SegReaderIsPending(pReader) ){
183636
- sqlite3_free(pReader->zTerm);
183637
- }
185072
+ sqlite3_free(pReader->zTerm);
183638185073
if( !fts3SegReaderIsRootOnly(pReader) ){
183639185074
sqlite3_free(pReader->aNode);
183640185075
}
183641185076
sqlite3_blob_close(pReader->pBlob);
183642185077
}
@@ -185824,11 +187259,11 @@
185824187259
185825187260
if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
185826187261
return FTS_CORRUPT_VTAB;
185827187262
}
185828187263
blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
185829
- if( rc==SQLITE_OK ){
187264
+ if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){
185830187265
memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
185831187266
p->term.n = nPrefix+nSuffix;
185832187267
p->iOff += nSuffix;
185833187268
if( p->iChild==0 ){
185834187269
p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
@@ -186218,11 +187653,15 @@
186218187653
const char *zRhs, int nRhs /* RHS of comparison */
186219187654
){
186220187655
int nCmp = MIN(nLhs, nRhs);
186221187656
int res;
186222187657
186223
- res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
187658
+ if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){
187659
+ res = memcmp(zLhs, zRhs, nCmp);
187660
+ }else{
187661
+ res = 0;
187662
+ }
186224187663
if( res==0 ) res = nLhs - nRhs;
186225187664
186226187665
return res;
186227187666
}
186228187667
@@ -186862,11 +188301,11 @@
186862188301
const char *aHint = sqlite3_column_blob(pSelect, 0);
186863188302
int nHint = sqlite3_column_bytes(pSelect, 0);
186864188303
if( aHint ){
186865188304
blobGrowBuffer(pHint, nHint, &rc);
186866188305
if( rc==SQLITE_OK ){
186867
- memcpy(pHint->a, aHint, nHint);
188306
+ if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint);
186868188307
pHint->n = nHint;
186869188308
}
186870188309
}
186871188310
}
186872188311
rc2 = sqlite3_reset(pSelect);
@@ -187979,13 +189418,12 @@
187979189418
MatchinfoBuffer *pRet;
187980189419
sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
187981189420
+ sizeof(MatchinfoBuffer);
187982189421
sqlite3_int64 nStr = strlen(zMatchinfo);
187983189422
187984
- pRet = sqlite3_malloc64(nByte + nStr+1);
189423
+ pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
187985189424
if( pRet ){
187986
- memset(pRet, 0, nByte);
187987189425
pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
187988189426
pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
187989189427
+ sizeof(u32)*((int)nElem+1);
187990189428
pRet->nElem = (int)nElem;
187991189429
pRet->zMatchinfo = ((char*)pRet) + nByte;
@@ -188385,15 +189823,14 @@
188385189823
188386189824
/* Now that it is known how many phrases there are, allocate and zero
188387189825
** the required space using malloc().
188388189826
*/
188389189827
nByte = sizeof(SnippetPhrase) * nList;
188390
- sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
189828
+ sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte);
188391189829
if( !sIter.aPhrase ){
188392189830
return SQLITE_NOMEM;
188393189831
}
188394
- memset(sIter.aPhrase, 0, nByte);
188395189832
188396189833
/* Initialize the contents of the SnippetIter object. Then iterate through
188397189834
** the set of phrases in the expression to populate the aPhrase[] array.
188398189835
*/
188399189836
sIter.pCsr = pCsr;
@@ -188953,14 +190390,16 @@
188953190390
** Advance the iterator passed as an argument to the next position. Return
188954190391
** 1 if the iterator is at EOF or if it now points to the start of the
188955190392
** position list for the next column.
188956190393
*/
188957190394
static int fts3LcsIteratorAdvance(LcsIterator *pIter){
188958
- char *pRead = pIter->pRead;
190395
+ char *pRead;
188959190396
sqlite3_int64 iRead;
188960190397
int rc = 0;
188961190398
190399
+ if( NEVER(pIter==0) ) return 1;
190400
+ pRead = pIter->pRead;
188962190401
pRead += sqlite3Fts3GetVarint(pRead, &iRead);
188963190402
if( iRead==0 || iRead==1 ){
188964190403
pRead = 0;
188965190404
rc = 1;
188966190405
}else{
@@ -188990,13 +190429,12 @@
188990190429
int rc = SQLITE_OK;
188991190430
188992190431
/* Allocate and populate the array of LcsIterator objects. The array
188993190432
** contains one element for each matchable phrase in the query.
188994190433
**/
188995
- aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
190434
+ aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase);
188996190435
if( !aIter ) return SQLITE_NOMEM;
188997
- memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
188998190436
(void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
188999190437
189000190438
for(i=0; i<pInfo->nPhrase; i++){
189001190439
LcsIterator *pIter = &aIter[i];
189002190440
nToken -= pIter->pExpr->pPhrase->nToken;
@@ -189453,11 +190891,11 @@
189453190891
/* Count the number of terms in the query */
189454190892
rc = fts3ExprLoadDoclists(pCsr, 0, &nToken);
189455190893
if( rc!=SQLITE_OK ) goto offsets_out;
189456190894
189457190895
/* Allocate the array of TermOffset iterators. */
189458
- sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken);
190896
+ sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken);
189459190897
if( 0==sCtx.aTerm ){
189460190898
rc = SQLITE_NOMEM;
189461190899
goto offsets_out;
189462190900
}
189463190901
sCtx.iDocid = pCsr->iPrevId;
@@ -189474,17 +190912,17 @@
189474190912
int iEnd = 0;
189475190913
int iCurrent = 0;
189476190914
const char *zDoc;
189477190915
int nDoc;
189478190916
189479
- /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
189480
- ** no way that this operation can fail, so the return code from
189481
- ** fts3ExprIterate() can be discarded.
190917
+ /* Initialize the contents of sCtx.aTerm[] for column iCol. This
190918
+ ** operation may fail if the database contains corrupt records.
189482190919
*/
189483190920
sCtx.iCol = iCol;
189484190921
sCtx.iTerm = 0;
189485
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190922
+ rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190923
+ if( rc!=SQLITE_OK ) goto offsets_out;
189486190924
189487190925
/* Retreive the text stored in column iCol. If an SQL NULL is stored
189488190926
** in column iCol, jump immediately to the next iteration of the loop.
189489190927
** If an OOM occurs while retrieving the data (this can happen if SQLite
189490190928
** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -190478,11 +191916,38 @@
190478191916
** but the definitions need to be repeated for separate compilation. */
190479191917
typedef sqlite3_uint64 u64;
190480191918
typedef unsigned int u32;
190481191919
typedef unsigned short int u16;
190482191920
typedef unsigned char u8;
191921
+# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
191922
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
191923
+# endif
191924
+# if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
191925
+# define ALWAYS(X) (1)
191926
+# define NEVER(X) (0)
191927
+# elif !defined(NDEBUG)
191928
+# define ALWAYS(X) ((X)?1:(assert(0),0))
191929
+# define NEVER(X) ((X)?(assert(0),1):0)
191930
+# else
191931
+# define ALWAYS(X) (X)
191932
+# define NEVER(X) (X)
191933
+# endif
191934
+# define testcase(X)
190483191935
#endif
191936
+#if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
191937
+# define VVA(X)
191938
+#else
191939
+# define VVA(X) X
191940
+#endif
191941
+
191942
+/*
191943
+** Some of the testcase() macros in this file are problematic for gcov
191944
+** in that they generate false-miss errors randomly. This is a gcov problem,
191945
+** not a problem in this case. But to work around it, we disable the
191946
+** problematic test cases for production builds.
191947
+*/
191948
+#define json_testcase(X)
190484191949
190485191950
/* Objects */
190486191951
typedef struct JsonString JsonString;
190487191952
typedef struct JsonNode JsonNode;
190488191953
typedef struct JsonParse JsonParse;
@@ -190536,17 +192001,18 @@
190536192001
/* A single node of parsed JSON
190537192002
*/
190538192003
struct JsonNode {
190539192004
u8 eType; /* One of the JSON_ type values */
190540192005
u8 jnFlags; /* JNODE flags */
192006
+ u8 eU; /* Which union element to use */
190541192007
u32 n; /* Bytes of content, or number of sub-nodes */
190542192008
union {
190543
- const char *zJContent; /* Content for INT, REAL, and STRING */
190544
- u32 iAppend; /* More terms for ARRAY and OBJECT */
190545
- u32 iKey; /* Key for ARRAY objects in json_tree() */
190546
- u32 iReplace; /* Replacement content for JNODE_REPLACE */
190547
- JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */
192009
+ const char *zJContent; /* 1: Content for INT, REAL, and STRING */
192010
+ u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
192011
+ u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
192012
+ u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */
192013
+ JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */
190548192014
} u;
190549192015
};
190550192016
190551192017
/* A completely parsed JSON string
190552192018
*/
@@ -190820,15 +192286,18 @@
190820192286
static void jsonRenderNode(
190821192287
JsonNode *pNode, /* The node to render */
190822192288
JsonString *pOut, /* Write JSON here */
190823192289
sqlite3_value **aReplace /* Replacement values */
190824192290
){
192291
+ assert( pNode!=0 );
190825192292
if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
190826
- if( pNode->jnFlags & JNODE_REPLACE ){
192293
+ if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){
192294
+ assert( pNode->eU==4 );
190827192295
jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
190828192296
return;
190829192297
}
192298
+ assert( pNode->eU==5 );
190830192299
pNode = pNode->u.pPatch;
190831192300
}
190832192301
switch( pNode->eType ){
190833192302
default: {
190834192303
assert( pNode->eType==JSON_NULL );
@@ -190843,17 +192312,19 @@
190843192312
jsonAppendRaw(pOut, "false", 5);
190844192313
break;
190845192314
}
190846192315
case JSON_STRING: {
190847192316
if( pNode->jnFlags & JNODE_RAW ){
192317
+ assert( pNode->eU==1 );
190848192318
jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
190849192319
break;
190850192320
}
190851192321
/* no break */ deliberate_fall_through
190852192322
}
190853192323
case JSON_REAL:
190854192324
case JSON_INT: {
192325
+ assert( pNode->eU==1 );
190855192326
jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
190856192327
break;
190857192328
}
190858192329
case JSON_ARRAY: {
190859192330
u32 j = 1;
@@ -190865,10 +192336,11 @@
190865192336
jsonRenderNode(&pNode[j], pOut, aReplace);
190866192337
}
190867192338
j += jsonNodeSize(&pNode[j]);
190868192339
}
190869192340
if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
192341
+ assert( pNode->eU==2 );
190870192342
pNode = &pNode[pNode->u.iAppend];
190871192343
j = 1;
190872192344
}
190873192345
jsonAppendChar(pOut, ']');
190874192346
break;
@@ -190885,10 +192357,11 @@
190885192357
jsonRenderNode(&pNode[j+1], pOut, aReplace);
190886192358
}
190887192359
j += 1 + jsonNodeSize(&pNode[j+1]);
190888192360
}
190889192361
if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
192362
+ assert( pNode->eU==2 );
190890192363
pNode = &pNode[pNode->u.iAppend];
190891192364
j = 1;
190892192365
}
190893192366
jsonAppendChar(pOut, '}');
190894192367
break;
@@ -190964,11 +192437,13 @@
190964192437
sqlite3_result_int(pCtx, 0);
190965192438
break;
190966192439
}
190967192440
case JSON_INT: {
190968192441
sqlite3_int64 i = 0;
190969
- const char *z = pNode->u.zJContent;
192442
+ const char *z;
192443
+ assert( pNode->eU==1 );
192444
+ z = pNode->u.zJContent;
190970192445
if( z[0]=='-' ){ z++; }
190971192446
while( z[0]>='0' && z[0]<='9' ){
190972192447
unsigned v = *(z++) - '0';
190973192448
if( i>=LARGEST_INT64/10 ){
190974192449
if( i>LARGEST_INT64/10 ) goto int_as_real;
@@ -190992,13 +192467,16 @@
190992192467
int_as_real: ; /* no break */ deliberate_fall_through
190993192468
}
190994192469
case JSON_REAL: {
190995192470
double r;
190996192471
#ifdef SQLITE_AMALGAMATION
190997
- const char *z = pNode->u.zJContent;
192472
+ const char *z;
192473
+ assert( pNode->eU==1 );
192474
+ z = pNode->u.zJContent;
190998192475
sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
190999192476
#else
192477
+ assert( pNode->eU==1 );
191000192478
r = strtod(pNode->u.zJContent, 0);
191001192479
#endif
191002192480
sqlite3_result_double(pCtx, r);
191003192481
break;
191004192482
}
@@ -191005,26 +192483,30 @@
191005192483
case JSON_STRING: {
191006192484
#if 0 /* Never happens because JNODE_RAW is only set by json_set(),
191007192485
** json_insert() and json_replace() and those routines do not
191008192486
** call jsonReturn() */
191009192487
if( pNode->jnFlags & JNODE_RAW ){
192488
+ assert( pNode->eU==1 );
191010192489
sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
191011192490
SQLITE_TRANSIENT);
191012192491
}else
191013192492
#endif
191014192493
assert( (pNode->jnFlags & JNODE_RAW)==0 );
191015192494
if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
191016192495
/* JSON formatted without any backslash-escapes */
192496
+ assert( pNode->eU==1 );
191017192497
sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
191018192498
SQLITE_TRANSIENT);
191019192499
}else{
191020192500
/* Translate JSON formatted string into raw text */
191021192501
u32 i;
191022192502
u32 n = pNode->n;
191023
- const char *z = pNode->u.zJContent;
192503
+ const char *z;
191024192504
char *zOut;
191025192505
u32 j;
192506
+ assert( pNode->eU==1 );
192507
+ z = pNode->u.zJContent;
191026192508
zOut = sqlite3_malloc( n+1 );
191027192509
if( zOut==0 ){
191028192510
sqlite3_result_error_nomem(pCtx);
191029192511
break;
191030192512
}
@@ -191141,16 +192623,17 @@
191141192623
u32 eType, /* Node type */
191142192624
u32 n, /* Content size or sub-node count */
191143192625
const char *zContent /* Content */
191144192626
){
191145192627
JsonNode *p;
191146
- if( pParse->nNode>=pParse->nAlloc ){
192628
+ if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
191147192629
return jsonParseAddNodeExpand(pParse, eType, n, zContent);
191148192630
}
191149192631
p = &pParse->aNode[pParse->nNode];
191150192632
p->eType = (u8)eType;
191151192633
p->jnFlags = 0;
192634
+ VVA( p->eU = zContent ? 1 : 0 );
191152192635
p->n = n;
191153192636
p->u.zJContent = zContent;
191154192637
return pParse->nNode++;
191155192638
}
191156192639
@@ -191214,10 +192697,11 @@
191214192697
return j+1;
191215192698
}else if( c=='[' ){
191216192699
/* Parse array */
191217192700
iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
191218192701
if( iThis<0 ) return -1;
192702
+ memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
191219192703
for(j=i+1;;j++){
191220192704
while( safe_isspace(z[j]) ){ j++; }
191221192705
if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
191222192706
x = jsonParseValue(pParse, j);
191223192707
pParse->iDepth--;
@@ -191478,10 +192962,11 @@
191478192962
/*
191479192963
** Compare the OBJECT label at pNode against zKey,nKey. Return true on
191480192964
** a match.
191481192965
*/
191482192966
static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
192967
+ assert( pNode->eU==1 );
191483192968
if( pNode->jnFlags & JNODE_RAW ){
191484192969
if( pNode->n!=nKey ) return 0;
191485192970
return strncmp(pNode->u.zJContent, zKey, nKey)==0;
191486192971
}else{
191487192972
if( pNode->n!=nKey+2 ) return 0;
@@ -191543,10 +193028,11 @@
191543193028
}
191544193029
j++;
191545193030
j += jsonNodeSize(&pRoot[j]);
191546193031
}
191547193032
if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
193033
+ assert( pRoot->eU==2 );
191548193034
iRoot += pRoot->u.iAppend;
191549193035
pRoot = &pParse->aNode[iRoot];
191550193036
j = 1;
191551193037
}
191552193038
if( pApnd ){
@@ -191557,12 +193043,14 @@
191557193043
zPath += i;
191558193044
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
191559193045
if( pParse->oom ) return 0;
191560193046
if( pNode ){
191561193047
pRoot = &pParse->aNode[iRoot];
193048
+ assert( pRoot->eU==0 );
191562193049
pRoot->u.iAppend = iStart - iRoot;
191563193050
pRoot->jnFlags |= JNODE_APPEND;
193051
+ VVA( pRoot->eU = 2 );
191564193052
pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
191565193053
}
191566193054
return pNode;
191567193055
}
191568193056
}else if( zPath[0]=='[' ){
@@ -191581,10 +193069,11 @@
191581193069
while( j<=pBase->n ){
191582193070
if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
191583193071
j += jsonNodeSize(&pBase[j]);
191584193072
}
191585193073
if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
193074
+ assert( pBase->eU==2 );
191586193075
iBase += pBase->u.iAppend;
191587193076
pBase = &pParse->aNode[iBase];
191588193077
j = 1;
191589193078
}
191590193079
j = 2;
@@ -191614,10 +193103,11 @@
191614193103
while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
191615193104
if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
191616193105
j += jsonNodeSize(&pRoot[j]);
191617193106
}
191618193107
if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
193108
+ assert( pRoot->eU==2 );
191619193109
iRoot += pRoot->u.iAppend;
191620193110
pRoot = &pParse->aNode[iRoot];
191621193111
j = 1;
191622193112
}
191623193113
if( j<=pRoot->n ){
@@ -191629,12 +193119,14 @@
191629193119
iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
191630193120
pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
191631193121
if( pParse->oom ) return 0;
191632193122
if( pNode ){
191633193123
pRoot = &pParse->aNode[iRoot];
193124
+ assert( pRoot->eU==0 );
191634193125
pRoot->u.iAppend = iStart - iRoot;
191635193126
pRoot->jnFlags |= JNODE_APPEND;
193127
+ VVA( pRoot->eU = 2 );
191636193128
}
191637193129
return pNode;
191638193130
}
191639193131
}else{
191640193132
*pzErr = zPath;
@@ -191784,13 +193276,17 @@
191784193276
}else{
191785193277
zType = jsonType[x.aNode[i].eType];
191786193278
}
191787193279
jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
191788193280
i, zType, x.aNode[i].n, x.aUp[i]);
193281
+ assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
191789193282
if( x.aNode[i].u.zJContent!=0 ){
193283
+ assert( x.aNode[i].eU==1 );
191790193284
jsonAppendRaw(&s, " ", 1);
191791193285
jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
193286
+ }else{
193287
+ assert( x.aNode[i].eU==0 );
191792193288
}
191793193289
jsonAppendRaw(&s, "\n", 1);
191794193290
}
191795193291
jsonParseReset(&x);
191796193292
jsonResult(&s);
@@ -191969,10 +193465,11 @@
191969193465
for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
191970193466
u32 nKey;
191971193467
const char *zKey;
191972193468
assert( pPatch[i].eType==JSON_STRING );
191973193469
assert( pPatch[i].jnFlags & JNODE_LABEL );
193470
+ assert( pPatch[i].eU==1 );
191974193471
nKey = pPatch[i].n;
191975193472
zKey = pPatch[i].u.zJContent;
191976193473
assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
191977193474
for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
191978193475
assert( pTarget[j].eType==JSON_STRING );
@@ -191985,10 +193482,16 @@
191985193482
}else{
191986193483
JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
191987193484
if( pNew==0 ) return 0;
191988193485
pTarget = &pParse->aNode[iTarget];
191989193486
if( pNew!=&pTarget[j+1] ){
193487
+ assert( pTarget[j+1].eU==0
193488
+ || pTarget[j+1].eU==1
193489
+ || pTarget[j+1].eU==2 );
193490
+ testcase( pTarget[j+1].eU==1 );
193491
+ testcase( pTarget[j+1].eU==2 );
193492
+ VVA( pTarget[j+1].eU = 5 );
191990193493
pTarget[j+1].u.pPatch = pNew;
191991193494
pTarget[j+1].jnFlags |= JNODE_PATCH;
191992193495
}
191993193496
}
191994193497
break;
@@ -192000,13 +193503,18 @@
192000193503
jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
192001193504
iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
192002193505
if( pParse->oom ) return 0;
192003193506
jsonRemoveAllNulls(pPatch);
192004193507
pTarget = &pParse->aNode[iTarget];
193508
+ assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 );
193509
+ testcase( pParse->aNode[iRoot].eU==2 );
192005193510
pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
193511
+ VVA( pParse->aNode[iRoot].eU = 2 );
192006193512
pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
192007193513
iRoot = iStart;
193514
+ assert( pParse->aNode[iPatch].eU==0 );
193515
+ VVA( pParse->aNode[iPatch].eU = 5 );
192008193516
pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
192009193517
pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
192010193518
}
192011193519
}
192012193520
return pTarget;
@@ -192144,15 +193652,19 @@
192144193652
for(i=1; i<(u32)argc; i+=2){
192145193653
zPath = (const char*)sqlite3_value_text(argv[i]);
192146193654
pNode = jsonLookup(&x, zPath, 0, ctx);
192147193655
if( x.nErr ) goto replace_err;
192148193656
if( pNode ){
193657
+ assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 );
193658
+ json_testcase( pNode->eU!=0 && pNode->eU!=1 );
192149193659
pNode->jnFlags |= (u8)JNODE_REPLACE;
193660
+ VVA( pNode->eU = 4 );
192150193661
pNode->u.iReplace = i + 1;
192151193662
}
192152193663
}
192153193664
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
193665
+ assert( x.aNode[0].eU==4 );
192154193666
sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
192155193667
}else{
192156193668
jsonReturnJson(x.aNode, ctx, argv);
192157193669
}
192158193670
replace_err:
@@ -192198,15 +193710,19 @@
192198193710
sqlite3_result_error_nomem(ctx);
192199193711
goto jsonSetDone;
192200193712
}else if( x.nErr ){
192201193713
goto jsonSetDone;
192202193714
}else if( pNode && (bApnd || bIsSet) ){
193715
+ json_testcase( pNode->eU!=0 && pNode->eU!=1 && pNode->eU!=4 );
193716
+ assert( pNode->eU!=3 || pNode->eU!=5 );
193717
+ VVA( pNode->eU = 4 );
192203193718
pNode->jnFlags |= (u8)JNODE_REPLACE;
192204193719
pNode->u.iReplace = i + 1;
192205193720
}
192206193721
}
192207193722
if( x.aNode[0].jnFlags & JNODE_REPLACE ){
193723
+ assert( x.aNode[0].eU==4 );
192208193724
sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
192209193725
}else{
192210193726
jsonReturnJson(x.aNode, ctx, argv);
192211193727
}
192212193728
jsonSetDone:
@@ -192553,10 +194069,13 @@
192553194069
if( p->i<p->iEnd ){
192554194070
u32 iUp = p->sParse.aUp[p->i];
192555194071
JsonNode *pUp = &p->sParse.aNode[iUp];
192556194072
p->eType = pUp->eType;
192557194073
if( pUp->eType==JSON_ARRAY ){
194074
+ assert( pUp->eU==0 || pUp->eU==3 );
194075
+ json_testcase( pUp->eU==3 );
194076
+ VVA( pUp->eU = 3 );
192558194077
if( iUp==p->i-1 ){
192559194078
pUp->u.iKey = 0;
192560194079
}else{
192561194080
pUp->u.iKey++;
192562194081
}
@@ -192599,16 +194118,19 @@
192599194118
iUp = p->sParse.aUp[i];
192600194119
jsonEachComputePath(p, pStr, iUp);
192601194120
pNode = &p->sParse.aNode[i];
192602194121
pUp = &p->sParse.aNode[iUp];
192603194122
if( pUp->eType==JSON_ARRAY ){
194123
+ assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) );
194124
+ testcase( pUp->eU==0 );
192604194125
jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
192605194126
}else{
192606194127
assert( pUp->eType==JSON_OBJECT );
192607194128
if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
192608194129
assert( pNode->eType==JSON_STRING );
192609194130
assert( pNode->jnFlags & JNODE_LABEL );
194131
+ assert( pNode->eU==1 );
192610194132
jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
192611194133
}
192612194134
}
192613194135
192614194136
/* Return the value of a column */
@@ -192626,10 +194148,11 @@
192626194148
jsonReturn(pThis, ctx, 0);
192627194149
}else if( p->eType==JSON_ARRAY ){
192628194150
u32 iKey;
192629194151
if( p->bRecursive ){
192630194152
if( p->iRowid==0 ) break;
194153
+ assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
192631194154
iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
192632194155
}else{
192633194156
iKey = p->iRowid;
192634194157
}
192635194158
sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
@@ -192675,10 +194198,11 @@
192675194198
jsonAppendChar(&x, '$');
192676194199
}
192677194200
if( p->eType==JSON_ARRAY ){
192678194201
jsonPrintf(30, &x, "[%d]", p->iRowid);
192679194202
}else if( p->eType==JSON_OBJECT ){
194203
+ assert( pThis->eU==1 );
192680194204
jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
192681194205
}
192682194206
}
192683194207
jsonResult(&x);
192684194208
break;
@@ -192742,10 +194266,11 @@
192742194266
int iCol;
192743194267
int iMask;
192744194268
if( pConstraint->iColumn < JEACH_JSON ) continue;
192745194269
iCol = pConstraint->iColumn - JEACH_JSON;
192746194270
assert( iCol==0 || iCol==1 );
194271
+ testcase( iCol==0 );
192747194272
iMask = 1 << iCol;
192748194273
if( pConstraint->usable==0 ){
192749194274
unusableMask |= iMask;
192750194275
}else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
192751194276
aIdx[iCol] = i;
@@ -192839,10 +194364,12 @@
192839194364
pNode = p->sParse.aNode;
192840194365
}
192841194366
p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
192842194367
p->eType = pNode->eType;
192843194368
if( p->eType>=JSON_ARRAY ){
194369
+ assert( pNode->eU==0 );
194370
+ VVA( pNode->eU = 3 );
192844194371
pNode->u.iKey = 0;
192845194372
p->iEnd = p->i + pNode->n + 1;
192846194373
if( p->bRecursive ){
192847194374
p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
192848194375
if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
@@ -193099,10 +194626,13 @@
193099194626
#endif
193100194627
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
193101194628
# undef NDEBUG
193102194629
#endif
193103194630
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
194631
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
194632
+#endif
194633
+#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
193104194634
# define ALWAYS(X) (1)
193105194635
# define NEVER(X) (0)
193106194636
#elif !defined(NDEBUG)
193107194637
# define ALWAYS(X) ((X)?1:(assert(0),0))
193108194638
# define NEVER(X) ((X)?(assert(0),1):0)
@@ -193450,11 +194980,16 @@
193450194980
193451194981
/* The testcase() macro should already be defined in the amalgamation. If
193452194982
** it is not, make it a no-op.
193453194983
*/
193454194984
#ifndef SQLITE_AMALGAMATION
193455
-# define testcase(X)
194985
+# if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
194986
+ unsigned int sqlite3RtreeTestcase = 0;
194987
+# define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; }
194988
+# else
194989
+# define testcase(X)
194990
+# endif
193456194991
#endif
193457194992
193458194993
/*
193459194994
** Make sure that the compiler intrinsics we desire are enabled when
193460194995
** compiling with an appropriate version of MSVC unless prevented by
@@ -194296,24 +195831,33 @@
194296195831
|| p->op==RTREE_FALSE );
194297195832
assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
194298195833
switch( p->op ){
194299195834
case RTREE_TRUE: return; /* Always satisfied */
194300195835
case RTREE_FALSE: break; /* Never satisfied */
194301
- case RTREE_LE:
194302
- case RTREE_LT:
194303195836
case RTREE_EQ:
194304195837
RTREE_DECODE_COORD(eInt, pCellData, val);
194305195838
/* val now holds the lower bound of the coordinate pair */
195839
+ if( p->u.rValue>=val ){
195840
+ pCellData += 4;
195841
+ RTREE_DECODE_COORD(eInt, pCellData, val);
195842
+ /* val now holds the upper bound of the coordinate pair */
195843
+ if( p->u.rValue<=val ) return;
195844
+ }
195845
+ break;
195846
+ case RTREE_LE:
195847
+ case RTREE_LT:
195848
+ RTREE_DECODE_COORD(eInt, pCellData, val);
195849
+ /* val now holds the lower bound of the coordinate pair */
194306195850
if( p->u.rValue>=val ) return;
194307
- if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */
194308
- /* Fall through for the RTREE_EQ case */
195851
+ break;
194309195852
194310
- default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */
195853
+ default:
194311195854
pCellData += 4;
194312195855
RTREE_DECODE_COORD(eInt, pCellData, val);
194313195856
/* val now holds the upper bound of the coordinate pair */
194314195857
if( p->u.rValue<=val ) return;
195858
+ break;
194315195859
}
194316195860
*peWithin = NOT_WITHIN;
194317195861
}
194318195862
194319195863
/*
@@ -195214,11 +196758,11 @@
195214196758
RtreeDValue fMinGrowth = RTREE_ZERO;
195215196759
RtreeDValue fMinArea = RTREE_ZERO;
195216196760
195217196761
int nCell = NCELL(pNode);
195218196762
RtreeCell cell;
195219
- RtreeNode *pChild;
196763
+ RtreeNode *pChild = 0;
195220196764
195221196765
RtreeCell *aCell = 0;
195222196766
195223196767
/* Select the child node which will be enlarged the least if pCell
195224196768
** is inserted into it. Resolve ties by choosing the entry with
@@ -195572,10 +197116,11 @@
195572197116
nodeRelease(pRtree, pChild->pParent);
195573197117
nodeReference(pNode);
195574197118
pChild->pParent = pNode;
195575197119
}
195576197120
}
197121
+ if( NEVER(pNode==0) ) return SQLITE_ERROR;
195577197122
return xSetMapping(pRtree, iRowid, pNode->iNode);
195578197123
}
195579197124
195580197125
static int SplitNode(
195581197126
Rtree *pRtree,
@@ -196876,10 +198421,11 @@
196876198421
tree.nDim = (u8)sqlite3_value_int(apArg[0]);
196877198422
if( tree.nDim<1 || tree.nDim>5 ) return;
196878198423
tree.nDim2 = tree.nDim*2;
196879198424
tree.nBytesPerCell = 8 + 8 * tree.nDim;
196880198425
node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
198426
+ if( node.zData==0 ) return;
196881198427
nData = sqlite3_value_bytes(apArg[1]);
196882198428
if( nData<4 ) return;
196883198429
if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
196884198430
196885198431
pOut = sqlite3_str_new(0);
@@ -197707,17 +199253,18 @@
197707199253
sqlite3_value *pVal, /* The value to decode */
197708199254
int *pRc /* Write error here */
197709199255
){
197710199256
GeoPoly *p = 0;
197711199257
int nByte;
199258
+ testcase( pCtx==0 );
197712199259
if( sqlite3_value_type(pVal)==SQLITE_BLOB
197713199260
&& (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
197714199261
){
197715199262
const unsigned char *a = sqlite3_value_blob(pVal);
197716199263
int nVertex;
197717199264
if( a==0 ){
197718
- sqlite3_result_error_nomem(pCtx);
199265
+ if( pCtx ) sqlite3_result_error_nomem(pCtx);
197719199266
return 0;
197720199267
}
197721199268
nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
197722199269
if( (a[0]==0 || a[0]==1)
197723199270
&& (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
@@ -198540,15 +200087,15 @@
198540200087
pActive = pSeg;
198541200088
needSort = 1;
198542200089
}else{
198543200090
/* Remove a segment */
198544200091
if( pActive==pThisEvent->pSeg ){
198545
- pActive = pActive->pNext;
200092
+ pActive = ALWAYS(pActive) ? pActive->pNext : 0;
198546200093
}else{
198547200094
for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
198548200095
if( pSeg->pNext==pThisEvent->pSeg ){
198549
- pSeg->pNext = pSeg->pNext->pNext;
200096
+ pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0;
198550200097
break;
198551200098
}
198552200099
}
198553200100
}
198554200101
}
@@ -198788,10 +200335,11 @@
198788200335
rc = nodeAcquire(pRtree, 1, 0, &pRoot);
198789200336
if( rc==SQLITE_OK && idxNum<=3 ){
198790200337
RtreeCoord bbox[4];
198791200338
RtreeConstraint *p;
198792200339
assert( argc==1 );
200340
+ assert( argv[0]!=0 );
198793200341
geopolyBBox(0, argv[0], bbox, &rc);
198794200342
if( rc ){
198795200343
goto geopoly_filter_end;
198796200344
}
198797200345
pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
@@ -199015,10 +200563,11 @@
199015200563
if( nData>1 /* not a DELETE */
199016200564
&& (!oldRowidValid /* INSERT */
199017200565
|| !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */
199018200566
|| oldRowid!=newRowid) /* Rowid change */
199019200567
){
200568
+ assert( aData[2]!=0 );
199020200569
geopolyBBox(0, aData[2], cell.aCoord, &rc);
199021200570
if( rc ){
199022200571
if( rc==SQLITE_ERROR ){
199023200572
pVtab->zErrMsg =
199024200573
sqlite3_mprintf("_shape does not contain a valid polygon");
@@ -200941,10 +202490,17 @@
200941202490
** Swap two objects of type TYPE.
200942202491
*/
200943202492
#if !defined(SQLITE_AMALGAMATION)
200944202493
# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
200945202494
#endif
202495
+
202496
+/*
202497
+** Name of the URI option that causes RBU to take an exclusive lock as
202498
+** part of the incremental checkpoint operation.
202499
+*/
202500
+#define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint"
202501
+
200946202502
200947202503
/*
200948202504
** The rbu_state table is used to save the state of a partially applied
200949202505
** update so that it can be resumed later. The table consists of integer
200950202506
** keys mapped to values as follows:
@@ -202388,11 +203944,11 @@
202388203944
**
202389203945
** If the expression cannot be created, NULL is returned. In this case,
202390203946
** the caller has to use an OFFSET clause to extract only the required
202391203947
** rows from the sourct table, just as it does for an RBU update operation.
202392203948
*/
202393
-char *rbuVacuumIndexStart(
203949
+static char *rbuVacuumIndexStart(
202394203950
sqlite3rbu *p, /* RBU handle */
202395203951
RbuObjIter *pIter /* RBU iterator object */
202396203952
){
202397203953
char *zOrder = 0;
202398203954
char *zLhs = 0;
@@ -203588,17 +205144,23 @@
203588205144
203589205145
203590205146
/*
203591205147
** Open the database handle and attach the RBU database as "rbu". If an
203592205148
** error occurs, leave an error code and message in the RBU handle.
205149
+**
205150
+** If argument dbMain is not NULL, then it is a database handle already
205151
+** open on the target database. Use this handle instead of opening a new
205152
+** one.
203593205153
*/
203594
-static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
205154
+static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
203595205155
assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
203596205156
assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
205157
+ assert( dbMain==0 || rbuIsVacuum(p)==0 );
203597205158
203598205159
/* Open the RBU database */
203599205160
p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
205161
+ p->dbMain = dbMain;
203600205162
203601205163
if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
203602205164
sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
203603205165
if( p->zState==0 ){
203604205166
const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -203960,19 +205522,35 @@
203960205522
p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
203961205523
}
203962205524
203963205525
203964205526
/*
203965
-** Take an EXCLUSIVE lock on the database file.
205527
+** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if
205528
+** successful, or an SQLite error code otherwise.
203966205529
*/
203967
-static void rbuLockDatabase(sqlite3rbu *p){
203968
- sqlite3_file *pReal = p->pTargetFd->pReal;
203969
- assert( p->rc==SQLITE_OK );
203970
- p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
203971
- if( p->rc==SQLITE_OK ){
203972
- p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
205530
+static int rbuLockDatabase(sqlite3 *db){
205531
+ int rc = SQLITE_OK;
205532
+ sqlite3_file *fd = 0;
205533
+ sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
205534
+
205535
+ if( fd->pMethods ){
205536
+ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
205537
+ if( rc==SQLITE_OK ){
205538
+ rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE);
205539
+ }
203973205540
}
205541
+ return rc;
205542
+}
205543
+
205544
+/*
205545
+** Return true if the database handle passed as the only argument
205546
+** was opened with the rbu_exclusive_checkpoint=1 URI parameter
205547
+** specified. Or false otherwise.
205548
+*/
205549
+static int rbuExclusiveCheckpoint(sqlite3 *db){
205550
+ const char *zUri = sqlite3_db_filename(db, 0);
205551
+ return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0);
203974205552
}
203975205553
203976205554
#if defined(_WIN32_WCE)
203977205555
static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
203978205556
int nChar;
@@ -204026,22 +205604,28 @@
204026205604
** in WAL mode). So no other connection may be writing the db.
204027205605
**
204028205606
** In order to ensure that there are no database readers, an EXCLUSIVE
204029205607
** lock is obtained here before the *-oal is moved to *-wal.
204030205608
*/
204031
- rbuLockDatabase(p);
205609
+ sqlite3 *dbMain = 0;
205610
+ rbuFileSuffix3(zBase, zWal);
205611
+ rbuFileSuffix3(zBase, zOal);
205612
+
205613
+ /* Re-open the databases. */
205614
+ rbuObjIterFinalize(&p->objiter);
205615
+ sqlite3_close(p->dbRbu);
205616
+ sqlite3_close(p->dbMain);
205617
+ p->dbMain = 0;
205618
+ p->dbRbu = 0;
205619
+
205620
+ dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
205621
+ if( dbMain ){
205622
+ assert( p->rc==SQLITE_OK );
205623
+ p->rc = rbuLockDatabase(dbMain);
205624
+ }
205625
+
204032205626
if( p->rc==SQLITE_OK ){
204033
- rbuFileSuffix3(zBase, zWal);
204034
- rbuFileSuffix3(zBase, zOal);
204035
-
204036
- /* Re-open the databases. */
204037
- rbuObjIterFinalize(&p->objiter);
204038
- sqlite3_close(p->dbRbu);
204039
- sqlite3_close(p->dbMain);
204040
- p->dbMain = 0;
204041
- p->dbRbu = 0;
204042
-
204043205627
#if defined(_WIN32_WCE)
204044205628
{
204045205629
LPWSTR zWideOal;
204046205630
LPWSTR zWideWal;
204047205631
@@ -204064,15 +205648,23 @@
204064205648
}
204065205649
}
204066205650
#else
204067205651
p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204068205652
#endif
205653
+ }
204069205654
204070
- if( p->rc==SQLITE_OK ){
204071
- rbuOpenDatabase(p, 0);
204072
- rbuSetupCheckpoint(p, 0);
204073
- }
205655
+ if( p->rc!=SQLITE_OK
205656
+ || rbuIsVacuum(p)
205657
+ || rbuExclusiveCheckpoint(dbMain)==0
205658
+ ){
205659
+ sqlite3_close(dbMain);
205660
+ dbMain = 0;
205661
+ }
205662
+
205663
+ if( p->rc==SQLITE_OK ){
205664
+ rbuOpenDatabase(p, dbMain, 0);
205665
+ rbuSetupCheckpoint(p, 0);
204074205666
}
204075205667
}
204076205668
204077205669
sqlite3_free(zWal);
204078205670
sqlite3_free(zOal);
@@ -204819,13 +206411,13 @@
204819206411
** to be a wal-mode db. But, this may have happened due to an earlier
204820206412
** RBU vacuum operation leaving an old wal file in the directory.
204821206413
** If this is the case, it will have been checkpointed and deleted
204822206414
** when the handle was closed and a second attempt to open the
204823206415
** database may succeed. */
204824
- rbuOpenDatabase(p, &bRetry);
206416
+ rbuOpenDatabase(p, 0, &bRetry);
204825206417
if( bRetry ){
204826
- rbuOpenDatabase(p, 0);
206418
+ rbuOpenDatabase(p, 0, 0);
204827206419
}
204828206420
}
204829206421
204830206422
if( p->rc==SQLITE_OK ){
204831206423
pState = rbuLoadState(p);
@@ -204916,10 +206508,18 @@
204916206508
}
204917206509
}
204918206510
}else if( p->eStage==RBU_STAGE_MOVE ){
204919206511
/* no-op */
204920206512
}else if( p->eStage==RBU_STAGE_CKPT ){
206513
+ if( !rbuIsVacuum(p) && rbuExclusiveCheckpoint(p->dbMain) ){
206514
+ /* If the rbu_exclusive_checkpoint=1 URI parameter was specified
206515
+ ** and an incremental checkpoint is being resumed, attempt an
206516
+ ** exclusive lock on the db file. If this fails, so be it. */
206517
+ p->eStage = RBU_STAGE_DONE;
206518
+ rbuLockDatabase(p->dbMain);
206519
+ p->eStage = RBU_STAGE_CKPT;
206520
+ }
204921206521
rbuSetupCheckpoint(p, pState);
204922206522
}else if( p->eStage==RBU_STAGE_DONE ){
204923206523
p->rc = SQLITE_DONE;
204924206524
}else{
204925206525
p->rc = SQLITE_CORRUPT;
@@ -204953,11 +206553,10 @@
204953206553
const char *zTarget,
204954206554
const char *zRbu,
204955206555
const char *zState
204956206556
){
204957206557
if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
204958
- /* TODO: Check that zTarget and zRbu are non-NULL */
204959206558
return openRbuHandle(zTarget, zRbu, zState);
204960206559
}
204961206560
204962206561
/*
204963206562
** Open a handle to begin or resume an RBU VACUUM operation.
@@ -207873,11 +209472,11 @@
207873209472
if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
207874209473
nVarint = sessionVarintLen(n);
207875209474
207876209475
if( aBuf ){
207877209476
sessionVarintPut(&aBuf[1], n);
207878
- if( n ) memcpy(&aBuf[nVarint + 1], z, n);
209477
+ if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n);
207879209478
}
207880209479
207881209480
nByte = 1 + nVarint + n;
207882209481
break;
207883209482
}
@@ -208478,20 +210077,36 @@
208478210077
"SELECT 2, 'stat', '', 0, '', 0"
208479210078
);
208480210079
}else if( rc==SQLITE_ERROR ){
208481210080
zPragma = sqlite3_mprintf("");
208482210081
}else{
210082
+ *pazCol = 0;
210083
+ *pabPK = 0;
210084
+ *pnCol = 0;
210085
+ if( pzTab ) *pzTab = 0;
208483210086
return rc;
208484210087
}
208485210088
}else{
208486210089
zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
208487210090
}
208488
- if( !zPragma ) return SQLITE_NOMEM;
210091
+ if( !zPragma ){
210092
+ *pazCol = 0;
210093
+ *pabPK = 0;
210094
+ *pnCol = 0;
210095
+ if( pzTab ) *pzTab = 0;
210096
+ return SQLITE_NOMEM;
210097
+ }
208489210098
208490210099
rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
208491210100
sqlite3_free(zPragma);
208492
- if( rc!=SQLITE_OK ) return rc;
210101
+ if( rc!=SQLITE_OK ){
210102
+ *pazCol = 0;
210103
+ *pabPK = 0;
210104
+ *pnCol = 0;
210105
+ if( pzTab ) *pzTab = 0;
210106
+ return rc;
210107
+ }
208493210108
208494210109
nByte = nThis + 1;
208495210110
while( SQLITE_ROW==sqlite3_step(pStmt) ){
208496210111
nByte += sqlite3_column_bytes(pStmt, 1);
208497210112
nDbCol++;
@@ -208905,11 +210520,15 @@
208905210520
if( pSession->xTableFilter==0
208906210521
|| pSession->xTableFilter(pSession->pFilterCtx, zName)
208907210522
){
208908210523
rc = sqlite3session_attach(pSession, zName);
208909210524
if( rc==SQLITE_OK ){
208910
- for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext);
210525
+ pRet = pSession->pTable;
210526
+ while( ALWAYS(pRet) && pRet->pNext ){
210527
+ pRet = pRet->pNext;
210528
+ }
210529
+ assert( pRet!=0 );
208911210530
assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
208912210531
}
208913210532
}
208914210533
}
208915210534
@@ -209678,10 +211297,11 @@
209678211297
int bNoop = 1; /* Set to zero if any values are modified */
209679211298
int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
209680211299
int i; /* Used to iterate through columns */
209681211300
u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
209682211301
211302
+ assert( abPK!=0 );
209683211303
sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
209684211304
sessionAppendByte(pBuf, p->bIndirect, &rc);
209685211305
for(i=0; i<sqlite3_column_count(pStmt); i++){
209686211306
int bChanged = 0;
209687211307
int nAdvance;
@@ -209982,16 +211602,18 @@
209982211602
sqlite3 *db = pSession->db; /* Source database handle */
209983211603
SessionTable *pTab; /* Used to iterate through attached tables */
209984211604
SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
209985211605
int rc; /* Return code */
209986211606
209987
- assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) );
211607
+ assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) );
211608
+ assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) );
209988211609
209989211610
/* Zero the output variables in case an error occurs. If this session
209990211611
** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
209991211612
** this call will be a no-op. */
209992211613
if( xOutput==0 ){
211614
+ assert( pnChangeset!=0 && ppChangeset!=0 );
209993211615
*pnChangeset = 0;
209994211616
*ppChangeset = 0;
209995211617
}
209996211618
209997211619
if( pSession->rc ) return pSession->rc;
@@ -210001,12 +211623,12 @@
210001211623
sqlite3_mutex_enter(sqlite3_db_mutex(db));
210002211624
210003211625
for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
210004211626
if( pTab->nEntry ){
210005211627
const char *zName = pTab->zName;
210006
- int nCol; /* Number of columns in table */
210007
- u8 *abPK; /* Primary key array */
211628
+ int nCol = 0; /* Number of columns in table */
211629
+ u8 *abPK = 0; /* Primary key array */
210008211630
const char **azCol = 0; /* Table columns */
210009211631
int i; /* Used to iterate through hash buckets */
210010211632
sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
210011211633
int nRewind = buf.nBuf; /* Initial size of write buffer */
210012211634
int nNoop; /* Size of buffer after writing tbl header */
@@ -210040,10 +211662,11 @@
210040211662
sessionAppendByte(&buf, p->bIndirect, &rc);
210041211663
for(iCol=0; iCol<nCol; iCol++){
210042211664
sessionAppendCol(&buf, pSel, iCol, &rc);
210043211665
}
210044211666
}else{
211667
+ assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */
210045211668
rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
210046211669
}
210047211670
}else if( p->op!=SQLITE_INSERT ){
210048211671
rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
210049211672
}
@@ -210100,11 +211723,14 @@
210100211723
SQLITE_API int sqlite3session_changeset(
210101211724
sqlite3_session *pSession, /* Session object */
210102211725
int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
210103211726
void **ppChangeset /* OUT: Buffer containing changeset */
210104211727
){
210105
- int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset);
211728
+ int rc;
211729
+
211730
+ if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE;
211731
+ rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset);
210106211732
assert( rc || pnChangeset==0
210107211733
|| pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
210108211734
);
210109211735
return rc;
210110211736
}
@@ -210115,10 +211741,11 @@
210115211741
SQLITE_API int sqlite3session_changeset_strm(
210116211742
sqlite3_session *pSession,
210117211743
int (*xOutput)(void *pOut, const void *pData, int nData),
210118211744
void *pOut
210119211745
){
211746
+ if( xOutput==0 ) return SQLITE_MISUSE;
210120211747
return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
210121211748
}
210122211749
210123211750
/*
210124211751
** Streaming version of sqlite3session_patchset().
@@ -210126,10 +211753,11 @@
210126211753
SQLITE_API int sqlite3session_patchset_strm(
210127211754
sqlite3_session *pSession,
210128211755
int (*xOutput)(void *pOut, const void *pData, int nData),
210129211756
void *pOut
210130211757
){
211758
+ if( xOutput==0 ) return SQLITE_MISUSE;
210131211759
return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
210132211760
}
210133211761
210134211762
/*
210135211763
** Obtain a patchset object containing all changes recorded by the
@@ -210141,10 +211769,11 @@
210141211769
SQLITE_API int sqlite3session_patchset(
210142211770
sqlite3_session *pSession, /* Session object */
210143211771
int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
210144211772
void **ppPatchset /* OUT: Buffer containing changeset */
210145211773
){
211774
+ if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE;
210146211775
return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
210147211776
}
210148211777
210149211778
/*
210150211779
** Enable or disable the session object passed as the first argument.
@@ -211104,15 +212733,15 @@
211104212733
if( rc!=SQLITE_OK ) goto finished_invert;
211105212734
}
211106212735
}
211107212736
211108212737
assert( rc==SQLITE_OK );
211109
- if( pnInverted ){
212738
+ if( pnInverted && ALWAYS(ppInverted) ){
211110212739
*pnInverted = sOut.nBuf;
211111212740
*ppInverted = sOut.aBuf;
211112212741
sOut.aBuf = 0;
211113
- }else if( sOut.nBuf>0 ){
212742
+ }else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){
211114212743
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
211115212744
}
211116212745
211117212746
finished_invert:
211118212747
sqlite3_free(sOut.aBuf);
@@ -211564,11 +213193,11 @@
211564213193
** in the code below. */
211565213194
assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
211566213195
211567213196
for(i=0; rc==SQLITE_OK && i<nCol; i++){
211568213197
if( !abPK || abPK[i] ){
211569
- sqlite3_value *pVal;
213198
+ sqlite3_value *pVal = 0;
211570213199
(void)xValue(pIter, i, &pVal);
211571213200
if( pVal==0 ){
211572213201
/* The value in the changeset was "undefined". This indicates a
211573213202
** corrupt changeset blob. */
211574213203
rc = SQLITE_CORRUPT_BKPT;
@@ -212707,13 +214336,13 @@
212707214336
}
212708214337
212709214338
if( rc==SQLITE_OK ){
212710214339
if( xOutput ){
212711214340
if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
212712
- }else{
214341
+ }else if( ppOut ){
212713214342
*ppOut = buf.aBuf;
212714
- *pnOut = buf.nBuf;
214343
+ if( pnOut ) *pnOut = buf.nBuf;
212715214344
buf.aBuf = 0;
212716214345
}
212717214346
}
212718214347
sqlite3_free(buf.aBuf);
212719214348
@@ -213109,11 +214738,11 @@
213109214738
if( rc==SQLITE_OK ){
213110214739
if( xOutput ){
213111214740
if( sOut.nBuf>0 ){
213112214741
rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
213113214742
}
213114
- }else{
214743
+ }else if( ppOut ){
213115214744
*ppOut = (void*)sOut.aBuf;
213116214745
*pnOut = sOut.nBuf;
213117214746
sOut.aBuf = 0;
213118214747
}
213119214748
}
@@ -213852,12 +215481,24 @@
213852215481
#ifndef ArraySize
213853215482
# define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
213854215483
#endif
213855215484
213856215485
#define testcase(x)
213857
-#define ALWAYS(x) 1
213858
-#define NEVER(x) 0
215486
+
215487
+#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
215488
+# define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
215489
+#endif
215490
+#if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
215491
+# define ALWAYS(X) (1)
215492
+# define NEVER(X) (0)
215493
+#elif !defined(NDEBUG)
215494
+# define ALWAYS(X) ((X)?1:(assert(0),0))
215495
+# define NEVER(X) ((X)?(assert(0),1):0)
215496
+#else
215497
+# define ALWAYS(X) (X)
215498
+# define NEVER(X) (X)
215499
+#endif
213859215500
213860215501
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
213861215502
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
213862215503
213863215504
/*
@@ -213913,11 +215554,11 @@
213913215554
213914215555
/*
213915215556
** A version of memcmp() that does not cause asan errors if one of the pointer
213916215557
** parameters is NULL and the number of bytes to compare is zero.
213917215558
*/
213918
-#define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n)))
215559
+#define fts5Memcmp(s1, s2, n) ((n)<=0 ? 0 : memcmp((s1), (s2), (n)))
213919215560
213920215561
/* Mark a function parameter as unused, to suppress nuisance compiler
213921215562
** warnings. */
213922215563
#ifndef UNUSED_PARAM
213923215564
# define UNUSED_PARAM(X) (void)(X)
@@ -215032,13 +216673,13 @@
215032216673
fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
215033216674
#endif
215034216675
};
215035216676
typedef struct fts5yyParser fts5yyParser;
215036216677
215037
-#ifndef NDEBUG
215038
-/* #include <stdio.h> */
215039216678
/* #include <assert.h> */
216679
+#ifndef NDEBUG
216680
+/* #include <stdio.h> */
215040216681
static FILE *fts5yyTraceFILE = 0;
215041216682
static char *fts5yyTracePrompt = 0;
215042216683
#endif /* NDEBUG */
215043216684
215044216685
#ifndef NDEBUG
@@ -215971,12 +217612,12 @@
215971217612
assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
215972217613
assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
215973217614
fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
215974217615
if( fts5yyact >= fts5YY_MIN_REDUCE ){
215975217616
unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
215976
- assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
215977217617
#ifndef NDEBUG
217618
+ assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
215978217619
if( fts5yyTraceFILE ){
215979217620
int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
215980217621
if( fts5yysize ){
215981217622
fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
215982217623
fts5yyTracePrompt,
@@ -216939,11 +218580,10 @@
216939218580
int *pRc,
216940218581
Fts5Buffer *pBuf,
216941218582
u32 nData,
216942218583
const u8 *pData
216943218584
){
216944
- assert_nc( *pRc || nData>=0 );
216945218585
if( nData ){
216946218586
if( fts5BufferGrow(pRc, pBuf, nData) ) return;
216947218587
memcpy(&pBuf->p[pBuf->n], pData, nData);
216948218588
pBuf->n += nData;
216949218589
}
@@ -217051,11 +218691,10 @@
217051218691
return 1;
217052218692
}else{
217053218693
i64 iOff = *piOff;
217054218694
u32 iVal;
217055218695
fts5FastGetVarint32(a, i, iVal);
217056
- assert( iVal>=0 );
217057218696
if( iVal<=1 ){
217058218697
if( iVal==0 ){
217059218698
*pi = i;
217060218699
return 0;
217061218700
}
@@ -217846,10 +219485,11 @@
217846219485
217847219486
z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
217848219487
z = fts5ConfigSkipWhitespace(z);
217849219488
if( z && *z=='=' ){
217850219489
bOption = 1;
219490
+ assert( zOne!=0 );
217851219491
z++;
217852219492
if( bMustBeCol ) z = 0;
217853219493
}
217854219494
z = fts5ConfigSkipWhitespace(z);
217855219495
if( z && z[0] ){
@@ -217862,11 +219502,15 @@
217862219502
if( z==0 ){
217863219503
*pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
217864219504
rc = SQLITE_ERROR;
217865219505
}else{
217866219506
if( bOption ){
217867
- rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr);
219507
+ rc = fts5ConfigParseSpecial(pGlobal, pRet,
219508
+ ALWAYS(zOne)?zOne:"",
219509
+ zTwo?zTwo:"",
219510
+ pzErr
219511
+ );
217868219512
}else{
217869219513
rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
217870219514
zOne = 0;
217871219515
}
217872219516
}
@@ -218679,10 +220323,11 @@
218679220323
static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
218680220324
i64 iRet = 0;
218681220325
int bRetValid = 0;
218682220326
Fts5ExprTerm *p;
218683220327
220328
+ assert( pTerm );
218684220329
assert( pTerm->pSynonym );
218685220330
assert( bDesc==0 || bDesc==1 );
218686220331
for(p=pTerm; p; p=p->pSynonym){
218687220332
if( 0==sqlite3Fts5IterEof(p->pIter) ){
218688220333
i64 iRowid = p->pIter->iRowid;
@@ -220119,11 +221764,11 @@
220119221764
/* This happens when parsing a token or quoted phrase that contains
220120221765
** no token characters at all. (e.g ... MATCH '""'). */
220121221766
sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
220122221767
}
220123221768
220124
- if( rc==SQLITE_OK ){
221769
+ if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
220125221770
/* All the allocations succeeded. Put the expression object together. */
220126221771
pNew->pIndex = pExpr->pIndex;
220127221772
pNew->pConfig = pExpr->pConfig;
220128221773
pNew->nPhrase = 1;
220129221774
pNew->apExprPhrase[0] = sCtx.pPhrase;
@@ -221100,20 +222745,29 @@
221100222745
Fts5PoslistWriter writer;
221101222746
int bOk; /* True if ok to populate */
221102222747
int bMiss;
221103222748
};
221104222749
222750
+/*
222751
+** Clear the position lists associated with all phrases in the expression
222752
+** passed as the first argument. Argument bLive is true if the expression
222753
+** might be pointing to a real entry, otherwise it has just been reset.
222754
+**
222755
+** At present this function is only used for detail=col and detail=none
222756
+** fts5 tables. This implies that all phrases must be at most 1 token
222757
+** in size, as phrase matches are not supported without detail=full.
222758
+*/
221105222759
static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
221106222760
Fts5PoslistPopulator *pRet;
221107222761
pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221108222762
if( pRet ){
221109222763
int i;
221110222764
memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221111222765
for(i=0; i<pExpr->nPhrase; i++){
221112222766
Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
221113222767
Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
221114
- assert( pExpr->apExprPhrase[i]->nTerm==1 );
222768
+ assert( pExpr->apExprPhrase[i]->nTerm<=1 );
221115222769
if( bLive &&
221116222770
(pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
221117222771
){
221118222772
pRet[i].bMiss = 1;
221119222773
}else{
@@ -221660,11 +223314,11 @@
221660223314
if( iCol>=0 ){
221661223315
if( pHash->eDetail==FTS5_DETAIL_NONE ){
221662223316
p->bContent = 1;
221663223317
}else{
221664223318
/* Append a new column value, if necessary */
221665
- assert( iCol>=p->iCol );
223319
+ assert_nc( iCol>=p->iCol );
221666223320
if( iCol!=p->iCol ){
221667223321
if( pHash->eDetail==FTS5_DETAIL_FULL ){
221668223322
pPtr[p->nData++] = 0x01;
221669223323
p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
221670223324
p->iCol = (i16)iCol;
@@ -222465,12 +224119,15 @@
222465224119
** +ve if pRight is smaller than pLeft. In other words:
222466224120
**
222467224121
** res = *pLeft - *pRight
222468224122
*/
222469224123
static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
222470
- int nCmp = MIN(pLeft->n, pRight->n);
222471
- int res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
224124
+ int nCmp, res;
224125
+ nCmp = MIN(pLeft->n, pRight->n);
224126
+ assert( nCmp<=0 || pLeft->p!=0 );
224127
+ assert( nCmp<=0 || pRight->p!=0 );
224128
+ res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
222472224129
return (res==0 ? (pLeft->n - pRight->n) : res);
222473224130
}
222474224131
222475224132
static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
222476224133
int ret;
@@ -222712,11 +224369,11 @@
222712224369
** an error occurs, (*pRc) is set to an SQLite error code before returning.
222713224370
*/
222714224371
static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
222715224372
Fts5Structure *p = *pp;
222716224373
if( *pRc==SQLITE_OK && p->nRef>1 ){
222717
- int nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
224374
+ i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
222718224375
Fts5Structure *pNew;
222719224376
pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
222720224377
if( pNew ){
222721224378
int i;
222722224379
memcpy(pNew, p, nByte);
@@ -223638,10 +225295,11 @@
223638225295
fts5SegIterNextPage(p, pIter);
223639225296
}
223640225297
223641225298
if( p->rc==SQLITE_OK ){
223642225299
pIter->iLeafOffset = 4;
225300
+ assert( pIter->pLeaf!=0 );
223643225301
assert_nc( pIter->pLeaf->nn>4 );
223644225302
assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
223645225303
pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
223646225304
fts5SegIterLoadTerm(p, pIter, 0);
223647225305
fts5SegIterLoadNPos(p, pIter);
@@ -223740,12 +225398,16 @@
223740225398
}
223741225399
}else{
223742225400
int iRowidOff;
223743225401
iRowidOff = fts5LeafFirstRowidOff(pNew);
223744225402
if( iRowidOff ){
223745
- pIter->pLeaf = pNew;
223746
- pIter->iLeafOffset = iRowidOff;
225403
+ if( iRowidOff>=pNew->szLeaf ){
225404
+ p->rc = FTS5_CORRUPT;
225405
+ }else{
225406
+ pIter->pLeaf = pNew;
225407
+ pIter->iLeafOffset = iRowidOff;
225408
+ }
223747225409
}
223748225410
}
223749225411
223750225412
if( pIter->pLeaf ){
223751225413
u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
@@ -224142,25 +225804,24 @@
224142225804
Fts5Index *p, /* Leave any error code here */
224143225805
int bGe, /* True for a >= search */
224144225806
Fts5SegIter *pIter, /* Iterator to seek */
224145225807
const u8 *pTerm, int nTerm /* Term to search for */
224146225808
){
224147
- int iOff;
225809
+ u32 iOff;
224148225810
const u8 *a = pIter->pLeaf->p;
224149
- int szLeaf = pIter->pLeaf->szLeaf;
224150
- int n = pIter->pLeaf->nn;
225811
+ u32 n = (u32)pIter->pLeaf->nn;
224151225812
224152225813
u32 nMatch = 0;
224153225814
u32 nKeep = 0;
224154225815
u32 nNew = 0;
224155225816
u32 iTermOff;
224156
- int iPgidx; /* Current offset in pgidx */
225817
+ u32 iPgidx; /* Current offset in pgidx */
224157225818
int bEndOfPage = 0;
224158225819
224159225820
assert( p->rc==SQLITE_OK );
224160225821
224161
- iPgidx = szLeaf;
225822
+ iPgidx = (u32)pIter->pLeaf->szLeaf;
224162225823
iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
224163225824
iOff = iTermOff;
224164225825
if( iOff>n ){
224165225826
p->rc = FTS5_CORRUPT;
224166225827
return;
@@ -224222,19 +225883,19 @@
224222225883
do {
224223225884
fts5SegIterNextPage(p, pIter);
224224225885
if( pIter->pLeaf==0 ) return;
224225225886
a = pIter->pLeaf->p;
224226225887
if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
224227
- iPgidx = pIter->pLeaf->szLeaf;
225888
+ iPgidx = (u32)pIter->pLeaf->szLeaf;
224228225889
iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
224229
- if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
225890
+ if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
224230225891
p->rc = FTS5_CORRUPT;
224231225892
return;
224232225893
}else{
224233225894
nKeep = 0;
224234225895
iTermOff = iOff;
224235
- n = pIter->pLeaf->nn;
225896
+ n = (u32)pIter->pLeaf->nn;
224236225897
iOff += fts5GetVarint32(&a[iOff], nNew);
224237225898
break;
224238225899
}
224239225900
}
224240225901
}while( 1 );
@@ -224598,11 +226259,11 @@
224598226259
pIter->pNextLeaf = 0;
224599226260
pIter->iLeafPgno = iLeafPgno-1;
224600226261
fts5SegIterNextPage(p, pIter);
224601226262
assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
224602226263
224603
- if( p->rc==SQLITE_OK ){
226264
+ if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){
224604226265
int iOff;
224605226266
u8 *a = pIter->pLeaf->p;
224606226267
int n = pIter->pLeaf->szLeaf;
224607226268
224608226269
iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
@@ -225030,11 +226691,15 @@
225030226691
Fts5Index *p,
225031226692
Fts5SegIter *pSeg,
225032226693
Fts5Colset *pColset,
225033226694
Fts5Buffer *pBuf
225034226695
){
226696
+ assert( pBuf!=0 );
226697
+ assert( pSeg!=0 );
225035226698
if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
226699
+ assert( pBuf->p!=0 );
226700
+ assert( pBuf->nSpace >= pBuf->n+pSeg->nPos+FTS5_DATA_ZERO_PADDING );
225036226701
memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
225037226702
if( pColset==0 ){
225038226703
fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
225039226704
}else{
225040226705
if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){
@@ -225254,10 +226919,11 @@
225254226919
pIter->base.nData = pIter->poslist.n;
225255226920
}
225256226921
}
225257226922
225258226923
static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
226924
+ assert( pIter!=0 || (*pRc)!=SQLITE_OK );
225259226925
if( *pRc==SQLITE_OK ){
225260226926
Fts5Config *pConfig = pIter->pIndex->pConfig;
225261226927
if( pConfig->eDetail==FTS5_DETAIL_NONE ){
225262226928
pIter->xSetOutputs = fts5IterSetOutputs_None;
225263226929
}
@@ -225325,11 +226991,14 @@
225325226991
}else{
225326226992
nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
225327226993
}
225328226994
}
225329226995
*ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
225330
- if( pNew==0 ) return;
226996
+ if( pNew==0 ){
226997
+ assert( p->rc!=SQLITE_OK );
226998
+ goto fts5MultiIterNew_post_check;
226999
+ }
225331227000
pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
225332227001
pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
225333227002
pNew->pColset = pColset;
225334227003
if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
225335227004
fts5IterSetOutputCb(&p->rc, pNew);
@@ -225389,10 +227058,14 @@
225389227058
225390227059
}else{
225391227060
fts5MultiIterFree(pNew);
225392227061
*ppOut = 0;
225393227062
}
227063
+
227064
+fts5MultiIterNew_post_check:
227065
+ assert( (*ppOut)!=0 || p->rc!=SQLITE_OK );
227066
+ return;
225394227067
}
225395227068
225396227069
/*
225397227070
** Create an Fts5Iter that iterates through the doclist provided
225398227071
** as the second argument.
@@ -225436,11 +227109,12 @@
225436227109
/*
225437227110
** Return true if the iterator is at EOF or if an error has occurred.
225438227111
** False otherwise.
225439227112
*/
225440227113
static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
225441
- assert( p->rc
227114
+ assert( pIter!=0 || p->rc!=SQLITE_OK );
227115
+ assert( p->rc!=SQLITE_OK
225442227116
|| (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof
225443227117
);
225444227118
return (p->rc || pIter->base.bEof);
225445227119
}
225446227120
@@ -226240,10 +227914,11 @@
226240227914
226241227915
/* Flush the last leaf page to disk. Set the output segment b-tree height
226242227916
** and last leaf page number at the same time. */
226243227917
fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
226244227918
227919
+ assert( pIter!=0 || p->rc!=SQLITE_OK );
226245227920
if( fts5MultiIterEof(p, pIter) ){
226246227921
int i;
226247227922
226248227923
/* Remove the redundant segments from the %_data table */
226249227924
for(i=0; i<nInput; i++){
@@ -226340,11 +228015,11 @@
226340228015
static void fts5IndexAutomerge(
226341228016
Fts5Index *p, /* FTS5 backend object */
226342228017
Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
226343228018
int nLeaf /* Number of output leaves just written */
226344228019
){
226345
- if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){
228020
+ if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 && ALWAYS((*ppStruct)!=0) ){
226346228021
Fts5Structure *pStruct = *ppStruct;
226347228022
u64 nWrite; /* Initial value of write-counter */
226348228023
int nWork; /* Number of work-quanta to perform */
226349228024
int nRem; /* Number of leaf pages left to write */
226350228025
@@ -227450,15 +229125,19 @@
227450229125
}
227451229126
}else{
227452229127
/* Scan multiple terms in the main index */
227453229128
int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
227454229129
fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
227455
- assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
227456
- fts5IterSetOutputCb(&p->rc, pRet);
227457
- if( p->rc==SQLITE_OK ){
227458
- Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
227459
- if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
229130
+ if( pRet==0 ){
229131
+ assert( p->rc!=SQLITE_OK );
229132
+ }else{
229133
+ assert( pRet->pColset==0 );
229134
+ fts5IterSetOutputCb(&p->rc, pRet);
229135
+ if( p->rc==SQLITE_OK ){
229136
+ Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
229137
+ if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
229138
+ }
227460229139
}
227461229140
}
227462229141
227463229142
if( p->rc ){
227464229143
sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
@@ -227702,11 +229381,11 @@
227702229381
int eDetail = p->pConfig->eDetail;
227703229382
u64 cksum = *pCksum;
227704229383
Fts5IndexIter *pIter = 0;
227705229384
int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
227706229385
227707
- while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
229386
+ while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
227708229387
i64 rowid = pIter->iRowid;
227709229388
227710229389
if( eDetail==FTS5_DETAIL_NONE ){
227711229390
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
227712229391
}else{
@@ -228067,10 +229746,11 @@
228067229746
int eDetail = p->pConfig->eDetail;
228068229747
u64 cksum2 = 0; /* Checksum based on contents of indexes */
228069229748
Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
228070229749
Fts5Iter *pIter; /* Used to iterate through entire index */
228071229750
Fts5Structure *pStruct; /* Index structure */
229751
+ int iLvl, iSeg;
228072229752
228073229753
#ifdef SQLITE_DEBUG
228074229754
/* Used by extra internal tests only run if NDEBUG is not defined */
228075229755
u64 cksum3 = 0; /* Checksum based on contents of indexes */
228076229756
Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
@@ -228077,19 +229757,20 @@
228077229757
#endif
228078229758
const int flags = FTS5INDEX_QUERY_NOOUTPUT;
228079229759
228080229760
/* Load the FTS index structure */
228081229761
pStruct = fts5StructureRead(p);
229762
+ if( pStruct==0 ){
229763
+ assert( p->rc!=SQLITE_OK );
229764
+ return fts5IndexReturn(p);
229765
+ }
228082229766
228083229767
/* Check that the internal nodes of each segment match the leaves */
228084
- if( pStruct ){
228085
- int iLvl, iSeg;
228086
- for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
228087
- for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
228088
- Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
228089
- fts5IndexIntegrityCheckSegment(p, pSeg);
228090
- }
229768
+ for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
229769
+ for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
229770
+ Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
229771
+ fts5IndexIntegrityCheckSegment(p, pSeg);
228091229772
}
228092229773
}
228093229774
228094229775
/* The cksum argument passed to this function is a checksum calculated
228095229776
** based on all expected entries in the FTS index (including prefix index
@@ -230032,11 +231713,12 @@
230032231713
pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
230033231714
rc = sqlite3Fts5StorageStmt(
230034231715
pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
230035231716
);
230036231717
if( rc==SQLITE_OK ){
230037
- if( pCsr->ePlan==FTS5_PLAN_ROWID ){
231718
+ if( pRowidEq!=0 ){
231719
+ assert( pCsr->ePlan==FTS5_PLAN_ROWID );
230038231720
sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
230039231721
}else{
230040231722
sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
230041231723
sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
230042231724
}
@@ -231450,11 +233132,11 @@
231450233132
int nArg, /* Number of args */
231451233133
sqlite3_value **apUnused /* Function arguments */
231452233134
){
231453233135
assert( nArg==0 );
231454233136
UNUSED_PARAM2(nArg, apUnused);
231455
- sqlite3_result_text(pCtx, "fts5: 2021-10-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813", -1, SQLITE_TRANSIENT);
233137
+ sqlite3_result_text(pCtx, "fts5: 2021-12-09 20:06:18 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882", -1, SQLITE_TRANSIENT);
231456233138
}
231457233139
231458233140
/*
231459233141
** Return true if zName is the extension on one of the shadow tables used
231460233142
** by this module.
@@ -232001,16 +233683,20 @@
232001233683
rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
232002233684
for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
232003233685
if( pConfig->abUnindexed[iCol-1]==0 ){
232004233686
const char *zText;
232005233687
int nText;
233688
+ assert( pSeek==0 || apVal==0 );
233689
+ assert( pSeek!=0 || apVal!=0 );
232006233690
if( pSeek ){
232007233691
zText = (const char*)sqlite3_column_text(pSeek, iCol);
232008233692
nText = sqlite3_column_bytes(pSeek, iCol);
232009
- }else{
233693
+ }else if( ALWAYS(apVal) ){
232010233694
zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
232011233695
nText = sqlite3_value_bytes(apVal[iCol-1]);
233696
+ }else{
233697
+ continue;
232012233698
}
232013233699
ctx.szCol = 0;
232014233700
rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
232015233701
zText, nText, (void*)&ctx, fts5StorageInsertCallback
232016233702
);
@@ -232642,12 +234328,13 @@
232642234328
sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
232643234329
int rc; /* Return Code */
232644234330
232645234331
assert( p->pConfig->bColumnsize );
232646234332
rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
232647
- if( rc==SQLITE_OK ){
234333
+ if( pLookup ){
232648234334
int bCorrupt = 1;
234335
+ assert( rc==SQLITE_OK );
232649234336
sqlite3_bind_int64(pLookup, 1, iRowid);
232650234337
if( SQLITE_ROW==sqlite3_step(pLookup) ){
232651234338
const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
232652234339
int nBlob = sqlite3_column_bytes(pLookup, 0);
232653234340
if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
@@ -232656,10 +234343,12 @@
232656234343
}
232657234344
rc = sqlite3_reset(pLookup);
232658234345
if( bCorrupt && rc==SQLITE_OK ){
232659234346
rc = FTS5_CORRUPT;
232660234347
}
234348
+ }else{
234349
+ assert( rc!=SQLITE_OK );
232661234350
}
232662234351
232663234352
return rc;
232664234353
}
232665234354
@@ -235660,11 +237349,11 @@
235660237349
rc = sqlite3Fts5FlushToDisk(pFts5);
235661237350
}
235662237351
}
235663237352
235664237353
if( rc==SQLITE_OK ){
235665
- int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
237354
+ i64 nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
235666237355
pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
235667237356
}
235668237357
235669237358
if( pCsr ){
235670237359
pCsr->pFts5 = pFts5;
235671237360
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.37.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -450,13 +450,13 @@
450 **
451 ** See also: [sqlite3_libversion()],
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-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -843,11 +843,10 @@
843 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
844 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
845 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
846 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
847 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
848 #define SQLITE_CANTOPEN_EXISTS (SQLITE_CANTOPEN | (7<<8))
849 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
850 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
851 #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
852 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
853 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -879,10 +878,23 @@
879 ** CAPI3REF: Flags For File Open Operations
880 **
881 ** These bit values are intended for use in the
882 ** 3rd parameter to the [sqlite3_open_v2()] interface and
883 ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
 
 
 
 
 
 
 
 
 
 
 
 
 
884 */
885 #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
886 #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
887 #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
888 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
@@ -901,10 +913,11 @@
901 #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
902 #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
903 #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
904 #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
905 #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
 
906
907 /* Reserved: 0x00F00000 */
908 /* Legacy compatibility: */
909 #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
910
@@ -3720,25 +3733,35 @@
3720 **
3721 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3722 ** <dd>The database is opened [shared cache] disabled, overriding
3723 ** the default shared cache setting provided by
3724 ** [sqlite3_enable_shared_cache()].)^
 
 
 
 
 
 
 
 
3725 **
3726 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3727 ** <dd>The database filename is not allowed to be a symbolic link</dd>
3728 **
3729 ** [[OPEN_EXCLUSIVE]] ^(<dt>[SQLITE_OPEN_EXCLUSIVE]</dt>
3730 ** <dd>This flag causes the open to fail if the database file already
3731 ** exists. The open will only be success if this flag is used in combination
3732 ** with the SQLITE_OPEN_CREATE and SQLITE_OPEN_READWRITE flags and if
3733 ** the file does not previously exist.</dd>
3734 ** </dl>)^
3735 **
3736 ** If the 3rd parameter to sqlite3_open_v2() is not one of the
3737 ** required combinations shown above optionally combined with other
3738 ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
3739 ** then the behavior is undefined.
 
 
 
 
 
 
 
 
3740 **
3741 ** ^The fourth parameter to sqlite3_open_v2() is the name of the
3742 ** [sqlite3_vfs] object that defines the operating system interface that
3743 ** the new database connection should use. ^If the fourth parameter is
3744 ** a NULL pointer then the default [sqlite3_vfs] object is used.
@@ -6695,10 +6718,76 @@
6695 **
6696 ** See also the [sqlite3_update_hook()] interface.
6697 */
6698 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
6699 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6700
6701 /*
6702 ** CAPI3REF: Data Change Notification Callbacks
6703 ** METHOD: sqlite3
6704 **
@@ -8159,11 +8248,12 @@
8159 #define SQLITE_TESTCTRL_PRNG_SEED 28
8160 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
8161 #define SQLITE_TESTCTRL_SEEK_COUNT 30
8162 #define SQLITE_TESTCTRL_TRACEFLAGS 31
8163 #define SQLITE_TESTCTRL_TUNE 32
8164 #define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */
 
8165
8166 /*
8167 ** CAPI3REF: SQL Keyword Checking
8168 **
8169 ** These routines provide access to the set of SQL language keywords
@@ -8681,10 +8771,20 @@
8681 ** <dd>^This is the number of times that the prepared statement has
8682 ** been run. A single "run" for the purposes of this counter is one
8683 ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
8684 ** The counter is incremented on the first [sqlite3_step()] call of each
8685 ** cycle.
 
 
 
 
 
 
 
 
 
 
8686 **
8687 ** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
8688 ** <dd>^This is the approximate number of bytes of heap memory
8689 ** used to store the prepared statement. ^This value is not actually
8690 ** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -8696,10 +8796,12 @@
8696 #define SQLITE_STMTSTATUS_SORT 2
8697 #define SQLITE_STMTSTATUS_AUTOINDEX 3
8698 #define SQLITE_STMTSTATUS_VM_STEP 4
8699 #define SQLITE_STMTSTATUS_REPREPARE 5
8700 #define SQLITE_STMTSTATUS_RUN 6
 
 
8701 #define SQLITE_STMTSTATUS_MEMUSED 99
8702
8703 /*
8704 ** CAPI3REF: Custom Page Cache Object
8705 **
@@ -13160,15 +13262,16 @@
13160 ** can be used to make sure boundary values are tested. For
13161 ** bitmask tests, testcase() can be used to make sure each bit
13162 ** is significant and used at least once. On switch statements
13163 ** where multiple cases go to the same block of code, testcase()
13164 ** can insure that all cases are evaluated.
13165 **
13166 */
13167 #ifdef SQLITE_COVERAGE_TEST
13168 SQLITE_PRIVATE void sqlite3Coverage(int);
13169 # define testcase(X) if( X ){ sqlite3Coverage(__LINE__); }
 
 
13170 #else
13171 # define testcase(X)
13172 #endif
13173
13174 /*
@@ -13194,10 +13297,18 @@
13194 # define VVA_ONLY(X) X
13195 #else
13196 # define VVA_ONLY(X)
13197 #endif
13198
 
 
 
 
 
 
 
 
13199 /*
13200 ** The ALWAYS and NEVER macros surround boolean expressions which
13201 ** are intended to always be true or false, respectively. Such
13202 ** expressions could be omitted from the code completely. But they
13203 ** are included in a few cases in order to enhance the resilience
@@ -13209,11 +13320,11 @@
13209 **
13210 ** When doing coverage testing ALWAYS and NEVER are hard-coded to
13211 ** be true and false so that the unreachable code they specify will
13212 ** not be counted as untested code.
13213 */
13214 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
13215 # define ALWAYS(X) (1)
13216 # define NEVER(X) (0)
13217 #elif !defined(NDEBUG)
13218 # define ALWAYS(X) ((X)?1:(assert(0),0))
13219 # define NEVER(X) ((X)?(assert(0),1):0)
@@ -13220,30 +13331,10 @@
13220 #else
13221 # define ALWAYS(X) (X)
13222 # define NEVER(X) (X)
13223 #endif
13224
13225 /*
13226 ** The harmless(X) macro indicates that expression X is usually false
13227 ** but can be true without causing any problems, but we don't know of
13228 ** any way to cause X to be true.
13229 **
13230 ** In debugging and testing builds, this macro will abort if X is ever
13231 ** true. In this way, developers are alerted to a possible test case
13232 ** that causes X to be true. If a harmless macro ever fails, that is
13233 ** an opportunity to change the macro into a testcase() and add a new
13234 ** test case to the test suite.
13235 **
13236 ** For normal production builds, harmless(X) is a no-op, since it does
13237 ** not matter whether expression X is true or false.
13238 */
13239 #ifdef SQLITE_DEBUG
13240 # define harmless(X) assert(!(X));
13241 #else
13242 # define harmless(X)
13243 #endif
13244
13245 /*
13246 ** Some conditionals are optimizations only. In other words, if the
13247 ** conditionals are replaced with a constant 1 (true) or 0 (false) then
13248 ** the correct answer is still obtained, though perhaps not as quickly.
13249 **
@@ -13422,11 +13513,11 @@
13422 /* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
13423
13424 /*
13425 ** Number of entries in a hash table
13426 */
13427 /* #define sqliteHashCount(H) ((H)->count) // NOT USED */
13428
13429 #endif /* SQLITE_HASH_H */
13430
13431 /************** End of hash.h ************************************************/
13432 /************** Continuing where we left off in sqliteInt.h ******************/
@@ -13474,14 +13565,14 @@
13474 #define TK_DETACH 40
13475 #define TK_EACH 41
13476 #define TK_FAIL 42
13477 #define TK_OR 43
13478 #define TK_AND 44
13479 #define TK_IS 45
13480 #define TK_MATCH 46
13481 #define TK_LIKE_KW 47
13482 #define TK_BETWEEN 48
13483 #define TK_IN 49
13484 #define TK_ISNULL 50
13485 #define TK_NOTNULL 51
13486 #define TK_NE 52
13487 #define TK_EQ 53
@@ -13718,11 +13809,11 @@
13718 ** The default initial allocation for the pagecache when using separate
13719 ** pagecaches for each database connection. A positive number is the
13720 ** number of pages. A negative number N translations means that a buffer
13721 ** of -1024*N bytes is allocated and used for as many pages as it will hold.
13722 **
13723 ** The default value of "20" was choosen to minimize the run-time of the
13724 ** speedtest1 test program with options: --shrink-memory --reprepare
13725 */
13726 #ifndef SQLITE_DEFAULT_PCACHE_INITSZ
13727 # define SQLITE_DEFAULT_PCACHE_INITSZ 20
13728 #endif
@@ -14075,15 +14166,29 @@
14075 int nBusy; /* Incremented with each busy call */
14076 };
14077
14078 /*
14079 ** Name of table that holds the database schema.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14080 */
14081 #define DFLT_SCHEMA_TABLE "sqlite_master"
14082 #define DFLT_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14083 #define ALT_SCHEMA_TABLE "sqlite_schema"
14084 #define ALT_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
14085
14086
14087 /*
14088 ** The root-page of the schema table.
14089 */
@@ -14091,11 +14196,11 @@
14091
14092 /*
14093 ** The name of the schema table. The name is different for TEMP.
14094 */
14095 #define SCHEMA_TABLE(x) \
14096 ((!OMIT_TEMPDB)&&(x==1)?DFLT_TEMP_SCHEMA_TABLE:DFLT_SCHEMA_TABLE)
14097
14098 /*
14099 ** A convenience macro that returns the number of elements in
14100 ** an array.
14101 */
@@ -15159,49 +15264,49 @@
15159 #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */
15160 #define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
15161 #define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */
15162 #define OP_IncrVacuum 61 /* jump */
15163 #define OP_VNext 62 /* jump */
15164 #define OP_Init 63 /* jump, synopsis: Start at P2 */
15165 #define OP_PureFunc 64 /* synopsis: r[P3]=func(r[P2@NP]) */
15166 #define OP_Function 65 /* synopsis: r[P3]=func(r[P2@NP]) */
15167 #define OP_Return 66
15168 #define OP_EndCoroutine 67
15169 #define OP_HaltIfNull 68 /* synopsis: if r[P3]=null halt */
15170 #define OP_Halt 69
15171 #define OP_Integer 70 /* synopsis: r[P2]=P1 */
15172 #define OP_Int64 71 /* synopsis: r[P2]=P4 */
15173 #define OP_String 72 /* synopsis: r[P2]='P4' (len=P1) */
15174 #define OP_Null 73 /* synopsis: r[P2..P3]=NULL */
15175 #define OP_SoftNull 74 /* synopsis: r[P1]=NULL */
15176 #define OP_Blob 75 /* synopsis: r[P2]=P4 (len=P1) */
15177 #define OP_Variable 76 /* synopsis: r[P2]=parameter(P1,P4) */
15178 #define OP_Move 77 /* synopsis: r[P2@P3]=r[P1@P3] */
15179 #define OP_Copy 78 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15180 #define OP_SCopy 79 /* synopsis: r[P2]=r[P1] */
15181 #define OP_IntCopy 80 /* synopsis: r[P2]=r[P1] */
15182 #define OP_ChngCntRow 81 /* synopsis: output=r[P1] */
15183 #define OP_ResultRow 82 /* synopsis: output=r[P1@P2] */
15184 #define OP_CollSeq 83
15185 #define OP_AddImm 84 /* synopsis: r[P1]=r[P1]+P2 */
15186 #define OP_RealAffinity 85
15187 #define OP_Cast 86 /* synopsis: affinity(r[P1]) */
15188 #define OP_Permutation 87
15189 #define OP_Compare 88 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15190 #define OP_IsTrue 89 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15191 #define OP_ZeroOrNull 90 /* synopsis: r[P2] = 0 OR NULL */
15192 #define OP_Offset 91 /* synopsis: r[P3] = sqlite_offset(P1) */
15193 #define OP_Column 92 /* synopsis: r[P3]=PX */
15194 #define OP_TypeCheck 93 /* synopsis: typecheck(r[P1@P2]) */
15195 #define OP_Affinity 94 /* synopsis: affinity(r[P1@P2]) */
15196 #define OP_MakeRecord 95 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15197 #define OP_Count 96 /* synopsis: r[P2]=count() */
15198 #define OP_ReadCookie 97
15199 #define OP_SetCookie 98
15200 #define OP_ReopenIdx 99 /* synopsis: root=P2 iDb=P3 */
15201 #define OP_OpenRead 100 /* synopsis: root=P2 iDb=P3 */
15202 #define OP_OpenWrite 101 /* synopsis: root=P2 iDb=P3 */
15203 #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
15204 #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
15205 #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
15206 #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
15207 #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15208,80 +15313,82 @@
15208 #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
15209 #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
15210 #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
15211 #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
15212 #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15213 #define OP_OpenDup 112
15214 #define OP_BitNot 113 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15215 #define OP_OpenAutoindex 114 /* synopsis: nColumn=P2 */
15216 #define OP_OpenEphemeral 115 /* synopsis: nColumn=P2 */
15217 #define OP_String8 116 /* same as TK_STRING, synopsis: r[P2]='P4' */
15218 #define OP_SorterOpen 117
15219 #define OP_SequenceTest 118 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15220 #define OP_OpenPseudo 119 /* synopsis: P3 columns in r[P2] */
15221 #define OP_Close 120
15222 #define OP_ColumnsUsed 121
15223 #define OP_SeekScan 122 /* synopsis: Scan-ahead up to P1 rows */
15224 #define OP_SeekHit 123 /* synopsis: set P2<=seekHit<=P3 */
15225 #define OP_Sequence 124 /* synopsis: r[P2]=cursor[P1].ctr++ */
15226 #define OP_NewRowid 125 /* synopsis: r[P2]=rowid */
15227 #define OP_Insert 126 /* synopsis: intkey=r[P3] data=r[P2] */
15228 #define OP_RowCell 127
15229 #define OP_Delete 128
15230 #define OP_ResetCount 129
15231 #define OP_SorterCompare 130 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15232 #define OP_SorterData 131 /* synopsis: r[P2]=data */
15233 #define OP_RowData 132 /* synopsis: r[P2]=data */
15234 #define OP_Rowid 133 /* synopsis: r[P2]=rowid */
15235 #define OP_NullRow 134
15236 #define OP_SeekEnd 135
15237 #define OP_IdxInsert 136 /* synopsis: key=r[P2] */
15238 #define OP_SorterInsert 137 /* synopsis: key=r[P2] */
15239 #define OP_IdxDelete 138 /* synopsis: key=r[P2@P3] */
15240 #define OP_DeferredSeek 139 /* synopsis: Move P3 to P1.rowid if needed */
15241 #define OP_IdxRowid 140 /* synopsis: r[P2]=rowid */
15242 #define OP_FinishSeek 141
15243 #define OP_Destroy 142
15244 #define OP_Clear 143
15245 #define OP_ResetSorter 144
15246 #define OP_CreateBtree 145 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15247 #define OP_SqlExec 146
15248 #define OP_ParseSchema 147
15249 #define OP_LoadAnalysis 148
15250 #define OP_DropTable 149
15251 #define OP_DropIndex 150
15252 #define OP_DropTrigger 151
15253 #define OP_Real 152 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15254 #define OP_IntegrityCk 153
15255 #define OP_RowSetAdd 154 /* synopsis: rowset(P1)=r[P2] */
15256 #define OP_Param 155
15257 #define OP_FkCounter 156 /* synopsis: fkctr[P1]+=P2 */
15258 #define OP_MemMax 157 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15259 #define OP_OffsetLimit 158 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15260 #define OP_AggInverse 159 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15261 #define OP_AggStep 160 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15262 #define OP_AggStep1 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15263 #define OP_AggValue 162 /* synopsis: r[P3]=value N=P2 */
15264 #define OP_AggFinal 163 /* synopsis: accum=r[P1] N=P2 */
15265 #define OP_Expire 164
15266 #define OP_CursorLock 165
15267 #define OP_CursorUnlock 166
15268 #define OP_TableLock 167 /* synopsis: iDb=P1 root=P2 write=P3 */
15269 #define OP_VBegin 168
15270 #define OP_VCreate 169
15271 #define OP_VDestroy 170
15272 #define OP_VOpen 171
15273 #define OP_VColumn 172 /* synopsis: r[P3]=vcolumn(P2) */
15274 #define OP_VRename 173
15275 #define OP_Pagecount 174
15276 #define OP_MaxPgcnt 175
15277 #define OP_Trace 176
15278 #define OP_CursorHint 177
15279 #define OP_ReleaseReg 178 /* synopsis: release r[P1@P2] mask P3 */
15280 #define OP_Noop 179
15281 #define OP_Explain 180
15282 #define OP_Abortable 181
 
 
15283
15284 /* Properties such as "out2" or "jump" that are specified in
15285 ** comments following the "case" for each opcode in the vdbe.c
15286 ** are encoded into bitvectors as follows:
15287 */
@@ -15298,33 +15405,34 @@
15298 /* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
15299 /* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15300 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15301 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15302 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15303 /* 64 */ 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10, 0x10,\
15304 /* 72 */ 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,\
15305 /* 80 */ 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x00,\
15306 /* 88 */ 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00,\
15307 /* 96 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x26, 0x26,\
15308 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15309 /* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\
15310 /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00,\
15311 /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,\
15312 /* 136 */ 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00,\
15313 /* 144 */ 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15314 /* 152 */ 0x10, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a, 0x00,\
15315 /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15316 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10,\
15317 /* 176 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,}
 
15318
15319 /* The resolve3P2Values() routine is able to run faster if it knows
15320 ** the value of the largest JUMP opcode. The smaller the maximum
15321 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15322 ** generated this include file strives to group all JUMP opcodes
15323 ** together near the beginning of the list.
15324 */
15325 #define SQLITE_MX_JUMP_OPCODE 63 /* Maximum JUMP opcode */
15326
15327 /************** End of opcodes.h *********************************************/
15328 /************** Continuing where we left off in vdbe.h ***********************/
15329
15330 /*
@@ -16420,14 +16528,14 @@
16420 int nVdbeExec; /* Number of nested calls to VdbeExec() */
16421 int nVDestroy; /* Number of active OP_VDestroy operations */
16422 int nExtension; /* Number of loaded extensions */
16423 void **aExtension; /* Array of shared library handles */
16424 union {
16425 void (*xLegacy)(void*,const char*); /* Legacy trace function */
16426 int (*xV2)(u32,void*,void*,void*); /* V2 Trace function */
16427 } trace;
16428 void *pTraceArg; /* Argument to the trace function */
16429 #ifndef SQLITE_OMIT_DEPRECATED
16430 void (*xProfile)(void*,const char*,u64); /* Profiling function */
16431 void *pProfileArg; /* Argument to profile function */
16432 #endif
16433 void *pCommitArg; /* Argument to xCommitCallback() */
@@ -16434,10 +16542,13 @@
16434 int (*xCommitCallback)(void*); /* Invoked at every commit. */
16435 void *pRollbackArg; /* Argument to xRollbackCallback() */
16436 void (*xRollbackCallback)(void*); /* Invoked at every commit. */
16437 void *pUpdateArg;
16438 void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
 
 
 
16439 Parse *pParse; /* Current parse */
16440 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
16441 void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
16442 void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
16443 void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
@@ -16563,10 +16674,11 @@
16563 #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
16564 #define SQLITE_EnableView 0x80000000 /* Enable the use of views */
16565 #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
16566 /* DELETE, or UPDATE and return */
16567 /* the count using a callback. */
 
16568
16569 /* Flags used only if debugging */
16570 #ifdef SQLITE_DEBUG
16571 #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
16572 #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -16611,10 +16723,12 @@
16611 #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
16612 #define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
16613 #define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */
16614 #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
16615 /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
 
 
16616 #define SQLITE_AllOpts 0xffffffff /* All optimizations */
16617
16618 /*
16619 ** Macros for testing whether or not optimizations are enabled or disabled.
16620 */
@@ -16659,11 +16773,11 @@
16659 void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
16660 const char *zName; /* SQL name of the function. */
16661 union {
16662 FuncDef *pHash; /* Next with a different name but the same hash */
16663 FuncDestructor *pDestructor; /* Reference counted destructor function */
16664 } u;
16665 };
16666
16667 /*
16668 ** This structure encapsulates a user-function destructor callback (as
16669 ** configured using create_function_v2()) and a reference counter. When
@@ -16720,10 +16834,11 @@
16720 #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
16721 #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
16722 #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
16723 #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
16724 #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */
 
16725 #define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */
16726
16727 /* Identifier numbers for each in-line function */
16728 #define INLINEFUNC_coalesce 0
16729 #define INLINEFUNC_implies_nonnull_row 1
@@ -16798,48 +16913,55 @@
16798 ** available as the function user-data (sqlite3_user_data()). The
16799 ** FuncDef.flags variable is set to the value passed as the flags
16800 ** parameter.
16801 */
16802 #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
16803 {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
 
16804 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16805 #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16806 {nArg, SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16807 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16808 #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16809 {nArg, SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
16810 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16811 #define MFUNCTION(zName, nArg, xPtr, xFunc) \
16812 {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
16813 xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
16814 #define INLINE_FUNC(zName, nArg, iArg, mFlags) \
16815 {nArg, SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
 
16816 SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
16817 #define TEST_FUNC(zName, nArg, iArg, mFlags) \
16818 {nArg, SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
 
16819 SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
16820 SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
16821 #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16822 {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
16823 0, 0, xFunc, 0, 0, 0, #zName, {0} }
16824 #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
16825 {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
 
16826 (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
16827 #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
16828 {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
 
16829 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16830 #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
16831 {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
 
16832 pArg, 0, xFunc, 0, 0, 0, #zName, }
16833 #define LIKEFUNC(zName, nArg, arg, flags) \
16834 {nArg, SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
16835 (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
16836 #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
16837 {nArg, SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
16838 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
16839 #define INTERNAL_FUNCTION(zName, nArg, xFunc) \
16840 {nArg, SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
 
16841 0, 0, xFunc, 0, 0, 0, #zName, {0} }
16842
16843
16844 /*
16845 ** All current savepoints are stored in a linked list starting at
@@ -17558,14 +17680,14 @@
17558 ** code representing the ">=" operator. This same integer code is reused
17559 ** to represent the greater-than-or-equal-to operator in the expression
17560 ** tree.
17561 **
17562 ** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
17563 ** or TK_STRING), then Expr.token contains the text of the SQL literal. If
17564 ** the expression is a variable (TK_VARIABLE), then Expr.token contains the
17565 ** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
17566 ** then Expr.token contains the name of the function.
17567 **
17568 ** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
17569 ** binary operator. Either or both may be NULL.
17570 **
17571 ** Expr.x.pList is a list of arguments if the expression is an SQL function,
@@ -17601,11 +17723,11 @@
17601 **
17602 ** Expr objects can use a lot of memory space in database schema. To
17603 ** help reduce memory requirements, sometimes an Expr object will be
17604 ** truncated. And to reduce the number of memory allocations, sometimes
17605 ** two or more Expr objects will be stored in a single memory allocation,
17606 ** together with Expr.zToken strings.
17607 **
17608 ** If the EP_Reduced and EP_TokenOnly flags are set when
17609 ** an Expr object is truncated. When EP_Reduced is set, then all
17610 ** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
17611 ** are contained within the same memory allocation. Note, however, that
@@ -17670,12 +17792,11 @@
17670 int regReturn; /* Register used to hold return address */
17671 } sub;
17672 } y;
17673 };
17674
17675 /*
17676 ** The following are the meanings of bits in the Expr.flags field.
17677 ** Value restrictions:
17678 **
17679 ** EP_Agg == NC_HasAgg == SF_HasAgg
17680 ** EP_Win == NC_HasWin
17681 */
@@ -17710,27 +17831,35 @@
17710 #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
17711 #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
17712 #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
17713 /* 0x80000000 // Available */
17714
17715 /*
17716 ** The EP_Propagate mask is a set of properties that automatically propagate
17717 ** upwards into parent nodes.
17718 */
17719 #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
17720
17721 /*
17722 ** These macros can be used to test, set, or clear bits in the
17723 ** Expr.flags field.
17724 */
17725 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
17726 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
17727 #define ExprSetProperty(E,P) (E)->flags|=(P)
17728 #define ExprClearProperty(E,P) (E)->flags&=~(P)
17729 #define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
17730 #define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
17731
 
 
 
 
 
 
 
 
 
 
17732
17733 /* Flags for use with Expr.vvaFlags
17734 */
17735 #define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */
17736 #define EP_Immutable 0x02 /* Do not change this Expr node */
@@ -17809,15 +17938,16 @@
17809 unsigned done :1; /* A flag to indicate when processing is finished */
17810 unsigned reusable :1; /* Constant expression is reusable */
17811 unsigned bSorterRef :1; /* Defer evaluation until after sorting */
17812 unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
17813 union {
17814 struct {
17815 u16 iOrderByCol; /* For ORDER BY, column number in result set */
17816 u16 iAlias; /* Index into Parse.aAlias[] for zName */
17817 } x;
17818 int iConstExprReg; /* Register in which Expr value is cached */
 
17819 } u;
17820 } a[1]; /* One slot for each expression in the list */
17821 };
17822
17823 /*
@@ -17851,10 +17981,17 @@
17851 };
17852
17853 /*
17854 ** The SrcItem object represents a single term in the FROM clause of a query.
17855 ** The SrcList object is mostly an array of SrcItems.
 
 
 
 
 
 
 
17856 */
17857 struct SrcItem {
17858 Schema *pSchema; /* Schema to which this item is fixed */
17859 char *zDatabase; /* Name of database holding this table */
17860 char *zName; /* Name of the table */
@@ -18382,11 +18519,10 @@
18382 TableLock *aTableLock; /* Required table locks for shared-cache mode */
18383 #endif
18384 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
18385 Parse *pToplevel; /* Parse structure for main program (or NULL) */
18386 Table *pTriggerTab; /* Table triggers are being coded for */
18387 Parse *pParentParse; /* Parent parser if this parser is nested */
18388 union {
18389 int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
18390 Returning *pReturning; /* The RETURNING clause */
18391 } u1;
18392 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
@@ -18445,10 +18581,12 @@
18445 #ifndef SQLITE_OMIT_ALTERTABLE
18446 RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */
18447 #endif
18448 };
18449
 
 
18450 #define PARSE_MODE_NORMAL 0
18451 #define PARSE_MODE_DECLARE_VTAB 1
18452 #define PARSE_MODE_RENAME 2
18453 #define PARSE_MODE_UNMAP 3
18454
@@ -18666,12 +18804,14 @@
18666 } InitData;
18667
18668 /*
18669 ** Allowed values for mInitFlags
18670 */
 
18671 #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
18672 #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
 
18673
18674 /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
18675 ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
18676 ** parameters are for temporary use during development, to help find
18677 ** optimial values for parameters in the query planner. The should not
@@ -18788,12 +18928,12 @@
18788 union { /* Extra data for callback */
18789 NameContext *pNC; /* Naming context */
18790 int n; /* A counter */
18791 int iCur; /* A cursor number */
18792 SrcList *pSrcList; /* FROM clause */
18793 struct SrcCount *pSrcCount; /* Counting column references */
18794 struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
 
18795 int *aiCol; /* array of column indexes */
18796 struct IdxCover *pIdxCover; /* Check for index coverage */
18797 struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
18798 ExprList *pGroupBy; /* GROUP BY clause */
18799 Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19387,10 +19527,11 @@
19387 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
19388 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
19389 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
19390 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
19391 #endif
 
19392 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
19393 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
19394 Upsert*);
19395 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
19396 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
@@ -19430,10 +19571,11 @@
19430 SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
19431 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
19432 #define LOCATE_VIEW 0x01
19433 #define LOCATE_NOERR 0x02
19434 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
 
19435 SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
19436 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
19437 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
19438 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
19439 SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
@@ -19446,11 +19588,11 @@
19446 SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
19447 SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
19448 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
19449 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
19450 SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19451 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
19452 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
19453 #ifndef SQLITE_UNTESTABLE
19454 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
19455 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
19456 #endif
@@ -19596,18 +19738,12 @@
19596 #endif
19597 SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
19598 SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
19599 SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
19600 SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
19601 #ifndef SQLITE_OMIT_VIRTUALTABLE
19602 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
19603 #endif
19604 #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
19605 defined(SQLITE_ENABLE_STAT4) || \
19606 defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
19607 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
19608 #endif
19609 SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
19610 SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
19611 SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
19612
19613 /*
@@ -19888,13 +20024,15 @@
19888 #endif
19889 SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
19890 #ifndef SQLITE_OMIT_VIRTUALTABLE
19891 SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
19892 SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
 
19893 #else
19894 # define sqlite3ShadowTableName(A,B) 0
19895 # define sqlite3IsShadowTableOf(A,B,C) 0
 
19896 #endif
19897 SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
19898 SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
19899 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
19900 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -19933,11 +20071,11 @@
19933 #else
19934 # define sqlite3CteNew(P,T,E,S) ((void*)0)
19935 # define sqlite3CteDelete(D,C)
19936 # define sqlite3CteWithAdd(P,W,C) ((void*)0)
19937 # define sqlite3WithDelete(x,y)
19938 # define sqlite3WithPush(x,y,z)
19939 #endif
19940 #ifndef SQLITE_OMIT_UPSERT
19941 SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
19942 SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
19943 SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
@@ -20101,12 +20239,12 @@
20101 ** All of this is no-op for a production build. It only comes into
20102 ** play when the SQLITE_MEMDEBUG compile-time option is used.
20103 */
20104 #ifdef SQLITE_MEMDEBUG
20105 SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8);
20106 SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8);
20107 SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8);
20108 #else
20109 # define sqlite3MemdebugSetType(X,Y) /* no-op */
20110 # define sqlite3MemdebugHasType(X,Y) 1
20111 # define sqlite3MemdebugNoType(X,Y) 1
20112 #endif
@@ -21425,10 +21563,22 @@
21425 ** database connections. After initialization, this table is
21426 ** read-only.
21427 */
21428 SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
21429
 
 
 
 
 
 
 
 
 
 
 
 
21430 #ifdef VDBE_PROFILE
21431 /*
21432 ** The following performance counter can be used in place of
21433 ** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
21434 */
@@ -21969,11 +22119,11 @@
21969 bft usesStmtJournal:1; /* True if uses a statement journal */
21970 bft readOnly:1; /* True for statements that do not write */
21971 bft bIsReader:1; /* True for statements that read */
21972 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
21973 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
21974 u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */
21975 char *zSql; /* Text of the SQL statement that generated this */
21976 #ifdef SQLITE_ENABLE_NORMALIZE
21977 char *zNormSql; /* Normalization of the associated SQL statement */
21978 DblquoteStr *pDblStr; /* List of double-quoted string literals */
21979 #endif
@@ -22065,19 +22215,23 @@
22065 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
22066 #endif
22067 SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
22068 SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
22069 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
 
22070 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
 
 
 
22071 #ifdef SQLITE_DEBUG
22072 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
22073 #endif
22074 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
22075 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
22076 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
22077 SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
22078 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*);
22079 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
22080 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
22081 SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
22082 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
22083 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
@@ -23071,11 +23225,13 @@
23071 pX = localtime(t);
23072 #ifndef SQLITE_UNTESTABLE
23073 if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
23074 #endif
23075 if( pX ) *pTm = *pX;
 
23076 sqlite3_mutex_leave(mutex);
 
23077 rc = pX==0;
23078 #else
23079 #ifndef SQLITE_UNTESTABLE
23080 if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
23081 #endif
@@ -23210,10 +23366,49 @@
23210 DateTime *p /* The date/time value to be modified */
23211 ){
23212 int rc = 1;
23213 double r;
23214 switch(sqlite3UpperToLower[(u8)z[0]] ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23215 #ifndef SQLITE_OMIT_LOCALTIME
23216 case 'l': {
23217 /* localtime
23218 **
23219 ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
@@ -23473,10 +23668,28 @@
23473 if( isDate(context, argc, argv, &x)==0 ){
23474 computeJD(&x);
23475 sqlite3_result_double(context, x.iJD/86400000.0);
23476 }
23477 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23478
23479 /*
23480 ** datetime( TIMESTRING, MOD, MOD, ...)
23481 **
23482 ** Return YYYY-MM-DD HH:MM:SS
@@ -23573,11 +23786,11 @@
23573
23574 computeJD(&x);
23575 computeYMD_HMS(&x);
23576 for(i=j=0; zFmt[i]; i++){
23577 if( zFmt[i]!='%' ) continue;
23578 if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j);
23579 i++;
23580 j = i + 1;
23581 switch( zFmt[i] ){
23582 case 'd': {
23583 sqlite3_str_appendf(&sRes, "%02d", x.D);
@@ -23649,11 +23862,11 @@
23649 sqlite3_str_reset(&sRes);
23650 return;
23651 }
23652 }
23653 }
23654 if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j);
23655 sqlite3ResultStrAccum(context, &sRes);
23656 }
23657
23658 /*
23659 ** current_time()
@@ -23750,10 +23963,11 @@
23750 */
23751 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
23752 static FuncDef aDateTimeFuncs[] = {
23753 #ifndef SQLITE_OMIT_DATETIME_FUNCS
23754 PURE_DATE(julianday, -1, 0, 0, juliandayFunc ),
 
23755 PURE_DATE(date, -1, 0, 0, dateFunc ),
23756 PURE_DATE(time, -1, 0, 0, timeFunc ),
23757 PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
23758 PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
23759 DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
@@ -24086,16 +24300,19 @@
24086 pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
24087 if( pFile ){
24088 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
24089 if( rc!=SQLITE_OK ){
24090 sqlite3_free(pFile);
 
24091 }else{
24092 *ppFile = pFile;
24093 }
24094 }else{
 
24095 rc = SQLITE_NOMEM_BKPT;
24096 }
 
24097 return rc;
24098 }
24099 SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
24100 assert( pFile );
24101 sqlite3OsClose(pFile);
@@ -24809,11 +25026,11 @@
24809 ** Given an allocation, find the MemBlockHdr for that allocation.
24810 **
24811 ** This routine checks the guards at either end of the allocation and
24812 ** if they are incorrect it asserts.
24813 */
24814 static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){
24815 struct MemBlockHdr *p;
24816 int *pInt;
24817 u8 *pU8;
24818 int nReserve;
24819
@@ -25056,11 +25273,11 @@
25056 ** This routine is designed for use within an assert() statement, to
25057 ** verify the type of an allocation. For example:
25058 **
25059 ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
25060 */
25061 SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){
25062 int rc = 1;
25063 if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
25064 struct MemBlockHdr *pHdr;
25065 pHdr = sqlite3MemsysGetHeader(p);
25066 assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
@@ -25078,11 +25295,11 @@
25078 ** This routine is designed for use within an assert() statement, to
25079 ** verify the type of an allocation. For example:
25080 **
25081 ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
25082 */
25083 SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){
25084 int rc = 1;
25085 if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
25086 struct MemBlockHdr *pHdr;
25087 pHdr = sqlite3MemsysGetHeader(p);
25088 assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
@@ -30543,10 +30760,11 @@
30543 zOp2[0] = 0;
30544 }
30545 sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s",
30546 pExpr->iColumn, zFlgs, zOp2);
30547 }else{
 
30548 sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s",
30549 pExpr->iTable, pExpr->iColumn,
30550 pExpr->y.pTab, zFlgs);
30551 }
30552 if( ExprHasProperty(pExpr, EP_FixedCol) ){
@@ -30562,15 +30780,17 @@
30562 }
30563 break;
30564 }
30565 #ifndef SQLITE_OMIT_FLOATING_POINT
30566 case TK_FLOAT: {
 
30567 sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
30568 break;
30569 }
30570 #endif
30571 case TK_STRING: {
 
30572 sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
30573 break;
30574 }
30575 case TK_NULL: {
30576 sqlite3TreeViewLine(pView,"NULL");
@@ -30581,30 +30801,34 @@
30581 sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs);
30582 break;
30583 }
30584 #ifndef SQLITE_OMIT_BLOB_LITERAL
30585 case TK_BLOB: {
 
30586 sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
30587 break;
30588 }
30589 #endif
30590 case TK_VARIABLE: {
 
30591 sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
30592 pExpr->u.zToken, pExpr->iColumn);
30593 break;
30594 }
30595 case TK_REGISTER: {
30596 sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
30597 break;
30598 }
30599 case TK_ID: {
 
30600 sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
30601 break;
30602 }
30603 #ifndef SQLITE_OMIT_CAST
30604 case TK_CAST: {
30605 /* Expressions of the form: CAST(pLeft AS token) */
 
30606 sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
30607 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
30608 break;
30609 }
30610 #endif /* SQLITE_OMIT_CAST */
@@ -30650,10 +30874,11 @@
30650 zUniOp = azOp[x];
30651 break;
30652 }
30653
30654 case TK_SPAN: {
 
30655 sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
30656 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
30657 break;
30658 }
30659
@@ -30661,10 +30886,11 @@
30661 /* COLLATE operators without the EP_Collate flag are intended to
30662 ** emulate collation associated with a table column. These show
30663 ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
30664 ** operators that appear in the original SQL always have the
30665 ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
 
30666 sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
30667 !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
30668 pExpr->u.zToken, zFlgs);
30669 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
30670 break;
@@ -30676,17 +30902,19 @@
30676 Window *pWin;
30677 if( ExprHasProperty(pExpr, EP_TokenOnly) ){
30678 pFarg = 0;
30679 pWin = 0;
30680 }else{
 
30681 pFarg = pExpr->x.pList;
30682 #ifndef SQLITE_OMIT_WINDOWFUNC
30683 pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0;
30684 #else
30685 pWin = 0;
30686 #endif
30687 }
 
30688 if( pExpr->op==TK_AGG_FUNCTION ){
30689 sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
30690 pExpr->op2, pExpr->u.zToken, zFlgs,
30691 pExpr->pAggInfo ? pExpr->pAggInfo->selId : 0,
30692 pExpr->iAgg, pExpr->pAggInfo);
@@ -30714,23 +30942,25 @@
30714 #endif
30715 break;
30716 }
30717 #ifndef SQLITE_OMIT_SUBQUERY
30718 case TK_EXISTS: {
 
30719 sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
30720 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
30721 break;
30722 }
30723 case TK_SELECT: {
 
30724 sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags);
30725 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
30726 break;
30727 }
30728 case TK_IN: {
30729 sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
30730 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
30731 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
30732 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
30733 }else{
30734 sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
30735 }
30736 break;
@@ -30747,13 +30977,16 @@
30747 ** X is stored in pExpr->pLeft.
30748 ** Y is stored in pExpr->pList->a[0].pExpr.
30749 ** Z is stored in pExpr->pList->a[1].pExpr.
30750 */
30751 case TK_BETWEEN: {
30752 Expr *pX = pExpr->pLeft;
30753 Expr *pY = pExpr->x.pList->a[0].pExpr;
30754 Expr *pZ = pExpr->x.pList->a[1].pExpr;
 
 
 
30755 sqlite3TreeViewLine(pView, "BETWEEN");
30756 sqlite3TreeViewExpr(pView, pX, 1);
30757 sqlite3TreeViewExpr(pView, pY, 1);
30758 sqlite3TreeViewExpr(pView, pZ, 0);
30759 break;
@@ -30771,10 +31004,11 @@
30771 break;
30772 }
30773 case TK_CASE: {
30774 sqlite3TreeViewLine(pView, "CASE");
30775 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
 
30776 sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
30777 break;
30778 }
30779 #ifndef SQLITE_OMIT_TRIGGER
30780 case TK_RAISE: {
@@ -30783,10 +31017,11 @@
30783 case OE_Rollback: zType = "rollback"; break;
30784 case OE_Abort: zType = "abort"; break;
30785 case OE_Fail: zType = "fail"; break;
30786 case OE_Ignore: zType = "ignore"; break;
30787 }
 
30788 sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
30789 break;
30790 }
30791 #endif
30792 case TK_MATCH: {
@@ -30795,18 +31030,20 @@
30795 sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
30796 break;
30797 }
30798 case TK_VECTOR: {
30799 char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
 
30800 sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
30801 sqlite3_free(z);
30802 break;
30803 }
30804 case TK_SELECT_COLUMN: {
30805 sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s",
30806 pExpr->iColumn, pExpr->iTable-1,
30807 pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : "");
 
30808 sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
30809 break;
30810 }
30811 case TK_IF_NULL_ROW: {
30812 sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
@@ -31879,20 +32116,10 @@
31879 /* #include <stdarg.h> */
31880 #ifndef SQLITE_OMIT_FLOATING_POINT
31881 #include <math.h>
31882 #endif
31883
31884 /*
31885 ** Routine needed to support the testcase() macro.
31886 */
31887 #ifdef SQLITE_COVERAGE_TEST
31888 SQLITE_PRIVATE void sqlite3Coverage(int x){
31889 static unsigned dummy = 0;
31890 dummy += (unsigned)x;
31891 }
31892 #endif
31893
31894 /*
31895 ** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
31896 ** or to bypass normal error detection during testing in order to let
31897 ** execute proceed futher downstream.
31898 **
@@ -32135,10 +32362,11 @@
32135 }
32136 }
32137 z[j] = 0;
32138 }
32139 SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
 
32140 assert( sqlite3Isquote(p->u.zToken[0]) );
32141 p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted;
32142 sqlite3Dequote(p->u.zToken);
32143 }
32144
@@ -33453,11 +33681,10 @@
33453 #endif
33454 }
33455 return a[x&7] + y - 10;
33456 }
33457
33458 #ifndef SQLITE_OMIT_VIRTUALTABLE
33459 /*
33460 ** Convert a double into a LogEst
33461 ** In other words, compute an approximation for 10*log2(x).
33462 */
33463 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
@@ -33468,38 +33695,23 @@
33468 if( x<=2000000000 ) return sqlite3LogEst((u64)x);
33469 memcpy(&a, &x, 8);
33470 e = (a>>52) - 1022;
33471 return e*10;
33472 }
33473 #endif /* SQLITE_OMIT_VIRTUALTABLE */
33474
33475 #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
33476 defined(SQLITE_ENABLE_STAT4) || \
33477 defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
33478 /*
33479 ** Convert a LogEst into an integer.
33480 **
33481 ** Note that this routine is only used when one or more of various
33482 ** non-standard compile-time options is enabled.
33483 */
33484 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
33485 u64 n;
33486 n = x%10;
33487 x /= 10;
33488 if( n>=5 ) n -= 2;
33489 else if( n>=1 ) n -= 1;
33490 #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \
33491 defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
33492 if( x>60 ) return (u64)LARGEST_INT64;
33493 #else
33494 /* If only SQLITE_ENABLE_STAT4 is on, then the largest input
33495 ** possible to this routine is 310, resulting in a maximum x of 31 */
33496 assert( x<=60 );
33497 #endif
33498 return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
33499 }
33500 #endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */
33501
33502 /*
33503 ** Add a new name/number pair to a VList. This might require that the
33504 ** VList object be reallocated, so return the new VList. If an OOM
33505 ** error occurs, the original VList returned and the
@@ -33949,49 +34161,49 @@
33949 /* 58 */ "ElseEq" OpHelp(""),
33950 /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
33951 /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
33952 /* 61 */ "IncrVacuum" OpHelp(""),
33953 /* 62 */ "VNext" OpHelp(""),
33954 /* 63 */ "Init" OpHelp("Start at P2"),
33955 /* 64 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
33956 /* 65 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
33957 /* 66 */ "Return" OpHelp(""),
33958 /* 67 */ "EndCoroutine" OpHelp(""),
33959 /* 68 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
33960 /* 69 */ "Halt" OpHelp(""),
33961 /* 70 */ "Integer" OpHelp("r[P2]=P1"),
33962 /* 71 */ "Int64" OpHelp("r[P2]=P4"),
33963 /* 72 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
33964 /* 73 */ "Null" OpHelp("r[P2..P3]=NULL"),
33965 /* 74 */ "SoftNull" OpHelp("r[P1]=NULL"),
33966 /* 75 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
33967 /* 76 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
33968 /* 77 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
33969 /* 78 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
33970 /* 79 */ "SCopy" OpHelp("r[P2]=r[P1]"),
33971 /* 80 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
33972 /* 81 */ "ChngCntRow" OpHelp("output=r[P1]"),
33973 /* 82 */ "ResultRow" OpHelp("output=r[P1@P2]"),
33974 /* 83 */ "CollSeq" OpHelp(""),
33975 /* 84 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
33976 /* 85 */ "RealAffinity" OpHelp(""),
33977 /* 86 */ "Cast" OpHelp("affinity(r[P1])"),
33978 /* 87 */ "Permutation" OpHelp(""),
33979 /* 88 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
33980 /* 89 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
33981 /* 90 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
33982 /* 91 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
33983 /* 92 */ "Column" OpHelp("r[P3]=PX"),
33984 /* 93 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
33985 /* 94 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
33986 /* 95 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
33987 /* 96 */ "Count" OpHelp("r[P2]=count()"),
33988 /* 97 */ "ReadCookie" OpHelp(""),
33989 /* 98 */ "SetCookie" OpHelp(""),
33990 /* 99 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
33991 /* 100 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
33992 /* 101 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
33993 /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
33994 /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
33995 /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
33996 /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
33997 /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -33998,80 +34210,82 @@
33998 /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
33999 /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
34000 /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
34001 /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
34002 /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34003 /* 112 */ "OpenDup" OpHelp(""),
34004 /* 113 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34005 /* 114 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34006 /* 115 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34007 /* 116 */ "String8" OpHelp("r[P2]='P4'"),
34008 /* 117 */ "SorterOpen" OpHelp(""),
34009 /* 118 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34010 /* 119 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34011 /* 120 */ "Close" OpHelp(""),
34012 /* 121 */ "ColumnsUsed" OpHelp(""),
34013 /* 122 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34014 /* 123 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34015 /* 124 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34016 /* 125 */ "NewRowid" OpHelp("r[P2]=rowid"),
34017 /* 126 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34018 /* 127 */ "RowCell" OpHelp(""),
34019 /* 128 */ "Delete" OpHelp(""),
34020 /* 129 */ "ResetCount" OpHelp(""),
34021 /* 130 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34022 /* 131 */ "SorterData" OpHelp("r[P2]=data"),
34023 /* 132 */ "RowData" OpHelp("r[P2]=data"),
34024 /* 133 */ "Rowid" OpHelp("r[P2]=rowid"),
34025 /* 134 */ "NullRow" OpHelp(""),
34026 /* 135 */ "SeekEnd" OpHelp(""),
34027 /* 136 */ "IdxInsert" OpHelp("key=r[P2]"),
34028 /* 137 */ "SorterInsert" OpHelp("key=r[P2]"),
34029 /* 138 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34030 /* 139 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34031 /* 140 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34032 /* 141 */ "FinishSeek" OpHelp(""),
34033 /* 142 */ "Destroy" OpHelp(""),
34034 /* 143 */ "Clear" OpHelp(""),
34035 /* 144 */ "ResetSorter" OpHelp(""),
34036 /* 145 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34037 /* 146 */ "SqlExec" OpHelp(""),
34038 /* 147 */ "ParseSchema" OpHelp(""),
34039 /* 148 */ "LoadAnalysis" OpHelp(""),
34040 /* 149 */ "DropTable" OpHelp(""),
34041 /* 150 */ "DropIndex" OpHelp(""),
34042 /* 151 */ "DropTrigger" OpHelp(""),
34043 /* 152 */ "Real" OpHelp("r[P2]=P4"),
34044 /* 153 */ "IntegrityCk" OpHelp(""),
34045 /* 154 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34046 /* 155 */ "Param" OpHelp(""),
34047 /* 156 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34048 /* 157 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34049 /* 158 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34050 /* 159 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34051 /* 160 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34052 /* 161 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34053 /* 162 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34054 /* 163 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34055 /* 164 */ "Expire" OpHelp(""),
34056 /* 165 */ "CursorLock" OpHelp(""),
34057 /* 166 */ "CursorUnlock" OpHelp(""),
34058 /* 167 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34059 /* 168 */ "VBegin" OpHelp(""),
34060 /* 169 */ "VCreate" OpHelp(""),
34061 /* 170 */ "VDestroy" OpHelp(""),
34062 /* 171 */ "VOpen" OpHelp(""),
34063 /* 172 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34064 /* 173 */ "VRename" OpHelp(""),
34065 /* 174 */ "Pagecount" OpHelp(""),
34066 /* 175 */ "MaxPgcnt" OpHelp(""),
34067 /* 176 */ "Trace" OpHelp(""),
34068 /* 177 */ "CursorHint" OpHelp(""),
34069 /* 178 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34070 /* 179 */ "Noop" OpHelp(""),
34071 /* 180 */ "Explain" OpHelp(""),
34072 /* 181 */ "Abortable" OpHelp(""),
 
 
34073 };
34074 return azName[i];
34075 }
34076 #endif
34077
@@ -38028,11 +38242,13 @@
38028 }
38029 }
38030
38031 /* Forward declaration */
38032 static int unixGetTempname(int nBuf, char *zBuf);
38033 static int unixFcntlExternalReader(unixFile*, int*);
 
 
38034
38035 /*
38036 ** Information and control of an open file handle.
38037 */
38038 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -38147,11 +38363,16 @@
38147 return proxyFileControl(id,op,pArg);
38148 }
38149 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
38150
38151 case SQLITE_FCNTL_EXTERNAL_READER: {
 
38152 return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
 
 
 
 
38153 }
38154 }
38155 return SQLITE_NOTFOUND;
38156 }
38157
@@ -39867,40 +40088,50 @@
39867 OpenCounter(+1);
39868 verifyDbFile(pNew);
39869 }
39870 return rc;
39871 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39872
39873 /*
39874 ** Return the name of a directory in which to put temporary files.
39875 ** If no suitable temporary file directory can be found, return NULL.
39876 */
39877 static const char *unixTempFileDir(void){
39878 static const char *azDirs[] = {
39879 0,
39880 0,
39881 "/var/tmp",
39882 "/usr/tmp",
39883 "/tmp",
39884 "."
39885 };
39886 unsigned int i = 0;
39887 struct stat buf;
39888 const char *zDir = sqlite3_temp_directory;
39889
39890 if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR");
39891 if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR");
39892 while(1){
39893 if( zDir!=0
39894 && osStat(zDir, &buf)==0
39895 && S_ISDIR(buf.st_mode)
39896 && osAccess(zDir, 03)==0
39897 ){
39898 return zDir;
39899 }
39900 if( i>=sizeof(azDirs)/sizeof(azDirs[0]) ) break;
39901 zDir = azDirs[i++];
39902 }
39903 return 0;
39904 }
39905
39906 /*
@@ -40201,10 +40432,15 @@
40201 if( randomnessPid!=osGetpid(0) ){
40202 randomnessPid = osGetpid(0);
40203 sqlite3_randomness(0,0);
40204 }
40205 memset(p, 0, sizeof(unixFile));
 
 
 
 
 
40206
40207 if( eType==SQLITE_OPEN_MAIN_DB ){
40208 UnixUnusedFd *pUnused;
40209 pUnused = findReusableFd(zName, flags);
40210 if( pUnused ){
@@ -40262,12 +40498,10 @@
40262 if( fd<0 ){
40263 if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
40264 /* If unable to create a journal because the directory is not
40265 ** writable, change the error code to indicate that. */
40266 rc = SQLITE_READONLY_DIRECTORY;
40267 }else if( errno==EEXIST ){
40268 rc = SQLITE_CANTOPEN_EXISTS;
40269 }else if( errno!=EISDIR && isReadWrite ){
40270 /* Failed to open the file for read/write access. Try read-only. */
40271 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
40272 openFlags &= ~(O_RDWR|O_CREAT);
40273 flags |= SQLITE_OPEN_READONLY;
@@ -42164,10 +42398,13 @@
42164 ** READ-4 UNIX_SHM_BASE+7 127
42165 ** DMS UNIX_SHM_BASE+8 128
42166 */
42167 assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */
42168 #endif
 
 
 
42169
42170 return SQLITE_OK;
42171 }
42172
42173 /*
@@ -48615,11 +48852,11 @@
48615 /*
48616 ** Try to enlarge the memory allocation to hold at least sz bytes
48617 */
48618 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
48619 unsigned char *pNew;
48620 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){
48621 return SQLITE_FULL;
48622 }
48623 if( newSz>p->szMax ){
48624 return SQLITE_FULL;
48625 }
@@ -48674,12 +48911,13 @@
48674 */
48675 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
48676 MemStore *p = ((MemFile*)pFile)->pStore;
48677 int rc = SQLITE_OK;
48678 memdbEnter(p);
48679 if( NEVER(size>p->sz) ){
48680 rc = SQLITE_FULL;
 
48681 }else{
48682 p->sz = size;
48683 }
48684 memdbLeave(p);
48685 return rc;
@@ -48814,11 +49052,11 @@
48814 int iAmt,
48815 void **pp
48816 ){
48817 MemStore *p = ((MemFile*)pFile)->pStore;
48818 memdbEnter(p);
48819 if( iOfst+iAmt>p->sz ){
48820 *pp = 0;
48821 }else{
48822 p->nMmap++;
48823 *pp = (void*)(p->aData + iOfst);
48824 }
@@ -48848,13 +49086,12 @@
48848 int *pOutFlags
48849 ){
48850 MemFile *pFile = (MemFile*)pFd;
48851 MemStore *p = 0;
48852 int szName;
48853 if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
48854 return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
48855 }
48856 memset(pFile, 0, sizeof(*pFile));
48857 szName = sqlite3Strlen30(zName);
48858 if( szName>1 && zName[0]=='/' ){
48859 int i;
48860 #ifndef SQLITE_MUTEX_OMIT
@@ -48910,12 +49147,13 @@
48910 memset(p, 0, sizeof(*p));
48911 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
48912 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
48913 }
48914 pFile->pStore = p;
48915 assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */
48916 *pOutFlags = flags | SQLITE_OPEN_MEMORY;
 
48917 pFd->pMethods = &memdb_io_methods;
48918 memdbLeave(p);
48919 return SQLITE_OK;
48920 }
48921
@@ -49576,11 +49814,11 @@
49576 /* NULL pBitvec tests */
49577 sqlite3BitvecSet(0, 1);
49578 sqlite3BitvecClear(0, 1, pTmpSpace);
49579
49580 /* Run the program */
49581 pc = 0;
49582 while( (op = aOp[pc])!=0 ){
49583 switch( op ){
49584 case 1:
49585 case 2:
49586 case 5: {
@@ -53106,10 +53344,11 @@
53106 u8 walSyncFlags; /* See description above */
53107 u8 tempFile; /* zFilename is a temporary or immutable file */
53108 u8 noLock; /* Do not lock (except in WAL mode) */
53109 u8 readOnly; /* True for a read-only database */
53110 u8 memDb; /* True to inhibit all file I/O */
 
53111
53112 /**************************************************************************
53113 ** The following block contains those class members that change during
53114 ** routine operation. Class members not in this block are either fixed
53115 ** when the pager is first created or else only change when there is a
@@ -55500,10 +55739,11 @@
55500 ** routine which only updates the change-counter if the update is actually
55501 ** needed, as determined by the pPager->changeCountDone state variable.
55502 */
55503 static void pager_write_changecounter(PgHdr *pPg){
55504 u32 change_counter;
 
55505
55506 /* Increment the value just read and write it back to byte 24. */
55507 change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
55508 put32bits(((char*)pPg->pData)+24, change_counter);
55509
@@ -57347,11 +57587,11 @@
57347 if( zFilename && zFilename[0] ){
57348 int fout = 0; /* VFS flags returned by xOpen() */
57349 rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
57350 assert( !memDb );
57351 #ifndef SQLITE_OMIT_DESERIALIZE
57352 memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
57353 #endif
57354 readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
57355
57356 /* If the file was successfully opened for read/write access,
57357 ** choose a default page size in case we have to create the
@@ -59284,11 +59524,11 @@
59284
59285 /*
59286 ** Return true if this is an in-memory or temp-file backed pager.
59287 */
59288 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
59289 return pPager->tempFile;
59290 }
59291
59292 /*
59293 ** Check that there are at least nSavepoint savepoints open. If there are
59294 ** currently less than nSavepoints open, then open one or more savepoints
@@ -59604,11 +59844,11 @@
59604 */
59605 pPg->flags &= ~PGHDR_NEED_SYNC;
59606 pPgOld = sqlite3PagerLookup(pPager, pgno);
59607 assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB );
59608 if( pPgOld ){
59609 if( pPgOld->nRef>1 ){
59610 sqlite3PagerUnrefNotNull(pPgOld);
59611 return SQLITE_CORRUPT_BKPT;
59612 }
59613 pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
59614 if( pPager->tempFile ){
@@ -60809,13 +61049,17 @@
60809 ** If the wal-index is currently smaller the iPage pages then the size
60810 ** of the wal-index might be increased, but only if it is safe to do
60811 ** so. It is safe to enlarge the wal-index if pWal->writeLock is true
60812 ** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
60813 **
60814 ** If this call is successful, *ppPage is set to point to the wal-index
60815 ** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
60816 ** then an SQLite error code is returned and *ppPage is set to 0.
 
 
 
 
60817 */
60818 static SQLITE_NOINLINE int walIndexPageRealloc(
60819 Wal *pWal, /* The WAL context */
60820 int iPage, /* The page we seek */
60821 volatile u32 **ppPage /* Write the page pointer here */
@@ -60844,11 +61088,13 @@
60844 if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
60845 }else{
60846 rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
60847 pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
60848 );
60849 assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
 
 
60850 testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
60851 if( rc==SQLITE_OK ){
60852 if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
60853 }else if( (rc&0xff)==SQLITE_READONLY ){
60854 pWal->readOnly |= WAL_SHM_RDONLY;
@@ -61183,12 +61429,12 @@
61183 ** in the wal-index file. Set pLoc->iZero to one less than the frame
61184 ** number of the first frame indexed by this hash table. If a
61185 ** slot in the hash table is set to N, it refers to frame number
61186 ** (pLoc->iZero+N) in the log.
61187 **
61188 ** Finally, set pLoc->aPgno so that pLoc->aPgno[1] is the page number of the
61189 ** first frame indexed by the hash table, frame (pLoc->iZero+1).
61190 */
61191 static int walHashGet(
61192 Wal *pWal, /* WAL handle */
61193 int iHash, /* Find the iHash'th table */
61194 WalHashLoc *pLoc /* OUT: Hash table location */
@@ -61196,19 +61442,20 @@
61196 int rc; /* Return code */
61197
61198 rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
61199 assert( rc==SQLITE_OK || iHash>0 );
61200
61201 if( rc==SQLITE_OK ){
61202 pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
61203 if( iHash==0 ){
61204 pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
61205 pLoc->iZero = 0;
61206 }else{
61207 pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
61208 }
61209 pLoc->aPgno = &pLoc->aPgno[-1];
 
61210 }
61211 return rc;
61212 }
61213
61214 /*
@@ -61286,25 +61533,26 @@
61286 }
61287
61288 /* Zero the entries in the aPgno array that correspond to frames with
61289 ** frame numbers greater than pWal->hdr.mxFrame.
61290 */
61291 nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit+1]);
61292 memset((void *)&sLoc.aPgno[iLimit+1], 0, nByte);
 
61293
61294 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61295 /* Verify that the every entry in the mapping region is still reachable
61296 ** via the hash table even after the cleanup.
61297 */
61298 if( iLimit ){
61299 int j; /* Loop counter */
61300 int iKey; /* Hash key */
61301 for(j=1; j<=iLimit; j++){
61302 for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
61303 if( sLoc.aHash[iKey]==j ) break;
61304 }
61305 assert( sLoc.aHash[iKey]==j );
61306 }
61307 }
61308 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61309 }
61310
@@ -61332,32 +61580,32 @@
61332
61333 /* If this is the first entry to be added to this hash-table, zero the
61334 ** entire hash table and aPgno[] array before proceeding.
61335 */
61336 if( idx==1 ){
61337 int nByte = (int)((u8 *)&sLoc.aHash[HASHTABLE_NSLOT]
61338 - (u8 *)&sLoc.aPgno[1]);
61339 memset((void*)&sLoc.aPgno[1], 0, nByte);
61340 }
61341
61342 /* If the entry in aPgno[] is already set, then the previous writer
61343 ** must have exited unexpectedly in the middle of a transaction (after
61344 ** writing one or more dirty pages to the WAL to free up memory).
61345 ** Remove the remnants of that writers uncommitted transaction from
61346 ** the hash-table before writing any new entries.
61347 */
61348 if( sLoc.aPgno[idx] ){
61349 walCleanupHash(pWal);
61350 assert( !sLoc.aPgno[idx] );
61351 }
61352
61353 /* Write the aPgno[] array entry and the hash-table slot. */
61354 nCollide = idx;
61355 for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61356 if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
61357 }
61358 sLoc.aPgno[idx] = iPage;
61359 AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
61360
61361 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61362 /* Verify that the number of entries in the hash table exactly equals
61363 ** the number of entries in the mapping region.
@@ -61374,22 +61622,21 @@
61374 ** thing to check, so only do this occasionally - not on every
61375 ** iteration.
61376 */
61377 if( (idx&0x3ff)==0 ){
61378 int i; /* Loop counter */
61379 for(i=1; i<=idx; i++){
61380 for(iKey=walHash(sLoc.aPgno[i]);
61381 sLoc.aHash[iKey];
61382 iKey=walNextHash(iKey)){
61383 if( sLoc.aHash[iKey]==i ) break;
61384 }
61385 assert( sLoc.aHash[iKey]==i );
61386 }
61387 }
61388 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61389 }
61390
61391
61392 return rc;
61393 }
61394
61395
@@ -61507,11 +61754,12 @@
61507 u32 iFrame; /* Index of last frame read */
61508 u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
61509 u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
61510 u32 nHdr, nHdr32;
61511 rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
61512 if( rc ) break;
 
61513 pWal->apWiData[iPg] = aPrivate;
61514
61515 for(iFrame=iFirst; iFrame<=iLast; iFrame++){
61516 i64 iOffset = walFrameOffset(iFrame, szPage);
61517 u32 pgno; /* Database page number for frame */
@@ -62004,11 +62252,10 @@
62004 if( rc==SQLITE_OK ){
62005 int j; /* Counter variable */
62006 int nEntry; /* Number of entries in this segment */
62007 ht_slot *aIndex; /* Sorted index for this segment */
62008
62009 sLoc.aPgno++;
62010 if( (i+1)==nSegment ){
62011 nEntry = (int)(iLast - sLoc.iZero);
62012 }else{
62013 nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
62014 }
@@ -63143,11 +63390,12 @@
63143 i64 iDbOff; /* Offset of db file entry */
63144 i64 iWalOff; /* Offset of wal file entry */
63145
63146 rc = walHashGet(pWal, walFramePage(i), &sLoc);
63147 if( rc!=SQLITE_OK ) break;
63148 pgno = sLoc.aPgno[i-sLoc.iZero];
 
63149 iDbOff = (i64)(pgno-1) * szPage;
63150
63151 if( iDbOff+szPage<=szDb ){
63152 iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
63153 rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
@@ -63376,11 +63624,11 @@
63376 }
63377 nCollide = HASHTABLE_NSLOT;
63378 iKey = walHash(pgno);
63379 while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
63380 u32 iFrame = iH + sLoc.iZero;
63381 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH]==pgno ){
63382 assert( iFrame>iRead || CORRUPT_DB );
63383 iRead = iFrame;
63384 }
63385 if( (nCollide--)==0 ){
63386 return SQLITE_CORRUPT_BKPT;
@@ -64628,11 +64876,10 @@
64628 ** Access to all fields of this structure is controlled by the mutex
64629 ** stored in MemPage.pBt->mutex.
64630 */
64631 struct MemPage {
64632 u8 isInit; /* True if previously initialized. MUST BE FIRST! */
64633 u8 bBusy; /* Prevent endless loops on corrupt database files */
64634 u8 intKey; /* True if table b-trees. False for index b-trees */
64635 u8 intKeyLeaf; /* True if the leaf of an intKey table */
64636 Pgno pgno; /* Page number for this page */
64637 /* Only the first 8 bytes (above) are zeroed by pager.c when a new page
64638 ** is allocated. All fields that follow must be initialized before use */
@@ -66870,11 +67117,11 @@
66870 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
66871 sz2 = get2byte(&data[iFree2+2]);
66872 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
66873 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
66874 sz += sz2;
66875 }else if( iFree+sz>usableSize ){
66876 return SQLITE_CORRUPT_PAGE(pPage);
66877 }
66878
66879 cbrk = top+sz;
66880 assert( cbrk+(iFree-top) <= usableSize );
@@ -68075,34 +68322,42 @@
68075 /*
68076 ** Make sure pBt->pTmpSpace points to an allocation of
68077 ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
68078 ** pointer.
68079 */
68080 static void allocateTempSpace(BtShared *pBt){
68081 if( !pBt->pTmpSpace ){
68082 pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
68083
68084 /* One of the uses of pBt->pTmpSpace is to format cells before
68085 ** inserting them into a leaf page (function fillInCell()). If
68086 ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
68087 ** by the various routines that manipulate binary cells. Which
68088 ** can mean that fillInCell() only initializes the first 2 or 3
68089 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
68090 ** it into a database page. This is not actually a problem, but it
68091 ** does cause a valgrind error when the 1 or 2 bytes of unitialized
68092 ** data is passed to system call write(). So to avoid this error,
68093 ** zero the first 4 bytes of temp space here.
68094 **
68095 ** Also: Provide four bytes of initialized space before the
68096 ** beginning of pTmpSpace as an area available to prepend the
68097 ** left-child pointer to the beginning of a cell.
68098 */
68099 if( pBt->pTmpSpace ){
68100 memset(pBt->pTmpSpace, 0, 8);
68101 pBt->pTmpSpace += 4;
68102 }
68103 }
 
 
 
 
 
 
 
 
68104 }
68105
68106 /*
68107 ** Free the pBt->pTmpSpace allocation
68108 */
@@ -68477,11 +68732,10 @@
68477 static int lockBtree(BtShared *pBt){
68478 int rc; /* Result code from subfunctions */
68479 MemPage *pPage1; /* Page 1 of the database file */
68480 u32 nPage; /* Number of pages in the database */
68481 u32 nPageFile = 0; /* Number of pages in the database file */
68482 u32 nPageHeader; /* Number of pages in the database according to hdr */
68483
68484 assert( sqlite3_mutex_held(pBt->mutex) );
68485 assert( pBt->pPage1==0 );
68486 rc = sqlite3PagerSharedLock(pBt->pPager);
68487 if( rc!=SQLITE_OK ) return rc;
@@ -68489,11 +68743,11 @@
68489 if( rc!=SQLITE_OK ) return rc;
68490
68491 /* Do some checking to help insure the file we opened really is
68492 ** a valid database file.
68493 */
68494 nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData);
68495 sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile);
68496 if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
68497 nPage = nPageFile;
68498 }
68499 if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
@@ -69322,27 +69576,30 @@
69322 }
69323
69324 /*
69325 ** This routine is called prior to sqlite3PagerCommit when a transaction
69326 ** is committed for an auto-vacuum database.
69327 **
69328 ** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages
69329 ** the database file should be truncated to during the commit process.
69330 ** i.e. the database has been reorganized so that only the first *pnTrunc
69331 ** pages are in use.
69332 */
69333 static int autoVacuumCommit(BtShared *pBt){
69334 int rc = SQLITE_OK;
69335 Pager *pPager = pBt->pPager;
69336 VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); )
 
 
 
 
 
 
 
69337
69338 assert( sqlite3_mutex_held(pBt->mutex) );
69339 invalidateAllOverflowCache(pBt);
69340 assert(pBt->autoVacuum);
69341 if( !pBt->incrVacuum ){
69342 Pgno nFin; /* Number of pages in database after autovacuuming */
69343 Pgno nFree; /* Number of pages on the freelist initially */
 
69344 Pgno iFree; /* The next page to be freed */
69345 Pgno nOrig; /* Database size before freeing */
69346
69347 nOrig = btreePagecount(pBt);
69348 if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
@@ -69352,22 +69609,46 @@
69352 */
69353 return SQLITE_CORRUPT_BKPT;
69354 }
69355
69356 nFree = get4byte(&pBt->pPage1->aData[36]);
69357 nFin = finalDbSize(pBt, nOrig, nFree);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69358 if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
69359 if( nFin<nOrig ){
69360 rc = saveAllCursors(pBt, 0, 0);
69361 }
69362 for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
69363 rc = incrVacuumStep(pBt, nFin, iFree, 1);
69364 }
69365 if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
69366 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
69367 put4byte(&pBt->pPage1->aData[32], 0);
69368 put4byte(&pBt->pPage1->aData[36], 0);
 
 
69369 put4byte(&pBt->pPage1->aData[28], nFin);
69370 pBt->bDoTruncate = 1;
69371 pBt->nPage = nFin;
69372 }
69373 if( rc!=SQLITE_OK ){
@@ -69414,11 +69695,11 @@
69414 if( p->inTrans==TRANS_WRITE ){
69415 BtShared *pBt = p->pBt;
69416 sqlite3BtreeEnter(p);
69417 #ifndef SQLITE_OMIT_AUTOVACUUM
69418 if( pBt->autoVacuum ){
69419 rc = autoVacuumCommit(pBt);
69420 if( rc!=SQLITE_OK ){
69421 sqlite3BtreeLeave(p);
69422 return rc;
69423 }
69424 }
@@ -69813,14 +70094,10 @@
69813 assert( p->inTrans>TRANS_NONE );
69814 assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
69815 assert( pBt->pPage1 && pBt->pPage1->aData );
69816 assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );
69817
69818 if( wrFlag ){
69819 allocateTempSpace(pBt);
69820 if( pBt->pTmpSpace==0 ) return SQLITE_NOMEM_BKPT;
69821 }
69822 if( iTable<=1 ){
69823 if( iTable<1 ){
69824 return SQLITE_CORRUPT_BKPT;
69825 }else if( btreePagecount(pBt)==0 ){
69826 assert( wrFlag==0 );
@@ -69833,23 +70110,29 @@
69833 pCur->pgnoRoot = iTable;
69834 pCur->iPage = -1;
69835 pCur->pKeyInfo = pKeyInfo;
69836 pCur->pBtree = p;
69837 pCur->pBt = pBt;
69838 pCur->curFlags = wrFlag ? BTCF_WriteFlag : 0;
69839 pCur->curPagerFlags = wrFlag ? 0 : PAGER_GET_READONLY;
69840 /* If there are two or more cursors on the same btree, then all such
69841 ** cursors *must* have the BTCF_Multiple flag set. */
69842 for(pX=pBt->pCursor; pX; pX=pX->pNext){
69843 if( pX->pgnoRoot==iTable ){
69844 pX->curFlags |= BTCF_Multiple;
69845 pCur->curFlags |= BTCF_Multiple;
69846 }
69847 }
 
69848 pCur->pNext = pBt->pCursor;
69849 pBt->pCursor = pCur;
69850 pCur->eState = CURSOR_INVALID;
 
 
 
 
 
 
69851 return SQLITE_OK;
69852 }
69853 static int btreeCursorWithLock(
69854 Btree *p, /* The btree */
69855 Pgno iTable, /* Root page of table to open */
@@ -70219,11 +70502,13 @@
70219 #endif
70220
70221 assert( pPage );
70222 assert( eOp==0 || eOp==1 );
70223 assert( pCur->eState==CURSOR_VALID );
70224 assert( pCur->ix<pPage->nCell );
 
 
70225 assert( cursorHoldsMutex(pCur) );
70226
70227 getCellInfo(pCur);
70228 aPayload = pCur->info.pPayload;
70229 assert( offset+amt <= pCur->info.nPayload );
@@ -70406,11 +70691,10 @@
70406 */
70407 SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
70408 assert( cursorHoldsMutex(pCur) );
70409 assert( pCur->eState==CURSOR_VALID );
70410 assert( pCur->iPage>=0 && pCur->pPage );
70411 assert( pCur->ix<pCur->pPage->nCell );
70412 return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
70413 }
70414
70415 /*
70416 ** This variant of sqlite3BtreePayload() works even if the cursor has not
@@ -70468,11 +70752,11 @@
70468 int amt;
70469 assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
70470 assert( pCur->eState==CURSOR_VALID );
70471 assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
70472 assert( cursorOwnsBtShared(pCur) );
70473 assert( pCur->ix<pCur->pPage->nCell );
70474 assert( pCur->info.nSize>0 );
70475 assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
70476 assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
70477 amt = pCur->info.nLocal;
70478 if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
@@ -71254,20 +71538,10 @@
71254 ** module cov1/btree78.test testcase 220 (2018-06-08) for an
71255 ** example. */
71256 return SQLITE_CORRUPT_BKPT;
71257 }
71258
71259 /* If the database file is corrupt, it is possible for the value of idx
71260 ** to be invalid here. This can only occur if a second cursor modifies
71261 ** the page while cursor pCur is holding a reference to it. Which can
71262 ** only happen if the database is corrupt in such a way as to link the
71263 ** page into more than one b-tree structure.
71264 **
71265 ** Update 2019-12-23: appears to long longer be possible after the
71266 ** addition of anotherValidCursor() condition on balance_deeper(). */
71267 harmless( idx>pPage->nCell );
71268
71269 if( idx>=pPage->nCell ){
71270 if( !pPage->leaf ){
71271 rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
71272 if( rc ) return rc;
71273 return moveToLeftmost(pCur);
@@ -71751,11 +72025,11 @@
71751
71752 assert( sqlite3_mutex_held(pBt->mutex) );
71753 assert( CORRUPT_DB || iPage>1 );
71754 assert( !pMemPage || pMemPage->pgno==iPage );
71755
71756 if( iPage<2 || iPage>pBt->nPage ){
71757 return SQLITE_CORRUPT_BKPT;
71758 }
71759 if( pMemPage ){
71760 pPage = pMemPage;
71761 sqlite3PagerRef(pPage->pDbPage);
@@ -73069,15 +73343,14 @@
73069 Pgno pgno; /* Temp var to store a page number in */
73070 u8 abDone[NB+2]; /* True after i'th new page is populated */
73071 Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */
73072 Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */
73073 u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */
73074 CellArray b; /* Parsed information on cells being balanced */
73075
73076 memset(abDone, 0, sizeof(abDone));
73077 b.nCell = 0;
73078 b.apCell = 0;
73079 pBt = pParent->pBt;
73080 assert( sqlite3_mutex_held(pBt->mutex) );
73081 assert( sqlite3PagerIswriteable(pParent->pDbPage) );
73082
73083 /* At this point pParent may have at most one overflow cell. And if
@@ -73884,11 +74157,11 @@
73884
73885 /*
73886 ** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
73887 ** on the same B-tree as pCur.
73888 **
73889 ** This can if a database is corrupt with two or more SQL tables
73890 ** pointing to the same b-tree. If an insert occurs on one SQL table
73891 ** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
73892 ** table linked to the same b-tree. If the secondary insert causes a
73893 ** rebalance, that can change content out from under the cursor on the
73894 ** first SQL table, violating invariants on the first insert.
@@ -74353,11 +74626,14 @@
74353 assert( szNew==pPage->xCellSize(pPage, newCell) );
74354 assert( szNew <= MX_CELL_SIZE(pBt) );
74355 idx = pCur->ix;
74356 if( loc==0 ){
74357 CellInfo info;
74358 assert( idx<pPage->nCell );
 
 
 
74359 rc = sqlite3PagerWrite(pPage->pDbPage);
74360 if( rc ){
74361 goto end_insert;
74362 }
74363 oldCell = findCell(pPage, idx);
@@ -74939,15 +75215,16 @@
74939 if( pgno>btreePagecount(pBt) ){
74940 return SQLITE_CORRUPT_BKPT;
74941 }
74942 rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
74943 if( rc ) return rc;
74944 if( pPage->bBusy ){
 
 
74945 rc = SQLITE_CORRUPT_BKPT;
74946 goto cleardatabasepage_out;
74947 }
74948 pPage->bBusy = 1;
74949 hdr = pPage->hdrOffset;
74950 for(i=0; i<pPage->nCell; i++){
74951 pCell = findCell(pPage, i);
74952 if( !pPage->leaf ){
74953 rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
@@ -74970,11 +75247,10 @@
74970 }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
74971 zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
74972 }
74973
74974 cleardatabasepage_out:
74975 pPage->bBusy = 0;
74976 releasePage(pPage);
74977 return rc;
74978 }
74979
74980 /*
@@ -75049,14 +75325,14 @@
75049 assert( iTable>=2 );
75050 if( iTable>btreePagecount(pBt) ){
75051 return SQLITE_CORRUPT_BKPT;
75052 }
75053
75054 rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
75055 if( rc ) return rc;
75056 rc = sqlite3BtreeClearTable(p, iTable, 0);
75057 if( rc ){
 
 
75058 releasePage(pPage);
75059 return rc;
75060 }
75061
75062 *piMoved = 0;
@@ -77209,10 +77485,11 @@
77209 */
77210 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
77211 #ifndef SQLITE_OMIT_UTF16
77212 int rc;
77213 #endif
 
77214 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77215 assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
77216 || desiredEnc==SQLITE_UTF16BE );
77217 if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
77218 return SQLITE_OK;
@@ -77341,10 +77618,11 @@
77341 ** MEM.zMalloc, where it can be safely written.
77342 **
77343 ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
77344 */
77345 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
 
77346 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77347 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77348 if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
77349 if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
77350 if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
@@ -77365,10 +77643,11 @@
77365 ** blob stored in dynamically allocated space.
77366 */
77367 #ifndef SQLITE_OMIT_INCRBLOB
77368 SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
77369 int nByte;
 
77370 assert( pMem->flags & MEM_Zero );
77371 assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
77372 testcase( sqlite3_value_nochange(pMem) );
77373 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77374 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -77380,10 +77659,12 @@
77380 nByte = 1;
77381 }
77382 if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
77383 return SQLITE_NOMEM_BKPT;
77384 }
 
 
77385
77386 memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
77387 pMem->n += pMem->u.nZero;
77388 pMem->flags &= ~(MEM_Zero|MEM_Term);
77389 return SQLITE_OK;
@@ -77392,10 +77673,11 @@
77392
77393 /*
77394 ** Make sure the given Mem is \u0000 terminated.
77395 */
77396 SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
 
77397 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77398 testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) );
77399 testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 );
77400 if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){
77401 return SQLITE_OK; /* Nothing to do */
@@ -77419,10 +77701,11 @@
77419 ** user and the latter is an internal programming error.
77420 */
77421 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
77422 const int nByte = 32;
77423
 
77424 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77425 assert( !(pMem->flags&MEM_Zero) );
77426 assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
77427 assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
77428 assert( !sqlite3VdbeMemIsRowSet(pMem) );
@@ -77454,10 +77737,11 @@
77454 */
77455 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
77456 sqlite3_context ctx;
77457 Mem t;
77458 assert( pFunc!=0 );
 
77459 assert( pFunc->xFinalize!=0 );
77460 assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
77461 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77462 memset(&ctx, 0, sizeof(ctx));
77463 memset(&t, 0, sizeof(t));
@@ -77597,17 +77881,18 @@
77597 ** it into an integer and return that. If pMem represents an
77598 ** an SQL-NULL value, return 0.
77599 **
77600 ** If pMem represents a string value, its encoding might be changed.
77601 */
77602 static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){
77603 i64 value = 0;
77604 sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
77605 return value;
77606 }
77607 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){
77608 int flags;
 
77609 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77610 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77611 flags = pMem->flags;
77612 if( flags & (MEM_Int|MEM_IntReal) ){
77613 testcase( flags & MEM_IntReal );
@@ -77632,10 +77917,11 @@
77632 double val = (double)0;
77633 sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
77634 return val;
77635 }
77636 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
 
77637 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77638 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77639 if( pMem->flags & MEM_Real ){
77640 return pMem->u.r;
77641 }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
@@ -77664,10 +77950,11 @@
77664 ** The MEM structure is already a MEM_Real. Try to also make it a
77665 ** MEM_Int if we can.
77666 */
77667 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
77668 i64 ix;
 
77669 assert( pMem->flags & MEM_Real );
77670 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77671 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77672 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77673
@@ -77691,10 +77978,11 @@
77691
77692 /*
77693 ** Convert pMem to type integer. Invalidate any prior representations.
77694 */
77695 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
 
77696 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77697 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77698 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77699
77700 pMem->u.i = sqlite3VdbeIntValue(pMem);
@@ -77705,10 +77993,11 @@
77705 /*
77706 ** Convert pMem so that it is of type MEM_Real.
77707 ** Invalidate any prior representations.
77708 */
77709 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
 
77710 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77711 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77712
77713 pMem->u.r = sqlite3VdbeRealValue(pMem);
77714 MemSetTypeFlag(pMem, MEM_Real);
@@ -77738,10 +78027,11 @@
77738 ** Every effort is made to force the conversion, even if the input
77739 ** is a string that does not look completely like a number. Convert
77740 ** as much of the string as we can and ignore the rest.
77741 */
77742 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
 
77743 testcase( pMem->flags & MEM_Int );
77744 testcase( pMem->flags & MEM_Real );
77745 testcase( pMem->flags & MEM_IntReal );
77746 testcase( pMem->flags & MEM_Null );
77747 if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
@@ -77847,19 +78137,35 @@
77847
77848 /*
77849 ** Delete any previous value and set the value to be a BLOB of length
77850 ** n containing all zeros.
77851 */
 
77852 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
77853 sqlite3VdbeMemRelease(pMem);
77854 pMem->flags = MEM_Blob|MEM_Zero;
77855 pMem->n = 0;
77856 if( n<0 ) n = 0;
77857 pMem->u.nZero = n;
77858 pMem->enc = SQLITE_UTF8;
77859 pMem->z = 0;
77860 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77861
77862 /*
77863 ** The pMem is known to contain content that needs to be destroyed prior
77864 ** to a value change. So invoke the destructor, then set the value to
77865 ** a 64-bit integer.
@@ -78089,10 +78395,11 @@
78089 ){
78090 i64 nByte = n; /* New value for pMem->n */
78091 int iLimit; /* Maximum allowed string or blob size */
78092 u16 flags = 0; /* New value for pMem->flags */
78093
 
78094 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
78095 assert( !sqlite3VdbeMemIsRowSet(pMem) );
78096
78097 /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
78098 if( !z ){
@@ -78414,12 +78721,14 @@
78414 ExprList *pList = 0; /* Function arguments */
78415 int i; /* Iterator variable */
78416
78417 assert( pCtx!=0 );
78418 assert( (p->flags & EP_TokenOnly)==0 );
 
78419 pList = p->x.pList;
78420 if( pList ) nVal = pList->nExpr;
 
78421 pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
78422 assert( pFunc );
78423 if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
78424 || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
78425 ){
@@ -78519,11 +78828,13 @@
78519 ** check ensures that an EP_TokenOnly expression is never passed down
78520 ** into valueFromFunction(). */
78521 assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
78522
78523 if( op==TK_CAST ){
78524 u8 aff = sqlite3AffinityType(pExpr->u.zToken,0);
 
 
78525 rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
78526 testcase( rc!=SQLITE_OK );
78527 if( *ppVal ){
78528 sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
78529 sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
@@ -78592,10 +78903,11 @@
78592 sqlite3VdbeMemSetNull(pVal);
78593 }
78594 #ifndef SQLITE_OMIT_BLOB_LITERAL
78595 else if( op==TK_BLOB ){
78596 int nVal;
 
78597 assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
78598 assert( pExpr->u.zToken[1]=='\'' );
78599 pVal = valueNew(db, pCtx);
78600 if( !pVal ) goto no_mem;
78601 zVal = &pExpr->u.zToken[2];
@@ -78609,10 +78921,11 @@
78609 else if( op==TK_FUNCTION && pCtx!=0 ){
78610 rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
78611 }
78612 #endif
78613 else if( op==TK_TRUEFALSE ){
 
78614 pVal = valueNew(db, pCtx);
78615 if( pVal ){
78616 pVal->flags = MEM_Int;
78617 pVal->u.i = pExpr->u.zToken[4]==0;
78618 }
@@ -79162,12 +79475,14 @@
79162 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
79163 assert( op>=0 && op<0xff );
79164 if( p->nOpAlloc<=i ){
79165 return growOp3(p, op, p1, p2, p3);
79166 }
 
79167 p->nOp++;
79168 pOp = &p->aOp[i];
 
79169 pOp->opcode = (u8)op;
79170 pOp->p5 = 0;
79171 pOp->p1 = p1;
79172 pOp->p2 = p2;
79173 pOp->p3 = p3;
@@ -80406,11 +80721,11 @@
80406 zOpName = sqlite3OpcodeName(pOp->opcode);
80407 nOpName = sqlite3Strlen30(zOpName);
80408 if( zOpName[nOpName+1] ){
80409 int seenCom = 0;
80410 char c;
80411 zSynopsis = zOpName += nOpName + 1;
80412 if( strncmp(zSynopsis,"IF ",3)==0 ){
80413 sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
80414 zSynopsis = zAlt;
80415 }
80416 for(ii=0; (c = zSynopsis[ii])!=0; ii++){
@@ -80479,10 +80794,11 @@
80479 */
80480 static void displayP4Expr(StrAccum *p, Expr *pExpr){
80481 const char *zOp = 0;
80482 switch( pExpr->op ){
80483 case TK_STRING:
 
80484 sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
80485 break;
80486 case TK_INTEGER:
80487 sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
80488 break;
@@ -80825,12 +81141,12 @@
80825 ** with no indexes using a single prepared INSERT statement, bind()
80826 ** and reset(). Inserts are grouped into a transaction.
80827 */
80828 testcase( p->flags & MEM_Agg );
80829 testcase( p->flags & MEM_Dyn );
80830 testcase( p->xDel==sqlite3VdbeFrameMemDel );
80831 if( p->flags&(MEM_Agg|MEM_Dyn) ){
 
80832 sqlite3VdbeMemRelease(p);
80833 }else if( p->szMalloc ){
80834 sqlite3DbFreeNN(db, p->zMalloc);
80835 p->szMalloc = 0;
80836 }
@@ -81974,13 +82290,19 @@
81974
81975 /* Lock all btrees used by the statement */
81976 sqlite3VdbeEnter(p);
81977
81978 /* Check for one of the special errors */
81979 mrc = p->rc & 0xff;
81980 isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR
81981 || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL;
 
 
 
 
 
 
81982 if( isSpecialError ){
81983 /* If the query was read-only and the error code is SQLITE_INTERRUPT,
81984 ** no rollback is necessary. Otherwise, at least a savepoint
81985 ** transaction must be rolled back to restore the database to a
81986 ** consistent state.
@@ -82028,10 +82350,13 @@
82028 if( NEVER(p->readOnly) ){
82029 sqlite3VdbeLeave(p);
82030 return SQLITE_ERROR;
82031 }
82032 rc = SQLITE_CONSTRAINT_FOREIGNKEY;
 
 
 
82033 }else{
82034 /* The auto-commit flag is true, the vdbe program was successful
82035 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
82036 ** key constraints to hold up the transaction. This means a commit
82037 ** is required. */
@@ -84132,10 +84457,12 @@
84132 }else{
84133 iKey2 = iKey1;
84134 }
84135 }
84136
 
 
84137 assert( pCsr->nField==pTab->nCol
84138 || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
84139 );
84140
84141 preupdate.v = v;
@@ -84531,12 +84858,12 @@
84531 /**************************** sqlite3_result_ *******************************
84532 ** The following routines are used by user-defined functions to specify
84533 ** the function result.
84534 **
84535 ** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the
84536 ** result as a string or blob but if the string or blob is too large, it
84537 ** then sets the error code to SQLITE_TOOBIG
84538 **
84539 ** The invokeValueDestructor(P,X) routine invokes destructor function X()
84540 ** on value P is not going to be used and need to be destroyed.
84541 */
84542 static void setResultStrOrError(
@@ -84544,12 +84871,20 @@
84544 const char *z, /* String pointer */
84545 int n, /* Bytes in string, or negative */
84546 u8 enc, /* Encoding of z. 0 for BLOBs */
84547 void (*xDel)(void*) /* Destructor function */
84548 ){
84549 if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){
84550 sqlite3_result_error_toobig(pCtx);
 
 
 
 
 
 
 
 
84551 }
84552 }
84553 static int invokeValueDestructor(
84554 const void *p, /* Value to destroy */
84555 void (*xDel)(void*), /* The destructor */
@@ -84702,12 +85037,16 @@
84702 Mem *pOut = pCtx->pOut;
84703 assert( sqlite3_mutex_held(pOut->db->mutex) );
84704 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
84705 return SQLITE_TOOBIG;
84706 }
 
84707 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
84708 return SQLITE_OK;
 
 
 
84709 }
84710 SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
84711 pCtx->isError = errCode ? errCode : -1;
84712 #ifdef SQLITE_DEBUG
84713 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85715,11 +86054,15 @@
85715 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
85716 int rc;
85717 Vdbe *p = (Vdbe *)pStmt;
85718 rc = vdbeUnbind(p, i);
85719 if( rc==SQLITE_OK ){
 
85720 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
 
 
 
85721 sqlite3_mutex_leave(p->db->mutex);
85722 }
85723 return rc;
85724 }
85725 SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86003,10 +86346,11 @@
86003 /* If the old.* record has not yet been loaded into memory, do so now. */
86004 if( p->pUnpacked==0 ){
86005 u32 nRec;
86006 u8 *aRec;
86007
 
86008 nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
86009 aRec = sqlite3DbMallocRaw(db, nRec);
86010 if( !aRec ) goto preupdate_old_out;
86011 rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
86012 if( rc==SQLITE_OK ){
@@ -87091,10 +87435,35 @@
87091 }else{
87092 pOut->flags = MEM_Int;
87093 return pOut;
87094 }
87095 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87096
87097 /*
87098 ** Return the symbolic name for the data type of a pMem
87099 */
87100 static const char *vdbeMemTypeName(Mem *pMem){
@@ -87746,16 +88115,22 @@
87746
87747 /* Opcode: Blob P1 P2 * P4 *
87748 ** Synopsis: r[P2]=P4 (len=P1)
87749 **
87750 ** P4 points to a blob of data P1 bytes long. Store this
87751 ** blob in register P2.
 
87752 */
87753 case OP_Blob: { /* out2 */
87754 assert( pOp->p1 <= SQLITE_MAX_LENGTH );
87755 pOut = out2Prerelease(p, pOp);
87756 sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
 
 
 
 
 
87757 pOut->enc = encoding;
87758 UPDATE_MAX_BLOBSIZE(pOut);
87759 break;
87760 }
87761
@@ -87900,28 +88275,26 @@
87900 pOut = &aMem[pOp->p2];
87901 sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
87902 break;
87903 }
87904
87905 /* Opcode: ChngCntRow P1 P2 * * *
87906 ** Synopsis: output=r[P1]
87907 **
87908 ** Output value in register P1 as the chance count for a DML statement,
87909 ** due to the "PRAGMA count_changes=ON" setting. Or, if there was a
87910 ** foreign key error in the statement, trigger the error now.
87911 **
87912 ** This opcode is a variant of OP_ResultRow that checks the foreign key
87913 ** immediate constraint count and throws an error if the count is
87914 ** non-zero. The P2 opcode must be 1.
87915 */
87916 case OP_ChngCntRow: {
87917 assert( pOp->p2==1 );
87918 if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
87919 goto abort_due_to_error;
87920 }
87921 /* Fall through to the next case, OP_ResultRow */
87922 /* no break */ deliberate_fall_through
87923 }
87924
87925 /* Opcode: ResultRow P1 P2 * * *
87926 ** Synopsis: output=r[P1@P2]
87927 **
@@ -89320,20 +89693,25 @@
89320 rc = SQLITE_CORRUPT_BKPT;
89321 goto abort_due_to_error;
89322 }
89323 }
89324
89325 /* Opcode: TypeCheck P1 P2 * P4 *
89326 ** Synopsis: typecheck(r[P1@P2])
89327 **
89328 ** Apply affinities to the range of P2 registers beginning with P1.
89329 ** Take the affinities from the Table object in P4. If any value
89330 ** cannot be coerced into the correct type, then raise an error.
89331 **
89332 ** This opcode is similar to OP_Affinity except that this opcode
89333 ** forces the register type to the Table column type. This is used
89334 ** to implement "strict affinity".
 
 
 
 
 
89335 **
89336 ** Preconditions:
89337 **
89338 ** <ul>
89339 ** <li> P2 should be the number of non-virtual columns in the
@@ -89353,11 +89731,14 @@
89353 assert( pTab->tabFlags & TF_Strict );
89354 assert( pTab->nNVCol==pOp->p2 );
89355 aCol = pTab->aCol;
89356 pIn1 = &aMem[pOp->p1];
89357 for(i=0; i<pTab->nCol; i++){
89358 if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
 
 
 
89359 assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
89360 applyAffinity(pIn1, aCol[i].affinity, encoding);
89361 if( (pIn1->flags & MEM_Null)==0 ){
89362 switch( aCol[i].eCType ){
89363 case COLTYPE_BLOB: {
@@ -89756,11 +90137,11 @@
89756 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
89757 REGISTER_TRACE(pOp->p3, pOut);
89758 break;
89759 }
89760
89761 /* Opcode: Count P1 P2 p3 * *
89762 ** Synopsis: r[P2]=count()
89763 **
89764 ** Store the number of entries (an integer value) in the table or index
89765 ** opened by cursor P1 in register P2.
89766 **
@@ -90077,12 +90458,20 @@
90077 assert( p->bIsReader );
90078 assert( p->readOnly==0 || pOp->p2==0 );
90079 assert( pOp->p2>=0 && pOp->p2<=2 );
90080 assert( pOp->p1>=0 && pOp->p1<db->nDb );
90081 assert( DbMaskTest(p->btreeMask, pOp->p1) );
90082 if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
90083 rc = SQLITE_READONLY;
 
 
 
 
 
 
 
 
90084 goto abort_due_to_error;
90085 }
90086 pBt = db->aDb[pOp->p1].pBt;
90087
90088 if( pBt ){
@@ -90120,11 +90509,12 @@
90120 p->nStmtDefCons = db->nDeferredCons;
90121 p->nStmtDefImmCons = db->nDeferredImmCons;
90122 }
90123 }
90124 assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
90125 if( pOp->p5
 
90126 && (iMeta!=pOp->p3
90127 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
90128 ){
90129 /*
90130 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -90514,11 +90904,11 @@
90514 assert( aMem[pOp->p3].flags & MEM_Null );
90515 aMem[pOp->p3].n = 0;
90516 aMem[pOp->p3].z = "";
90517 }
90518 pCx = p->apCsr[pOp->p1];
90519 if( pCx && !pCx->hasBeenDuped ){
90520 /* If the ephermeral table is already open and has no duplicates from
90521 ** OP_OpenDup, then erase all existing content so that the table is
90522 ** empty again, rather than creating a new table. */
90523 assert( pCx->isEphemeral );
90524 pCx->seqCount = 0;
@@ -91677,11 +92067,11 @@
91677 zDb = db->aDb[pC->iDb].zDbSName;
91678 pTab = pOp->p4.pTab;
91679 assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
91680 }else{
91681 pTab = 0;
91682 zDb = 0; /* Not needed. Silence a compiler warning. */
91683 }
91684
91685 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
91686 /* Invoke the pre-update hook, if any */
91687 if( pTab ){
@@ -91830,17 +92220,18 @@
91830 pTab = pOp->p4.pTab;
91831 if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
91832 pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
91833 }
91834 }else{
91835 zDb = 0; /* Not needed. Silence a compiler warning. */
91836 pTab = 0; /* Not needed. Silence a compiler warning. */
91837 }
91838
91839 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
91840 /* Invoke the pre-update-hook if required. */
91841 if( db->xPreUpdateCallback && pOp->p4.pTab ){
 
91842 assert( !(opflags & OPFLAG_ISUPDATE)
91843 || HasRowid(pTab)==0
91844 || (aMem[pOp->p3].flags & MEM_Int)
91845 );
91846 sqlite3VdbePreUpdateHook(p, pC,
@@ -91877,11 +92268,11 @@
91877 if( rc ) goto abort_due_to_error;
91878
91879 /* Invoke the update-hook if required. */
91880 if( opflags & OPFLAG_NCHANGE ){
91881 p->nChange++;
91882 if( db->xUpdateCallback && HasRowid(pTab) ){
91883 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
91884 pC->movetoTarget);
91885 assert( pC->iDb>=0 );
91886 }
91887 }
@@ -92925,11 +93316,11 @@
92925 db->mDbFlags |= DBFLAG_SchemaChange;
92926 p->expired = 0;
92927 }else
92928 #endif
92929 {
92930 zSchema = DFLT_SCHEMA_TABLE;
92931 initData.db = db;
92932 initData.iDb = iDb;
92933 initData.pzErrMsg = &p->zErrMsg;
92934 initData.mInitFlags = 0;
92935 initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
@@ -94145,10 +94536,11 @@
94145 pQuery = &aMem[pOp->p3];
94146 pArgc = &pQuery[1];
94147 pCur = p->apCsr[pOp->p1];
94148 assert( memIsValid(pQuery) );
94149 REGISTER_TRACE(pOp->p3, pQuery);
 
94150 assert( pCur->eCurType==CURTYPE_VTAB );
94151 pVCur = pCur->uc.pVCur;
94152 pVtab = pVCur->pVtab;
94153 pModule = pVtab->pModule;
94154
@@ -94193,10 +94585,11 @@
94193 const sqlite3_module *pModule;
94194 Mem *pDest;
94195 sqlite3_context sContext;
94196
94197 VdbeCursor *pCur = p->apCsr[pOp->p1];
 
94198 assert( pCur->eCurType==CURTYPE_VTAB );
94199 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
94200 pDest = &aMem[pOp->p3];
94201 memAboutToChange(p, pDest);
94202 if( pCur->nullRow ){
@@ -94246,10 +94639,11 @@
94246 const sqlite3_module *pModule;
94247 int res;
94248 VdbeCursor *pCur;
94249
94250 pCur = p->apCsr[pOp->p1];
 
94251 assert( pCur->eCurType==CURTYPE_VTAB );
94252 if( pCur->nullRow ){
94253 break;
94254 }
94255 pVtab = pCur->uc.pVCur->pVtab;
@@ -94341,11 +94735,11 @@
94341 case OP_VUpdate: {
94342 sqlite3_vtab *pVtab;
94343 const sqlite3_module *pModule;
94344 int nArg;
94345 int i;
94346 sqlite_int64 rowid;
94347 Mem **apArg;
94348 Mem *pX;
94349
94350 assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
94351 || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -94528,10 +94922,81 @@
94528
94529 REGISTER_TRACE(pOp->p3, pOut);
94530 UPDATE_MAX_BLOBSIZE(pOut);
94531 break;
94532 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94533
94534 /* Opcode: Trace P1 P2 * P4 *
94535 **
94536 ** Write P4 on the statement trace output if statement tracing is
94537 ** enabled.
@@ -94788,11 +95253,18 @@
94788 rc = SQLITE_CORRUPT_BKPT;
94789 }
94790 assert( rc );
94791 #ifdef SQLITE_DEBUG
94792 if( db->flags & SQLITE_VdbeTrace ){
94793 printf("ABORT-due-to-error. rc=%d\n", rc);
 
 
 
 
 
 
 
94794 }
94795 #endif
94796 if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
94797 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
94798 }
@@ -94801,10 +95273,13 @@
94801 testcase( sqlite3GlobalConfig.xLog!=0 );
94802 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
94803 (int)(pOp - aOp), p->zSql, p->zErrMsg);
94804 sqlite3VdbeHalt(p);
94805 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
 
 
 
94806 rc = SQLITE_ERROR;
94807 if( resetSchemaOnFault>0 ){
94808 sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
94809 }
94810
@@ -94932,11 +95407,14 @@
94932 }else{
94933 rc = sqlite3_step(p->pStmt);
94934 }
94935 if( rc==SQLITE_ROW ){
94936 VdbeCursor *pC = v->apCsr[0];
94937 u32 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
 
 
 
94938 testcase( pC->nHdrParsed==p->iCol );
94939 testcase( pC->nHdrParsed==p->iCol+1 );
94940 if( type<12 ){
94941 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
94942 type==0?"null": type==7?"real": "integer"
@@ -95069,11 +95547,11 @@
95069 /* Check that the column is not part of an FK child key definition. It
95070 ** is not necessary to check if it is part of a parent key, as parent
95071 ** key columns must be indexed. The check below will pick up this
95072 ** case. */
95073 FKey *pFKey;
95074 assert( !IsVirtual(pTab) );
95075 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
95076 int j;
95077 for(j=0; j<pFKey->nCol; j++){
95078 if( pFKey->aCol[j].iFrom==iCol ){
95079 zFault = "foreign key";
@@ -95277,10 +95755,12 @@
95277 ** using the incremental-blob API, this works. For the sessions module
95278 ** anyhow.
95279 */
95280 sqlite3_int64 iKey;
95281 iKey = sqlite3BtreeIntegerKey(p->pCsr);
 
 
95282 sqlite3VdbePreUpdateHook(
95283 v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
95284 );
95285 }
95286 #endif
@@ -96659,11 +97139,11 @@
96659 void *p = 0;
96660 int chunksize = 4*1024;
96661 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
96662 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
96663 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
96664 sqlite3OsUnfetch(pFd, 0, p);
96665 }
96666 }
96667 #else
96668 # define vdbeSorterExtendFile(x,y,z)
96669 #endif
@@ -97377,10 +97857,11 @@
97377 pTask->file2.iEof += pIncr->mxSz;
97378 }else{
97379 vdbeMergeEngineFree(pMerger);
97380 rc = SQLITE_NOMEM_BKPT;
97381 }
 
97382 return rc;
97383 }
97384
97385 #if SQLITE_MAX_WORKER_THREADS>0
97386 /*
@@ -99078,11 +99559,11 @@
99078 if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
99079 if( pExpr->pRight ){
99080 assert( !ExprHasProperty(pExpr, EP_WinFunc) );
99081 pExpr = pExpr->pRight;
99082 continue;
99083 }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
99084 assert( !ExprHasProperty(pExpr, EP_WinFunc) );
99085 if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
99086 }else{
99087 if( pExpr->x.pList ){
99088 if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
@@ -99350,10 +99831,11 @@
99350 sqlite3ExprDelete(db, pDup);
99351 pDup = 0;
99352 }else{
99353 incrAggFunctionDepth(pDup, nSubquery);
99354 if( pExpr->op==TK_COLLATE ){
 
99355 pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
99356 }
99357
99358 /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
99359 ** prevents ExprDelete() from deleting the Expr structure itself,
@@ -99453,10 +99935,11 @@
99453 SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){
99454 int n;
99455 Table *pExTab;
99456
99457 n = pExpr->iColumn;
 
99458 pExTab = pExpr->y.pTab;
99459 assert( pExTab!=0 );
99460 if( (pExTab->tabFlags & TF_HasGenerated)!=0
99461 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
99462 ){
@@ -99590,10 +100073,11 @@
99590 const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
99591 assert( zTabName!=0 );
99592 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
99593 continue;
99594 }
 
99595 if( IN_RENAME_OBJECT && pItem->zAlias ){
99596 sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
99597 }
99598 }
99599 hCol = sqlite3StrIHash(zCol);
@@ -99621,10 +100105,11 @@
99621 pMatch = pItem;
99622 }
99623 }
99624 if( pMatch ){
99625 pExpr->iTable = pMatch->iCursor;
 
99626 pExpr->y.pTab = pMatch->pTab;
99627 /* RIGHT JOIN not (yet) supported */
99628 assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
99629 if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
99630 ExprSetProperty(pExpr, EP_CanBeNull);
@@ -99694,10 +100179,11 @@
99694 cnt++;
99695 pMatch = 0;
99696 #ifndef SQLITE_OMIT_UPSERT
99697 if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
99698 testcase( iCol==(-1) );
 
99699 if( IN_RENAME_OBJECT ){
99700 pExpr->iColumn = iCol;
99701 pExpr->y.pTab = pTab;
99702 eNewExprOp = TK_COLUMN;
99703 }else{
@@ -99706,10 +100192,11 @@
99706 eNewExprOp = TK_REGISTER;
99707 }
99708 }else
99709 #endif /* SQLITE_OMIT_UPSERT */
99710 {
 
99711 pExpr->y.pTab = pTab;
99712 if( pParse->bReturning ){
99713 eNewExprOp = TK_REGISTER;
99714 pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
99715 sqlite3TableColumnToStorage(pTab, iCol) + 1;
@@ -99780,12 +100267,12 @@
99780 if( pEList->a[j].eEName==ENAME_NAME
99781 && sqlite3_stricmp(zAs, zCol)==0
99782 ){
99783 Expr *pOrig;
99784 assert( pExpr->pLeft==0 && pExpr->pRight==0 );
99785 assert( pExpr->x.pList==0 );
99786 assert( pExpr->x.pSelect==0 );
99787 pOrig = pEList->a[j].pExpr;
99788 if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
99789 sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
99790 return WRC_Abort;
99791 }
@@ -99853,11 +100340,11 @@
99853 "double-quoted string literal: \"%w\"", zCol);
99854 #ifdef SQLITE_ENABLE_NORMALIZE
99855 sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
99856 #endif
99857 pExpr->op = TK_STRING;
99858 pExpr->y.pTab = 0;
99859 return WRC_Prune;
99860 }
99861 if( sqlite3ExprIdToTrueFalse(pExpr) ){
99862 return WRC_Prune;
99863 }
@@ -99939,11 +100426,13 @@
99939 */
99940 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
99941 Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
99942 if( p ){
99943 SrcItem *pItem = &pSrc->a[iSrc];
99944 Table *pTab = p->y.pTab = pItem->pTab;
 
 
99945 p->iTable = pItem->iCursor;
99946 if( p->y.pTab->iPKey==iCol ){
99947 p->iColumn = -1;
99948 }else{
99949 p->iColumn = (ynVar)iCol;
@@ -100006,10 +100495,11 @@
100006 ** value between 1.0 and 0.0.
100007 */
100008 static int exprProbability(Expr *p){
100009 double r = -1.0;
100010 if( p->op!=TK_FLOAT ) return -1;
 
100011 sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
100012 assert( r>=0.0 );
100013 if( r>1.0 ) return -1;
100014 return (int)(r*134217728.0);
100015 }
@@ -100054,10 +100544,11 @@
100054 SrcList *pSrcList = pNC->pSrcList;
100055 SrcItem *pItem;
100056 assert( pSrcList && pSrcList->nSrc>=1 );
100057 pItem = pSrcList->a;
100058 pExpr->op = TK_COLUMN;
 
100059 pExpr->y.pTab = pItem->pTab;
100060 pExpr->iTable = pItem->iCursor;
100061 pExpr->iColumn--;
100062 pExpr->affExpr = SQLITE_AFF_INTEGER;
100063 break;
@@ -100086,10 +100577,11 @@
100086 anRef[i] = p->nRef;
100087 }
100088 sqlite3WalkExpr(pWalker, pExpr->pLeft);
100089 if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
100090 testcase( ExprHasProperty(pExpr, EP_FromJoin) );
 
100091 if( pExpr->op==TK_NOTNULL ){
100092 pExpr->u.zToken = "true";
100093 ExprSetProperty(pExpr, EP_IsTrue);
100094 }else{
100095 pExpr->u.zToken = "false";
@@ -100121,10 +100613,11 @@
100121 Expr *pRight;
100122
100123 if( pExpr->op==TK_ID ){
100124 zDb = 0;
100125 zTable = 0;
 
100126 zColumn = pExpr->u.zToken;
100127 }else{
100128 Expr *pLeft = pExpr->pLeft;
100129 testcase( pNC->ncFlags & NC_IdxExpr );
100130 testcase( pNC->ncFlags & NC_GenCol );
@@ -100133,16 +100626,19 @@
100133 pRight = pExpr->pRight;
100134 if( pRight->op==TK_ID ){
100135 zDb = 0;
100136 }else{
100137 assert( pRight->op==TK_DOT );
 
100138 zDb = pLeft->u.zToken;
100139 pLeft = pRight->pLeft;
100140 pRight = pRight->pRight;
100141 }
 
100142 zTable = pLeft->u.zToken;
100143 zColumn = pRight->u.zToken;
 
100144 if( IN_RENAME_OBJECT ){
100145 sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
100146 sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
100147 }
100148 }
@@ -100163,11 +100659,11 @@
100163 u8 enc = ENC(pParse->db); /* The database encoding */
100164 int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100165 #ifndef SQLITE_OMIT_WINDOWFUNC
100166 Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100167 #endif
100168 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
100169 zId = pExpr->u.zToken;
100170 nId = sqlite3Strlen30(zId);
100171 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100172 if( pDef==0 ){
100173 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
@@ -100327,11 +100823,11 @@
100327 sqlite3WalkExprList(pWalker, pList);
100328 if( is_agg ){
100329 #ifndef SQLITE_OMIT_WINDOWFUNC
100330 if( pWin ){
100331 Select *pSel = pNC->pWinSelect;
100332 assert( pWin==pExpr->y.pWin );
100333 if( IN_RENAME_OBJECT==0 ){
100334 sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
100335 if( pParse->db->mallocFailed ) break;
100336 }
100337 sqlite3WalkExprList(pWalker, pWin->pPartition);
@@ -100340,19 +100836,22 @@
100340 sqlite3WindowLink(pSel, pWin);
100341 pNC->ncFlags |= NC_HasWin;
100342 }else
100343 #endif /* SQLITE_OMIT_WINDOWFUNC */
100344 {
100345 NameContext *pNC2 = pNC;
100346 pExpr->op = TK_AGG_FUNCTION;
100347 pExpr->op2 = 0;
100348 #ifndef SQLITE_OMIT_WINDOWFUNC
100349 if( ExprHasProperty(pExpr, EP_WinFunc) ){
100350 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100351 }
100352 #endif
100353 while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
 
 
 
100354 pExpr->op2++;
100355 pNC2 = pNC2->pNext;
100356 }
100357 assert( pDef!=0 || IN_RENAME_OBJECT );
100358 if( pNC2 && pDef ){
@@ -100376,11 +100875,11 @@
100376 case TK_SELECT:
100377 case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
100378 #endif
100379 case TK_IN: {
100380 testcase( pExpr->op==TK_IN );
100381 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
100382 int nRef = pNC->nRef;
100383 testcase( pNC->ncFlags & NC_IsCheck );
100384 testcase( pNC->ncFlags & NC_PartIdx );
100385 testcase( pNC->ncFlags & NC_IdxExpr );
100386 testcase( pNC->ncFlags & NC_GenCol );
@@ -100433,10 +100932,11 @@
100433 int nLeft, nRight;
100434 if( pParse->db->mallocFailed ) break;
100435 assert( pExpr->pLeft!=0 );
100436 nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
100437 if( pExpr->op==TK_BETWEEN ){
 
100438 nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
100439 if( nRight==nLeft ){
100440 nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
100441 }
100442 }else{
@@ -100481,11 +100981,13 @@
100481 int i; /* Loop counter */
100482
100483 UNUSED_PARAMETER(pParse);
100484
100485 if( pE->op==TK_ID ){
100486 char *zCol = pE->u.zToken;
 
 
100487 for(i=0; i<pEList->nExpr; i++){
100488 if( pEList->a[i].eEName==ENAME_NAME
100489 && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
100490 ){
100491 return i+1;
@@ -101315,12 +101817,12 @@
101315
101316 /*
101317 ** Return the affinity character for a single column of a table.
101318 */
101319 SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101320 assert( iCol<pTab->nCol );
101321 return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
101322 }
101323
101324 /*
101325 ** Return the 'affinity' of the expression pExpr if any.
101326 **
@@ -101346,15 +101848,18 @@
101346 pExpr = pExpr->pLeft;
101347 assert( pExpr!=0 );
101348 }
101349 op = pExpr->op;
101350 if( op==TK_REGISTER ) op = pExpr->op2;
101351 if( (op==TK_COLUMN || op==TK_AGG_COLUMN) && pExpr->y.pTab ){
101352 return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
 
 
 
101353 }
101354 if( op==TK_SELECT ){
101355 assert( pExpr->flags&EP_xIsSelect );
101356 assert( pExpr->x.pSelect!=0 );
101357 assert( pExpr->x.pSelect->pEList!=0 );
101358 assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
101359 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
101360 }
@@ -101363,18 +101868,19 @@
101363 assert( !ExprHasProperty(pExpr, EP_IntValue) );
101364 return sqlite3AffinityType(pExpr->u.zToken, 0);
101365 }
101366 #endif
101367 if( op==TK_SELECT_COLUMN ){
101368 assert( pExpr->pLeft->flags&EP_xIsSelect );
101369 assert( pExpr->iColumn < pExpr->iTable );
101370 assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
101371 return sqlite3ExprAffinity(
101372 pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
101373 );
101374 }
101375 if( op==TK_VECTOR ){
 
101376 return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
101377 }
101378 return pExpr->affExpr;
101379 }
101380
@@ -101430,11 +101936,11 @@
101430 ** expression.
101431 */
101432 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
101433 while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
101434 if( ExprHasProperty(pExpr, EP_Unlikely) ){
101435 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
101436 assert( pExpr->x.pList->nExpr>0 );
101437 assert( pExpr->op==TK_FUNCTION );
101438 pExpr = pExpr->x.pList->a[0].pExpr;
101439 }else{
101440 assert( pExpr->op==TK_COLLATE );
@@ -101463,45 +101969,46 @@
101463 CollSeq *pColl = 0;
101464 const Expr *p = pExpr;
101465 while( p ){
101466 int op = p->op;
101467 if( op==TK_REGISTER ) op = p->op2;
101468 if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
101469 && p->y.pTab!=0
101470 ){
101471 /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
101472 ** a TK_COLUMN but was previously evaluated and cached in a register */
101473 int j = p->iColumn;
101474 if( j>=0 ){
101475 const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]);
101476 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
101477 }
101478 break;
 
101479 }
101480 if( op==TK_CAST || op==TK_UPLUS ){
101481 p = p->pLeft;
101482 continue;
101483 }
101484 if( op==TK_VECTOR ){
 
101485 p = p->x.pList->a[0].pExpr;
101486 continue;
101487 }
101488 if( op==TK_COLLATE ){
 
101489 pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
101490 break;
101491 }
101492 if( p->flags & EP_Collate ){
101493 if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
101494 p = p->pLeft;
101495 }else{
101496 Expr *pNext = p->pRight;
101497 /* The Expr.x union is never used at the same time as Expr.pRight */
 
101498 assert( p->x.pList==0 || p->pRight==0 );
101499 if( p->x.pList!=0
101500 && !db->mallocFailed
101501 && ALWAYS(!ExprHasProperty(p, EP_xIsSelect))
101502 ){
101503 int i;
101504 for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
101505 if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
101506 pNext = p->x.pList->a[i].pExpr;
101507 break;
@@ -101580,11 +102087,11 @@
101580 pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
101581 assert( pExpr->pLeft );
101582 aff = sqlite3ExprAffinity(pExpr->pLeft);
101583 if( pExpr->pRight ){
101584 aff = sqlite3CompareAffinity(pExpr->pRight, aff);
101585 }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){
101586 aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
101587 }else if( aff==0 ){
101588 aff = SQLITE_AFF_BLOB;
101589 }
101590 return aff;
@@ -101720,12 +102227,14 @@
101720 */
101721 SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){
101722 u8 op = pExpr->op;
101723 if( op==TK_REGISTER ) op = pExpr->op2;
101724 if( op==TK_VECTOR ){
 
101725 return pExpr->x.pList->nExpr;
101726 }else if( op==TK_SELECT ){
 
101727 return pExpr->x.pSelect->pEList->nExpr;
101728 }else{
101729 return 1;
101730 }
101731 }
@@ -101748,12 +102257,14 @@
101748 SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
101749 assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
101750 if( sqlite3ExprIsVector(pVector) ){
101751 assert( pVector->op2==0 || pVector->op==TK_REGISTER );
101752 if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
 
101753 return pVector->x.pSelect->pEList->a[i].pExpr;
101754 }else{
 
101755 return pVector->x.pList->a[i].pExpr;
101756 }
101757 }
101758 return pVector;
101759 }
@@ -101785,11 +102296,11 @@
101785 int iField, /* Which column of the vector to return */
101786 int nField /* Total number of columns in the vector */
101787 ){
101788 Expr *pRet;
101789 if( pVector->op==TK_SELECT ){
101790 assert( pVector->flags & EP_xIsSelect );
101791 /* The TK_SELECT_COLUMN Expr node:
101792 **
101793 ** pLeft: pVector containing TK_SELECT. Not deleted.
101794 ** pRight: not used. But recursively deleted.
101795 ** iColumn: Index of a column in pVector
@@ -101810,11 +102321,13 @@
101810 pRet->iColumn = iField;
101811 pRet->pLeft = pVector;
101812 }
101813 }else{
101814 if( pVector->op==TK_VECTOR ){
101815 Expr **ppVector = &pVector->x.pList->a[iField].pExpr;
 
 
101816 pVector = *ppVector;
101817 if( IN_RENAME_OBJECT ){
101818 /* This must be a vector UPDATE inside a trigger */
101819 *ppVector = 0;
101820 return pVector;
@@ -101874,14 +102387,16 @@
101874 if( op==TK_REGISTER ){
101875 *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
101876 return pVector->iTable+iField;
101877 }
101878 if( op==TK_SELECT ){
 
101879 *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
101880 return regSelect+iField;
101881 }
101882 if( op==TK_VECTOR ){
 
101883 *ppExpr = pVector->x.pList->a[iField].pExpr;
101884 return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
101885 }
101886 return 0;
101887 }
@@ -102052,11 +102567,11 @@
102052 */
102053 static void exprSetHeight(Expr *p){
102054 int nHeight = 0;
102055 heightOfExpr(p->pLeft, &nHeight);
102056 heightOfExpr(p->pRight, &nHeight);
102057 if( ExprHasProperty(p, EP_xIsSelect) ){
102058 heightOfSelect(p->x.pSelect, &nHeight);
102059 }else if( p->x.pList ){
102060 heightOfExprList(p->x.pList, &nHeight);
102061 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
102062 }
@@ -102091,11 +102606,11 @@
102091 ** Propagate all EP_Propagate flags from the Expr.x.pList into
102092 ** Expr.flags.
102093 */
102094 SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
102095 if( pParse->nErr ) return;
102096 if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){
102097 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
102098 }
102099 }
102100 #define exprSetHeight(y)
102101 #endif /* SQLITE_MAX_EXPR_DEPTH>0 */
@@ -102275,17 +102790,24 @@
102275 Select *pRet = 0;
102276 assert( nElem>1 );
102277 for(ii=0; ii<pEList->nExpr; ii++){
102278 Select *pSel;
102279 Expr *pExpr = pEList->a[ii].pExpr;
102280 int nExprElem = (pExpr->op==TK_VECTOR ? pExpr->x.pList->nExpr : 1);
 
 
 
 
 
 
102281 if( nExprElem!=nElem ){
102282 sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d",
102283 nExprElem, nExprElem>1?"s":"", nElem
102284 );
102285 break;
102286 }
 
102287 pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0);
102288 pExpr->x.pList = 0;
102289 if( pSel ){
102290 if( pRet ){
102291 pSel->op = TK_ALL;
@@ -102351,11 +102873,11 @@
102351 ){
102352 sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
102353 }
102354 pNew->x.pList = pList;
102355 ExprSetProperty(pNew, EP_HasFunc);
102356 assert( !ExprHasProperty(pNew, EP_xIsSelect) );
102357 sqlite3ExprSetHeightAndFlags(pParse, pNew);
102358 if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
102359 return pNew;
102360 }
102361
@@ -102477,31 +102999,30 @@
102477 /*
102478 ** Recursively delete an expression tree.
102479 */
102480 static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
102481 assert( p!=0 );
102482 /* Sanity check: Assert that the IntValue is non-negative if it exists */
102483 assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 );
102484
102485 assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed );
102486 assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
102487 || p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
102488 #ifdef SQLITE_DEBUG
102489 if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
102490 assert( p->pLeft==0 );
102491 assert( p->pRight==0 );
102492 assert( p->x.pSelect==0 );
 
102493 }
102494 #endif
102495 if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
102496 /* The Expr.x union is never used at the same time as Expr.pRight */
102497 assert( p->x.pList==0 || p->pRight==0 );
102498 if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
102499 if( p->pRight ){
102500 assert( !ExprHasProperty(p, EP_WinFunc) );
102501 sqlite3ExprDeleteNN(db, p->pRight);
102502 }else if( ExprHasProperty(p, EP_xIsSelect) ){
102503 assert( !ExprHasProperty(p, EP_WinFunc) );
102504 sqlite3SelectDelete(db, p->x.pSelect);
102505 }else{
102506 sqlite3ExprListDelete(db, p->x.pList);
102507 #ifndef SQLITE_OMIT_WINDOWFUNC
@@ -102509,11 +103030,14 @@
102509 sqlite3WindowDelete(db, p->y.pWin);
102510 }
102511 #endif
102512 }
102513 }
102514 if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken);
 
 
 
102515 if( !ExprHasProperty(p, EP_Static) ){
102516 sqlite3DbFreeNN(db, p);
102517 }
102518 }
102519 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -102725,11 +103249,11 @@
102725 memcpy(zToken, p->u.zToken, nToken);
102726 }
102727
102728 if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
102729 /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
102730 if( ExprHasProperty(p, EP_xIsSelect) ){
102731 pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
102732 }else{
102733 pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
102734 }
102735 }
@@ -103019,11 +103543,11 @@
103019 }
103020
103021 return pRet;
103022 }
103023 #else
103024 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){
103025 assert( p==0 );
103026 return 0;
103027 }
103028 #endif
103029
@@ -103352,11 +103876,11 @@
103352 ** the conversion happened, and zero if the expression is unaltered.
103353 */
103354 SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
103355 u32 v;
103356 assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
103357 if( !ExprHasProperty(pExpr, EP_Quoted)
103358 && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
103359 ){
103360 pExpr->op = TK_TRUEFALSE;
103361 ExprSetProperty(pExpr, v);
103362 return 1;
@@ -103369,10 +103893,11 @@
103369 ** and 0 if it is FALSE.
103370 */
103371 SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
103372 pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
103373 assert( pExpr->op==TK_TRUEFALSE );
 
103374 assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
103375 || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
103376 return pExpr->u.zToken[4]==0;
103377 }
103378
@@ -103573,11 +104098,11 @@
103573 }
103574 }
103575 }
103576
103577 /* Check if pExpr is a sub-select. If so, consider it variable. */
103578 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
103579 pWalker->eCode = 0;
103580 return WRC_Abort;
103581 }
103582
103583 return exprNodeIsConstant(pWalker, pExpr);
@@ -103680,13 +104205,13 @@
103680 case TK_UPLUS: {
103681 rc = sqlite3ExprIsInteger(p->pLeft, pValue);
103682 break;
103683 }
103684 case TK_UMINUS: {
103685 int v;
103686 if( sqlite3ExprIsInteger(p->pLeft, &v) ){
103687 assert( v!=(-2147483647-1) );
103688 *pValue = -v;
103689 rc = 1;
103690 }
103691 break;
103692 }
@@ -103723,14 +104248,15 @@
103723 case TK_STRING:
103724 case TK_FLOAT:
103725 case TK_BLOB:
103726 return 0;
103727 case TK_COLUMN:
 
103728 return ExprHasProperty(p, EP_CanBeNull) ||
103729 p->y.pTab==0 || /* Reference to column of index on expression */
103730 (p->iColumn>=0
103731 && ALWAYS(p->y.pTab->aCol!=0) /* Defense against OOM problems */
103732 && p->y.pTab->aCol[p->iColumn].notNull==0);
103733 default:
103734 return 1;
103735 }
103736 }
@@ -103800,11 +104326,11 @@
103800 Select *p;
103801 SrcList *pSrc;
103802 ExprList *pEList;
103803 Table *pTab;
103804 int i;
103805 if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0; /* Not a subquery */
103806 if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
103807 p = pX->x.pSelect;
103808 if( p->pPrior ) return 0; /* Not a compound SELECT */
103809 if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
103810 testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -103971,11 +104497,11 @@
103971 /* If the RHS of this IN(...) operator is a SELECT, and if it matters
103972 ** whether or not the SELECT result contains NULL values, check whether
103973 ** or not NULL is actually possible (it may not be, for example, due
103974 ** to NOT NULL constraints in the schema). If no NULL values are possible,
103975 ** set prRhsHasNull to 0 before continuing. */
103976 if( prRhsHasNull && (pX->flags & EP_xIsSelect) ){
103977 int i;
103978 ExprList *pEList = pX->x.pSelect->pEList;
103979 for(i=0; i<pEList->nExpr; i++){
103980 if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
103981 }
@@ -104072,11 +104598,12 @@
104072 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104073 Expr *pRhs = pEList->a[i].pExpr;
104074 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104075 int j;
104076
104077 assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr );
 
104078 for(j=0; j<nExpr; j++){
104079 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104080 assert( pIdx->azColl[j] );
104081 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104082 continue;
@@ -104127,11 +104654,11 @@
104127 ** then it is not worth creating an ephemeral table to evaluate
104128 ** the IN operator so return IN_INDEX_NOOP.
104129 */
104130 if( eType==0
104131 && (inFlags & IN_INDEX_NOOP_OK)
104132 && !ExprHasProperty(pX, EP_xIsSelect)
104133 && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
104134 ){
104135 eType = IN_INDEX_NOOP;
104136 }
104137
@@ -104175,11 +104702,11 @@
104175 ** string is eventually freed using sqlite3DbFree().
104176 */
104177 static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
104178 Expr *pLeft = pExpr->pLeft;
104179 int nVal = sqlite3ExprVectorSize(pLeft);
104180 Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
104181 char *zRet;
104182
104183 assert( pExpr->op==TK_IN );
104184 zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
104185 if( zRet ){
@@ -104225,11 +104752,11 @@
104225 **
104226 ** "row value misused"
104227 */
104228 SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
104229 #ifndef SQLITE_OMIT_SUBQUERY
104230 if( pExpr->flags & EP_xIsSelect ){
104231 sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
104232 }else
104233 #endif
104234 {
104235 sqlite3ErrorMsg(pParse, "row value misused");
@@ -104289,22 +104816,24 @@
104289 /* If this routine has already been coded, but the previous code
104290 ** might not have been invoked yet, so invoke it now as a subroutine.
104291 */
104292 if( ExprHasProperty(pExpr, EP_Subrtn) ){
104293 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
104294 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104295 ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
104296 pExpr->x.pSelect->selId));
104297 }
 
104298 sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
104299 pExpr->y.sub.iAddr);
104300 sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
104301 sqlite3VdbeJumpHere(v, addrOnce);
104302 return;
104303 }
104304
104305 /* Begin coding the subroutine */
 
104306 ExprSetProperty(pExpr, EP_Subrtn);
104307 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
104308 pExpr->y.sub.regReturn = ++pParse->nMem;
104309 pExpr->y.sub.iAddr =
104310 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
@@ -104321,19 +104850,19 @@
104321 ** RHS of the IN operator.
104322 */
104323 pExpr->iTable = iTab;
104324 addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
104325 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
104326 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104327 VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
104328 }else{
104329 VdbeComment((v, "RHS of IN operator"));
104330 }
104331 #endif
104332 pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
104333
104334 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
104335 /* Case 1: expr IN (SELECT ...)
104336 **
104337 ** Generate code to write the results of the select into the temporary
104338 ** table allocated and opened above.
104339 */
@@ -104427,10 +104956,11 @@
104427 sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
104428 }
104429 if( addrOnce ){
104430 sqlite3VdbeJumpHere(v, addrOnce);
104431 /* Subroutine return */
 
104432 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
104433 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
104434 sqlite3ClearTempRegCache(pParse);
104435 }
104436 }
@@ -104463,23 +104993,26 @@
104463 assert( v!=0 );
104464 if( pParse->nErr ) return 0;
104465 testcase( pExpr->op==TK_EXISTS );
104466 testcase( pExpr->op==TK_SELECT );
104467 assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
104468 assert( ExprHasProperty(pExpr, EP_xIsSelect) );
104469 pSel = pExpr->x.pSelect;
104470
104471 /* If this routine has already been coded, then invoke it as a
104472 ** subroutine. */
104473 if( ExprHasProperty(pExpr, EP_Subrtn) ){
104474 ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
 
104475 sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
104476 pExpr->y.sub.iAddr);
104477 return pExpr->iTable;
104478 }
104479
104480 /* Begin coding the subroutine */
 
 
104481 ExprSetProperty(pExpr, EP_Subrtn);
104482 pExpr->y.sub.regReturn = ++pParse->nMem;
104483 pExpr->y.sub.iAddr =
104484 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
104485 VdbeComment((v, "return address"));
@@ -104555,10 +105088,11 @@
104555 if( addrOnce ){
104556 sqlite3VdbeJumpHere(v, addrOnce);
104557 }
104558
104559 /* Subroutine return */
 
104560 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
104561 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
104562 sqlite3ClearTempRegCache(pParse);
104563 return rReg;
104564 }
@@ -104571,11 +105105,11 @@
104571 ** columns as the vector on the LHS. Or, if the RHS of the IN() is not
104572 ** a sub-query, that the LHS is a vector of size 1.
104573 */
104574 SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
104575 int nVector = sqlite3ExprVectorSize(pIn->pLeft);
104576 if( (pIn->flags & EP_xIsSelect)!=0 && !pParse->db->mallocFailed ){
104577 if( nVector!=pIn->x.pSelect->pEList->nExpr ){
104578 sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
104579 return 1;
104580 }
104581 }else if( nVector!=1 ){
@@ -104705,17 +105239,19 @@
104705 ** sequence of comparisons.
104706 **
104707 ** This is step (1) in the in-operator.md optimized algorithm.
104708 */
104709 if( eType==IN_INDEX_NOOP ){
104710 ExprList *pList = pExpr->x.pList;
104711 CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
104712 int labelOk = sqlite3VdbeMakeLabel(pParse);
104713 int r2, regToFree;
104714 int regCkNull = 0;
104715 int ii;
104716 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
 
 
104717 if( destIfNull!=destIfFalse ){
104718 regCkNull = sqlite3GetTempReg(pParse);
104719 sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
104720 }
104721 for(ii=0; ii<pList->nExpr; ii++){
@@ -105097,10 +105633,11 @@
105097 #endif
105098 }else{
105099 int i;
105100 iResult = pParse->nMem+1;
105101 pParse->nMem += nResult;
 
105102 for(i=0; i<nResult; i++){
105103 sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
105104 }
105105 }
105106 }
@@ -105295,10 +105832,11 @@
105295 ** datatype by applying the Affinity of the table column to the
105296 ** constant.
105297 */
105298 int aff;
105299 iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
 
105300 if( pExpr->y.pTab ){
105301 aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
105302 }else{
105303 aff = pExpr->affExpr;
105304 }
@@ -105318,13 +105856,15 @@
105318 ** The row is unpacked into registers beginning at
105319 ** 0-(pParse->iSelfTab). The rowid (if any) is in a register
105320 ** immediately prior to the first column.
105321 */
105322 Column *pCol;
105323 Table *pTab = pExpr->y.pTab;
105324 int iSrc;
105325 int iCol = pExpr->iColumn;
 
 
105326 assert( pTab!=0 );
105327 assert( iCol>=XN_ROWID );
105328 assert( iCol<pTab->nCol );
105329 if( iCol<0 ){
105330 return -1-pParse->iSelfTab;
@@ -105358,10 +105898,11 @@
105358 /* Coding an expression that is part of an index where column names
105359 ** in the index refer to the table to which the index belongs */
105360 iTab = pParse->iSelfTab - 1;
105361 }
105362 }
 
105363 iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
105364 pExpr->iColumn, iTab, target,
105365 pExpr->op2);
105366 if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){
105367 sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
@@ -105435,10 +105976,11 @@
105435 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
105436 if( inReg!=target ){
105437 sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
105438 inReg = target;
105439 }
 
105440 sqlite3VdbeAddOp2(v, OP_Cast, target,
105441 sqlite3AffinityType(pExpr->u.zToken, 0));
105442 return inReg;
105443 }
105444 #endif /* SQLITE_OMIT_CAST */
@@ -105602,12 +106144,12 @@
105602 if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
105603 /* SQL functions can be expensive. So try to avoid running them
105604 ** multiple times if we know they always give the same result */
105605 return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
105606 }
105607 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
105608 assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
 
105609 pFarg = pExpr->x.pList;
105610 nFarg = pFarg ? pFarg->nExpr : 0;
105611 assert( !ExprHasProperty(pExpr, EP_IntValue) );
105612 zId = pExpr->u.zToken;
105613 pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
@@ -105692,11 +106234,11 @@
105692 if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
105693 if( !pColl ) pColl = db->pDfltColl;
105694 sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
105695 }
105696 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
105697 if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){
105698 Expr *pArg = pFarg->a[0].pExpr;
105699 if( pArg->op==TK_COLUMN ){
105700 sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
105701 }else{
105702 sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -105722,11 +106264,14 @@
105722 int nCol;
105723 testcase( op==TK_EXISTS );
105724 testcase( op==TK_SELECT );
105725 if( pParse->db->mallocFailed ){
105726 return 0;
105727 }else if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
 
 
 
105728 sqlite3SubselectError(pParse, nCol, 1);
105729 }else{
105730 return sqlite3CodeSubselect(pParse, pExpr);
105731 }
105732 break;
@@ -105804,13 +106349,18 @@
105804 **
105805 ** p1==0 -> old.rowid p1==3 -> new.rowid
105806 ** p1==1 -> old.a p1==4 -> new.a
105807 ** p1==2 -> old.b p1==5 -> new.b
105808 */
105809 Table *pTab = pExpr->y.pTab;
105810 int iCol = pExpr->iColumn;
105811 int p1 = pExpr->iTable * (pTab->nCol+1) + 1
 
 
 
 
 
105812 + sqlite3TableColumnToStorage(pTab, iCol);
105813
105814 assert( pExpr->iTable==0 || pExpr->iTable==1 );
105815 assert( iCol>=-1 && iCol<pTab->nCol );
105816 assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
@@ -105894,11 +106444,11 @@
105894 Expr *pX; /* The X expression */
105895 Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
105896 Expr *pDel = 0;
105897 sqlite3 *db = pParse->db;
105898
105899 assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
105900 assert(pExpr->x.pList->nExpr > 0);
105901 pEList = pExpr->x.pList;
105902 aListelem = pEList->a;
105903 nExpr = pEList->nExpr;
105904 endLabel = sqlite3VdbeMakeLabel(pParse);
@@ -106239,11 +106789,11 @@
106239
106240 memset(&compLeft, 0, sizeof(Expr));
106241 memset(&compRight, 0, sizeof(Expr));
106242 memset(&exprAnd, 0, sizeof(Expr));
106243
106244 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
106245 pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
106246 if( db->mallocFailed==0 ){
106247 exprAnd.op = TK_AND;
106248 exprAnd.pLeft = &compLeft;
106249 exprAnd.pRight = &compRight;
@@ -106714,11 +107264,13 @@
106714 if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
106715 return 1;
106716 }
106717 return 2;
106718 }
106719 if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){
 
 
106720 if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
106721 if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
106722 #ifndef SQLITE_OMIT_WINDOWFUNC
106723 assert( pA->op==pB->op );
106724 if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
@@ -106732,11 +107284,16 @@
106732 #endif
106733 }else if( pA->op==TK_NULL ){
106734 return 0;
106735 }else if( pA->op==TK_COLLATE ){
106736 if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
106737 }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
 
 
 
 
 
106738 return 2;
106739 }
106740 }
106741 if( (pA->flags & (EP_Distinct|EP_Commuted))
106742 != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
@@ -106821,16 +107378,17 @@
106821 return pNN->op!=TK_NULL;
106822 }
106823 switch( p->op ){
106824 case TK_IN: {
106825 if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
106826 assert( ExprHasProperty(p,EP_xIsSelect)
106827 || (p->x.pList!=0 && p->x.pList->nExpr>0) );
106828 return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
106829 }
106830 case TK_BETWEEN: {
106831 ExprList *pList = p->x.pList;
 
 
106832 assert( pList!=0 );
106833 assert( pList->nExpr==2 );
106834 if( seenNot ) return 0;
106835 if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
106836 || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
@@ -107003,14 +107561,18 @@
107003 testcase( pExpr->op==TK_LE );
107004 testcase( pExpr->op==TK_GT );
107005 testcase( pExpr->op==TK_GE );
107006 /* The y.pTab=0 assignment in wherecode.c always happens after the
107007 ** impliesNotNullRow() test */
107008 if( (pLeft->op==TK_COLUMN && pLeft->y.pTab!=0
107009 && IsVirtual(pLeft->y.pTab))
107010 || (pRight->op==TK_COLUMN && pRight->y.pTab!=0
107011 && IsVirtual(pRight->y.pTab))
 
 
 
 
107012 ){
107013 return WRC_Prune;
107014 }
107015 /* no break */ deliberate_fall_through
107016 }
@@ -107115,92 +107677,129 @@
107115 sqlite3WalkExpr(&w, pExpr);
107116 return !w.eCode;
107117 }
107118
107119
107120 /*
107121 ** An instance of the following structure is used by the tree walker
107122 ** to count references to table columns in the arguments of an
107123 ** aggregate function, in order to implement the
107124 ** sqlite3FunctionThisSrc() routine.
107125 */
107126 struct SrcCount {
107127 SrcList *pSrc; /* One particular FROM clause in a nested query */
107128 int iSrcInner; /* Smallest cursor number in this context */
107129 int nThis; /* Number of references to columns in pSrcList */
107130 int nOther; /* Number of references to columns in other FROM clauses */
107131 };
107132
107133 /*
107134 ** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
107135 ** SELECT with a FROM clause encountered during this iteration, set
107136 ** SrcCount.iSrcInner to the cursor number of the leftmost object in
107137 ** the FROM cause.
 
 
107138 */
107139 static int selectSrcCount(Walker *pWalker, Select *pSel){
107140 struct SrcCount *p = pWalker->u.pSrcCount;
107141 if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
107142 pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
 
 
 
 
 
 
 
 
 
 
 
 
 
107143 }
107144 return WRC_Continue;
107145 }
107146
107147 /*
107148 ** Count the number of references to columns.
107149 */
107150 static int exprSrcCount(Walker *pWalker, Expr *pExpr){
107151 /* There was once a NEVER() on the second term on the grounds that
107152 ** sqlite3FunctionUsesThisSrc() was always called before
107153 ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet
107154 ** been converted into TK_AGG_COLUMN. But this is no longer true due
107155 ** to window functions - sqlite3WindowRewrite() may now indirectly call
107156 ** FunctionUsesThisSrc() when creating a new sub-select. */
107157 if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){
107158 int i;
107159 struct SrcCount *p = pWalker->u.pSrcCount;
107160 SrcList *pSrc = p->pSrc;
 
 
 
 
 
 
 
 
 
107161 int nSrc = pSrc ? pSrc->nSrc : 0;
107162 for(i=0; i<nSrc; i++){
107163 if( pExpr->iTable==pSrc->a[i].iCursor ) break;
107164 }
107165 if( i<nSrc ){
107166 p->nThis++;
107167 }else if( pExpr->iTable<p->iSrcInner ){
107168 /* In a well-formed parse tree (no name resolution errors),
107169 ** TK_COLUMN nodes with smaller Expr.iTable values are in an
107170 ** outer context. Those are the only ones to count as "other" */
107171 p->nOther++;
107172 }
107173 }
107174 return WRC_Continue;
107175 }
107176
107177 /*
107178 ** Determine if any of the arguments to the pExpr Function reference
107179 ** pSrcList. Return true if they do. Also return true if the function
107180 ** has no arguments or has only constant arguments. Return false if pExpr
107181 ** references columns but not columns of tables found in pSrcList.
 
 
 
 
 
 
 
 
 
107182 */
107183 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
107184 Walker w;
107185 struct SrcCount cnt;
 
 
 
 
 
 
 
 
107186 assert( pExpr->op==TK_AGG_FUNCTION );
107187 memset(&w, 0, sizeof(w));
107188 w.xExprCallback = exprSrcCount;
107189 w.xSelectCallback = selectSrcCount;
107190 w.u.pSrcCount = &cnt;
107191 cnt.pSrc = pSrcList;
107192 cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
107193 cnt.nThis = 0;
107194 cnt.nOther = 0;
107195 sqlite3WalkExprList(&w, pExpr->x.pList);
107196 #ifndef SQLITE_OMIT_WINDOWFUNC
107197 if( ExprHasProperty(pExpr, EP_WinFunc) ){
107198 sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107199 }
107200 #endif
107201 return cnt.nThis>0 || cnt.nOther==0;
 
 
 
 
 
 
 
107202 }
107203
107204 /*
107205 ** This is a Walker expression node callback.
107206 **
@@ -107331,10 +107930,11 @@
107331 }
107332 if( (k>=pAggInfo->nColumn)
107333 && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
107334 ){
107335 pCol = &pAggInfo->aCol[k];
 
107336 pCol->pTab = pExpr->y.pTab;
107337 pCol->iTable = pExpr->iTable;
107338 pCol->iColumn = pExpr->iColumn;
107339 pCol->iMem = ++pParse->nMem;
107340 pCol->iSorterColumn = -1;
@@ -107394,11 +107994,11 @@
107394 if( i>=0 ){
107395 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
107396 pItem = &pAggInfo->aFunc[i];
107397 pItem->pFExpr = pExpr;
107398 pItem->iMem = ++pParse->nMem;
107399 assert( !ExprHasProperty(pExpr, EP_IntValue) );
107400 pItem->pFunc = sqlite3FindFunction(pParse->db,
107401 pExpr->u.zToken,
107402 pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
107403 if( pExpr->flags & EP_Distinct ){
107404 pItem->iDistinct = pParse->nTab++;
@@ -107609,11 +108209,11 @@
107609 int bNoDQS /* Do not allow DQS in the schema */
107610 ){
107611 pParse->colNamesSet = 1;
107612 sqlite3NestedParse(pParse,
107613 "SELECT 1 "
107614 "FROM \"%w\"." DFLT_SCHEMA_TABLE " "
107615 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107616 " AND sql NOT LIKE 'create virtual%%'"
107617 " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
107618 zDb,
107619 zDb, bTemp, zWhen, bNoDQS
@@ -107620,11 +108220,11 @@
107620 );
107621
107622 if( bTemp==0 ){
107623 sqlite3NestedParse(pParse,
107624 "SELECT 1 "
107625 "FROM temp." DFLT_SCHEMA_TABLE " "
107626 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107627 " AND sql NOT LIKE 'create virtual%%'"
107628 " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
107629 zDb, zWhen, bNoDQS
107630 );
@@ -107638,18 +108238,18 @@
107638 ** not true, similarly update all SQL statements in the sqlite_schema table
107639 ** of the temp db.
107640 */
107641 static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
107642 sqlite3NestedParse(pParse,
107643 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE
107644 " SET sql = sqlite_rename_quotefix(%Q, sql)"
107645 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107646 " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
107647 );
107648 if( bTemp==0 ){
107649 sqlite3NestedParse(pParse,
107650 "UPDATE temp." DFLT_SCHEMA_TABLE
107651 " SET sql = sqlite_rename_quotefix('temp', sql)"
107652 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107653 " AND sql NOT LIKE 'create virtual%%'"
107654 );
107655 }
@@ -107763,21 +108363,21 @@
107763 nTabName = sqlite3Utf8CharLen(zTabName, -1);
107764
107765 /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
107766 ** the schema to use the new table name. */
107767 sqlite3NestedParse(pParse,
107768 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
107769 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
107770 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
107771 "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
107772 , zDb, zDb, zTabName, zName, (iDb==1), zTabName
107773 );
107774
107775 /* Update the tbl_name and name columns of the sqlite_schema table
107776 ** as required. */
107777 sqlite3NestedParse(pParse,
107778 "UPDATE %Q." DFLT_SCHEMA_TABLE " SET "
107779 "tbl_name = %Q, "
107780 "name = CASE "
107781 "WHEN type='table' THEN %Q "
107782 "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
107783 " AND type='index' THEN "
@@ -107916,10 +108516,11 @@
107916 */
107917 assert( pDflt==0 || pDflt->op==TK_SPAN );
107918 if( pDflt && pDflt->pLeft->op==TK_NULL ){
107919 pDflt = 0;
107920 }
 
107921 if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){
107922 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
107923 "Cannot add a REFERENCES column with non-NULL default value");
107924 }
107925 if( pCol->notNull && !pDflt ){
@@ -107958,13 +108559,14 @@
107958 while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
107959 *zEnd-- = '\0';
107960 }
107961 /* substr() operations on characters, but addColOffset is in bytes. So we
107962 ** have to use printf() to translate between these units: */
107963 assert( !IsVirtual(pTab) );
 
107964 sqlite3NestedParse(pParse,
107965 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
107966 "sql = printf('%%.%ds, ',sql) || %Q"
107967 " || substr(sql,1+length(printf('%%.%ds',sql))) "
107968 "WHERE type = 'table' AND name = %Q",
107969 zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,
107970 zTab
@@ -107986,11 +108588,11 @@
107986 VdbeCoverage(v);
107987 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
107988 sqlite3ReleaseTempReg(pParse, r1);
107989
107990 /* Reload the table definition */
107991 renameReloadSchema(pParse, iDb, INITFLAG_AlterRename);
107992
107993 /* Verify that constraints are still satisfied */
107994 if( pNew->pCheck!=0
107995 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
107996 ){
@@ -108052,10 +108654,11 @@
108052 if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
108053 goto exit_begin_add_column;
108054 }
108055
108056 sqlite3MayAbort(pParse);
 
108057 assert( pTab->u.tab.addColOffset>0 );
108058 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
108059
108060 /* Put a copy of the Table struct in Parse.pNewTable for the
108061 ** sqlite3AddColumn() function and friends to modify. But modify
@@ -108082,11 +108685,11 @@
108082 for(i=0; i<pNew->nCol; i++){
108083 Column *pCol = &pNew->aCol[i];
108084 pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName);
108085 pCol->hName = sqlite3StrIHash(pCol->zCnName);
108086 }
108087 assert( !IsVirtual(pNew) );
108088 pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0);
108089 pNew->pSchema = db->aDb[iDb].pSchema;
108090 pNew->u.tab.addColOffset = pTab->u.tab.addColOffset;
108091 pNew->nTabRef = 1;
108092
@@ -108193,21 +108796,21 @@
108193 zNew = sqlite3NameFromToken(db, pNew);
108194 if( !zNew ) goto exit_rename_column;
108195 assert( pNew->n>0 );
108196 bQuote = sqlite3Isquote(pNew->z[0]);
108197 sqlite3NestedParse(pParse,
108198 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
108199 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
108200 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
108201 " AND (type != 'index' OR tbl_name = %Q)",
108202 zDb,
108203 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
108204 pTab->zName
108205 );
108206
108207 sqlite3NestedParse(pParse,
108208 "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
108209 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
108210 "WHERE type IN ('trigger', 'view')",
108211 zDb, pTab->zName, iCol, zNew, bQuote
108212 );
108213
@@ -108351,11 +108954,13 @@
108351 ** Walker callback used by sqlite3RenameExprUnmap().
108352 */
108353 static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
108354 Parse *pParse = pWalker->pParse;
108355 sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr);
108356 sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);
 
 
108357 return WRC_Continue;
108358 }
108359
108360 /*
108361 ** Iterate through the Select objects that are part of WITH clauses attached
@@ -108413,11 +109018,13 @@
108413 */
108414 static int renameUnmapSelectCb(Walker *pWalker, Select *p){
108415 Parse *pParse = pWalker->pParse;
108416 int i;
108417 if( pParse->nErr ) return WRC_Abort;
108418 if( NEVER(p->selFlags & (SF_View|SF_CopyCte)) ){
 
 
108419 return WRC_Prune;
108420 }
108421 if( ALWAYS(p->pEList) ){
108422 ExprList *pList = p->pEList;
108423 for(i=0; i<pList->nExpr; i++){
@@ -108550,10 +109157,11 @@
108550 && pWalker->pParse->pTriggerTab==p->pTab
108551 ){
108552 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
108553 }else if( pExpr->op==TK_COLUMN
108554 && pExpr->iColumn==p->iCol
 
108555 && p->pTab==pExpr->y.pTab
108556 ){
108557 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
108558 }
108559 return WRC_Continue;
@@ -108874,10 +109482,13 @@
108874 p->pTab->nTabRef++;
108875 rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
108876 }
108877 }
108878 }
 
 
 
108879 sNC.pSrcList = pSrc;
108880 if( rc==SQLITE_OK && pStep->pWhere ){
108881 rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
108882 }
108883 if( rc==SQLITE_OK ){
@@ -109080,11 +109691,11 @@
109080 sqlite3WalkExpr(&sWalker, pExpr);
109081 }
109082 #endif
109083 }
109084
109085 assert( !IsVirtual(sParse.pNewTable) );
109086 for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
109087 for(i=0; i<pFKey->nCol; i++){
109088 if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
109089 renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
109090 }
@@ -109152,11 +109763,14 @@
109152 /*
109153 ** Walker expression callback used by "RENAME TABLE".
109154 */
109155 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
109156 RenameCtx *p = pWalker->u.pRename;
109157 if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){
 
 
 
109158 renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
109159 }
109160 return WRC_Continue;
109161 }
109162
@@ -109270,11 +109884,11 @@
109270 #ifndef SQLITE_OMIT_FOREIGN_KEY
109271 if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys))
109272 && !IsVirtual(pTab)
109273 ){
109274 FKey *pFKey;
109275 assert( !IsVirtual(pTab) );
109276 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
109277 if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
109278 renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
109279 }
109280 }
@@ -109591,11 +110205,11 @@
109591 if( iCol<pTab->nCol-1 ){
109592 RenameToken *pEnd;
109593 pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName);
109594 zEnd = (const char*)pEnd->t.z;
109595 }else{
109596 assert( !IsVirtual(pTab) );
109597 zEnd = (const char*)&zSql[pTab->u.tab.addColOffset];
109598 while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--;
109599 }
109600
109601 zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd);
@@ -109673,11 +110287,11 @@
109673 assert( iDb>=0 );
109674 zDb = db->aDb[iDb].zDbSName;
109675 renameTestSchema(pParse, zDb, iDb==1, "", 0);
109676 renameFixQuotes(pParse, zDb, iDb==1);
109677 sqlite3NestedParse(pParse,
109678 "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
109679 "sql = sqlite_drop_column(%d, sql, %d) "
109680 "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
109681 , zDb, iDb, iCol, pTab->zName
109682 );
109683
@@ -110766,11 +111380,11 @@
110766 pParse->nMem = MAX(pParse->nMem, iMem);
110767 v = sqlite3GetVdbe(pParse);
110768 if( v==0 || NEVER(pTab==0) ){
110769 return;
110770 }
110771 if( pTab->tnum==0 ){
110772 /* Do not gather statistics on views or virtual tables */
110773 return;
110774 }
110775 if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
110776 /* Do not gather statistics on system tables */
@@ -112049,21 +112663,22 @@
112049 if( pParse->nErr ) goto attach_end;
112050 memset(&sName, 0, sizeof(NameContext));
112051 sName.pParse = pParse;
112052
112053 if(
112054 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pFilename)) ||
112055 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pDbname)) ||
112056 SQLITE_OK!=(rc = resolveAttachExpr(&sName, pKey))
112057 ){
112058 goto attach_end;
112059 }
112060
112061 #ifndef SQLITE_OMIT_AUTHORIZATION
112062 if( pAuthArg ){
112063 char *zAuthArg;
112064 if( pAuthArg->op==TK_STRING ){
 
112065 zAuthArg = pAuthArg->u.zToken;
112066 }else{
112067 zAuthArg = 0;
112068 }
112069 rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
@@ -112744,21 +113359,26 @@
112744 Returning *pReturning = pParse->u1.pReturning;
112745 int addrRewind;
112746 int i;
112747 int reg;
112748
112749 addrRewind =
112750 sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
112751 VdbeCoverage(v);
112752 reg = pReturning->iRetReg;
112753 for(i=0; i<pReturning->nRetCol; i++){
112754 sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i);
112755 }
112756 sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i);
112757 sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1);
112758 VdbeCoverage(v);
112759 sqlite3VdbeJumpHere(v, addrRewind);
 
 
 
 
 
112760 }
112761 sqlite3VdbeAddOp0(v, OP_Halt);
112762
112763 #if SQLITE_USER_AUTHENTICATION
112764 if( pParse->nTableLock>0 && db->init.busy==0 ){
@@ -112835,11 +113455,15 @@
112835 }
112836 }
112837
112838 if( pParse->bReturning ){
112839 Returning *pRet = pParse->u1.pReturning;
112840 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
 
 
 
 
112841 }
112842
112843 /* Finally, jump back to the beginning of the executable code. */
112844 sqlite3VdbeGoto(v, 1);
112845 }
@@ -112953,21 +113577,21 @@
112953 }
112954 }
112955 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
112956 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
112957 if( i==1 ){
112958 if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0
112959 || sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0
112960 || sqlite3StrICmp(zName+7, &DFLT_SCHEMA_TABLE[7])==0
112961 ){
112962 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
112963 DFLT_TEMP_SCHEMA_TABLE);
112964 }
112965 }else{
112966 if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
112967 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
112968 DFLT_SCHEMA_TABLE);
112969 }
112970 }
112971 }
112972 }else{
112973 /* Match against TEMP first */
@@ -112981,15 +113605,15 @@
112981 assert( sqlite3SchemaMutexHeld(db, i, 0) );
112982 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
112983 if( p ) break;
112984 }
112985 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
112986 if( sqlite3StrICmp(zName+7, &ALT_SCHEMA_TABLE[7])==0 ){
112987 p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, DFLT_SCHEMA_TABLE);
112988 }else if( sqlite3StrICmp(zName+7, &ALT_TEMP_SCHEMA_TABLE[7])==0 ){
112989 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
112990 DFLT_TEMP_SCHEMA_TABLE);
112991 }
112992 }
112993 }
112994 return p;
112995 }
@@ -113080,10 +113704,26 @@
113080 }else{
113081 zDb = p->zDatabase;
113082 }
113083 return sqlite3LocateTable(pParse, flags, p->zName, zDb);
113084 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113085
113086 /*
113087 ** Locate the in-memory structure that describes
113088 ** a particular index given the name of that index
113089 ** and the name of the database that contains the index.
@@ -113257,11 +113897,11 @@
113257 Table *pTab, /* The table containing the column */
113258 Column *pCol, /* The column to receive the new DEFAULT expression */
113259 Expr *pExpr /* The new default expression */
113260 ){
113261 ExprList *pList;
113262 assert( !IsVirtual(pTab) );
113263 pList = pTab->u.tab.pDfltList;
113264 if( pCol->iDflt==0
113265 || NEVER(pList==0)
113266 || NEVER(pList->nExpr<pCol->iDflt)
113267 ){
@@ -113278,11 +113918,11 @@
113278 ** the DEFAULT clause or the AS clause of a generated column.
113279 ** Return NULL if the column has no associated expression.
113280 */
113281 SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
113282 if( pCol->iDflt==0 ) return 0;
113283 if( NEVER(IsVirtual(pTab)) ) return 0;
113284 if( NEVER(pTab->u.tab.pDfltList==0) ) return 0;
113285 if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0;
113286 return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
113287 }
113288
@@ -113292,12 +113932,12 @@
113292 SQLITE_PRIVATE void sqlite3ColumnSetColl(
113293 sqlite3 *db,
113294 Column *pCol,
113295 const char *zColl
113296 ){
113297 int nColl;
113298 int n;
113299 char *zNew;
113300 assert( zColl!=0 );
113301 n = sqlite3Strlen30(pCol->zCnName) + 1;
113302 if( pCol->colFlags & COLFLAG_HASTYPE ){
113303 n += sqlite3Strlen30(pCol->zCnName+n) + 1;
@@ -113337,17 +113977,17 @@
113337 for(i=0; i<pTable->nCol; i++, pCol++){
113338 assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) );
113339 sqlite3DbFree(db, pCol->zCnName);
113340 }
113341 sqlite3DbFree(db, pTable->aCol);
113342 if( !IsVirtual(pTable) ){
113343 sqlite3ExprListDelete(db, pTable->u.tab.pDfltList);
113344 }
113345 if( db==0 || db->pnBytesFreed==0 ){
113346 pTable->aCol = 0;
113347 pTable->nCol = 0;
113348 if( !IsVirtual(pTable) ){
113349 pTable->u.tab.pDfltList = 0;
113350 }
113351 }
113352 }
113353 }
@@ -113479,11 +114119,11 @@
113479 ** Open the sqlite_schema table stored in database number iDb for
113480 ** writing. The table is opened using cursor 0.
113481 */
113482 SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){
113483 Vdbe *v = sqlite3GetVdbe(p);
113484 sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, DFLT_SCHEMA_TABLE);
113485 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
113486 if( p->nTab==0 ){
113487 p->nTab = 1;
113488 }
113489 }
@@ -114098,11 +114738,11 @@
114098 break;
114099 }
114100 }
114101 }
114102
114103 z = sqlite3DbMallocRaw(db, sName.n + 1 + sType.n + (sType.n>0) );
114104 if( z==0 ) return;
114105 if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName);
114106 memcpy(z, sName.z, sName.n);
114107 z[sName.n] = 0;
114108 sqlite3Dequote(z);
@@ -114112,11 +114752,11 @@
114112 sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
114113 sqlite3DbFree(db, z);
114114 return;
114115 }
114116 }
114117 aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+1)*sizeof(p->aCol[0]));
114118 if( aNew==0 ){
114119 sqlite3DbFree(db, z);
114120 return;
114121 }
114122 p->aCol = aNew;
@@ -114410,11 +115050,13 @@
114410 for(i=0; i<nTerm; i++){
114411 Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
114412 assert( pCExpr!=0 );
114413 sqlite3StringToId(pCExpr);
114414 if( pCExpr->op==TK_ID ){
114415 const char *zCName = pCExpr->u.zToken;
 
 
114416 for(iCol=0; iCol<pTab->nCol; iCol++){
114417 if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){
114418 pCol = &pTab->aCol[iCol];
114419 makeColumnPartOfPrimaryKey(pParse, pCol);
114420 break;
@@ -114782,11 +115424,10 @@
114782 ** This is used to determine if the column number x appears in any of the
114783 ** first nCol entries of an index.
114784 */
114785 static int hasColumn(const i16 *aiCol, int nCol, int x){
114786 while( nCol-- > 0 ){
114787 assert( aiCol[0]>=0 );
114788 if( x==*(aiCol++) ){
114789 return 1;
114790 }
114791 }
114792 return 0;
@@ -115057,10 +115698,45 @@
115057 if( pMod->pModule->xShadowName==0 ) return 0;
115058 return pMod->pModule->xShadowName(zName+nName+1);
115059 }
115060 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115061
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115062 #ifndef SQLITE_OMIT_VIRTUALTABLE
115063 /*
115064 ** Return true if zName is a shadow table name in the current database
115065 ** connection.
115066 **
@@ -115158,11 +115834,11 @@
115158 **
115159 ** If the root page number is 1, that means this is the sqlite_schema
115160 ** table itself. So mark it read-only.
115161 */
115162 if( db->init.busy ){
115163 if( pSelect ){
115164 sqlite3ErrorMsg(pParse, "");
115165 return;
115166 }
115167 p->tnum = db->init.newTnum;
115168 if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
@@ -115385,11 +116061,11 @@
115385 /* A slot for the record has already been allocated in the
115386 ** schema table. We just need to update that slot with all
115387 ** the information we've collected.
115388 */
115389 sqlite3NestedParse(pParse,
115390 "UPDATE %Q." DFLT_SCHEMA_TABLE
115391 " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
115392 " WHERE rowid=#%d",
115393 db->aDb[iDb].zDbSName,
115394 zType,
115395 p->zName,
@@ -115571,17 +116247,16 @@
115571 #endif
115572
115573 assert( pTable );
115574
115575 #ifndef SQLITE_OMIT_VIRTUALTABLE
115576 db->nSchemaLock++;
115577 rc = sqlite3VtabCallConnect(pParse, pTable);
115578 db->nSchemaLock--;
115579 if( rc ){
115580 return 1;
115581 }
115582 if( IsVirtual(pTable) ) return 0;
115583 #endif
115584
115585 #ifndef SQLITE_OMIT_VIEW
115586 /* A positive nCol means the columns names for this view are
115587 ** already known.
@@ -115765,11 +116440,11 @@
115765 ** The "#NNN" in the SQL is a special constant that means whatever value
115766 ** is in register NNN. See grammar rules associated with the TK_REGISTER
115767 ** token for additional information.
115768 */
115769 sqlite3NestedParse(pParse,
115770 "UPDATE %Q." DFLT_SCHEMA_TABLE
115771 " SET rootpage=%d WHERE #%d AND rootpage=#%d",
115772 pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
115773 #endif
115774 sqlite3ReleaseTempReg(pParse, r1);
115775 }
@@ -115900,11 +116575,11 @@
115900 ** dropped. Triggers are handled separately because a trigger can be
115901 ** created in the temp database that refers to a table in another
115902 ** database.
115903 */
115904 sqlite3NestedParse(pParse,
115905 "DELETE FROM %Q." DFLT_SCHEMA_TABLE
115906 " WHERE tbl_name=%Q and type!='trigger'",
115907 pDb->zDbSName, pTab->zName);
115908 if( !isView && !IsVirtual(pTab) ){
115909 destroyTable(pParse, pTab);
115910 }
@@ -115947,10 +116622,13 @@
115947 if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
115948 return 1;
115949 }
115950 if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
115951 return 1;
 
 
 
115952 }
115953 return 0;
115954 }
115955
115956 /*
@@ -116087,11 +116765,11 @@
116087 sqlite3 *db = pParse->db;
116088 #ifndef SQLITE_OMIT_FOREIGN_KEY
116089 FKey *pFKey = 0;
116090 FKey *pNextTo;
116091 Table *p = pParse->pNewTable;
116092 int nByte;
116093 int i;
116094 int nCol;
116095 char *z;
116096
116097 assert( pTo!=0 );
@@ -116123,10 +116801,11 @@
116123 pFKey = sqlite3DbMallocZero(db, nByte );
116124 if( pFKey==0 ){
116125 goto fk_end;
116126 }
116127 pFKey->pFrom = p;
 
116128 pFKey->pNextFrom = p->u.tab.pFKey;
116129 z = (char*)&pFKey->aCol[nCol];
116130 pFKey->zTo = z;
116131 if( IN_RENAME_OBJECT ){
116132 sqlite3RenameTokenMap(pParse, (void*)z, pTo);
@@ -116188,11 +116867,11 @@
116188 pNextTo->pPrevTo = pFKey;
116189 }
116190
116191 /* Link the foreign key to the table as the last step.
116192 */
116193 assert( !IsVirtual(p) );
116194 p->u.tab.pFKey = pFKey;
116195 pFKey = 0;
116196
116197 fk_end:
116198 sqlite3DbFree(db, pFKey);
@@ -116211,11 +116890,11 @@
116211 SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
116212 #ifndef SQLITE_OMIT_FOREIGN_KEY
116213 Table *pTab;
116214 FKey *pFKey;
116215 if( (pTab = pParse->pNewTable)==0 ) return;
116216 if( NEVER(IsVirtual(pTab)) ) return;
116217 if( (pFKey = pTab->u.tab.pFKey)==0 ) return;
116218 assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
116219 pFKey->isDeferred = (u8)isDeferred;
116220 #endif
116221 }
@@ -116613,10 +117292,11 @@
116613 */
116614 for(i=0; i<pList->nExpr; i++){
116615 Expr *pExpr = pList->a[i].pExpr;
116616 assert( pExpr!=0 );
116617 if( pExpr->op==TK_COLLATE ){
 
116618 nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
116619 }
116620 }
116621
116622 /*
@@ -116708,10 +117388,11 @@
116708 pIndex->aiColumn[i] = (i16)j;
116709 }
116710 zColl = 0;
116711 if( pListItem->pExpr->op==TK_COLLATE ){
116712 int nColl;
 
116713 zColl = pListItem->pExpr->u.zToken;
116714 nColl = sqlite3Strlen30(zColl) + 1;
116715 assert( nExtra>=nColl );
116716 memcpy(zExtra, zColl, nColl);
116717 zColl = zExtra;
@@ -116914,17 +117595,17 @@
116914 }
116915
116916 /* Add an entry in sqlite_schema for this index
116917 */
116918 sqlite3NestedParse(pParse,
116919 "INSERT INTO %Q." DFLT_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
116920 db->aDb[iDb].zDbSName,
116921 pIndex->zName,
116922 pTab->zName,
116923 iMem,
116924 zStmt
116925 );
116926 sqlite3DbFree(db, zStmt);
116927
116928 /* Fill the index with data and reparse the schema. Code an OP_Expire
116929 ** to invalidate all pre-compiled statements.
116930 */
@@ -117100,11 +117781,11 @@
117100 /* Generate code to remove the index and from the schema table */
117101 v = sqlite3GetVdbe(pParse);
117102 if( v ){
117103 sqlite3BeginWriteOperation(pParse, 1, iDb);
117104 sqlite3NestedParse(pParse,
117105 "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117106 db->aDb[iDb].zDbSName, pIndex->zName
117107 );
117108 sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
117109 sqlite3ChangeCookie(pParse, iDb);
117110 destroyRootPage(pParse, pIndex->tnum, iDb);
@@ -117468,11 +118149,11 @@
117468 pItem->pSelect = pSubquery;
117469 pItem->pOn = pOn;
117470 pItem->pUsing = pUsing;
117471 return p;
117472
117473 append_from_error:
117474 assert( p==0 );
117475 sqlite3ExprDelete(db, pOn);
117476 sqlite3IdListDelete(db, pUsing);
117477 sqlite3SelectDelete(db, pSubquery);
117478 return 0;
@@ -117496,10 +118177,11 @@
117496 ** construct "indexed_opt" for details. */
117497 pItem->fg.notIndexed = 1;
117498 }else{
117499 pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
117500 pItem->fg.isIndexedBy = 1;
 
117501 }
117502 }
117503 }
117504
117505 /*
@@ -118476,10 +119158,11 @@
118476 int h, /* Hash of the name */
118477 const char *zFunc /* Name of function */
118478 ){
118479 FuncDef *p;
118480 for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
 
118481 if( sqlite3StrICmp(p->zName, zFunc)==0 ){
118482 return p;
118483 }
118484 }
118485 return 0;
@@ -118497,10 +119180,11 @@
118497 FuncDef *pOther;
118498 const char *zName = aDef[i].zName;
118499 int nName = sqlite3Strlen30(zName);
118500 int h = SQLITE_FUNC_HASH(zName[0], nName);
118501 assert( zName[0]>='a' && zName[0]<='z' );
 
118502 pOther = sqlite3FunctionSearch(h, zName);
118503 if( pOther ){
118504 assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
118505 aDef[i].pNext = pOther->pNext;
118506 pOther->pNext = &aDef[i];
@@ -118721,10 +119405,20 @@
118721 pTab = 0;
118722 }
118723 }
118724 return pTab;
118725 }
 
 
 
 
 
 
 
 
 
 
118726
118727 /* Return true if table pTab is read-only.
118728 **
118729 ** A table is read-only if any of the following are true:
118730 **
@@ -118888,10 +119582,11 @@
118888 ** and the SELECT subtree. */
118889 pSrc->a[0].pTab = 0;
118890 pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
118891 pSrc->a[0].pTab = pTab;
118892 if( pSrc->a[0].fg.isIndexedBy ){
 
118893 pSrc->a[0].u2.pIBIndex = 0;
118894 pSrc->a[0].fg.isIndexedBy = 0;
118895 sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
118896 }else if( pSrc->a[0].fg.isCte ){
118897 pSrc->a[0].u2.pCteUse->nUse++;
@@ -119296,13 +119991,11 @@
119296 /* Return the number of rows that were deleted. If this routine is
119297 ** generating code because of a call to sqlite3NestedParse(), do not
119298 ** invoke the callback function.
119299 */
119300 if( memCnt ){
119301 sqlite3VdbeAddOp2(v, OP_ChngCntRow, memCnt, 1);
119302 sqlite3VdbeSetNumCols(v, 1);
119303 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC);
119304 }
119305
119306 delete_from_cleanup:
119307 sqlite3AuthContextPop(&sContext);
119308 sqlite3SrcListDelete(db, pTabList);
@@ -121472,11 +122165,15 @@
121472 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
121473 pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
121474 /* pGCC is always non-NULL since groupConcatStep() will have always
121475 ** run frist to initialize it */
121476 if( ALWAYS(pGCC) ){
121477 int nVS = sqlite3_value_bytes(argv[0]);
 
 
 
 
121478 pGCC->nAccum -= 1;
121479 if( pGCC->pnSepLengths!=0 ){
121480 assert(pGCC->nAccum >= 0);
121481 if( pGCC->nAccum>0 ){
121482 nVS += *pGCC->pnSepLengths;
@@ -121587,15 +122284,16 @@
121587 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
121588 FuncDef *pDef;
121589 int nExpr;
121590 assert( pExpr!=0 );
121591 assert( pExpr->op==TK_FUNCTION );
 
121592 if( !pExpr->x.pList ){
121593 return 0;
121594 }
121595 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
121596 nExpr = pExpr->x.pList->nExpr;
 
121597 pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
121598 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
121599 if( pDef==0 ) return 0;
121600 #endif
121601 if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
@@ -121615,10 +122313,11 @@
121615 aWc[3] = 0;
121616 }else{
121617 Expr *pEscape = pExpr->x.pList->a[2].pExpr;
121618 char *zEscape;
121619 if( pEscape->op!=TK_STRING ) return 0;
 
121620 zEscape = pEscape->u.zToken;
121621 if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
121622 if( zEscape[0]==aWc[0] ) return 0;
121623 if( zEscape[0]==aWc[1] ) return 0;
121624 aWc[3] = zEscape[0];
@@ -121996,10 +122695,11 @@
121996 for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
121997 printf("FUNC-HASH %02d:", i);
121998 for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
121999 int n = sqlite3Strlen30(p->zName);
122000 int h = p->zName[0] + n;
 
122001 printf(" %s(%d)", p->zName, h);
122002 }
122003 printf("\n");
122004 }
122005 }
@@ -122518,10 +123218,11 @@
122518 int iCursor, /* The open cursor on the table */
122519 i16 iCol /* The column that is wanted */
122520 ){
122521 Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
122522 if( pExpr ){
 
122523 pExpr->y.pTab = pTab;
122524 pExpr->iTable = iCursor;
122525 pExpr->iColumn = iCol;
122526 }
122527 return pExpr;
@@ -122728,17 +123429,16 @@
122728 ** the table from the database. Triggers are disabled while running this
122729 ** DELETE, but foreign key actions are not.
122730 */
122731 SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
122732 sqlite3 *db = pParse->db;
122733 if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){
122734 int iSkip = 0;
122735 Vdbe *v = sqlite3GetVdbe(pParse);
122736
122737 assert( v ); /* VDBE has already been allocated */
122738 assert( !IsView(pTab) ); /* Not a view */
122739 assert( !IsVirtual(pTab) );
122740 if( sqlite3FkReferences(pTab)==0 ){
122741 /* Search for a deferred foreign key constraint for which this table
122742 ** is the child table. If one cannot be found, return without
122743 ** generating any VDBE code. If one can be found, then jump over
122744 ** the entire DELETE if there are no outstanding deferred constraints
@@ -122898,17 +123598,17 @@
122898 /* Exactly one of regOld and regNew should be non-zero. */
122899 assert( (regOld==0)!=(regNew==0) );
122900
122901 /* If foreign-keys are disabled, this function is a no-op. */
122902 if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
 
122903
122904 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
122905 zDb = db->aDb[iDb].zDbSName;
122906
122907 /* Loop through all the foreign key constraints for which pTab is the
122908 ** child table (the table that the foreign key definition is part of). */
122909 assert( !IsVirtual(pTab) );
122910 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
122911 Table *pTo; /* Parent table of foreign key pFKey */
122912 Index *pIdx = 0; /* Index on key columns in pTo */
122913 int *aiFree = 0;
122914 int *aiCol;
@@ -123087,14 +123787,13 @@
123087 SQLITE_PRIVATE u32 sqlite3FkOldmask(
123088 Parse *pParse, /* Parse context */
123089 Table *pTab /* Table being modified */
123090 ){
123091 u32 mask = 0;
123092 if( pParse->db->flags&SQLITE_ForeignKeys ){
123093 FKey *p;
123094 int i;
123095 assert( !IsVirtual(pTab) );
123096 for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){
123097 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
123098 }
123099 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
123100 Index *pIdx = 0;
@@ -123141,11 +123840,11 @@
123141 int *aChange, /* Non-NULL for UPDATE operations */
123142 int chngRowid /* True for UPDATE that affects rowid */
123143 ){
123144 int eRet = 1; /* Value to return if bHaveFK is true */
123145 int bHaveFK = 0; /* If FK processing is required */
123146 if( pParse->db->flags&SQLITE_ForeignKeys && !IsVirtual(pTab) ){
123147 if( !aChange ){
123148 /* A DELETE operation. Foreign key processing is required if the
123149 ** table in question is either the child or parent table for any
123150 ** foreign key constraint. */
123151 bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey);
@@ -123429,11 +124128,11 @@
123429 */
123430 SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
123431 FKey *pFKey; /* Iterator variable */
123432 FKey *pNext; /* Copy of pFKey->pNextFrom */
123433
123434 assert( !IsVirtual(pTab) );
123435 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){
123436 assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
123437
123438 /* Remove the FK from the fkeyHash hash table. */
123439 if( !db || db->pnBytesFreed==0 ){
@@ -123750,28 +124449,34 @@
123750
123751 /* Before computing generated columns, first go through and make sure
123752 ** that appropriate affinity has been applied to the regular columns
123753 */
123754 sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
123755 if( (pTab->tabFlags & TF_HasStored)!=0
123756 && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity
123757 ){
123758 /* Change the OP_Affinity argument to '@' (NONE) for all stored
123759 ** columns. '@' is the no-op affinity and those columns have not
123760 ** yet been computed. */
123761 int ii, jj;
123762 char *zP4 = pOp->p4.z;
123763 assert( zP4!=0 );
123764 assert( pOp->p4type==P4_DYNAMIC );
123765 for(ii=jj=0; zP4[jj]; ii++){
123766 if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
123767 continue;
123768 }
123769 if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
123770 zP4[jj] = SQLITE_AFF_NONE;
123771 }
123772 jj++;
 
 
 
 
 
 
123773 }
123774 }
123775
123776 /* Because there can be multiple generated columns that refer to one another,
123777 ** this is a two-pass algorithm. On the first pass, mark all generated
@@ -124844,13 +125549,11 @@
124844 ** Return the number of rows inserted. If this routine is
124845 ** generating code because of a call to sqlite3NestedParse(), do not
124846 ** invoke the callback function.
124847 */
124848 if( regRowCount ){
124849 sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
124850 sqlite3VdbeSetNumCols(v, 1);
124851 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC);
124852 }
124853
124854 insert_cleanup:
124855 sqlite3SrcListDelete(db, pTabList);
124856 sqlite3ExprListDelete(db, pList);
@@ -125688,10 +126391,11 @@
125688 ** (5) No FK constraint counters need to be updated if a conflict occurs.
125689 **
125690 ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
125691 ** must be explicitly deleted in order to ensure any pre-update hook
125692 ** is invoked. */
 
125693 #ifndef SQLITE_ENABLE_PREUPDATE_HOOK
125694 if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
125695 && pPk==pIdx /* Condition 2 */
125696 && onError==OE_Replace /* Condition 1 */
125697 && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
@@ -125794,11 +126498,12 @@
125794 default: {
125795 int nConflictCk; /* Number of opcodes in conflict check logic */
125796
125797 assert( onError==OE_Replace );
125798 nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
125799 assert( nConflictCk>0 );
 
125800 testcase( nConflictCk>1 );
125801 if( regTrigCnt ){
125802 sqlite3MultiWrite(pParse);
125803 nReplaceTrig++;
125804 }
@@ -126080,12 +126785,13 @@
126080
126081 assert( op==OP_OpenRead || op==OP_OpenWrite );
126082 assert( op==OP_OpenWrite || p5==0 );
126083 if( IsVirtual(pTab) ){
126084 /* This routine is a no-op for virtual tables. Leave the output
126085 ** variables *piDataCur and *piIdxCur uninitialized so that valgrind
126086 ** can detect if they are used by mistake in the caller. */
 
126087 return 0;
126088 }
126089 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
126090 v = pParse->pVdbe;
126091 assert( v!=0 );
@@ -126368,11 +127074,13 @@
126368 /* Default values for second and subsequent columns need to match. */
126369 if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){
126370 Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol);
126371 Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol);
126372 assert( pDestExpr==0 || pDestExpr->op==TK_SPAN );
 
126373 assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN );
 
126374 if( (pDestExpr==0)!=(pSrcExpr==0)
126375 || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken,
126376 pSrcExpr->u.zToken)!=0)
126377 ){
126378 return 0; /* Default values must be the same for all columns */
@@ -126408,10 +127116,11 @@
126408 ** But the main beneficiary of the transfer optimization is the VACUUM
126409 ** command, and the VACUUM command disables foreign key constraints. So
126410 ** the extra complication to make this rule less restrictive is probably
126411 ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
126412 */
 
126413 if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){
126414 return 0;
126415 }
126416 #endif
126417 if( (db->flags & SQLITE_CountRows)!=0 ){
@@ -127089,10 +127798,14 @@
127089 /* Version 3.34.0 and later */
127090 int (*txn_state)(sqlite3*,const char*);
127091 /* Version 3.36.1 and later */
127092 sqlite3_int64 (*changes64)(sqlite3*);
127093 sqlite3_int64 (*total_changes64)(sqlite3*);
 
 
 
 
127094 };
127095
127096 /*
127097 ** This is the function signature used for all extension entry points. It
127098 ** is also defined in the file "loadext.c".
@@ -127395,10 +128108,15 @@
127395 #define sqlite3_create_filename sqlite3_api->create_filename
127396 #define sqlite3_free_filename sqlite3_api->free_filename
127397 #define sqlite3_database_file_object sqlite3_api->database_file_object
127398 /* Version 3.34.0 and later */
127399 #define sqlite3_txn_state sqlite3_api->txn_state
 
 
 
 
 
127400 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
127401
127402 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
127403 /* This case when the file really is being compiled as a loadable
127404 ** extension */
@@ -127882,10 +128600,12 @@
127882 /* Version 3.34.0 and later */
127883 sqlite3_txn_state,
127884 /* Version 3.36.1 and later */
127885 sqlite3_changes64,
127886 sqlite3_total_changes64,
 
 
127887 };
127888
127889 /* True if x is the directory separator character
127890 */
127891 #if SQLITE_OS_WIN
@@ -128871,11 +129591,11 @@
128871 /* iArg: */ 0 },
128872 {/* zName: */ "table_list",
128873 /* ePragTyp: */ PragTyp_TABLE_LIST,
128874 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1,
128875 /* ColNames: */ 15, 6,
128876 /* iArg: */ 1 },
128877 {/* zName: */ "table_xinfo",
128878 /* ePragTyp: */ PragTyp_TABLE_INFO,
128879 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
128880 /* ColNames: */ 8, 7,
128881 /* iArg: */ 1 },
@@ -129400,11 +130120,15 @@
129400 goto pragma_out;
129401 }
129402
129403 /* Locate the pragma in the lookup table */
129404 pPragma = pragmaLocate(zLeft);
129405 if( pPragma==0 ) goto pragma_out;
 
 
 
 
129406
129407 /* Make sure the database schema is loaded if the pragma requires that */
129408 if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
129409 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
129410 }
@@ -130050,10 +130774,18 @@
130050 if( sqlite3GetBoolean(zRight, 0) ){
130051 db->flags |= mask;
130052 }else{
130053 db->flags &= ~mask;
130054 if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
 
 
 
 
 
 
 
 
130055 }
130056
130057 /* Many of the flag-pragmas modify the code generated by the SQL
130058 ** compiler (eg. count_changes). So add an opcode to expire all
130059 ** compiled SQL statements after modifying a pragma value.
@@ -130090,10 +130822,11 @@
130090 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
130091 pParse->nMem = 7;
130092 sqlite3ViewGetColumnNames(pParse, pTab);
130093 for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
130094 int isHidden = 0;
 
130095 if( pCol->colFlags & COLFLAG_NOINSERT ){
130096 if( pPragma->iArg==0 ){
130097 nHidden++;
130098 continue;
130099 }
@@ -130110,20 +130843,20 @@
130110 }else if( pPk==0 ){
130111 k = 1;
130112 }else{
130113 for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
130114 }
130115 assert( sqlite3ColumnExpr(pTab,pCol)==0
130116 || sqlite3ColumnExpr(pTab,pCol)->op==TK_SPAN
130117 || isHidden>=2 );
 
130118 sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
130119 i-nHidden,
130120 pCol->zCnName,
130121 sqlite3ColumnType(pCol,""),
130122 pCol->notNull ? 1 : 0,
130123 isHidden>=2 || sqlite3ColumnExpr(pTab,pCol)==0 ? 0 :
130124 sqlite3ColumnExpr(pTab,pCol)->u.zToken,
130125 k,
130126 isHidden);
130127 }
130128 }
130129 }
@@ -130147,12 +130880,39 @@
130147 pParse->nMem = 6;
130148 sqlite3CodeVerifyNamedSchema(pParse, zDb);
130149 for(ii=0; ii<db->nDb; ii++){
130150 HashElem *k;
130151 Hash *pHash;
 
130152 if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue;
 
 
 
 
 
 
130153 pHash = &db->aDb[ii].pSchema->tblHash;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130154 for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){
130155 Table *pTab = sqliteHashData(k);
130156 const char *zType;
130157 if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue;
130158 if( IsView(pTab) ){
@@ -130164,11 +130924,11 @@
130164 }else{
130165 zType = "table";
130166 }
130167 sqlite3VdbeMultiLoad(v, 1, "sssiii",
130168 db->aDb[ii].zDbSName,
130169 pTab->zName,
130170 zType,
130171 pTab->nCol,
130172 (pTab->tabFlags & TF_WithoutRowid)!=0,
130173 (pTab->tabFlags & TF_Strict)!=0
130174 );
@@ -130184,11 +130944,11 @@
130184 pParse->nMem = 5;
130185 sqlite3CodeVerifySchema(pParse, iDb);
130186 for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
130187 Table *pTab = sqliteHashData(i);
130188 sqlite3VdbeMultiLoad(v, 1, "ssiii",
130189 pTab->zName,
130190 0,
130191 pTab->szTabRow,
130192 pTab->nRowLogEst,
130193 pTab->tabFlags);
130194 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -130303,15 +131063,17 @@
130303 FuncDef *p;
130304 int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0;
130305 pParse->nMem = 6;
130306 for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
130307 for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
 
130308 pragmaFunclistLine(v, p, 1, showInternFunc);
130309 }
130310 }
130311 for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
130312 p = (FuncDef*)sqliteHashData(j);
 
130313 pragmaFunclistLine(v, p, 0, showInternFunc);
130314 }
130315 }
130316 break;
130317
@@ -130341,11 +131103,11 @@
130341 #ifndef SQLITE_OMIT_FOREIGN_KEY
130342 case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
130343 FKey *pFK;
130344 Table *pTab;
130345 pTab = sqlite3FindTable(db, zRight, zDb);
130346 if( pTab && !IsVirtual(pTab) ){
130347 pFK = pTab->u.tab.pFKey;
130348 if( pFK ){
130349 int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
130350 int i = 0;
130351 pParse->nMem = 8;
@@ -130401,19 +131163,19 @@
130401 k = 0;
130402 }else{
130403 pTab = (Table*)sqliteHashData(k);
130404 k = sqliteHashNext(k);
130405 }
130406 if( pTab==0 || IsVirtual(pTab) || pTab->u.tab.pFKey==0 ) continue;
130407 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
130408 zDb = db->aDb[iDb].zDbSName;
130409 sqlite3CodeVerifySchema(pParse, iDb);
130410 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
130411 if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
130412 sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
130413 sqlite3VdbeLoadString(v, regResult, pTab->zName);
130414 assert( !IsVirtual(pTab) );
130415 for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
130416 pParent = sqlite3FindTable(db, pFK->zTo, zDb);
130417 if( pParent==0 ) continue;
130418 pIdx = 0;
130419 sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
@@ -130432,11 +131194,11 @@
130432 }
130433 assert( pParse->nErr>0 || pFK==0 );
130434 if( pFK ) break;
130435 if( pParse->nTab<i ) pParse->nTab = i;
130436 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
130437 assert( !IsVirtual(pTab) );
130438 for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
130439 pParent = sqlite3FindTable(db, pFK->zTo, zDb);
130440 pIdx = 0;
130441 aiCols = 0;
130442 if( pParent ){
@@ -130636,11 +131398,11 @@
130636 int loopTop;
130637 int iDataCur, iIdxCur;
130638 int r1 = -1;
130639 int bStrict;
130640
130641 if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */
130642 if( pObjTab && pObjTab!=pTab ) continue;
130643 pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
130644 sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
130645 1, 0, &iDataCur, &iIdxCur);
130646 /* reg[7] counts the number of entries in the table.
@@ -130677,11 +131439,11 @@
130677 if( pCol->notNull ){
130678 jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
130679 zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
130680 pCol->zCnName);
130681 sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
130682 if( bStrict ){
130683 sqlite3VdbeGoto(v, doError);
130684 }else{
130685 integrityCheckResultRow(v);
130686 }
130687 sqlite3VdbeJumpHere(v, jmp2);
@@ -131231,16 +131993,16 @@
131231 ** in each index that it looks at. Return the new limit.
131232 */
131233 case PragTyp_ANALYSIS_LIMIT: {
131234 sqlite3_int64 N;
131235 if( zRight
131236 && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK
131237 && N>=0
131238 ){
131239 db->nAnalysisLimit = (int)(N&0x7fffffff);
131240 }
131241 returnSingleInt(v, db->nAnalysisLimit);
131242 break;
131243 }
131244
131245 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
131246 /*
@@ -131638,14 +132400,19 @@
131638 sqlite3 *db = pData->db;
131639 if( db->mallocFailed ){
131640 pData->rc = SQLITE_NOMEM_BKPT;
131641 }else if( pData->pzErrMsg[0]!=0 ){
131642 /* A error message has already been generated. Do not overwrite it */
131643 }else if( pData->mInitFlags & (INITFLAG_AlterRename|INITFLAG_AlterDrop) ){
 
 
 
 
 
131644 *pData->pzErrMsg = sqlite3MPrintf(db,
131645 "error in %s %s after %s: %s", azObj[0], azObj[1],
131646 (pData->mInitFlags & INITFLAG_AlterRename) ? "rename" : "drop column",
131647 zExtra
131648 );
131649 pData->rc = SQLITE_ERROR;
131650 }else if( db->flags & SQLITE_WriteSchema ){
131651 pData->rc = SQLITE_CORRUPT_BKPT;
@@ -132412,10 +133179,11 @@
132412 /* Make multiple attempts to compile the SQL, until it either succeeds
132413 ** or encounters a permanent error. A schema problem after one schema
132414 ** reset is considered a permanent error. */
132415 rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
132416 assert( rc==SQLITE_OK || *ppStmt==0 );
 
132417 }while( rc==SQLITE_ERROR_RETRY
132418 || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
132419 sqlite3BtreeLeaveAll(db);
132420 rc = sqlite3ApiExit(db, rc);
132421 assert( (rc&db->errMask)==rc );
@@ -133023,14 +133791,17 @@
133023 while( p ){
133024 ExprSetProperty(p, EP_FromJoin);
133025 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
133026 ExprSetVVAProperty(p, EP_NoReduce);
133027 p->iRightJoinTable = iTable;
133028 if( p->op==TK_FUNCTION && p->x.pList ){
133029 int i;
133030 for(i=0; i<p->x.pList->nExpr; i++){
133031 sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
 
 
 
133032 }
133033 }
133034 sqlite3SetJoinExpr(p->pLeft, iTable);
133035 p = p->pRight;
133036 }
@@ -133049,14 +133820,17 @@
133049 ExprClearProperty(p, EP_FromJoin);
133050 }
133051 if( p->op==TK_COLUMN && p->iTable==iTable ){
133052 ExprClearProperty(p, EP_CanBeNull);
133053 }
133054 if( p->op==TK_FUNCTION && p->x.pList ){
133055 int i;
133056 for(i=0; i<p->x.pList->nExpr; i++){
133057 unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
 
 
 
133058 }
133059 }
133060 unsetJoinExpr(p->pLeft, iTable);
133061 p = p->pRight;
133062 }
@@ -133567,13 +134341,17 @@
133567 ExprList *pExtra = 0;
133568 for(i=0; i<pEList->nExpr; i++){
133569 struct ExprList_item *pItem = &pEList->a[i];
133570 if( pItem->u.x.iOrderByCol==0 ){
133571 Expr *pExpr = pItem->pExpr;
133572 Table *pTab = pExpr->y.pTab;
133573 if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
133574 && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
 
 
 
 
133575 ){
133576 int j;
133577 for(j=0; j<nDefer; j++){
133578 if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
133579 }
@@ -133590,10 +134368,11 @@
133590 }
133591 for(k=0; k<nKey; k++){
133592 Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
133593 if( pNew ){
133594 pNew->iTable = pExpr->iTable;
 
133595 pNew->y.pTab = pExpr->y.pTab;
133596 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
133597 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
133598 }
133599 }
@@ -134438,11 +135217,11 @@
134438 ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
134439 ** branch below. */
134440 break;
134441 }
134442
134443 assert( pTab && pExpr->y.pTab==pTab );
134444 if( pS ){
134445 /* The "table" is actually a sub-select or a view in the FROM clause
134446 ** of the SELECT statement. Return the declaration type and origin
134447 ** data for the result-set column of the sub-select.
134448 */
@@ -134498,13 +135277,15 @@
134498 /* The expression is a sub-select. Return the declaration type and
134499 ** origin info for the single column in the result set of the SELECT
134500 ** statement.
134501 */
134502 NameContext sNC;
134503 Select *pS = pExpr->x.pSelect;
134504 Expr *p = pS->pEList->a[0].pExpr;
134505 assert( ExprHasProperty(pExpr, EP_xIsSelect) );
 
 
134506 sNC.pSrcList = pS->pSrc;
134507 sNC.pNext = pNC;
134508 sNC.pParse = pNC->pParse;
134509 zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
134510 break;
@@ -134629,11 +135410,12 @@
134629 for(i=0; i<pEList->nExpr; i++){
134630 Expr *p = pEList->a[i].pExpr;
134631
134632 assert( p!=0 );
134633 assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
134634 assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */
 
134635 if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
134636 /* An AS clause always takes first priority */
134637 char *zName = pEList->a[i].zEName;
134638 sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
134639 }else if( srcName && p->op==TK_COLUMN ){
@@ -134725,11 +135507,14 @@
134725 Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
134726 while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
134727 pColExpr = pColExpr->pRight;
134728 assert( pColExpr!=0 );
134729 }
134730 if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->y.pTab)!=0 ){
 
 
 
134731 /* For columns use the column name name */
134732 int iCol = pColExpr->iColumn;
134733 if( iCol<0 ) iCol = pTab->iPKey;
134734 zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
134735 }else if( pColExpr->op==TK_ID ){
@@ -134811,11 +135596,11 @@
134811 memset(&sNC, 0, sizeof(sNC));
134812 sNC.pSrcList = pSelect->pSrc;
134813 a = pSelect->pEList->a;
134814 for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
134815 const char *zType;
134816 int n, m;
134817 pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
134818 p = a[i].pExpr;
134819 zType = columnType(&sNC, p, 0, 0, 0);
134820 /* pCol->szEst = ... // Column size est for SELECT tables never used */
134821 pCol->affinity = sqlite3ExprAffinity(p);
@@ -134824,10 +135609,13 @@
134824 n = sqlite3Strlen30(pCol->zCnName);
134825 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
134826 if( pCol->zCnName ){
134827 memcpy(&pCol->zCnName[n+1], zType, m+1);
134828 pCol->colFlags |= COLFLAG_HASTYPE;
 
 
 
134829 }
134830 }
134831 if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
134832 pColl = sqlite3ExprCollSeq(pParse, p);
134833 if( pColl ){
@@ -134994,11 +135782,11 @@
134994 ** function is responsible for ensuring that this structure is eventually
134995 ** freed.
134996 */
134997 static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
134998 ExprList *pOrderBy = p->pOrderBy;
134999 int nOrderBy = p->pOrderBy->nExpr;
135000 sqlite3 *db = pParse->db;
135001 KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
135002 if( pRet ){
135003 int i;
135004 for(i=0; i<nOrderBy; i++){
@@ -135615,10 +136403,11 @@
135615 Select *pLoop; /* For looping through SELECT statements */
135616 CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
135617 int nCol; /* Number of columns in result set */
135618
135619 assert( p->pNext==0 );
 
135620 nCol = p->pEList->nExpr;
135621 pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
135622 if( !pKeyInfo ){
135623 rc = SQLITE_NOMEM_BKPT;
135624 goto multi_select_end;
@@ -135966,10 +136755,11 @@
135966 */
135967 if( op!=TK_ALL ){
135968 for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
135969 struct ExprList_item *pItem;
135970 for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
 
135971 assert( pItem->u.x.iOrderByCol>0 );
135972 if( pItem->u.x.iOrderByCol==i ) break;
135973 }
135974 if( j==nOrderBy ){
135975 Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
@@ -135992,10 +136782,11 @@
135992 aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1));
135993 if( aPermute ){
135994 struct ExprList_item *pItem;
135995 aPermute[0] = nOrderBy;
135996 for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
 
135997 assert( pItem->u.x.iOrderByCol>0 );
135998 assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
135999 aPermute[i] = pItem->u.x.iOrderByCol - 1;
136000 }
136001 pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -136304,11 +137095,11 @@
136304 if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
136305 pExpr->iTable = pSubst->iNewTable;
136306 }
136307 pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
136308 pExpr->pRight = substExpr(pSubst, pExpr->pRight);
136309 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
136310 substSelect(pSubst, pExpr->x.pSelect, 1);
136311 }else{
136312 substExprList(pSubst, pExpr->x.pList);
136313 }
136314 #ifndef SQLITE_OMIT_WINDOWFUNC
@@ -136791,11 +137582,11 @@
136791 /* Restriction (23) */
136792 if( (p->selFlags & SF_Recursive) ) return 0;
136793
136794 if( pSrc->nSrc>1 ){
136795 if( pParse->nSelect>500 ) return 0;
136796 aCsrMap = sqlite3DbMallocZero(db, (pParse->nTab+1)*sizeof(int));
136797 if( aCsrMap ) aCsrMap[0] = pParse->nTab;
136798 }
136799 }
136800
136801 /***** If we reach this point, flattening is permitted. *****/
@@ -137515,25 +138306,28 @@
137515 ** located but before their arguments have been subjected to aggregate
137516 ** analysis.
137517 */
137518 static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
137519 int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
137520 ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */
137521 const char *zFunc; /* Name of aggregate function pFunc */
137522 ExprList *pOrderBy;
137523 u8 sortFlags = 0;
137524
137525 assert( *ppMinMax==0 );
137526 assert( pFunc->op==TK_AGG_FUNCTION );
137527 assert( !IsWindowFunc(pFunc) );
 
 
137528 if( pEList==0
137529 || pEList->nExpr!=1
137530 || ExprHasProperty(pFunc, EP_WinFunc)
137531 || OptimizationDisabled(db, SQLITE_MinMaxOpt)
137532 ){
137533 return eRet;
137534 }
 
137535 zFunc = pFunc->u.zToken;
137536 if( sqlite3StrICmp(zFunc, "min")==0 ){
137537 eRet = WHERE_ORDERBY_MIN;
137538 if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
137539 sortFlags = KEYINFO_ORDER_BIGNULL;
@@ -137557,31 +138351,44 @@
137557 **
137558 ** SELECT count(*) FROM <tbl>
137559 **
137560 ** where table is a database table, not a sub-select or view. If the query
137561 ** does match this pattern, then a pointer to the Table object representing
137562 ** <tbl> is returned. Otherwise, 0 is returned.
 
 
 
 
 
 
137563 */
137564 static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
137565 Table *pTab;
137566 Expr *pExpr;
137567
137568 assert( !p->pGroupBy );
137569
137570 if( p->pWhere || p->pEList->nExpr!=1
137571 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect
 
 
 
137572 ){
137573 return 0;
137574 }
137575 pTab = p->pSrc->a[0].pTab;
 
 
 
137576 pExpr = p->pEList->a[0].pExpr;
137577 assert( pTab && !IsView(pTab) && pExpr );
137578
137579 if( IsVirtual(pTab) ) return 0;
137580 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
137581 if( NEVER(pAggInfo->nFunc==0) ) return 0;
137582 if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
 
 
 
137583 if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
137584
137585 return pTab;
137586 }
137587
@@ -137606,10 +138413,11 @@
137606 if( !pIdx ){
137607 sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
137608 pParse->checkSchema = 1;
137609 return SQLITE_ERROR;
137610 }
 
137611 pFrom->u2.pIBIndex = pIdx;
137612 return SQLITE_OK;
137613 }
137614
137615 /*
@@ -137863,10 +138671,14 @@
137863 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
137864 pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
137865 if( db->mallocFailed ) return 2;
137866 pFrom->pSelect->selFlags |= SF_CopyCte;
137867 assert( pFrom->pSelect );
 
 
 
 
137868 pFrom->fg.isCte = 1;
137869 pFrom->u2.pCteUse = pCteUse;
137870 pCteUse->nUse++;
137871 if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
137872 pCteUse->eM10d = M10d_Yes;
@@ -138498,11 +139310,11 @@
138498 #endif
138499 sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
138500 for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
138501 if( pFunc->iDistinct>=0 ){
138502 Expr *pE = pFunc->pFExpr;
138503 assert( !ExprHasProperty(pE, EP_xIsSelect) );
138504 if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
138505 sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
138506 "argument");
138507 pFunc->iDistinct = -1;
138508 }else{
@@ -138523,12 +139335,13 @@
138523 static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
138524 Vdbe *v = pParse->pVdbe;
138525 int i;
138526 struct AggInfo_func *pF;
138527 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
138528 ExprList *pList = pF->pFExpr->x.pList;
138529 assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
 
138530 sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
138531 sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
138532 }
138533 }
138534
@@ -138558,13 +139371,14 @@
138558 pAggInfo->directMode = 1;
138559 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
138560 int nArg;
138561 int addrNext = 0;
138562 int regAgg;
138563 ExprList *pList = pF->pFExpr->x.pList;
138564 assert( !ExprHasProperty(pF->pFExpr, EP_xIsSelect) );
138565 assert( !IsWindowFunc(pF->pFExpr) );
 
138566 if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
138567 Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
138568 if( pAggInfo->nAccumulator
138569 && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
138570 && regAcc
@@ -138806,11 +139620,13 @@
138806 if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
138807 if( p->pWhere ) return 0;
138808 if( p->pGroupBy ) return 0;
138809 pExpr = p->pEList->a[0].pExpr;
138810 if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
 
138811 if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
 
138812 if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
138813 if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
138814 pSub = p->pSrc->a[0].pSelect;
138815 if( pSub==0 ) return 0; /* The FROM is a subquery */
138816 if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
@@ -139621,11 +140437,11 @@
139621 }else{
139622 minMaxFlag = WHERE_ORDERBY_NORMAL;
139623 }
139624 for(i=0; i<pAggInfo->nFunc; i++){
139625 Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
139626 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
139627 sNC.ncFlags |= NC_InAggFunc;
139628 sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
139629 #ifndef SQLITE_OMIT_WINDOWFUNC
139630 assert( !IsWindowFunc(pExpr) );
139631 if( ExprHasProperty(pExpr, EP_WinFunc) ){
@@ -139676,11 +140492,13 @@
139676 u16 distFlag = 0;
139677 int eDist = WHERE_DISTINCT_NOOP;
139678
139679 if( pAggInfo->nFunc==1
139680 && pAggInfo->aFunc[0].iDistinct>=0
139681 && pAggInfo->aFunc[0].pFExpr->x.pList
 
 
139682 ){
139683 Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr;
139684 pExpr = sqlite3ExprDup(db, pExpr, 0);
139685 pDistinct = sqlite3ExprListDup(db, pGroupBy, 0);
139686 pDistinct = sqlite3ExprListAppend(pParse, pDistinct, pExpr);
@@ -139997,10 +140815,11 @@
139997 if( i==pAggInfo->nFunc ){
139998 regAcc = ++pParse->nMem;
139999 sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
140000 }
140001 }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){
 
140002 pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList;
140003 distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0;
140004 }
140005
140006 /* This case runs if the aggregate has no GROUP BY clause. The
@@ -140670,11 +141489,11 @@
140670 if( v==0 ) goto triggerfinish_cleanup;
140671 sqlite3BeginWriteOperation(pParse, 0, iDb);
140672 z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
140673 testcase( z==0 );
140674 sqlite3NestedParse(pParse,
140675 "INSERT INTO %Q." DFLT_SCHEMA_TABLE
140676 " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
140677 db->aDb[iDb].zDbSName, zName,
140678 pTrig->table, z);
140679 sqlite3DbFree(db, z);
140680 sqlite3ChangeCookie(pParse, iDb);
@@ -140984,11 +141803,11 @@
140984
140985 /* Generate code to destroy the database record of the trigger.
140986 */
140987 if( (v = sqlite3GetVdbe(pParse))!=0 ){
140988 sqlite3NestedParse(pParse,
140989 "DELETE FROM %Q." DFLT_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
140990 db->aDb[iDb].zDbSName, pTrigger->zName
140991 );
140992 sqlite3ChangeCookie(pParse, iDb);
140993 sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
140994 }
@@ -142852,13 +143671,11 @@
142852 /*
142853 ** Return the number of rows that were changed, if we are tracking
142854 ** that information.
142855 */
142856 if( regRowCount ){
142857 sqlite3VdbeAddOp2(v, OP_ChngCntRow, regRowCount, 1);
142858 sqlite3VdbeSetNumCols(v, 1);
142859 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC);
142860 }
142861
142862 update_cleanup:
142863 sqlite3AuthContextPop(&sContext);
142864 sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
@@ -143637,11 +144454,13 @@
143637 rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
143638 if( rc!=SQLITE_OK ) goto end_of_vacuum;
143639
143640 /* Do not attempt to change the page size for a WAL database */
143641 if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
143642 ==PAGER_JOURNALMODE_WAL ){
 
 
143643 db->nextPagesize = 0;
143644 }
143645
143646 if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
143647 || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
@@ -144022,11 +144841,14 @@
144022 ** Except, if argument db is not NULL, then the entry associated with
144023 ** connection db is left in the p->u.vtab.p list.
144024 */
144025 static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
144026 VTable *pRet = 0;
144027 VTable *pVTable = p->u.vtab.p;
 
 
 
144028 p->u.vtab.p = 0;
144029
144030 /* Assert that the mutex (if any) associated with the BtShared database
144031 ** that contains table p is held by the caller. See header comments
144032 ** above function sqlite3VtabUnlockList() for an explanation of why
@@ -144130,10 +144952,11 @@
144130 ** structure being xDisconnected and free). Any other VTable structures
144131 ** in the list are moved to the sqlite3.pDisconnect list of the associated
144132 ** database connection.
144133 */
144134 SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
 
144135 if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
144136 if( p->u.vtab.azArg ){
144137 int i;
144138 for(i=0; i<p->u.vtab.nArg; i++){
144139 if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]);
@@ -144147,13 +144970,16 @@
144147 ** The string is not copied - the pointer is stored. The
144148 ** string will be freed automatically when the table is
144149 ** deleted.
144150 */
144151 static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
144152 sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg);
144153 char **azModuleArg;
144154 sqlite3 *db = pParse->db;
 
 
 
144155 if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
144156 sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
144157 }
144158 azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes);
144159 if( azModuleArg==0 ){
@@ -144236,10 +145062,11 @@
144236 SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
144237 Table *pTab = pParse->pNewTable; /* The table being constructed */
144238 sqlite3 *db = pParse->db; /* The database connection */
144239
144240 if( pTab==0 ) return;
 
144241 addArgumentToVtab(pParse);
144242 pParse->sArg.z = 0;
144243 if( pTab->u.vtab.nArg<1 ) return;
144244
144245 /* If the CREATE VIRTUAL TABLE statement is being entered for the
@@ -144271,11 +145098,11 @@
144271 ** entry in the sqlite_schema table tht was created for this vtab
144272 ** by sqlite3StartTable().
144273 */
144274 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
144275 sqlite3NestedParse(pParse,
144276 "UPDATE %Q." DFLT_SCHEMA_TABLE " "
144277 "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
144278 "WHERE rowid=#%d",
144279 db->aDb[iDb].zDbSName,
144280 pTab->zName,
144281 pTab->zName,
@@ -144291,22 +145118,18 @@
144291 sqlite3DbFree(db, zStmt);
144292
144293 iReg = ++pParse->nMem;
144294 sqlite3VdbeLoadString(v, iReg, pTab->zName);
144295 sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
144296 }
144297
144298 /* If we are rereading the sqlite_schema table create the in-memory
144299 ** record of the table. The xConnect() method is not called until
144300 ** the first time the virtual table is used in an SQL statement. This
144301 ** allows a schema that contains virtual tables to be loaded before
144302 ** the required virtual table implementations are registered. */
144303 else {
144304 Table *pOld;
144305 Schema *pSchema = pTab->pSchema;
144306 const char *zName = pTab->zName;
144307 assert( sqlite3SchemaMutexHeld(db, 0, pSchema) );
 
144308 pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
144309 if( pOld ){
144310 sqlite3OomFault(db);
144311 assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
144312 return;
@@ -144353,17 +145176,20 @@
144353 char **pzErr
144354 ){
144355 VtabCtx sCtx;
144356 VTable *pVTable;
144357 int rc;
144358 const char *const*azArg = (const char *const*)pTab->u.vtab.azArg;
144359 int nArg = pTab->u.vtab.nArg;
144360 char *zErr = 0;
144361 char *zModuleName;
144362 int iDb;
144363 VtabCtx *pCtx;
144364
 
 
 
144365 /* Check that the virtual-table is not already being initialized */
144366 for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
144367 if( pCtx->pTab==pTab ){
144368 *pzErr = sqlite3MPrintf(db,
144369 "vtable constructor called recursively: %s", pTab->zName
@@ -144483,11 +145309,12 @@
144483 const char *zMod;
144484 Module *pMod;
144485 int rc;
144486
144487 assert( pTab );
144488 if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){
 
144489 return SQLITE_OK;
144490 }
144491
144492 /* Locate the required virtual table module */
144493 zMod = pTab->u.vtab.azArg[0];
@@ -144687,11 +145514,14 @@
144687 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
144688 int rc = SQLITE_OK;
144689 Table *pTab;
144690
144691 pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
144692 if( pTab!=0 && ALWAYS(pTab->u.vtab.p!=0) ){
 
 
 
144693 VTable *p;
144694 int (*xDestroy)(sqlite3_vtab *);
144695 for(p=pTab->u.vtab.p; p; p=p->pNext){
144696 assert( p->pVtab );
144697 if( p->pVtab->nRef>0 ){
@@ -144920,10 +145750,11 @@
144920 int rc = 0;
144921
144922 /* Check to see the left operand is a column in a virtual table */
144923 if( NEVER(pExpr==0) ) return pDef;
144924 if( pExpr->op!=TK_COLUMN ) return pDef;
 
144925 pTab = pExpr->y.pTab;
144926 if( pTab==0 ) return pDef;
144927 if( !IsVirtual(pTab) ) return pDef;
144928 pVtab = sqlite3GetVTable(db, pTab)->pVtab;
144929 assert( pVtab!=0 );
@@ -145214,10 +146045,11 @@
145214 int addrBignull; /* Jump here for next part of big-null scan */
145215 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
145216 u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
145217 int addrLikeRep; /* LIKE range processing address */
145218 #endif
 
145219 u8 iFrom; /* Which entry in the FROM clause */
145220 u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
145221 int p1, p2; /* Operands of the opcode used to end the loop */
145222 union { /* Information that depends on pWLoop->wsFlags */
145223 struct {
@@ -145228,11 +146060,11 @@
145228 int iBase; /* Base register of multi-key index record */
145229 int nPrefix; /* Number of prior entires in the key */
145230 u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
145231 } *aInLoop; /* Information about each nested IN operator */
145232 } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
145233 Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
145234 } u;
145235 struct WhereLoop *pWLoop; /* The selected WhereLoop object */
145236 Bitmask notReady; /* FROM entries not usable at this level */
145237 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
145238 int addrVisit; /* Address at which row is visited */
@@ -145442,15 +146274,15 @@
145442 struct WhereScan {
145443 WhereClause *pOrigWC; /* Original, innermost WhereClause */
145444 WhereClause *pWC; /* WhereClause currently being scanned */
145445 const char *zCollName; /* Required collating sequence, if not NULL */
145446 Expr *pIdxExpr; /* Search for this index expression */
145447 char idxaff; /* Must match this affinity, if zCollName!=NULL */
145448 unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
145449 unsigned char iEquiv; /* Next unused slot in aiCur[] and aiColumn[] */
145450 u32 opMask; /* Acceptable operators */
145451 int k; /* Resume scanning at this->pWC->a[this->k] */
 
 
145452 int aiCur[11]; /* Cursors in the equivalence class */
145453 i16 aiColumn[11]; /* Corresponding column number in the eq-class */
145454 };
145455
145456 /*
@@ -145470,10 +146302,11 @@
145470 WhereClause *pOuter; /* Outer conjunction */
145471 u8 op; /* Split operator. TK_AND or TK_OR */
145472 u8 hasOr; /* True if any a[].eOperator is WO_OR */
145473 int nTerm; /* Number of terms */
145474 int nSlot; /* Number of entries in a[] */
 
145475 WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
145476 #if defined(SQLITE_SMALL_STACK)
145477 WhereTerm aStatic[1]; /* Initial static space for a[] */
145478 #else
145479 WhereTerm aStatic[8]; /* Initial static space for a[] */
@@ -145527,15 +146360,10 @@
145527 int bVarSelect; /* Used by sqlite3WhereExprUsage() */
145528 int n; /* Number of assigned cursor values */
145529 int ix[BMS]; /* Cursor assigned to each bit */
145530 };
145531
145532 /*
145533 ** Initialize a WhereMaskSet object
145534 */
145535 #define initMaskSet(P) (P)->n=0
145536
145537 /*
145538 ** This object is a convenience wrapper holding all information needed
145539 ** to construct WhereLoop objects for a particular query.
145540 */
145541 struct WhereLoopBuilder {
@@ -145660,12 +146488,18 @@
145660 Parse *pParse, /* Parse context */
145661 SrcList *pTabList, /* Table list this loop refers to */
145662 WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
145663 u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
145664 );
 
 
 
 
 
145665 #else
145666 # define sqlite3WhereExplainOneScan(u,v,w,x) 0
 
145667 #endif /* SQLITE_OMIT_EXPLAIN */
145668 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
145669 SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
145670 Vdbe *v, /* Vdbe to add scanstatus entry to */
145671 SrcList *pSrclist, /* FROM clause pLvl reads data from */
@@ -145754,10 +146588,12 @@
145754 #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
145755 #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
145756 #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
145757 #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
145758 #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
 
 
145759
145760 #endif /* !defined(SQLITE_WHEREINT_H) */
145761
145762 /************** End of whereInt.h ********************************************/
145763 /************** Continuing where we left off in wherecode.c ******************/
@@ -145916,23 +146752,31 @@
145916 sqlite3_str_append(&str, " USING ", 7);
145917 sqlite3_str_appendf(&str, zFmt, pIdx->zName);
145918 explainIndexRange(&str, pLoop);
145919 }
145920 }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
145921 const char *zRangeOp;
 
 
 
 
 
 
 
 
145922 if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
145923 zRangeOp = "=";
145924 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
145925 zRangeOp = ">? AND rowid<";
 
145926 }else if( flags&WHERE_BTM_LIMIT ){
145927 zRangeOp = ">";
145928 }else{
145929 assert( flags&WHERE_TOP_LIMIT);
145930 zRangeOp = "<";
145931 }
145932 sqlite3_str_appendf(&str,
145933 " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
145934 }
145935 #ifndef SQLITE_OMIT_VIRTUALTABLE
145936 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
145937 sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
145938 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
@@ -145951,10 +146795,60 @@
145951 ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
145952 pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
145953 }
145954 return ret;
145955 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145956 #endif /* SQLITE_OMIT_EXPLAIN */
145957
145958 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
145959 /*
145960 ** Configure the VM passed as the first argument with an
@@ -146156,20 +147050,27 @@
146156 ){
146157 sqlite3 *db = pParse->db;
146158 Expr *pNew;
146159 pNew = sqlite3ExprDup(db, pX, 0);
146160 if( db->mallocFailed==0 ){
146161 ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */
146162 ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */
146163 ExprList *pRhs = 0; /* New RHS after modifications */
146164 ExprList *pLhs = 0; /* New LHS after mods */
146165 int i; /* Loop counter */
146166 Select *pSelect; /* Pointer to the SELECT on the RHS */
146167
 
 
 
 
 
146168 for(i=iEq; i<pLoop->nLTerm; i++){
146169 if( pLoop->aLTerm[i]->pExpr==pX ){
146170 int iField = pLoop->aLTerm[i]->u.x.iField - 1;
 
 
146171 if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
146172 pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
146173 pOrigRhs->a[iField].pExpr = 0;
146174 assert( pOrigLhs->a[iField].pExpr!=0 );
146175 pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
@@ -146280,11 +147181,11 @@
146280 assert( pLoop->aLTerm[i]!=0 );
146281 if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
146282 }
146283
146284 iTab = 0;
146285 if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
146286 eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
146287 }else{
146288 sqlite3 *db = pParse->db;
146289 pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
146290
@@ -146302,12 +147203,12 @@
146302 bRev = !bRev;
146303 }
146304 sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
146305 VdbeCoverageIf(v, bRev);
146306 VdbeCoverageIf(v, !bRev);
 
146307 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
146308
146309 pLoop->wsFlags |= WHERE_IN_ABLE;
146310 if( pLevel->u.in.nIn==0 ){
146311 pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
146312 }
146313 if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
@@ -146703,11 +147604,11 @@
146703 sHint.pIdx = pLoop->u.btree.pIndex;
146704 memset(&sWalker, 0, sizeof(sWalker));
146705 sWalker.pParse = pParse;
146706 sWalker.u.pCCurHint = &sHint;
146707 pWC = &pWInfo->sWC;
146708 for(i=0; i<pWC->nTerm; i++){
146709 pTerm = &pWC->a[i];
146710 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
146711 if( pTerm->prereqAll & pLevel->notReady ) continue;
146712
146713 /* Any terms specified as part of the ON(...) clause for any LEFT
@@ -146845,21 +147746,23 @@
146845 */
146846 static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
146847 assert( nReg>0 );
146848 if( p && sqlite3ExprIsVector(p) ){
146849 #ifndef SQLITE_OMIT_SUBQUERY
146850 if( (p->flags & EP_xIsSelect) ){
146851 Vdbe *v = pParse->pVdbe;
146852 int iSelect;
146853 assert( p->op==TK_SELECT );
146854 iSelect = sqlite3CodeSubselect(pParse, p);
146855 sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
146856 }else
146857 #endif
146858 {
146859 int i;
146860 ExprList *pList = p->x.pList;
 
 
146861 assert( nReg<=pList->nExpr );
146862 for(i=0; i<nReg; i++){
146863 sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
146864 }
146865 }
@@ -146908,14 +147811,14 @@
146908 preserveExpr(pX, pExpr);
146909 pExpr->affExpr = sqlite3ExprAffinity(pExpr);
146910 pExpr->op = TK_COLUMN;
146911 pExpr->iTable = pX->iIdxCur;
146912 pExpr->iColumn = pX->iIdxCol;
146913 pExpr->y.pTab = 0;
146914 testcase( ExprHasProperty(pExpr, EP_Skip) );
146915 testcase( ExprHasProperty(pExpr, EP_Unlikely) );
146916 ExprClearProperty(pExpr, EP_Skip|EP_Unlikely);
 
146917 return WRC_Prune;
146918 }else{
146919 return WRC_Continue;
146920 }
146921 }
@@ -146926,11 +147829,11 @@
146926 */
146927 static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){
146928 if( pExpr->op==TK_COLUMN ){
146929 IdxExprTrans *pX = p->u.pIdxTrans;
146930 if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){
146931 assert( pExpr->y.pTab!=0 );
146932 preserveExpr(pX, pExpr);
146933 pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn);
146934 pExpr->iTable = pX->iIdxCur;
146935 pExpr->iColumn = pX->iIdxCol;
146936 pExpr->y.pTab = 0;
@@ -146974,11 +147877,11 @@
146974 x.pWInfo = pWInfo;
146975 x.db = pWInfo->pParse->db;
146976 for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){
146977 i16 iRef = pIdx->aiColumn[iIdxCol];
146978 if( iRef==XN_EXPR ){
146979 assert( aColExpr->a[iIdxCol].pExpr!=0 );
146980 x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
146981 if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue;
146982 w.xExprCallback = whereIndexExprTransNode;
146983 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
146984 }else if( iRef>=0
@@ -147031,10 +147934,67 @@
147031 if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){
147032 pTerm->wtFlags |= TERM_CODED;
147033 }
147034 }
147035 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147036
147037 /*
147038 ** Generate code for the start of the iLevel-th loop in the WHERE clause
147039 ** implementation described by pWInfo.
147040 */
@@ -147163,11 +148123,16 @@
147163 ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
147164 if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
147165 pLevel->p1 = iCur;
147166 pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
147167 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
147168 iIn = pLevel->u.in.nIn;
 
 
 
 
 
147169 for(j=nConstraint-1; j>=0; j--){
147170 pTerm = pLoop->aLTerm[j];
147171 if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
147172 if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
147173 disableTerm(pLevel, pTerm);
@@ -147237,10 +148202,16 @@
147237 testcase( pTerm->wtFlags & TERM_VIRTUAL );
147238 iReleaseReg = ++pParse->nMem;
147239 iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
147240 if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
147241 addrNxt = pLevel->addrNxt;
 
 
 
 
 
 
147242 sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
147243 VdbeCoverage(v);
147244 pLevel->op = OP_Noop;
147245 }else if( (pLoop->wsFlags & WHERE_IPK)!=0
147246 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
@@ -147562,10 +148533,16 @@
147562 }else{
147563 if( regBignull ){
147564 sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
147565 VdbeComment((v, "NULL-scan pass ctr"));
147566 }
 
 
 
 
 
 
147567
147568 op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
147569 assert( op!=0 );
147570 if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
147571 assert( regBignull==0 );
@@ -147610,12 +148587,23 @@
147610
147611 /* Load the value for the inequality constraint at the end of the
147612 ** range (if any).
147613 */
147614 nConstraint = nEq;
 
147615 if( pRangeEnd ){
147616 Expr *pRight = pRangeEnd->pExpr->pRight;
 
 
 
 
 
 
 
 
 
 
147617 codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
147618 whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
147619 if( (pRangeEnd->wtFlags & TERM_VNULL)==0
147620 && sqlite3ExprCanBeNull(pRight)
147621 ){
@@ -147645,11 +148633,11 @@
147645 }
147646 sqlite3DbFree(db, zStartAff);
147647 sqlite3DbFree(db, zEndAff);
147648
147649 /* Top of the loop body */
147650 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
147651
147652 /* Check if the index cursor is past the end of the range. */
147653 if( nConstraint ){
147654 if( regBignull ){
147655 /* Except, skip the end-of-range check while doing the NULL-scan */
@@ -148052,11 +149040,14 @@
148052 }
148053 sqlite3ExprDelete(db, pDelete);
148054 }
148055 }
148056 ExplainQueryPlanPop(pParse);
148057 pLevel->u.pCovidx = pCov;
 
 
 
148058 if( pCov ) pLevel->iIdxCur = iCovCur;
148059 if( pAndExpr ){
148060 pAndExpr->pLeft = 0;
148061 sqlite3ExprDelete(db, pAndExpr);
148062 }
@@ -148179,11 +149170,11 @@
148179 ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
148180 ** and we are coding the t1 loop and the t2 loop has not yet coded,
148181 ** then we cannot use the "t1.a=t2.b" constraint, but we can code
148182 ** the implied "t1.a=123" constraint.
148183 */
148184 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
148185 Expr *pE, sEAlt;
148186 WhereTerm *pAlt;
148187 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
148188 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
148189 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
@@ -148196,16 +149187,17 @@
148196 sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
148197 }
148198 #endif
148199 assert( !ExprHasProperty(pE, EP_FromJoin) );
148200 assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
 
148201 pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
148202 WO_EQ|WO_IN|WO_IS, 0);
148203 if( pAlt==0 ) continue;
148204 if( pAlt->wtFlags & (TERM_CODED) ) continue;
148205 if( (pAlt->eOperator & WO_IN)
148206 && (pAlt->pExpr->flags & EP_xIsSelect)
148207 && (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
148208 ){
148209 continue;
148210 }
148211 testcase( pAlt->eOperator & WO_EQ );
@@ -148223,11 +149215,11 @@
148223 */
148224 if( pLevel->iLeftJoin ){
148225 pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
148226 sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
148227 VdbeComment((v, "record LEFT JOIN hit"));
148228 for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
148229 testcase( pTerm->wtFlags & TERM_VIRTUAL );
148230 testcase( pTerm->wtFlags & TERM_CODED );
148231 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
148232 if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
148233 assert( pWInfo->untestedTerms );
@@ -148334,10 +149326,11 @@
148334 sqlite3DbFree(db, pOld);
148335 }
148336 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
148337 }
148338 pTerm = &pWC->a[idx = pWC->nTerm++];
 
148339 if( p && ExprHasProperty(p, EP_Unlikely) ){
148340 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
148341 }else{
148342 pTerm->truthProb = 1;
148343 }
@@ -148450,10 +149443,11 @@
148450 return 0;
148451 }
148452 #ifdef SQLITE_EBCDIC
148453 if( *pnoCase ) return 0;
148454 #endif
 
148455 pList = pExpr->x.pList;
148456 pLeft = pList->a[1].pExpr;
148457
148458 pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
148459 op = pRight->op;
@@ -148465,11 +149459,12 @@
148465 z = sqlite3_value_text(pVal);
148466 }
148467 sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
148468 assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
148469 }else if( op==TK_STRING ){
148470 z = (u8*)pRight->u.zToken;
 
148471 }
148472 if( z ){
148473
148474 /* Count the number of prefix characters prior to the first wildcard */
148475 cnt = 0;
@@ -148494,11 +149489,13 @@
148494
148495 /* Get the pattern prefix. Remove all escapes from the prefix. */
148496 pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
148497 if( pPrefix ){
148498 int iFrom, iTo;
148499 char *zNew = pPrefix->u.zToken;
 
 
148500 zNew[cnt] = 0;
148501 for(iFrom=iTo=0; iFrom<cnt; iFrom++){
148502 if( zNew[iFrom]==wc[3] ) iFrom++;
148503 zNew[iTo++] = zNew[iFrom];
148504 }
@@ -148518,11 +149515,13 @@
148518 ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
148519 ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
148520 */
148521 if( pLeft->op!=TK_COLUMN
148522 || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
148523 || (pLeft->y.pTab && IsVirtual(pLeft->y.pTab)) /* Might be numeric */
 
 
148524 ){
148525 int isNum;
148526 double rDummy;
148527 isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
148528 if( isNum<=0 ){
@@ -148546,10 +149545,11 @@
148546 /* If the RHS pattern is a bound parameter, make arrangements to
148547 ** reprepare the statement when that parameter is rebound */
148548 if( op==TK_VARIABLE ){
148549 Vdbe *v = pParse->pVdbe;
148550 sqlite3VdbeSetVarmask(v, pRight->iColumn);
 
148551 if( *pisComplete && pRight->u.zToken[1] ){
148552 /* If the rhs of the LIKE expression is a variable, and the current
148553 ** value of the variable means there is no need to invoke the LIKE
148554 ** function, then no OP_Variable will be added to the program.
148555 ** This causes problems for the sqlite3_bind_parameter_name()
@@ -148619,10 +149619,11 @@
148619 };
148620 ExprList *pList;
148621 Expr *pCol; /* Column reference */
148622 int i;
148623
 
148624 pList = pExpr->x.pList;
148625 if( pList==0 || pList->nExpr!=2 ){
148626 return 0;
148627 }
148628
@@ -148632,13 +149633,15 @@
148632 **
148633 ** vtab_column MATCH expression
148634 ** MATCH(expression,vtab_column)
148635 */
148636 pCol = pList->a[1].pExpr;
 
148637 testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
148638 if( ExprIsVtab(pCol) ){
148639 for(i=0; i<ArraySize(aOp); i++){
 
148640 if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
148641 *peOp2 = aOp[i].eOp2;
148642 *ppRight = pList->a[0].pExpr;
148643 *ppLeft = pCol;
148644 return 1;
@@ -148655,20 +149658,22 @@
148655 ** Historically, xFindFunction expected to see lower-case function
148656 ** names. But for this use case, xFindFunction is expected to deal
148657 ** with function names in an arbitrary case.
148658 */
148659 pCol = pList->a[0].pExpr;
 
148660 testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
148661 if( ExprIsVtab(pCol) ){
148662 sqlite3_vtab *pVtab;
148663 sqlite3_module *pMod;
148664 void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
148665 void *pNotUsed;
148666 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
148667 assert( pVtab!=0 );
148668 assert( pVtab->pModule!=0 );
148669 pMod = (sqlite3_module *)pVtab->pModule;
 
148670 if( pMod->xFindFunction!=0 ){
148671 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
148672 if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
148673 *peOp2 = i;
148674 *ppRight = pList->a[1].pExpr;
@@ -148679,14 +149684,16 @@
148679 }
148680 }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
148681 int res = 0;
148682 Expr *pLeft = pExpr->pLeft;
148683 Expr *pRight = pExpr->pRight;
 
148684 testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
148685 if( ExprIsVtab(pLeft) ){
148686 res++;
148687 }
 
148688 testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
148689 if( pRight && ExprIsVtab(pRight) ){
148690 res++;
148691 SWAP(Expr*, pLeft, pRight);
148692 }
@@ -148935,10 +149942,11 @@
148935 int j;
148936 Bitmask b = 0;
148937 pOrTerm->u.pAndInfo = pAndInfo;
148938 pOrTerm->wtFlags |= TERM_ANDINFO;
148939 pOrTerm->eOperator = WO_AND;
 
148940 pAndWC = &pAndInfo->wc;
148941 memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
148942 sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
148943 sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
148944 sqlite3WhereExprAnalyze(pSrc, pAndWC);
@@ -148977,15 +149985,14 @@
148977 /*
148978 ** Record the set of tables that satisfy case 3. The set might be
148979 ** empty.
148980 */
148981 pOrInfo->indexable = indexable;
 
 
148982 if( indexable ){
148983 pTerm->eOperator = WO_OR;
148984 pWC->hasOr = 1;
148985 }else{
148986 pTerm->eOperator = WO_OR;
148987 }
148988
148989 /* For a two-way OR, attempt to implementation case 2.
148990 */
148991 if( indexable && pOrWc->nTerm==2 ){
@@ -149054,10 +150061,11 @@
149054 testcase( pOrTerm->wtFlags & TERM_COPIED );
149055 testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
149056 assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
149057 continue;
149058 }
 
149059 iColumn = pOrTerm->u.x.leftColumn;
149060 iCursor = pOrTerm->leftCursor;
149061 pLeft = pOrTerm->pExpr->pLeft;
149062 break;
149063 }
@@ -149074,10 +150082,11 @@
149074 /* We have found a candidate table and column. Check to see if that
149075 ** table and column is common to every term in the OR clause */
149076 okToChngToIN = 1;
149077 for(; i>=0 && okToChngToIN; i--, pOrTerm++){
149078 assert( pOrTerm->eOperator & WO_EQ );
 
149079 if( pOrTerm->leftCursor!=iCursor ){
149080 pOrTerm->wtFlags &= ~TERM_OR_OK;
149081 }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR
149082 && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
149083 )){
@@ -149110,10 +150119,11 @@
149110 Expr *pNew; /* The complete IN operator */
149111
149112 for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
149113 if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
149114 assert( pOrTerm->eOperator & WO_EQ );
 
149115 assert( pOrTerm->leftCursor==iCursor );
149116 assert( pOrTerm->u.x.leftColumn==iColumn );
149117 pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
149118 pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
149119 pLeft = pOrTerm->pExpr->pLeft;
@@ -149122,11 +150132,11 @@
149122 pDup = sqlite3ExprDup(db, pLeft, 0);
149123 pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
149124 if( pNew ){
149125 int idxNew;
149126 transferJoinMarkings(pNew, pExpr);
149127 assert( !ExprHasProperty(pNew, EP_xIsSelect) );
149128 pNew->x.pList = pList;
149129 idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
149130 testcase( idxNew==0 );
149131 exprAnalyze(pSrc, pWC, idxNew);
149132 /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */
@@ -149250,10 +150260,11 @@
149250 ** on the first element of the vector. */
149251 assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
149252 assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
149253 assert( op<=TK_GE );
149254 if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
 
149255 pExpr = pExpr->x.pList->a[0].pExpr;
149256
149257 }
149258
149259 if( pExpr->op==TK_COLUMN ){
@@ -149307,32 +150318,49 @@
149307 int nLeft; /* Number of elements on left side vector */
149308
149309 if( db->mallocFailed ){
149310 return;
149311 }
 
149312 pTerm = &pWC->a[idxTerm];
149313 pMaskSet = &pWInfo->sMaskSet;
149314 pExpr = pTerm->pExpr;
 
149315 assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
 
149316 prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
149317 op = pExpr->op;
149318 if( op==TK_IN ){
149319 assert( pExpr->pRight==0 );
149320 if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
149321 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
149322 pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
149323 }else{
149324 pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList);
149325 }
149326 }else if( op==TK_ISNULL ){
149327 pTerm->prereqRight = 0;
149328 }else{
149329 pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
 
 
 
 
 
 
 
 
149330 }
149331 pMaskSet->bVarSelect = 0;
149332 prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
149333 if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
 
 
 
 
 
 
 
 
 
149334 if( ExprHasProperty(pExpr, EP_FromJoin) ){
149335 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
149336 prereqAll |= x;
149337 extraRight = x-1; /* ON clause terms may not be used with an index
149338 ** on left table of a LEFT JOIN. Ticket #3015 */
@@ -149352,15 +150380,17 @@
149352 u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
149353
149354 if( pTerm->u.x.iField>0 ){
149355 assert( op==TK_IN );
149356 assert( pLeft->op==TK_VECTOR );
 
149357 pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
149358 }
149359
149360 if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
149361 pTerm->leftCursor = aiCurCol[0];
 
149362 pTerm->u.x.leftColumn = aiCurCol[1];
149363 pTerm->eOperator = operatorMask(op) & opMask;
149364 }
149365 if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
149366 if( pRight
@@ -149394,10 +150424,11 @@
149394 pDup = pExpr;
149395 pNew = pTerm;
149396 }
149397 pNew->wtFlags |= exprCommute(pParse, pDup);
149398 pNew->leftCursor = aiCurCol[0];
 
149399 pNew->u.x.leftColumn = aiCurCol[1];
149400 testcase( (prereqLeft | extraRight) != prereqLeft );
149401 pNew->prereqRight = prereqLeft | extraRight;
149402 pNew->prereqAll = prereqAll;
149403 pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
@@ -149404,10 +150435,11 @@
149404 }else
149405 if( op==TK_ISNULL
149406 && !ExprHasProperty(pExpr,EP_FromJoin)
149407 && 0==sqlite3ExprCanBeNull(pLeft)
149408 ){
 
149409 pExpr->op = TK_TRUEFALSE;
149410 pExpr->u.zToken = "false";
149411 ExprSetProperty(pExpr, EP_IsFalse);
149412 pTerm->prereqAll = 0;
149413 pTerm->eOperator = 0;
@@ -149429,13 +150461,15 @@
149429 ** term. That means that if the BETWEEN term is coded, the children are
149430 ** skipped. Or, if the children are satisfied by an index, the original
149431 ** BETWEEN term is skipped.
149432 */
149433 else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
149434 ExprList *pList = pExpr->x.pList;
149435 int i;
149436 static const u8 ops[] = {TK_GE, TK_LE};
 
 
149437 assert( pList!=0 );
149438 assert( pList->nExpr==2 );
149439 for(i=0; i<2; i++){
149440 Expr *pNewExpr;
149441 int idxNew;
@@ -149524,12 +150558,16 @@
149524 int idxNew1;
149525 int idxNew2;
149526 const char *zCollSeqName; /* Name of collating sequence */
149527 const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
149528
 
149529 pLeft = pExpr->x.pList->a[1].pExpr;
149530 pStr2 = sqlite3ExprDup(db, pStr1, 0);
 
 
 
149531
149532 /* Convert the lower bound to upper-case and the upper bound to
149533 ** lower-case (upper-case is less than lower-case in ASCII) so that
149534 ** the range constraints also work for BLOBs
149535 */
@@ -149625,10 +150663,11 @@
149625 ** not use window functions.
149626 */
149627 else if( pExpr->op==TK_IN
149628 && pTerm->u.x.iField==0
149629 && pExpr->pLeft->op==TK_VECTOR
 
149630 && pExpr->x.pSelect->pPrior==0
149631 #ifndef SQLITE_OMIT_WINDOWFUNC
149632 && pExpr->x.pSelect->pWin==0
149633 #endif
149634 && pWC->op==TK_AND
@@ -149741,10 +150780,11 @@
149741 ){
149742 pWC->pWInfo = pWInfo;
149743 pWC->hasOr = 0;
149744 pWC->pOuter = 0;
149745 pWC->nTerm = 0;
 
149746 pWC->nSlot = ArraySize(pWC->aStatic);
149747 pWC->a = pWC->aStatic;
149748 }
149749
149750 /*
@@ -149751,21 +150791,37 @@
149751 ** Deallocate a WhereClause structure. The WhereClause structure
149752 ** itself is not freed. This routine is the inverse of
149753 ** sqlite3WhereClauseInit().
149754 */
149755 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
149756 int i;
149757 WhereTerm *a;
149758 sqlite3 *db = pWC->pWInfo->pParse->db;
149759 for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){
149760 if( a->wtFlags & TERM_DYNAMIC ){
149761 sqlite3ExprDelete(db, a->pExpr);
149762 }
149763 if( a->wtFlags & TERM_ORINFO ){
149764 whereOrInfoDelete(db, a->u.pOrInfo);
149765 }else if( a->wtFlags & TERM_ANDINFO ){
149766 whereAndInfoDelete(db, a->u.pAndInfo);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149767 }
149768 }
149769 if( pWC->a!=pWC->aStatic ){
149770 sqlite3DbFree(db, pWC->a);
149771 }
@@ -149774,38 +150830,71 @@
149774
149775 /*
149776 ** These routines walk (recursively) an expression tree and generate
149777 ** a bitmask indicating which tables are used in that expression
149778 ** tree.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149779 */
149780 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
 
 
 
149781 Bitmask mask;
149782 if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
149783 return sqlite3WhereGetMask(pMaskSet, p->iTable);
149784 }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
149785 assert( p->op!=TK_IF_NULL_ROW );
149786 return 0;
149787 }
149788 mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
149789 if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
149790 if( p->pRight ){
149791 mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
149792 assert( p->x.pList==0 );
149793 }else if( ExprHasProperty(p, EP_xIsSelect) ){
149794 if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
149795 mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
149796 }else if( p->x.pList ){
149797 mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
149798 }
149799 #ifndef SQLITE_OMIT_WINDOWFUNC
149800 if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){
 
149801 mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
149802 mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
149803 mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter);
149804 }
149805 #endif
149806 return mask;
 
 
 
 
 
 
 
 
 
149807 }
149808 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
149809 return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
149810 }
149811 SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
@@ -149870,10 +150959,11 @@
149870 }
149871 pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
149872 if( pColRef==0 ) return;
149873 pColRef->iTable = pItem->iCursor;
149874 pColRef->iColumn = k++;
 
149875 pColRef->y.pTab = pTab;
149876 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
149877 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
149878 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
149879 if( pItem->fg.jointype & JT_LEFT ){
@@ -150119,11 +151209,16 @@
150119 ** iCursor is not in the set.
150120 */
150121 SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){
150122 int i;
150123 assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
150124 for(i=0; i<pMaskSet->n; i++){
 
 
 
 
 
150125 if( pMaskSet->ix[i]==iCursor ){
150126 return MASKBIT(i);
150127 }
150128 }
150129 return 0;
@@ -150171,12 +151266,14 @@
150171 pWC = pScan->pWC;
150172 while(1){
150173 iColumn = pScan->aiColumn[pScan->iEquiv-1];
150174 iCur = pScan->aiCur[pScan->iEquiv-1];
150175 assert( pWC!=0 );
 
150176 do{
150177 for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
 
150178 if( pTerm->leftCursor==iCur
150179 && pTerm->u.x.leftColumn==iColumn
150180 && (iColumn!=XN_EXPR
150181 || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
150182 pScan->pIdxExpr,iCur)==0)
@@ -150214,11 +151311,12 @@
150214 if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
150215 continue;
150216 }
150217 }
150218 if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
150219 && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
 
150220 && pX->iTable==pScan->aiCur[0]
150221 && pX->iColumn==pScan->aiColumn[0]
150222 ){
150223 testcase( pTerm->eOperator & WO_IS );
150224 continue;
@@ -150301,20 +151399,20 @@
150301 pScan->nEquiv = 1;
150302 pScan->iEquiv = 1;
150303 if( pIdx ){
150304 int j = iColumn;
150305 iColumn = pIdx->aiColumn[j];
150306 if( iColumn==XN_EXPR ){
 
 
 
 
 
150307 pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
150308 pScan->zCollName = pIdx->azColl[j];
150309 pScan->aiColumn[0] = XN_EXPR;
150310 return whereScanInitIndexExpr(pScan);
150311 }else if( iColumn==pIdx->pTable->iPKey ){
150312 iColumn = XN_ROWID;
150313 }else if( iColumn>=0 ){
150314 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
150315 pScan->zCollName = pIdx->azColl[j];
150316 }
150317 }else if( iColumn==XN_EXPR ){
150318 return 0;
150319 }
150320 pScan->aiColumn[0] = iColumn;
@@ -150594,13 +151692,13 @@
150594 ** Return TRUE if the WHERE clause term pTerm is of a form where it
150595 ** could be used with an index to access pSrc, assuming an appropriate
150596 ** index existed.
150597 */
150598 static int termCanDriveIndex(
150599 WhereTerm *pTerm, /* WHERE clause term to check */
150600 SrcItem *pSrc, /* Table we are trying to access */
150601 Bitmask notReady /* Tables in outer loops of the join */
150602 ){
150603 char aff;
150604 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
150605 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
150606 if( (pSrc->fg.jointype & JT_LEFT)
@@ -150611,10 +151709,11 @@
150611 ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
150612 ** the ON clause. */
150613 return 0;
150614 }
150615 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
 
150616 if( pTerm->u.x.leftColumn<0 ) return 0;
150617 aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
150618 if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
150619 testcase( pTerm->pExpr->op==TK_IS );
150620 return 1;
@@ -150626,15 +151725,15 @@
150626 /*
150627 ** Generate code to construct the Index object for an automatic index
150628 ** and to set up the WhereLevel object pLevel so that the code generator
150629 ** makes use of the automatic index.
150630 */
150631 static void constructAutomaticIndex(
150632 Parse *pParse, /* The parsing context */
150633 WhereClause *pWC, /* The WHERE clause */
150634 SrcItem *pSrc, /* The FROM clause term to get the next index */
150635 Bitmask notReady, /* Mask of cursors that are not available */
150636 WhereLevel *pLevel /* Write new index here */
150637 ){
150638 int nKeyCol; /* Number of columns in the constructed index */
150639 WhereTerm *pTerm; /* A single term of the WHERE clause */
150640 WhereTerm *pWCEnd; /* End of pWC->a[] */
@@ -150672,23 +151771,26 @@
150672 pWCEnd = &pWC->a[pWC->nTerm];
150673 pLoop = pLevel->pWLoop;
150674 idxCols = 0;
150675 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
150676 Expr *pExpr = pTerm->pExpr;
150677 assert( !ExprHasProperty(pExpr, EP_FromJoin) /* prereq always non-zero */
150678 || pExpr->iRightJoinTable!=pSrc->iCursor /* for the right-hand */
150679 || pLoop->prereq!=0 ); /* table of a LEFT JOIN */
150680 if( pLoop->prereq==0
150681 && (pTerm->wtFlags & TERM_VIRTUAL)==0
150682 && !ExprHasProperty(pExpr, EP_FromJoin)
150683 && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){
150684 pPartial = sqlite3ExprAnd(pParse, pPartial,
150685 sqlite3ExprDup(pParse->db, pExpr, 0));
150686 }
150687 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
150688 int iCol = pTerm->u.x.leftColumn;
150689 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
 
 
 
150690 testcase( iCol==BMS );
150691 testcase( iCol==BMS-1 );
150692 if( !sentWarning ){
150693 sqlite3_log(SQLITE_WARNING_AUTOINDEX,
150694 "automatic index on %s(%s)", pTable->zName,
@@ -150736,12 +151838,15 @@
150736 pIdx->pTable = pTable;
150737 n = 0;
150738 idxCols = 0;
150739 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
150740 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
150741 int iCol = pTerm->u.x.leftColumn;
150742 Bitmask cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
 
 
 
150743 testcase( iCol==BMS-1 );
150744 testcase( iCol==BMS );
150745 if( (idxCols & cMask)==0 ){
150746 Expr *pX = pTerm->pExpr;
150747 idxCols |= cMask;
@@ -150779,10 +151884,14 @@
150779 assert( pLevel->iIdxCur>=0 );
150780 pLevel->iIdxCur = pParse->nTab++;
150781 sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
150782 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
150783 VdbeComment((v, "for %s", pTable->zName));
 
 
 
 
150784
150785 /* Fill the automatic index with content */
150786 pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
150787 if( pTabItem->fg.viaCoroutine ){
150788 int regYield = pTabItem->regReturn;
@@ -150801,10 +151910,14 @@
150801 }
150802 regRecord = sqlite3GetTempReg(pParse);
150803 regBase = sqlite3GenerateIndexKey(
150804 pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
150805 );
 
 
 
 
150806 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
150807 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
150808 if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
150809 if( pTabItem->fg.viaCoroutine ){
150810 sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
@@ -150826,10 +151939,127 @@
150826
150827 end_auto_index_create:
150828 sqlite3ExprDelete(pParse->db, pPartial);
150829 }
150830 #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150831
150832 #ifndef SQLITE_OMIT_VIRTUALTABLE
150833 /*
150834 ** Allocate and populate an sqlite3_index_info structure. It is the
150835 ** responsibility of the caller to eventually release the structure
@@ -150864,10 +152094,11 @@
150864 testcase( pTerm->eOperator & WO_ISNULL );
150865 testcase( pTerm->eOperator & WO_IS );
150866 testcase( pTerm->eOperator & WO_ALL );
150867 if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
150868 if( pTerm->wtFlags & TERM_VNULL ) continue;
 
150869 assert( pTerm->u.x.leftColumn>=(-1) );
150870 nTerm++;
150871 }
150872
150873 /* If the ORDER BY clause contains only columns in the current
@@ -150924,10 +152155,11 @@
150924 if( (pSrc->fg.jointype & JT_LEFT)!=0
150925 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
150926 ){
150927 continue;
150928 }
 
150929 assert( pTerm->u.x.leftColumn>=(-1) );
150930 pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
150931 pIdxCons[j].iTermOffset = i;
150932 op = pTerm->eOperator & WO_ALL;
150933 if( op==WO_IN ) op = WO_EQ;
@@ -151687,10 +152919,11 @@
151687 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
151688 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
151689 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
151690 if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
151691 if( pTerm->eOperator & WO_SINGLE ){
 
151692 sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
151693 pTerm->leftCursor, pTerm->u.x.leftColumn);
151694 }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
151695 sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
151696 pTerm->u.pOrInfo->indexable);
@@ -151704,11 +152937,11 @@
151704 ** shown about each Term */
151705 if( sqlite3WhereTrace & 0x10000 ){
151706 sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
151707 pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
151708 }
151709 if( pTerm->u.x.iField ){
151710 sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
151711 }
151712 if( pTerm->iParent>=0 ){
151713 sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
151714 }
@@ -151766,13 +152999,13 @@
151766 }
151767 sqlite3DebugPrintf(" %-19s", z);
151768 sqlite3_free(z);
151769 }
151770 if( p->wsFlags & WHERE_SKIPSCAN ){
151771 sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
151772 }else{
151773 sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
151774 }
151775 sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
151776 if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
151777 int i;
151778 for(i=0; i<p->nLTerm; i++){
@@ -151868,11 +153101,12 @@
151868 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
151869 int i;
151870 assert( pWInfo!=0 );
151871 for(i=0; i<pWInfo->nLevel; i++){
151872 WhereLevel *pLevel = &pWInfo->a[i];
151873 if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){
 
151874 sqlite3DbFree(db, pLevel->u.in.aInLoop);
151875 }
151876 }
151877 sqlite3WhereClauseClear(&pWInfo->sWC);
151878 while( pWInfo->pLoops ){
@@ -152227,22 +153461,29 @@
152227 Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
152228 int i, j;
152229 LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
152230
152231 assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
152232 for(i=pWC->nTerm, pTerm=pWC->a; i>0; i--, pTerm++){
152233 assert( pTerm!=0 );
152234 if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) break;
152235 if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
152236 if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
152237 for(j=pLoop->nLTerm-1; j>=0; j--){
152238 pX = pLoop->aLTerm[j];
152239 if( pX==0 ) continue;
152240 if( pX==pTerm ) break;
152241 if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
152242 }
152243 if( j<0 ){
 
 
 
 
 
 
 
152244 if( pTerm->truthProb<=0 ){
152245 /* If a truth probability is specified using the likelihood() hints,
152246 ** then use the probability provided by the application. */
152247 pLoop->nOut += pTerm->truthProb;
152248 }else{
@@ -152266,11 +153507,13 @@
152266 }
152267 }
152268 }
152269 }
152270 }
152271 if( pLoop->nOut > nRow-iReduce ) pLoop->nOut = nRow - iReduce;
 
 
152272 }
152273
152274 /*
152275 ** Term pTerm is a vector range comparison operation. The first comparison
152276 ** in the vector can be optimized using column nEq of the index. This
@@ -152303,13 +153546,16 @@
152303 /* Test if comparison i of pTerm is compatible with column (i+nEq)
152304 ** of the index. If not, exit the loop. */
152305 char aff; /* Comparison affinity */
152306 char idxaff = 0; /* Indexed columns affinity */
152307 CollSeq *pColl; /* Comparison collation sequence */
152308 Expr *pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
152309 Expr *pRhs = pTerm->pExpr->pRight;
152310 if( pRhs->flags & EP_xIsSelect ){
 
 
 
152311 pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
152312 }else{
152313 pRhs = pRhs->x.pList->a[i].pExpr;
152314 }
152315
@@ -152466,11 +153712,11 @@
152466 || (pNew->wsFlags & WHERE_SKIPSCAN)!=0
152467 );
152468
152469 if( eOp & WO_IN ){
152470 Expr *pExpr = pTerm->pExpr;
152471 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
152472 /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
152473 int i;
152474 nIn = 46; assert( 46==sqlite3LogEst(25) );
152475
152476 /* The expression may actually be of the form (x, y) IN (SELECT...).
@@ -152607,11 +153853,11 @@
152607 #ifdef SQLITE_ENABLE_STAT4
152608 tRowcnt nOut = 0;
152609 if( nInMul==0
152610 && pProbe->nSample
152611 && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol)
152612 && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
152613 && OptimizationEnabled(db, SQLITE_Stat4)
152614 ){
152615 Expr *pExpr = pTerm->pExpr;
152616 if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
152617 testcase( eOp & WO_EQ );
@@ -152883,10 +154129,11 @@
152883 pTab = pSrc->pTab;
152884 pWC = pBuilder->pWC;
152885 assert( !IsVirtual(pSrc->pTab) );
152886
152887 if( pSrc->fg.isIndexedBy ){
 
152888 /* An INDEXED BY clause specifies a particular index to use */
152889 pProbe = pSrc->u2.pIBIndex;
152890 }else if( !HasRowid(pTab) ){
152891 pProbe = pTab->pIndex;
152892 }else{
@@ -153498,10 +154745,11 @@
153498 }else if( pOrTerm->leftCursor==iCur ){
153499 tempWC.pWInfo = pWC->pWInfo;
153500 tempWC.pOuter = pWC;
153501 tempWC.op = TK_AND;
153502 tempWC.nTerm = 1;
 
153503 tempWC.a = pOrTerm;
153504 sSubBuild.pWC = &tempWC;
153505 }else{
153506 continue;
153507 }
@@ -153969,11 +155217,11 @@
153969 }
153970 } /* End the loop over all WhereLoops from outer-most down to inner-most */
153971 if( obSat==obDone ) return (i8)nOrderBy;
153972 if( !isOrderDistinct ){
153973 for(i=nOrderBy-1; i>0; i--){
153974 Bitmask m = MASKBIT(i) - 1;
153975 if( (obSat&m)==m ) return i;
153976 }
153977 return 0;
153978 }
153979 return -1;
@@ -154494,13 +155742,13 @@
154494 pWC = &pWInfo->sWC;
154495 pLoop = pBuilder->pNew;
154496 pLoop->wsFlags = 0;
154497 pLoop->nSkip = 0;
154498 pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0);
 
154499 if( pTerm ){
154500 testcase( pTerm->eOperator & WO_IS );
154501 assert( pTerm->prereqRight==0 );
154502 pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
154503 pLoop->aLTerm[0] = pTerm;
154504 pLoop->nLTerm = 1;
154505 pLoop->u.btree.nEq = 1;
154506 /* TUNING: Cost of a rowid lookup is 10 */
@@ -154604,10 +155852,154 @@
154604 }
154605 # define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C)
154606 #else
154607 # define WHERETRACE_ALL_LOOPS(W,C)
154608 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154609
154610 /*
154611 ** Generate the beginning of the loop used for WHERE clause processing.
154612 ** The return value is a pointer to an opaque structure that contains
154613 ** information needed to terminate the loop. Later, the calling routine
@@ -154735,16 +156127,10 @@
154735 /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
154736 testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
154737 if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
154738 sWLB.pOrderBy = pOrderBy;
154739
154740 /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
154741 ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
154742 if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
154743 wctrlFlags &= ~WHERE_WANT_DISTINCT;
154744 }
154745
154746 /* The number of tables in the FROM clause is limited by the number of
154747 ** bits in a Bitmask
154748 */
154749 testcase( pTabList->nSrc==BMS );
154750 if( pTabList->nSrc>BMS ){
@@ -154787,10 +156173,14 @@
154787 memset(&pWInfo->nOBSat, 0,
154788 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
154789 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
154790 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
154791 pMaskSet = &pWInfo->sMaskSet;
 
 
 
 
154792 sWLB.pWInfo = pWInfo;
154793 sWLB.pWC = &pWInfo->sWC;
154794 sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
154795 assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
154796 whereLoopInit(sWLB.pNew);
@@ -154799,19 +156189,20 @@
154799 #endif
154800
154801 /* Split the WHERE clause into separate subexpressions where each
154802 ** subexpression is separated by an AND operator.
154803 */
154804 initMaskSet(pMaskSet);
154805 sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo);
154806 sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND);
154807
154808 /* Special case: No FROM clause
154809 */
154810 if( nTabList==0 ){
154811 if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr;
154812 if( wctrlFlags & WHERE_WANT_DISTINCT ){
 
 
154813 pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
154814 }
154815 ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
154816 }else{
154817 /* Assign a bit from the bitmask to every term in the FROM clause.
@@ -154858,21 +156249,26 @@
154858 ** preserves SQLite's legacy behaviour in the following two cases:
154859 **
154860 ** FROM ... WHERE random()>0; -- eval random() once per row
154861 ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall
154862 */
154863 for(ii=0; ii<sWLB.pWC->nTerm; ii++){
154864 WhereTerm *pT = &sWLB.pWC->a[ii];
154865 if( pT->wtFlags & TERM_VIRTUAL ) continue;
154866 if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
154867 sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
154868 pT->wtFlags |= TERM_CODED;
154869 }
154870 }
154871
154872 if( wctrlFlags & WHERE_WANT_DISTINCT ){
154873 if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
 
 
 
 
 
154874 /* The DISTINCT marking is pointless. Ignore it. */
154875 pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
154876 }else if( pOrderBy==0 ){
154877 /* Try to ORDER BY the result set to make distinct processing easier */
154878 pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
@@ -154969,88 +156365,40 @@
154969 sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
154970 }
154971 }
154972 #endif
154973
154974 /* Attempt to omit tables from the join that do not affect the result.
154975 ** For a table to not affect the result, the following must be true:
154976 **
154977 ** 1) The query must not be an aggregate.
154978 ** 2) The table must be the RHS of a LEFT JOIN.
154979 ** 3) Either the query must be DISTINCT, or else the ON or USING clause
154980 ** must contain a constraint that limits the scan of the table to
154981 ** at most a single row.
154982 ** 4) The table must not be referenced by any part of the query apart
154983 ** from its own USING or ON clause.
154984 **
154985 ** For example, given:
154986 **
154987 ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
154988 ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
154989 ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
154990 **
154991 ** then table t2 can be omitted from the following:
154992 **
154993 ** SELECT v1, v3 FROM t1
154994 ** LEFT JOIN t2 ON (t1.ipk=t2.ipk)
154995 ** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
154996 **
154997 ** or from:
154998 **
154999 ** SELECT DISTINCT v1, v3 FROM t1
155000 ** LEFT JOIN t2
155001 ** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
155002 */
155003 notReady = ~(Bitmask)0;
155004 if( pWInfo->nLevel>=2
155005 && pResultSet!=0 /* these two combine to guarantee */
155006 && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */
155007 && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
155008 ){
155009 int i;
155010 Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet);
155011 if( sWLB.pOrderBy ){
155012 tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy);
155013 }
155014 for(i=pWInfo->nLevel-1; i>=1; i--){
155015 WhereTerm *pTerm, *pEnd;
155016 SrcItem *pItem;
155017 pLoop = pWInfo->a[i].pWLoop;
155018 pItem = &pWInfo->pTabList->a[pLoop->iTab];
155019 if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
155020 if( (wctrlFlags & WHERE_WANT_DISTINCT)==0
155021 && (pLoop->wsFlags & WHERE_ONEROW)==0
155022 ){
155023 continue;
155024 }
155025 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
155026 pEnd = sWLB.pWC->a + sWLB.pWC->nTerm;
155027 for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
155028 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155029 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
155030 || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
155031 ){
155032 break;
155033 }
155034 }
155035 }
155036 if( pTerm<pEnd ) continue;
155037 WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
155038 notReady &= ~pLoop->maskSelf;
155039 for(pTerm=sWLB.pWC->a; pTerm<pEnd; pTerm++){
155040 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155041 pTerm->wtFlags |= TERM_CODED;
155042 }
155043 }
155044 if( i!=pWInfo->nLevel-1 ){
155045 int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
155046 memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
155047 }
155048 pWInfo->nLevel--;
155049 nTabList--;
155050 }
155051 }
155052 #if defined(WHERETRACE_ENABLED)
155053 if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
155054 sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n");
155055 sqlite3WhereClausePrint(sWLB.pWC);
155056 }
@@ -155232,19 +156580,24 @@
155232 ** program.
155233 */
155234 for(ii=0; ii<nTabList; ii++){
155235 int addrExplain;
155236 int wsFlags;
 
155237 pLevel = &pWInfo->a[ii];
155238 wsFlags = pLevel->pWLoop->wsFlags;
 
 
155239 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
155240 if( (pLevel->pWLoop->wsFlags & WHERE_AUTO_INDEX)!=0 ){
155241 constructAutomaticIndex(pParse, &pWInfo->sWC,
155242 &pTabList->a[pLevel->iFrom], notReady, pLevel);
 
 
 
155243 if( db->mallocFailed ) goto whereBeginError;
155244 }
155245 #endif
155246 addrExplain = sqlite3WhereExplainOneScan(
155247 pParse, pTabList, pLevel, wctrlFlags
155248 );
155249 pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
155250 notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
@@ -155353,11 +156706,11 @@
155353 if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
155354 #endif
155355 }else{
155356 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
155357 }
155358 if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){
155359 struct InLoop *pIn;
155360 int j;
155361 sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
155362 for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
155363 assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull
@@ -155422,14 +156775,14 @@
155422 if( (ws & WHERE_IDX_ONLY)==0 ){
155423 assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
155424 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
155425 }
155426 if( (ws & WHERE_INDEXED)
155427 || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx)
155428 ){
155429 if( ws & WHERE_MULTI_OR ){
155430 Index *pIx = pLevel->u.pCovidx;
155431 int iDb = sqlite3SchemaToIndex(db, pIx->pSchema);
155432 sqlite3VdbeAddOp3(v, OP_ReopenIdx, pLevel->iIdxCur, pIx->tnum, iDb);
155433 sqlite3VdbeSetP4KeyInfo(pParse, pIx);
155434 }
155435 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
@@ -155506,11 +156859,11 @@
155506 ** reference the index.
155507 */
155508 if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
155509 pIdx = pLoop->u.btree.pIndex;
155510 }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
155511 pIdx = pLevel->u.pCovidx;
155512 }
155513 if( pIdx
155514 && !db->mallocFailed
155515 ){
155516 if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){
@@ -156167,28 +157520,28 @@
156167 static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
156168
156169 /* Window functions that use all window interfaces: xStep, xFinal,
156170 ** xValue, and xInverse */
156171 #define WINDOWFUNCALL(name,nArg,extra) { \
156172 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
156173 name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
156174 name ## InvFunc, name ## Name, {0} \
156175 }
156176
156177 /* Window functions that are implemented using bytecode and thus have
156178 ** no-op routines for their methods */
156179 #define WINDOWFUNCNOOP(name,nArg,extra) { \
156180 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
156181 noopStepFunc, noopValueFunc, noopValueFunc, \
156182 noopStepFunc, name ## Name, {0} \
156183 }
156184
156185 /* Window functions that use all window interfaces: xStep, the
156186 ** same routine for xFinalize and xValue and which never call
156187 ** xInverse. */
156188 #define WINDOWFUNCX(name,nArg,extra) { \
156189 nArg, (SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
156190 name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
156191 noopStepFunc, name ## Name, {0} \
156192 }
156193
156194
@@ -156527,11 +157880,12 @@
156527 return WRC_Continue;
156528 }
156529
156530 static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
156531 if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
156532 sqlite3ErrorMsg(pWalker->pParse,
 
156533 "misuse of aggregate: %s()", pExpr->u.zToken);
156534 }
156535 return WRC_Continue;
156536 }
156537
@@ -156615,11 +157969,13 @@
156615 /* Append the arguments passed to each window function to the
156616 ** sub-select expression list. Also allocate two registers for each
156617 ** window function - one for the accumulator, another for interim
156618 ** results. */
156619 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
156620 ExprList *pArgs = pWin->pOwner->x.pList;
 
 
156621 if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
156622 selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
156623 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
156624 pWin->bExprArgs = 1;
156625 }else{
@@ -156682,11 +158038,15 @@
156682 }
156683 }else{
156684 sqlite3SelectDelete(db, pSub);
156685 }
156686 if( db->mallocFailed ) rc = SQLITE_NOMEM;
156687 sqlite3DbFree(db, pTab);
 
 
 
 
156688 }
156689
156690 if( rc ){
156691 if( pParse->nErr==0 ){
156692 assert( pParse->db->mallocFailed );
@@ -157008,12 +158368,15 @@
157008 **
157009 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
157010 ** regApp+1: integer value used to ensure keys are unique
157011 ** regApp+2: output of MakeRecord
157012 */
157013 ExprList *pList = pWin->pOwner->x.pList;
157014 KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
 
 
 
157015 pWin->csrApp = pParse->nTab++;
157016 pWin->regApp = pParse->nMem+1;
157017 pParse->nMem += 3;
157018 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
157019 assert( pKeyInfo->aSortFlags[0]==0 );
@@ -157097,11 +158460,13 @@
157097 /*
157098 ** Return the number of arguments passed to the window-function associated
157099 ** with the object passed as the only argument to this function.
157100 */
157101 static int windowArgCount(Window *pWin){
157102 ExprList *pList = pWin->pOwner->x.pList;
 
 
157103 return (pList ? pList->nExpr : 0);
157104 }
157105
157106 typedef struct WindowCodeArg WindowCodeArg;
157107 typedef struct WindowCsrAndReg WindowCsrAndReg;
@@ -157282,10 +158647,11 @@
157282 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
157283 }else if( pFunc->xSFunc!=noopStepFunc ){
157284 int addrIf = 0;
157285 if( pWin->pFilter ){
157286 int regTmp;
 
157287 assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
157288 assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
157289 regTmp = sqlite3GetTempReg(pParse);
157290 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
157291 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
@@ -157295,10 +158661,11 @@
157295
157296 if( pWin->bExprArgs ){
157297 int iOp = sqlite3VdbeCurrentAddr(v);
157298 int iEnd;
157299
 
157300 nArg = pWin->pOwner->x.pList->nExpr;
157301 regArg = sqlite3GetTempRange(pParse, nArg);
157302 sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
157303
157304 for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
@@ -157309,10 +158676,11 @@
157309 }
157310 }
157311 if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
157312 CollSeq *pColl;
157313 assert( nArg>0 );
 
157314 pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
157315 sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
157316 }
157317 sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
157318 bInverse, regArg, pWin->regAccum);
@@ -157494,10 +158862,11 @@
157494 Parse *pParse = p->pParse;
157495 Window *pWin;
157496
157497 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
157498 FuncDef *pFunc = pWin->pFunc;
 
157499 if( pFunc->zName==nth_valueName
157500 || pFunc->zName==first_valueName
157501 ){
157502 int csr = pWin->csrApp;
157503 int lbl = sqlite3VdbeMakeLabel(pParse);
@@ -158843,13 +160212,13 @@
158843 p->affExpr = 0;
158844 p->flags = EP_Leaf;
158845 ExprClearVVAProperties(p);
158846 p->iAgg = -1;
158847 p->pLeft = p->pRight = 0;
158848 p->x.pList = 0;
158849 p->pAggInfo = 0;
158850 p->y.pTab = 0;
 
158851 p->op2 = 0;
158852 p->iTable = 0;
158853 p->iColumn = 0;
158854 p->u.zToken = (char*)&p[1];
158855 memcpy(p->u.zToken, t.z, t.n);
@@ -158951,14 +160320,14 @@
158951 #define TK_DETACH 40
158952 #define TK_EACH 41
158953 #define TK_FAIL 42
158954 #define TK_OR 43
158955 #define TK_AND 44
158956 #define TK_IS 45
158957 #define TK_MATCH 46
158958 #define TK_LIKE_KW 47
158959 #define TK_BETWEEN 48
158960 #define TK_IN 49
158961 #define TK_ISNULL 50
158962 #define TK_NOTNULL 51
158963 #define TK_NE 52
158964 #define TK_EQ 53
@@ -159266,216 +160635,215 @@
159266 ** yy_reduce_ofst[] For each state, the offset into yy_action for
159267 ** shifting non-terminals after a reduce.
159268 ** yy_default[] Default action for each state.
159269 **
159270 *********** Begin parsing tables **********************************************/
159271 #define YY_ACTTAB_COUNT (2037)
159272 static const YYACTIONTYPE yy_action[] = {
159273 /* 0 */ 564, 115, 112, 220, 169, 199, 115, 112, 220, 564,
159274 /* 10 */ 375, 1266, 564, 376, 564, 270, 1309, 1309, 406, 407,
159275 /* 20 */ 1084, 199, 1513, 41, 41, 515, 489, 521, 558, 558,
159276 /* 30 */ 558, 965, 41, 41, 395, 41, 41, 51, 51, 966,
159277 /* 40 */ 296, 1269, 296, 122, 123, 113, 1207, 1207, 1041, 1044,
159278 /* 50 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 564, 407,
159279 /* 60 */ 275, 275, 275, 275, 1268, 115, 112, 220, 115, 112,
159280 /* 70 */ 220, 1512, 846, 561, 516, 561, 115, 112, 220, 250,
159281 /* 80 */ 217, 71, 71, 122, 123, 113, 1207, 1207, 1041, 1044,
159282 /* 90 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 440, 440,
159283 /* 100 */ 440, 1149, 119, 119, 119, 119, 118, 118, 117, 117,
159284 /* 110 */ 117, 116, 442, 1183, 1149, 116, 442, 1149, 546, 513,
159285 /* 120 */ 1548, 1554, 374, 442, 6, 1183, 1154, 522, 1154, 407,
159286 /* 130 */ 1556, 461, 373, 1554, 535, 99, 463, 332, 121, 121,
159287 /* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117,
159288 /* 150 */ 117, 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044,
159289 /* 160 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 1257, 1183,
159290 /* 170 */ 1184, 1185, 243, 1064, 564, 502, 499, 498, 567, 124,
159291 /* 180 */ 567, 1183, 1184, 1185, 474, 497, 119, 119, 119, 119,
159292 /* 190 */ 118, 118, 117, 117, 117, 116, 442, 70, 70, 407,
159293 /* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 442,
159294 /* 210 */ 1409, 1469, 119, 119, 119, 119, 118, 118, 117, 117,
159295 /* 220 */ 117, 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044,
159296 /* 230 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 407, 1031,
159297 /* 240 */ 1031, 1042, 1045, 81, 382, 541, 378, 80, 119, 119,
159298 /* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 381,
159299 /* 260 */ 463, 332, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159300 /* 270 */ 1034, 120, 120, 121, 121, 121, 121, 262, 215, 512,
159301 /* 280 */ 1424, 422, 119, 119, 119, 119, 118, 118, 117, 117,
159302 /* 290 */ 117, 116, 442, 1231, 1, 1, 571, 2, 1235, 1573,
159303 /* 300 */ 571, 2, 1235, 307, 1149, 141, 1600, 307, 407, 141,
159304 /* 310 */ 1183, 361, 1317, 1035, 866, 531, 1317, 1149, 359, 1567,
159305 /* 320 */ 1149, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159306 /* 330 */ 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159307 /* 340 */ 1034, 120, 120, 121, 121, 121, 121, 275, 275, 1001,
159308 /* 350 */ 426, 275, 275, 1128, 1627, 1021, 1627, 137, 542, 1541,
159309 /* 360 */ 561, 272, 950, 950, 561, 1423, 1183, 1184, 1185, 1594,
159310 /* 370 */ 866, 1012, 530, 315, 231, 1011, 468, 1276, 231, 119,
159311 /* 380 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
159312 /* 390 */ 1570, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159313 /* 400 */ 116, 442, 330, 359, 1567, 564, 446, 1011, 1011, 1013,
159314 /* 410 */ 446, 207, 564, 306, 555, 407, 363, 1021, 363, 346,
159315 /* 420 */ 184, 118, 118, 117, 117, 117, 116, 442, 71, 71,
159316 /* 430 */ 439, 438, 1126, 1012, 472, 71, 71, 1011, 205, 122,
159317 /* 440 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120,
159318 /* 450 */ 121, 121, 121, 121, 219, 219, 472, 1183, 407, 570,
159319 /* 460 */ 1183, 1235, 503, 1477, 149, 546, 307, 489, 141, 1011,
159320 /* 470 */ 1011, 1013, 546, 140, 545, 1317, 1214, 191, 1214, 950,
159321 /* 480 */ 950, 514, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159322 /* 490 */ 1034, 120, 120, 121, 121, 121, 121, 563, 119, 119,
159323 /* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 283,
159324 /* 510 */ 275, 275, 415, 1183, 1184, 1185, 1183, 1184, 1185, 372,
159325 /* 520 */ 1183, 243, 344, 561, 502, 499, 498, 1539, 407, 1540,
159326 /* 530 */ 1183, 288, 870, 143, 497, 1549, 185, 231, 9, 6,
159327 /* 540 */ 253, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159328 /* 550 */ 116, 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034,
159329 /* 560 */ 1034, 120, 120, 121, 121, 121, 121, 407, 137, 446,
159330 /* 570 */ 447, 863, 169, 1183, 397, 1204, 1183, 1184, 1185, 931,
159331 /* 580 */ 526, 1001, 98, 339, 564, 342, 1183, 1184, 1185, 306,
159332 /* 590 */ 555, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034,
159333 /* 600 */ 120, 120, 121, 121, 121, 121, 452, 71, 71, 275,
159334 /* 610 */ 275, 119, 119, 119, 119, 118, 118, 117, 117, 117,
159335 /* 620 */ 116, 442, 561, 417, 306, 555, 1183, 1307, 1307, 1183,
159336 /* 630 */ 1184, 1185, 1204, 1149, 330, 458, 318, 407, 363, 470,
159337 /* 640 */ 431, 1167, 32, 541, 527, 350, 1149, 1629, 393, 1149,
159338 /* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
159339 /* 660 */ 442, 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034,
159340 /* 670 */ 120, 120, 121, 121, 121, 121, 407, 199, 472, 1183,
159341 /* 680 */ 1022, 472, 1183, 1184, 1185, 386, 151, 539, 1548, 277,
159342 /* 690 */ 400, 137, 6, 317, 5, 564, 562, 3, 920, 920,
159343 /* 700 */ 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120,
159344 /* 710 */ 120, 121, 121, 121, 121, 411, 505, 83, 71, 71,
159345 /* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
159346 /* 730 */ 442, 1183, 218, 428, 1183, 1183, 1184, 1185, 363, 261,
159347 /* 740 */ 278, 358, 508, 353, 507, 248, 407, 306, 555, 1539,
159348 /* 750 */ 1006, 349, 363, 291, 489, 302, 293, 1542, 281, 119,
159349 /* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
159350 /* 770 */ 122, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120,
159351 /* 780 */ 120, 121, 121, 121, 121, 407, 148, 1183, 1184, 1185,
159352 /* 790 */ 1183, 1184, 1185, 275, 275, 1304, 1257, 1283, 483, 1476,
159353 /* 800 */ 150, 489, 480, 564, 1187, 1304, 561, 1587, 1255, 122,
159354 /* 810 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120,
159355 /* 820 */ 121, 121, 121, 121, 564, 886, 13, 13, 520, 119,
159356 /* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
159357 /* 840 */ 1183, 420, 417, 564, 269, 269, 1316, 13, 13, 1539,
159358 /* 850 */ 1546, 16, 16, 322, 6, 407, 506, 561, 1089, 1089,
159359 /* 860 */ 486, 1187, 425, 1539, 887, 292, 71, 71, 119, 119,
159360 /* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 122,
159361 /* 880 */ 123, 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120,
159362 /* 890 */ 121, 121, 121, 121, 564, 12, 1183, 1184, 1185, 407,
159363 /* 900 */ 275, 275, 451, 303, 834, 835, 836, 417, 489, 276,
159364 /* 910 */ 276, 1547, 284, 561, 319, 6, 321, 71, 71, 429,
159365 /* 920 */ 451, 450, 561, 952, 101, 113, 1207, 1207, 1041, 1044,
159366 /* 930 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 119, 119,
159367 /* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 1105,
159368 /* 950 */ 1183, 489, 564, 1312, 437, 455, 478, 564, 246, 245,
159369 /* 960 */ 244, 1409, 1545, 547, 1106, 405, 6, 1544, 196, 1258,
159370 /* 970 */ 413, 6, 105, 462, 103, 71, 71, 286, 564, 1107,
159371 /* 980 */ 13, 13, 119, 119, 119, 119, 118, 118, 117, 117,
159372 /* 990 */ 117, 116, 442, 451, 104, 427, 337, 320, 275, 275,
159373 /* 1000 */ 906, 13, 13, 564, 1482, 1105, 1183, 1184, 1185, 126,
159374 /* 1010 */ 907, 561, 546, 564, 407, 478, 295, 1321, 253, 200,
159375 /* 1020 */ 1106, 548, 1482, 1484, 280, 1409, 55, 55, 1287, 561,
159376 /* 1030 */ 478, 380, 423, 951, 407, 1107, 71, 71, 122, 123,
159377 /* 1040 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121,
159378 /* 1050 */ 121, 121, 121, 1204, 407, 287, 552, 309, 122, 123,
159379 /* 1060 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121,
159380 /* 1070 */ 121, 121, 121, 441, 1128, 1628, 146, 1628, 122, 111,
159381 /* 1080 */ 113, 1207, 1207, 1041, 1044, 1034, 1034, 120, 120, 121,
159382 /* 1090 */ 121, 121, 121, 404, 403, 1482, 424, 119, 119, 119,
159383 /* 1100 */ 119, 118, 118, 117, 117, 117, 116, 442, 1183, 564,
159384 /* 1110 */ 1204, 544, 1086, 858, 329, 361, 1086, 119, 119, 119,
159385 /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 442, 564, 294,
159386 /* 1130 */ 144, 523, 56, 56, 224, 564, 510, 119, 119, 119,
159387 /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 442, 484, 1409,
159388 /* 1150 */ 537, 15, 15, 1126, 434, 439, 438, 407, 13, 13,
159389 /* 1160 */ 1523, 12, 926, 1211, 1183, 1184, 1185, 925, 1213, 536,
159390 /* 1170 */ 858, 557, 413, 193, 1525, 494, 1212, 448, 1160, 1222,
159391 /* 1180 */ 1183, 564, 123, 113, 1207, 1207, 1041, 1044, 1034, 1034,
159392 /* 1190 */ 120, 120, 121, 121, 121, 121, 1521, 1149, 564, 965,
159393 /* 1200 */ 564, 1214, 247, 1214, 13, 13, 1409, 966, 538, 564,
159394 /* 1210 */ 1149, 108, 556, 1149, 4, 310, 392, 1227, 17, 194,
159395 /* 1220 */ 485, 43, 43, 57, 57, 306, 555, 524, 559, 1160,
159396 /* 1230 */ 464, 564, 44, 44, 392, 1127, 1183, 1184, 1185, 479,
159397 /* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
159398 /* 1250 */ 442, 443, 564, 327, 13, 13, 564, 418, 1315, 414,
159399 /* 1260 */ 171, 564, 311, 553, 213, 529, 1253, 564, 517, 543,
159400 /* 1270 */ 412, 108, 556, 137, 4, 58, 58, 435, 314, 59,
159401 /* 1280 */ 59, 274, 217, 549, 60, 60, 349, 476, 559, 1353,
159402 /* 1290 */ 61, 61, 1021, 275, 275, 1228, 213, 564, 106, 106,
159403 /* 1300 */ 8, 275, 275, 275, 275, 107, 561, 443, 566, 565,
159404 /* 1310 */ 564, 443, 1011, 1228, 561, 564, 561, 564, 275, 275,
159405 /* 1320 */ 62, 62, 1352, 553, 247, 456, 564, 98, 110, 306,
159406 /* 1330 */ 555, 561, 564, 45, 45, 405, 1203, 533, 46, 46,
159407 /* 1340 */ 47, 47, 532, 465, 1011, 1011, 1013, 1014, 27, 49,
159408 /* 1350 */ 49, 564, 1021, 405, 469, 50, 50, 564, 106, 106,
159409 /* 1360 */ 305, 564, 84, 204, 405, 107, 564, 443, 566, 565,
159410 /* 1370 */ 405, 564, 1011, 564, 63, 63, 564, 1599, 564, 895,
159411 /* 1380 */ 64, 64, 457, 477, 65, 65, 147, 96, 38, 14,
159412 /* 1390 */ 14, 1528, 412, 564, 66, 66, 128, 128, 926, 67,
159413 /* 1400 */ 67, 52, 52, 925, 1011, 1011, 1013, 1014, 27, 1572,
159414 /* 1410 */ 1171, 445, 208, 1123, 279, 394, 68, 68, 228, 390,
159415 /* 1420 */ 390, 389, 264, 387, 1171, 445, 843, 877, 279, 108,
159416 /* 1430 */ 556, 453, 4, 390, 390, 389, 264, 387, 564, 225,
159417 /* 1440 */ 843, 313, 328, 1003, 98, 252, 559, 544, 471, 312,
159418 /* 1450 */ 252, 564, 208, 225, 564, 313, 473, 30, 252, 279,
159419 /* 1460 */ 466, 69, 69, 312, 390, 390, 389, 264, 387, 443,
159420 /* 1470 */ 333, 843, 98, 564, 53, 53, 323, 157, 157, 227,
159421 /* 1480 */ 495, 553, 249, 289, 225, 564, 313, 162, 31, 1501,
159422 /* 1490 */ 135, 564, 1500, 227, 312, 533, 158, 158, 885, 884,
159423 /* 1500 */ 534, 162, 873, 301, 135, 564, 481, 226, 76, 76,
159424 /* 1510 */ 1021, 347, 1071, 98, 54, 54, 106, 106, 1067, 564,
159425 /* 1520 */ 249, 226, 519, 107, 227, 443, 566, 565, 72, 72,
159426 /* 1530 */ 1011, 334, 162, 564, 230, 135, 108, 556, 959, 4,
159427 /* 1540 */ 252, 408, 129, 129, 564, 1349, 306, 555, 564, 923,
159428 /* 1550 */ 564, 110, 226, 559, 564, 408, 73, 73, 564, 873,
159429 /* 1560 */ 306, 555, 1011, 1011, 1013, 1014, 27, 130, 130, 1071,
159430 /* 1570 */ 449, 131, 131, 127, 127, 357, 443, 156, 156, 892,
159431 /* 1580 */ 893, 155, 155, 338, 449, 356, 408, 564, 553, 968,
159432 /* 1590 */ 969, 306, 555, 1015, 341, 564, 108, 556, 564, 4,
159433 /* 1600 */ 1132, 1286, 533, 564, 856, 343, 145, 532, 345, 1300,
159434 /* 1610 */ 136, 136, 1083, 559, 1083, 449, 564, 1021, 134, 134,
159435 /* 1620 */ 1284, 132, 132, 106, 106, 1285, 133, 133, 564, 352,
159436 /* 1630 */ 107, 564, 443, 566, 565, 1340, 443, 1011, 362, 75,
159437 /* 1640 */ 75, 1082, 564, 1082, 564, 924, 1561, 110, 553, 551,
159438 /* 1650 */ 1015, 77, 77, 1361, 74, 74, 1408, 1336, 1347, 550,
159439 /* 1660 */ 1414, 1265, 1256, 1244, 1243, 42, 42, 48, 48, 1011,
159440 /* 1670 */ 1011, 1013, 1014, 27, 1245, 1580, 490, 1021, 267, 202,
159441 /* 1680 */ 1333, 365, 11, 106, 106, 930, 367, 210, 369, 391,
159442 /* 1690 */ 107, 1395, 443, 566, 565, 223, 1390, 1011, 500, 454,
159443 /* 1700 */ 282, 1400, 285, 108, 556, 214, 4, 325, 1383, 1283,
159444 /* 1710 */ 475, 355, 1473, 1583, 1472, 1399, 371, 1222, 326, 398,
159445 /* 1720 */ 559, 290, 331, 197, 100, 556, 209, 4, 198, 1011,
159446 /* 1730 */ 1011, 1013, 1014, 27, 385, 256, 1520, 1518, 554, 1219,
159447 /* 1740 */ 416, 559, 83, 443, 173, 206, 182, 221, 459, 167,
159448 /* 1750 */ 177, 460, 175, 493, 233, 553, 79, 178, 1396, 179,
159449 /* 1760 */ 35, 180, 96, 1402, 443, 396, 36, 467, 1478, 1401,
159450 /* 1770 */ 482, 237, 1404, 399, 82, 186, 553, 1467, 89, 488,
159451 /* 1780 */ 190, 268, 239, 491, 1021, 340, 240, 401, 1246, 1489,
159452 /* 1790 */ 106, 106, 336, 509, 1294, 241, 1303, 107, 430, 443,
159453 /* 1800 */ 566, 565, 1302, 91, 1011, 1021, 1598, 1301, 1273, 215,
159454 /* 1810 */ 1597, 106, 106, 402, 877, 432, 354, 1272, 107, 1271,
159455 /* 1820 */ 443, 566, 565, 1596, 1566, 1011, 1293, 433, 518, 299,
159456 /* 1830 */ 300, 360, 95, 525, 1344, 364, 1011, 1011, 1013, 1014,
159457 /* 1840 */ 27, 254, 255, 1552, 436, 1551, 125, 544, 10, 379,
159458 /* 1850 */ 1326, 1453, 102, 97, 1345, 528, 304, 1011, 1011, 1013,
159459 /* 1860 */ 1014, 27, 366, 377, 1343, 1342, 368, 370, 1325, 384,
159460 /* 1870 */ 201, 383, 34, 1368, 1367, 568, 1177, 266, 263, 265,
159461 /* 1880 */ 1505, 159, 569, 1241, 1236, 1506, 160, 142, 1504, 1503,
159462 /* 1890 */ 297, 211, 830, 161, 212, 78, 444, 203, 308, 222,
159463 /* 1900 */ 1081, 139, 1079, 316, 174, 163, 1203, 229, 176, 909,
159464 /* 1910 */ 324, 232, 1095, 181, 409, 410, 172, 164, 165, 419,
159465 /* 1920 */ 183, 85, 86, 421, 166, 87, 88, 1098, 1094, 234,
159466 /* 1930 */ 235, 152, 18, 236, 335, 1087, 1216, 252, 187, 487,
159467 /* 1940 */ 238, 188, 37, 845, 492, 356, 242, 496, 351, 501,
159468 /* 1950 */ 189, 90, 19, 504, 348, 20, 875, 92, 298, 168,
159469 /* 1960 */ 888, 153, 93, 511, 94, 1165, 154, 1047, 1134, 39,
159470 /* 1970 */ 216, 1133, 271, 273, 958, 192, 953, 110, 1151, 1155,
159471 /* 1980 */ 251, 7, 21, 1159, 1139, 22, 1153, 33, 23, 24,
159472 /* 1990 */ 25, 540, 1158, 195, 98, 1062, 26, 1048, 1046, 1050,
159473 /* 2000 */ 1104, 1051, 1103, 257, 258, 28, 40, 1173, 1016, 857,
159474 /* 2010 */ 109, 29, 560, 388, 138, 1172, 259, 170, 260, 1232,
159475 /* 2020 */ 1232, 919, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1232,
159476 /* 2030 */ 1232, 1232, 1589, 1232, 1232, 1232, 1588,
159477 };
159478 static const YYCODETYPE yy_lookahead[] = {
159479 /* 0 */ 192, 273, 274, 275, 192, 192, 273, 274, 275, 192,
159480 /* 10 */ 218, 215, 192, 218, 192, 212, 234, 235, 205, 19,
159481 /* 20 */ 11, 192, 294, 215, 216, 203, 192, 203, 209, 210,
@@ -159486,202 +160854,202 @@
159486 /* 70 */ 275, 237, 21, 251, 252, 251, 273, 274, 275, 255,
159487 /* 80 */ 256, 215, 216, 43, 44, 45, 46, 47, 48, 49,
159488 /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 209, 210,
159489 /* 100 */ 211, 76, 102, 103, 104, 105, 106, 107, 108, 109,
159490 /* 110 */ 110, 111, 112, 59, 89, 111, 112, 92, 252, 307,
159491 /* 120 */ 308, 313, 314, 112, 312, 59, 86, 261, 88, 19,
159492 /* 130 */ 313, 80, 315, 313, 314, 25, 127, 128, 54, 55,
159493 /* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109,
159494 /* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49,
159495 /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 192, 115,
159496 /* 170 */ 116, 117, 118, 122, 192, 121, 122, 123, 202, 69,
159497 /* 180 */ 204, 115, 116, 117, 192, 131, 102, 103, 104, 105,
159498 /* 190 */ 106, 107, 108, 109, 110, 111, 112, 215, 216, 19,
159499 /* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112,
159500 /* 210 */ 192, 160, 102, 103, 104, 105, 106, 107, 108, 109,
159501 /* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49,
159502 /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 46,
159503 /* 240 */ 47, 48, 49, 24, 248, 192, 250, 67, 102, 103,
159504 /* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 277,
159505 /* 260 */ 127, 128, 43, 44, 45, 46, 47, 48, 49, 50,
159506 /* 270 */ 51, 52, 53, 54, 55, 56, 57, 26, 164, 165,
159507 /* 280 */ 272, 263, 102, 103, 104, 105, 106, 107, 108, 109,
159508 /* 290 */ 110, 111, 112, 184, 185, 186, 187, 188, 189, 186,
159509 /* 300 */ 187, 188, 189, 194, 76, 196, 229, 194, 19, 196,
159510 /* 310 */ 59, 192, 203, 120, 59, 87, 203, 89, 310, 311,
159511 /* 320 */ 92, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159512 /* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50,
159513 /* 340 */ 51, 52, 53, 54, 55, 56, 57, 238, 239, 73,
159514 /* 350 */ 231, 238, 239, 22, 23, 100, 25, 81, 305, 306,
159515 /* 360 */ 251, 23, 25, 25, 251, 272, 115, 116, 117, 214,
159516 /* 370 */ 115, 116, 144, 192, 265, 120, 114, 222, 265, 102,
159517 /* 380 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
159518 /* 390 */ 192, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159519 /* 400 */ 111, 112, 126, 310, 311, 192, 297, 152, 153, 154,
159520 /* 410 */ 297, 149, 192, 137, 138, 19, 192, 100, 192, 23,
159521 /* 420 */ 22, 106, 107, 108, 109, 110, 111, 112, 215, 216,
159522 /* 430 */ 106, 107, 101, 116, 192, 215, 216, 120, 149, 43,
159523 /* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
159524 /* 450 */ 54, 55, 56, 57, 117, 117, 192, 59, 19, 187,
159525 /* 460 */ 59, 189, 23, 282, 240, 252, 194, 192, 196, 152,
159526 /* 470 */ 153, 154, 252, 72, 261, 203, 152, 25, 154, 142,
159527 /* 480 */ 142, 261, 43, 44, 45, 46, 47, 48, 49, 50,
159528 /* 490 */ 51, 52, 53, 54, 55, 56, 57, 192, 102, 103,
159529 /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 267,
159530 /* 510 */ 238, 239, 237, 115, 116, 117, 115, 116, 117, 192,
159531 /* 520 */ 59, 118, 16, 251, 121, 122, 123, 303, 19, 303,
159532 /* 530 */ 59, 267, 23, 72, 131, 308, 22, 265, 22, 312,
159533 /* 540 */ 24, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159534 /* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50,
159535 /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 81, 297,
159536 /* 570 */ 295, 23, 192, 59, 203, 59, 115, 116, 117, 108,
159537 /* 580 */ 192, 73, 25, 77, 192, 79, 115, 116, 117, 137,
159538 /* 590 */ 138, 43, 44, 45, 46, 47, 48, 49, 50, 51,
159539 /* 600 */ 52, 53, 54, 55, 56, 57, 119, 215, 216, 238,
159540 /* 610 */ 239, 102, 103, 104, 105, 106, 107, 108, 109, 110,
159541 /* 620 */ 111, 112, 251, 192, 137, 138, 59, 234, 235, 115,
159542 /* 630 */ 116, 117, 116, 76, 126, 127, 128, 19, 192, 268,
159543 /* 640 */ 19, 23, 22, 192, 252, 24, 89, 300, 301, 92,
159544 /* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
159545 /* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51,
159546 /* 670 */ 52, 53, 54, 55, 56, 57, 19, 192, 192, 59,
159547 /* 680 */ 23, 192, 115, 116, 117, 200, 240, 307, 308, 22,
159548 /* 690 */ 205, 81, 312, 262, 22, 192, 133, 22, 135, 136,
159549 /* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
159550 /* 710 */ 53, 54, 55, 56, 57, 197, 95, 150, 215, 216,
159551 /* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
159552 /* 730 */ 112, 59, 192, 112, 59, 115, 116, 117, 192, 118,
159553 /* 740 */ 119, 120, 121, 122, 123, 124, 19, 137, 138, 303,
159554 /* 750 */ 23, 130, 192, 267, 192, 252, 267, 306, 203, 102,
159555 /* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
159556 /* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
159557 /* 780 */ 53, 54, 55, 56, 57, 19, 240, 115, 116, 117,
159558 /* 790 */ 115, 116, 117, 238, 239, 222, 192, 224, 280, 237,
159559 /* 800 */ 240, 192, 284, 192, 59, 232, 251, 140, 204, 43,
159560 /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
159561 /* 820 */ 54, 55, 56, 57, 192, 35, 215, 216, 192, 102,
159562 /* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
159563 /* 840 */ 59, 230, 192, 192, 238, 239, 237, 215, 216, 303,
159564 /* 850 */ 308, 215, 216, 16, 312, 19, 66, 251, 126, 127,
159565 /* 860 */ 128, 116, 230, 303, 74, 203, 215, 216, 102, 103,
159566 /* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43,
159567 /* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
159568 /* 890 */ 54, 55, 56, 57, 192, 212, 115, 116, 117, 19,
159569 /* 900 */ 238, 239, 192, 252, 7, 8, 9, 192, 192, 238,
159570 /* 910 */ 239, 308, 262, 251, 77, 312, 79, 215, 216, 129,
159571 /* 920 */ 210, 211, 251, 142, 158, 45, 46, 47, 48, 49,
159572 /* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103,
159573 /* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 12,
159574 /* 950 */ 59, 192, 192, 237, 252, 243, 192, 192, 126, 127,
159575 /* 960 */ 128, 192, 308, 203, 27, 253, 312, 308, 285, 207,
159576 /* 970 */ 208, 312, 157, 290, 159, 215, 216, 262, 192, 42,
159577 /* 980 */ 215, 216, 102, 103, 104, 105, 106, 107, 108, 109,
159578 /* 990 */ 110, 111, 112, 283, 158, 230, 237, 160, 238, 239,
159579 /* 1000 */ 63, 215, 216, 192, 192, 12, 115, 116, 117, 22,
159580 /* 1010 */ 73, 251, 252, 192, 19, 192, 230, 239, 24, 24,
159581 /* 1020 */ 27, 261, 210, 211, 99, 192, 215, 216, 225, 251,
159582 /* 1030 */ 192, 192, 263, 142, 19, 42, 215, 216, 43, 44,
159583 /* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
159584 /* 1050 */ 55, 56, 57, 59, 19, 291, 63, 132, 43, 44,
159585 /* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
159586 /* 1070 */ 55, 56, 57, 252, 22, 23, 22, 25, 43, 44,
159587 /* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
159588 /* 1090 */ 55, 56, 57, 106, 107, 283, 263, 102, 103, 104,
159589 /* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 192,
159590 /* 1110 */ 116, 144, 29, 59, 291, 192, 33, 102, 103, 104,
159591 /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 192, 291,
159592 /* 1130 */ 163, 19, 215, 216, 15, 192, 108, 102, 103, 104,
159593 /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 65, 192,
159594 /* 1150 */ 66, 215, 216, 101, 231, 106, 107, 19, 215, 216,
159595 /* 1160 */ 192, 212, 134, 114, 115, 116, 117, 139, 119, 85,
159596 /* 1170 */ 116, 207, 208, 230, 192, 19, 127, 192, 94, 60,
159597 /* 1180 */ 59, 192, 44, 45, 46, 47, 48, 49, 50, 51,
159598 /* 1190 */ 52, 53, 54, 55, 56, 57, 192, 76, 192, 31,
159599 /* 1200 */ 192, 152, 46, 154, 215, 216, 192, 39, 87, 192,
159600 /* 1210 */ 89, 19, 20, 92, 22, 192, 22, 23, 22, 230,
159601 /* 1220 */ 263, 215, 216, 215, 216, 137, 138, 115, 36, 145,
159602 /* 1230 */ 128, 192, 215, 216, 22, 23, 115, 116, 117, 290,
159603 /* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
159604 /* 1250 */ 112, 59, 192, 151, 215, 216, 192, 61, 203, 298,
159605 /* 1260 */ 299, 192, 192, 71, 25, 144, 203, 192, 203, 230,
159606 /* 1270 */ 114, 19, 20, 81, 22, 215, 216, 263, 192, 215,
159607 /* 1280 */ 216, 255, 256, 203, 215, 216, 130, 19, 36, 192,
159608 /* 1290 */ 215, 216, 100, 238, 239, 101, 25, 192, 106, 107,
159609 /* 1300 */ 48, 238, 239, 238, 239, 113, 251, 115, 116, 117,
159610 /* 1310 */ 192, 59, 120, 101, 251, 192, 251, 192, 238, 239,
159611 /* 1320 */ 215, 216, 192, 71, 46, 243, 192, 25, 25, 137,
159612 /* 1330 */ 138, 251, 192, 215, 216, 253, 25, 85, 215, 216,
159613 /* 1340 */ 215, 216, 90, 243, 152, 153, 154, 155, 156, 215,
159614 /* 1350 */ 216, 192, 100, 253, 243, 215, 216, 192, 106, 107,
159615 /* 1360 */ 243, 192, 148, 149, 253, 113, 192, 115, 116, 117,
159616 /* 1370 */ 253, 192, 120, 192, 215, 216, 192, 23, 192, 25,
159617 /* 1380 */ 215, 216, 192, 115, 215, 216, 22, 148, 24, 215,
159618 /* 1390 */ 216, 192, 114, 192, 215, 216, 215, 216, 134, 215,
159619 /* 1400 */ 216, 215, 216, 139, 152, 153, 154, 155, 156, 0,
159620 /* 1410 */ 1, 2, 141, 23, 5, 25, 215, 216, 24, 10,
159621 /* 1420 */ 11, 12, 13, 14, 1, 2, 17, 125, 5, 19,
159622 /* 1430 */ 20, 268, 22, 10, 11, 12, 13, 14, 192, 30,
159623 /* 1440 */ 17, 32, 23, 23, 25, 25, 36, 144, 23, 40,
159624 /* 1450 */ 25, 192, 141, 30, 192, 32, 23, 22, 25, 5,
159625 /* 1460 */ 128, 215, 216, 40, 10, 11, 12, 13, 14, 59,
159626 /* 1470 */ 23, 17, 25, 192, 215, 216, 192, 215, 216, 70,
159627 /* 1480 */ 23, 71, 25, 151, 30, 192, 32, 78, 53, 192,
159628 /* 1490 */ 81, 192, 192, 70, 40, 85, 215, 216, 119, 120,
159629 /* 1500 */ 90, 78, 59, 254, 81, 192, 192, 98, 215, 216,
159630 /* 1510 */ 100, 23, 59, 25, 215, 216, 106, 107, 23, 192,
159631 /* 1520 */ 25, 98, 19, 113, 70, 115, 116, 117, 215, 216,
159632 /* 1530 */ 120, 192, 78, 192, 140, 81, 19, 20, 23, 22,
159633 /* 1540 */ 25, 132, 215, 216, 192, 192, 137, 138, 192, 23,
159634 /* 1550 */ 192, 25, 98, 36, 192, 132, 215, 216, 192, 116,
159635 /* 1560 */ 137, 138, 152, 153, 154, 155, 156, 215, 216, 116,
159636 /* 1570 */ 161, 215, 216, 215, 216, 120, 59, 215, 216, 7,
159637 /* 1580 */ 8, 215, 216, 192, 161, 130, 132, 192, 71, 83,
159638 /* 1590 */ 84, 137, 138, 59, 192, 192, 19, 20, 192, 22,
159639 /* 1600 */ 97, 225, 85, 192, 23, 192, 25, 90, 192, 192,
159640 /* 1610 */ 215, 216, 152, 36, 154, 161, 192, 100, 215, 216,
159641 /* 1620 */ 192, 215, 216, 106, 107, 225, 215, 216, 192, 192,
159642 /* 1630 */ 113, 192, 115, 116, 117, 257, 59, 120, 192, 215,
159643 /* 1640 */ 216, 152, 192, 154, 192, 23, 317, 25, 71, 235,
159644 /* 1650 */ 116, 215, 216, 192, 215, 216, 192, 192, 192, 192,
159645 /* 1660 */ 192, 192, 192, 192, 192, 215, 216, 215, 216, 152,
159646 /* 1670 */ 153, 154, 155, 156, 192, 192, 287, 100, 286, 241,
159647 /* 1680 */ 254, 254, 242, 106, 107, 108, 254, 213, 254, 190,
159648 /* 1690 */ 113, 270, 115, 116, 117, 296, 266, 120, 219, 258,
159649 /* 1700 */ 244, 270, 258, 19, 20, 228, 22, 292, 266, 224,
159650 /* 1710 */ 292, 218, 218, 195, 218, 270, 258, 60, 245, 270,
159651 /* 1720 */ 36, 245, 244, 248, 19, 20, 242, 22, 248, 152,
159652 /* 1730 */ 153, 154, 155, 156, 244, 140, 199, 199, 279, 38,
159653 /* 1740 */ 199, 36, 150, 59, 296, 149, 22, 296, 18, 43,
159654 /* 1750 */ 236, 199, 233, 18, 198, 71, 293, 236, 271, 236,
159655 /* 1760 */ 269, 236, 148, 271, 59, 245, 269, 245, 282, 271,
159656 /* 1770 */ 199, 198, 233, 245, 293, 233, 71, 245, 157, 62,
159657 /* 1780 */ 22, 199, 198, 220, 100, 199, 198, 220, 199, 289,
159658 /* 1790 */ 106, 107, 288, 114, 226, 198, 217, 113, 64, 115,
159659 /* 1800 */ 116, 117, 217, 22, 120, 100, 223, 217, 217, 164,
159660 /* 1810 */ 223, 106, 107, 220, 125, 24, 217, 219, 113, 217,
159661 /* 1820 */ 115, 116, 117, 217, 311, 120, 226, 112, 304, 281,
159662 /* 1830 */ 281, 220, 114, 143, 260, 259, 152, 153, 154, 155,
159663 /* 1840 */ 156, 199, 91, 316, 82, 316, 147, 144, 22, 199,
159664 /* 1850 */ 249, 276, 157, 146, 260, 145, 278, 152, 153, 154,
159665 /* 1860 */ 155, 156, 259, 248, 260, 260, 259, 259, 249, 245,
159666 /* 1870 */ 247, 246, 25, 264, 264, 201, 13, 6, 193, 193,
159667 /* 1880 */ 212, 206, 191, 191, 191, 212, 206, 221, 212, 212,
159668 /* 1890 */ 221, 213, 4, 206, 213, 212, 3, 22, 162, 15,
159669 /* 1900 */ 23, 16, 23, 138, 150, 129, 25, 24, 141, 20,
159670 /* 1910 */ 16, 143, 1, 141, 302, 302, 299, 129, 129, 61,
159671 /* 1920 */ 150, 53, 53, 37, 129, 53, 53, 115, 1, 34,
159672 /* 1930 */ 140, 5, 22, 114, 160, 68, 75, 25, 68, 41,
159673 /* 1940 */ 140, 114, 24, 20, 19, 130, 124, 67, 24, 67,
159674 /* 1950 */ 22, 22, 22, 96, 23, 22, 59, 22, 67, 37,
159675 /* 1960 */ 28, 23, 148, 22, 25, 23, 23, 23, 23, 22,
159676 /* 1970 */ 140, 97, 23, 23, 115, 22, 142, 25, 88, 75,
159677 /* 1980 */ 34, 44, 34, 75, 23, 34, 86, 22, 34, 34,
159678 /* 1990 */ 34, 24, 93, 25, 25, 23, 34, 23, 23, 23,
159679 /* 2000 */ 23, 11, 23, 25, 22, 22, 22, 1, 23, 23,
159680 /* 2010 */ 22, 22, 25, 15, 23, 1, 140, 25, 140, 318,
159681 /* 2020 */ 318, 134, 318, 318, 318, 318, 318, 318, 318, 318,
159682 /* 2030 */ 318, 318, 140, 318, 318, 318, 140, 318, 318, 318,
159683 /* 2040 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159684 /* 2050 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159685 /* 2060 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159686 /* 2070 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159687 /* 2080 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
@@ -159694,122 +161062,120 @@
159694 /* 2150 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159695 /* 2160 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159696 /* 2170 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159697 /* 2180 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159698 /* 2190 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159699 /* 2200 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159700 /* 2210 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
159701 /* 2220 */ 318,
159702 };
159703 #define YY_SHIFT_COUNT (571)
159704 #define YY_SHIFT_MIN (0)
159705 #define YY_SHIFT_MAX (2014)
159706 static const unsigned short int yy_shift_ofst[] = {
159707 /* 0 */ 1423, 1409, 1454, 1192, 1192, 610, 1252, 1410, 1517, 1684,
159708 /* 10 */ 1684, 1684, 276, 0, 0, 180, 1015, 1684, 1684, 1684,
159709 /* 20 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159710 /* 30 */ 1049, 1049, 1121, 1121, 54, 487, 610, 610, 610, 610,
159711 /* 40 */ 610, 40, 110, 219, 289, 396, 439, 509, 548, 618,
159712 /* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015,
159713 /* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015,
159714 /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1577, 1684,
159715 /* 80 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159716 /* 90 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159717 /* 100 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684, 1684,
159718 /* 110 */ 1684, 1684, 1684, 1705, 1684, 1684, 1684, 1684, 1684, 1684,
159719 /* 120 */ 1684, 1684, 1684, 1684, 1684, 1684, 1684, 146, 84, 84,
159720 /* 130 */ 84, 84, 84, 277, 315, 401, 97, 461, 251, 66,
159721 /* 140 */ 66, 51, 1156, 66, 66, 324, 324, 66, 452, 452,
159722 /* 150 */ 452, 452, 133, 114, 114, 4, 11, 2037, 2037, 621,
159723 /* 160 */ 621, 621, 567, 398, 398, 398, 398, 937, 937, 228,
159724 /* 170 */ 251, 331, 1052, 66, 66, 66, 66, 66, 66, 66,
159725 /* 180 */ 66, 66, 66, 66, 66, 66, 66, 66, 66, 66,
159726 /* 190 */ 66, 66, 66, 557, 557, 66, 9, 25, 25, 745,
159727 /* 200 */ 745, 967, 1088, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
159728 /* 210 */ 255, 317, 317, 514, 403, 620, 471, 672, 781, 891,
159729 /* 220 */ 675, 66, 66, 66, 66, 66, 66, 66, 66, 66,
159730 /* 230 */ 66, 508, 66, 66, 66, 66, 66, 66, 66, 66,
159731 /* 240 */ 66, 66, 66, 66, 790, 790, 790, 66, 66, 66,
159732 /* 250 */ 338, 66, 66, 66, 516, 1084, 66, 66, 993, 66,
159733 /* 260 */ 66, 66, 66, 66, 66, 66, 66, 732, 1083, 563,
159734 /* 270 */ 994, 994, 994, 994, 337, 563, 563, 1028, 987, 897,
159735 /* 280 */ 1119, 262, 1214, 1271, 1112, 1214, 1112, 1268, 1239, 262,
159736 /* 290 */ 262, 1239, 262, 1271, 1268, 1302, 1354, 1278, 1168, 1168,
159737 /* 300 */ 1168, 1112, 1303, 1303, 815, 1311, 1264, 1364, 1657, 1657,
159738 /* 310 */ 1595, 1595, 1701, 1701, 1595, 1592, 1596, 1724, 1706, 1730,
159739 /* 320 */ 1730, 1730, 1730, 1595, 1735, 1614, 1596, 1596, 1614, 1724,
159740 /* 330 */ 1706, 1614, 1706, 1614, 1595, 1735, 1621, 1717, 1595, 1735,
159741 /* 340 */ 1758, 1595, 1735, 1595, 1735, 1758, 1679, 1679, 1679, 1734,
159742 /* 350 */ 1781, 1781, 1758, 1679, 1689, 1679, 1734, 1679, 1679, 1645,
159743 /* 360 */ 1791, 1715, 1715, 1758, 1690, 1718, 1690, 1718, 1690, 1718,
159744 /* 370 */ 1690, 1718, 1595, 1751, 1751, 1762, 1762, 1699, 1703, 1826,
159745 /* 380 */ 1595, 1695, 1699, 1707, 1710, 1614, 1847, 1863, 1863, 1871,
159746 /* 390 */ 1871, 1871, 2037, 2037, 2037, 2037, 2037, 2037, 2037, 2037,
159747 /* 400 */ 2037, 2037, 2037, 2037, 2037, 2037, 2037, 193, 837, 1194,
159748 /* 410 */ 1212, 506, 832, 1054, 1390, 925, 1435, 1394, 1102, 1332,
159749 /* 420 */ 1419, 1196, 1420, 1425, 1433, 1447, 1457, 1488, 1443, 1379,
159750 /* 430 */ 1572, 1455, 1503, 1453, 1495, 1515, 1506, 1526, 1460, 1489,
159751 /* 440 */ 1581, 1622, 1534, 667, 1888, 1893, 1875, 1736, 1884, 1885,
159752 /* 450 */ 1877, 1879, 1765, 1754, 1776, 1881, 1881, 1883, 1767, 1889,
159753 /* 460 */ 1768, 1894, 1911, 1772, 1788, 1881, 1789, 1858, 1886, 1881,
159754 /* 470 */ 1770, 1868, 1869, 1872, 1873, 1795, 1812, 1895, 1790, 1927,
159755 /* 480 */ 1926, 1910, 1819, 1774, 1867, 1912, 1870, 1861, 1898, 1800,
159756 /* 490 */ 1827, 1918, 1923, 1925, 1815, 1822, 1928, 1880, 1929, 1930,
159757 /* 500 */ 1931, 1933, 1882, 1897, 1924, 1857, 1932, 1935, 1891, 1922,
159758 /* 510 */ 1938, 1814, 1941, 1942, 1943, 1944, 1939, 1945, 1947, 1874,
159759 /* 520 */ 1830, 1949, 1950, 1859, 1946, 1953, 1834, 1952, 1948, 1951,
159760 /* 530 */ 1954, 1955, 1890, 1904, 1900, 1937, 1908, 1899, 1956, 1961,
159761 /* 540 */ 1965, 1967, 1968, 1969, 1962, 1972, 1952, 1974, 1975, 1976,
159762 /* 550 */ 1977, 1978, 1979, 1982, 1990, 1983, 1984, 1985, 1986, 1988,
159763 /* 560 */ 1989, 1987, 1887, 1876, 1878, 1892, 1896, 1992, 1991, 1998,
159764 /* 570 */ 2006, 2014,
159765 };
159766 #define YY_REDUCE_COUNT (406)
159767 #define YY_REDUCE_MIN (-272)
159768 #define YY_REDUCE_MAX (1693)
159769 static const short yy_reduce_ofst[] = {
159770 /* 0 */ 109, 113, 272, 760, -178, -176, -192, -183, -180, -134,
159771 /* 10 */ 213, 220, 371, -208, -205, -272, -197, 611, 632, 765,
159772 /* 20 */ 786, 392, 943, 989, 503, 651, 1039, -18, 702, 821,
159773 /* 30 */ 710, 812, -188, 380, -187, 555, 662, 1055, 1063, 1065,
159774 /* 40 */ 1080, -267, -267, -267, -267, -267, -267, -267, -267, -267,
159775 /* 50 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267,
159776 /* 60 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267,
159777 /* 70 */ -267, -267, -267, -267, -267, -267, -267, -267, 636, 811,
159778 /* 80 */ 917, 936, 1006, 1008, 1017, 1060, 1064, 1069, 1075, 1105,
159779 /* 90 */ 1118, 1123, 1125, 1134, 1140, 1159, 1165, 1169, 1174, 1179,
159780 /* 100 */ 1181, 1184, 1186, 1201, 1246, 1259, 1262, 1281, 1293, 1299,
159781 /* 110 */ 1313, 1327, 1341, 1352, 1356, 1358, 1362, 1366, 1395, 1403,
159782 /* 120 */ 1406, 1411, 1424, 1436, 1439, 1450, 1452, -267, -267, -267,
159783 /* 130 */ -267, -267, -267, -267, -267, 224, -267, 446, -24, 275,
159784 /* 140 */ 546, 518, 573, 560, 53, -181, -111, 485, 606, 671,
159785 /* 150 */ 606, 671, 683, 8, 93, -267, -267, -267, -267, 155,
159786 /* 160 */ 155, 155, 181, 242, 264, 486, 489, -218, 393, 227,
159787 /* 170 */ 604, 347, 347, -171, 431, 650, 715, -166, 562, 609,
159788 /* 180 */ 716, 764, 18, 823, 769, 833, 838, 957, 759, 119,
159789 /* 190 */ 923, 226, 1014, 542, 603, 451, 949, 654, 659, 762,
159790 /* 200 */ 964, -4, 778, 961, 712, 1082, 1100, 1111, 1026, 1117,
159791 /* 210 */ -204, -174, -151, -8, 77, 198, 305, 327, 388, 540,
159792 /* 220 */ 839, 968, 982, 985, 1004, 1023, 1070, 1086, 1097, 1130,
159793 /* 230 */ 1190, 1163, 1199, 1284, 1297, 1300, 1314, 1339, 1353, 1391,
159794 /* 240 */ 1402, 1413, 1416, 1417, 803, 1376, 1400, 1428, 1437, 1446,
159795 /* 250 */ 1378, 1461, 1464, 1465, 1249, 1329, 1466, 1467, 1414, 1468,
159796 /* 260 */ 305, 1469, 1470, 1471, 1472, 1482, 1483, 1389, 1392, 1438,
159797 /* 270 */ 1426, 1427, 1432, 1434, 1378, 1438, 1438, 1440, 1474, 1499,
159798 /* 280 */ 1399, 1421, 1430, 1456, 1441, 1442, 1444, 1415, 1473, 1431,
159799 /* 290 */ 1445, 1476, 1449, 1478, 1418, 1479, 1477, 1485, 1493, 1494,
159800 /* 300 */ 1496, 1458, 1475, 1480, 1459, 1490, 1484, 1518, 1448, 1451,
159801 /* 310 */ 1537, 1538, 1463, 1481, 1541, 1486, 1487, 1491, 1519, 1514,
159802 /* 320 */ 1521, 1523, 1525, 1552, 1556, 1520, 1492, 1498, 1522, 1497,
159803 /* 330 */ 1539, 1528, 1542, 1532, 1571, 1573, 1500, 1504, 1582, 1584,
159804 /* 340 */ 1563, 1586, 1588, 1589, 1597, 1567, 1579, 1585, 1590, 1568,
159805 /* 350 */ 1583, 1587, 1593, 1591, 1598, 1599, 1600, 1602, 1606, 1513,
159806 /* 360 */ 1524, 1548, 1549, 1611, 1574, 1576, 1594, 1603, 1604, 1607,
159807 /* 370 */ 1605, 1608, 1642, 1527, 1529, 1609, 1610, 1601, 1615, 1575,
159808 /* 380 */ 1650, 1578, 1619, 1623, 1625, 1624, 1674, 1685, 1686, 1691,
159809 /* 390 */ 1692, 1693, 1612, 1613, 1617, 1675, 1668, 1673, 1676, 1677,
159810 /* 400 */ 1680, 1666, 1669, 1678, 1681, 1683, 1687,
159811 };
159812 static const YYACTIONTYPE yy_default[] = {
159813 /* 0 */ 1633, 1633, 1633, 1462, 1230, 1341, 1230, 1230, 1230, 1462,
159814 /* 10 */ 1462, 1462, 1230, 1371, 1371, 1515, 1263, 1230, 1230, 1230,
159815 /* 20 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1461, 1230, 1230,
@@ -159930,14 +161296,14 @@
159930 59, /* DETACH => ID */
159931 59, /* EACH => ID */
159932 59, /* FAIL => ID */
159933 0, /* OR => nothing */
159934 0, /* AND => nothing */
159935 0, /* IS => nothing */
159936 59, /* MATCH => ID */
159937 59, /* LIKE_KW => ID */
159938 0, /* BETWEEN => nothing */
 
159939 0, /* IN => nothing */
159940 0, /* ISNULL => nothing */
159941 0, /* NOTNULL => nothing */
159942 0, /* NE => nothing */
159943 0, /* EQ => nothing */
@@ -160120,13 +161486,13 @@
160120 yyStackEntry *yystackEnd; /* Last entry in the stack */
160121 #endif
160122 };
160123 typedef struct yyParser yyParser;
160124
 
160125 #ifndef NDEBUG
160126 /* #include <stdio.h> */
160127 /* #include <assert.h> */
160128 static FILE *yyTraceFILE = 0;
160129 static char *yyTracePrompt = 0;
160130 #endif /* NDEBUG */
160131
160132 #ifndef NDEBUG
@@ -160202,14 +161568,14 @@
160202 /* 40 */ "DETACH",
160203 /* 41 */ "EACH",
160204 /* 42 */ "FAIL",
160205 /* 43 */ "OR",
160206 /* 44 */ "AND",
160207 /* 45 */ "IS",
160208 /* 46 */ "MATCH",
160209 /* 47 */ "LIKE_KW",
160210 /* 48 */ "BETWEEN",
160211 /* 49 */ "IN",
160212 /* 50 */ "ISNULL",
160213 /* 51 */ "NOTNULL",
160214 /* 52 */ "NE",
160215 /* 53 */ "EQ",
@@ -163871,12 +165237,12 @@
163871 assert( yypParser->yytos>=yypParser->yystack );
163872 assert( yyact==yypParser->yytos->stateno );
163873 yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
163874 if( yyact >= YY_MIN_REDUCE ){
163875 unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
163876 assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
163877 #ifndef NDEBUG
 
163878 if( yyTraceFILE ){
163879 int yysize = yyRuleInfoNRhs[yyruleno];
163880 if( yysize ){
163881 fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
163882 yyTracePrompt,
@@ -165119,10 +166485,11 @@
165119 int n = 0; /* Length of the next token token */
165120 int tokenType; /* type of the next token */
165121 int lastTokenParsed = -1; /* type of the previous token */
165122 sqlite3 *db = pParse->db; /* The database connection */
165123 int mxSqlLen; /* Max length of an SQL string */
 
165124 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
165125 yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
165126 #endif
165127 VVA_ONLY( u8 startedWithOom = db->mallocFailed );
165128
@@ -165154,11 +166521,11 @@
165154 #endif
165155 assert( pParse->pNewTable==0 );
165156 assert( pParse->pNewTrigger==0 );
165157 assert( pParse->nVar==0 );
165158 assert( pParse->pVList==0 );
165159 pParse->pParentParse = db->pParse;
165160 db->pParse = pParse;
165161 while( 1 ){
165162 n = sqlite3GetToken((u8*)zSql, &tokenType);
165163 mxSqlLen -= n;
165164 if( mxSqlLen<0 ){
@@ -165269,12 +166636,11 @@
165269 }
165270 if( !IN_RENAME_OBJECT ){
165271 sqlite3DeleteTrigger(db, pParse->pNewTrigger);
165272 }
165273 sqlite3DbFree(db, pParse->pVList);
165274 db->pParse = pParse->pParentParse;
165275 pParse->pParentParse = 0;
165276 assert( nErr==0 || pParse->rc!=SQLITE_OK );
165277 return nErr;
165278 }
165279
165280
@@ -166939,11 +168305,13 @@
166939 ** if this is not the last copy of the function, do not invoke it. Multiple
166940 ** copies of a single function are created when create_function() is called
166941 ** with SQLITE_ANY as the encoding.
166942 */
166943 static void functionDestroy(sqlite3 *db, FuncDef *p){
166944 FuncDestructor *pDestructor = p->u.pDestructor;
 
 
166945 if( pDestructor ){
166946 pDestructor->nRef--;
166947 if( pDestructor->nRef==0 ){
166948 pDestructor->xDestroy(pDestructor->pUserData);
166949 sqlite3DbFree(db, pDestructor);
@@ -167202,10 +168570,13 @@
167202 ** So it needs to be freed here. Todo: Why not roll the temp schema into
167203 ** the same sqliteMalloc() as the one that allocates the database
167204 ** structure?
167205 */
167206 sqlite3DbFree(db, db->aDb[1].pSchema);
 
 
 
167207 sqlite3_mutex_leave(db->mutex);
167208 db->eOpenState = SQLITE_STATE_CLOSED;
167209 sqlite3_mutex_free(db->mutex);
167210 assert( sqlite3LookasideUsed(db,0)==0 );
167211 if( db->lookaside.bMalloced ){
@@ -167256,11 +168627,11 @@
167256 sqlite3BtreeLeaveAll(db);
167257
167258 /* Any deferred constraint violations have now been resolved. */
167259 db->nDeferredCons = 0;
167260 db->nDeferredImmCons = 0;
167261 db->flags &= ~(u64)SQLITE_DeferFKs;
167262
167263 /* If one has been configured, invoke the rollback-hook callback */
167264 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
167265 db->xRollbackCallback(db->pRollbackArg);
167266 }
@@ -167620,21 +168991,20 @@
167620 void (*xValue)(sqlite3_context*),
167621 void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
167622 FuncDestructor *pDestructor
167623 ){
167624 FuncDef *p;
167625 int nName;
167626 int extraFlags;
167627
167628 assert( sqlite3_mutex_held(db->mutex) );
167629 assert( xValue==0 || xSFunc==0 );
167630 if( zFunctionName==0 /* Must have a valid name */
167631 || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */
167632 || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */
167633 || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */
167634 || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
167635 || (255<(nName = sqlite3Strlen30( zFunctionName)))
167636 ){
167637 return SQLITE_MISUSE_BKPT;
167638 }
167639
167640 assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
@@ -168103,10 +169473,38 @@
168103 db->pPreUpdateArg = pArg;
168104 sqlite3_mutex_leave(db->mutex);
168105 return pRet;
168106 }
168107 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168108
168109 #ifndef SQLITE_OMIT_WAL
168110 /*
168111 ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
168112 ** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
@@ -168626,10 +170024,12 @@
168626 }
168627 oldLimit = db->aLimit[limitId];
168628 if( newLimit>=0 ){ /* IMP: R-52476-28732 */
168629 if( newLimit>aHardLimit[limitId] ){
168630 newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
 
 
168631 }
168632 db->aLimit[limitId] = newLimit;
168633 }
168634 return oldLimit; /* IMP: R-53341-35419 */
168635 }
@@ -168897,11 +170297,11 @@
168897 ** This routine does the core work of extracting URI parameters from a
168898 ** database filename for the sqlite3_uri_parameter() interface.
168899 */
168900 static const char *uriParameter(const char *zFilename, const char *zParam){
168901 zFilename += sqlite3Strlen30(zFilename) + 1;
168902 while( zFilename[0] ){
168903 int x = strcmp(zFilename, zParam);
168904 zFilename += sqlite3Strlen30(zFilename) + 1;
168905 if( x==0 ) return zFilename;
168906 zFilename += sqlite3Strlen30(zFilename) + 1;
168907 }
@@ -168957,14 +170357,15 @@
168957 **
168958 ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
168959 ** dealt with in the previous code block. Besides these, the only
168960 ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
168961 ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
168962 ** SQLITE_OPEN_PRIVATECACHE, and some reserved bits. Silently mask
168963 ** off all other flags.
168964 */
168965 flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
 
168966 SQLITE_OPEN_MAIN_DB |
168967 SQLITE_OPEN_TEMP_DB |
168968 SQLITE_OPEN_TRANSIENT_DB |
168969 SQLITE_OPEN_MAIN_JOURNAL |
168970 SQLITE_OPEN_TEMP_JOURNAL |
@@ -168992,11 +170393,11 @@
168992 if( isThreadsafe==0 ){
168993 sqlite3MutexWarnOnContention(db->mutex);
168994 }
168995 }
168996 sqlite3_mutex_enter(db->mutex);
168997 db->errMask = 0xff;
168998 db->nDb = 2;
168999 db->eOpenState = SQLITE_STATE_BUSY;
169000 db->aDb = db->aDbStatic;
169001 db->lookaside.bDisable = 1;
169002 db->lookaside.sz = 0;
@@ -169224,12 +170625,12 @@
169224 assert( db->mutex!=0 || isThreadsafe==0
169225 || sqlite3GlobalConfig.bFullMutex==0 );
169226 sqlite3_mutex_leave(db->mutex);
169227 }
169228 rc = sqlite3_errcode(db);
169229 assert( db!=0 || rc==SQLITE_NOMEM );
169230 if( rc==SQLITE_NOMEM ){
169231 sqlite3_close(db);
169232 db = 0;
169233 }else if( rc!=SQLITE_OK ){
169234 db->eOpenState = SQLITE_STATE_SICK;
169235 }
@@ -169240,11 +170641,11 @@
169240 void *pArg = sqlite3GlobalConfig.pSqllogArg;
169241 sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
169242 }
169243 #endif
169244 sqlite3_free_filename(zOpen);
169245 return rc & 0xff;
169246 }
169247
169248
169249 /*
169250 ** Open a new database handle.
@@ -170028,16 +171429,20 @@
170028 ** the schema to be reparsed the next time it is needed. This has the
170029 ** effect of erasing all imposter tables.
170030 */
170031 case SQLITE_TESTCTRL_IMPOSTER: {
170032 sqlite3 *db = va_arg(ap, sqlite3*);
 
170033 sqlite3_mutex_enter(db->mutex);
170034 db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
170035 db->init.busy = db->init.imposterTable = va_arg(ap,int);
170036 db->init.newTnum = va_arg(ap,int);
170037 if( db->init.busy==0 && db->init.newTnum>0 ){
170038 sqlite3ResetAllSchemasOfConnection(db);
 
 
 
170039 }
170040 sqlite3_mutex_leave(db->mutex);
170041 break;
170042 }
170043
@@ -170108,10 +171513,30 @@
170108 case 2: *ptr = sqlite3WhereTrace; break;
170109 case 3: sqlite3WhereTrace = *ptr; break;
170110 }
170111 break;
170112 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170113
170114 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
170115 /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue)
170116 **
170117 ** If "id" is an integer between 1 and SQLITE_NTUNE then set the value
@@ -170245,11 +171670,11 @@
170245 */
170246 SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){
170247 if( zFilename==0 || N<0 ) return 0;
170248 zFilename = databaseName(zFilename);
170249 zFilename += sqlite3Strlen30(zFilename) + 1;
170250 while( zFilename[0] && (N--)>0 ){
170251 zFilename += sqlite3Strlen30(zFilename) + 1;
170252 zFilename += sqlite3Strlen30(zFilename) + 1;
170253 }
170254 return zFilename[0] ? zFilename : 0;
170255 }
@@ -170295,11 +171720,11 @@
170295 }
170296 SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){
170297 if( zFilename==0 ) return 0;
170298 zFilename = databaseName(zFilename);
170299 zFilename += sqlite3Strlen30(zFilename) + 1;
170300 while( zFilename[0] ){
170301 zFilename += sqlite3Strlen30(zFilename) + 1;
170302 zFilename += sqlite3Strlen30(zFilename) + 1;
170303 }
170304 return zFilename + 1;
170305 }
@@ -171599,21 +173024,22 @@
171599 #ifndef SQLITE_AMALGAMATION
171600 /*
171601 ** Macros indicating that conditional expressions are always true or
171602 ** false.
171603 */
171604 #ifdef SQLITE_COVERAGE_TEST
171605 # define ALWAYS(x) (1)
171606 # define NEVER(X) (0)
171607 #elif defined(SQLITE_DEBUG)
171608 # define ALWAYS(x) sqlite3Fts3Always((x)!=0)
171609 # define NEVER(x) sqlite3Fts3Never((x)!=0)
171610 SQLITE_PRIVATE int sqlite3Fts3Always(int b);
171611 SQLITE_PRIVATE int sqlite3Fts3Never(int b);
 
171612 #else
171613 # define ALWAYS(x) (x)
171614 # define NEVER(x) (x)
171615 #endif
171616
171617 /*
171618 ** Internal types used by SQLite.
171619 */
@@ -172068,10 +173494,11 @@
172068 SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
172069 #ifdef SQLITE_TEST
172070 SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
172071 SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
172072 #endif
 
172073
172074 SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
172075 sqlite3_tokenizer_cursor **
172076 );
172077
@@ -172125,17 +173552,10 @@
172125 static int fts3EvalNext(Fts3Cursor *pCsr);
172126 static int fts3EvalStart(Fts3Cursor *pCsr);
172127 static int fts3TermSegReaderCursor(
172128 Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
172129
172130 #ifndef SQLITE_AMALGAMATION
172131 # if defined(SQLITE_DEBUG)
172132 SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; }
172133 SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; }
172134 # endif
172135 #endif
172136
172137 /*
172138 ** This variable is set to false when running tests for which the on disk
172139 ** structures should not be corrupt. Otherwise, true. If it is false, extra
172140 ** assert() conditions in the fts3 code are activated - conditions that are
172141 ** only true if it is guaranteed that the fts3 database is not corrupt.
@@ -177156,12 +178576,12 @@
177156 case FTSQUERY_OR: {
177157 Fts3Expr *pLeft = pExpr->pLeft;
177158 Fts3Expr *pRight = pExpr->pRight;
177159 sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
177160
177161 assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
177162 assert( pRight->bStart || pLeft->iDocid==pRight->iDocid );
177163
177164 if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
177165 fts3EvalNextRow(pCsr, pLeft, pRc);
177166 }else if( pLeft->bEof || iCmp>0 ){
177167 fts3EvalNextRow(pCsr, pRight, pRc);
@@ -177795,10 +179215,13 @@
177795 while( rc==SQLITE_OK && !pNear->bEof ){
177796 fts3EvalNextRow(pCsr, pNear, &rc);
177797 if( bEofSave==0 && pNear->iDocid==iDocid ) break;
177798 }
177799 assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
 
 
 
177800 }
177801 if( bTreeEof ){
177802 while( rc==SQLITE_OK && !pNear->bEof ){
177803 fts3EvalNextRow(pCsr, pNear, &rc);
177804 }
@@ -178217,10 +179640,11 @@
178217 }
178218
178219 if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM;
178220 memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat);
178221 iCol = 0;
 
178222
178223 while( i<nDoclist ){
178224 sqlite3_int64 v = 0;
178225
178226 i += sqlite3Fts3GetVarint(&aDoclist[i], &v);
@@ -178260,19 +179684,22 @@
178260 break;
178261
178262 /* State 3. The integer just read is a column number. */
178263 default: assert( eState==3 );
178264 iCol = (int)v;
 
 
 
 
178265 if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM;
178266 pCsr->aStat[iCol+1].nDoc++;
178267 eState = 2;
178268 break;
178269 }
178270 }
178271
178272 pCsr->iCol = 0;
178273 rc = SQLITE_OK;
178274 }else{
178275 pCsr->isEof = 1;
178276 }
178277 return rc;
178278 }
@@ -178597,11 +180024,11 @@
178597 /*
178598 ** Allocate nByte bytes of memory using sqlite3_malloc(). If successful,
178599 ** zero the memory before returning a pointer to it. If unsuccessful,
178600 ** return NULL.
178601 */
178602 static void *fts3MallocZero(sqlite3_int64 nByte){
178603 void *pRet = sqlite3_malloc64(nByte);
178604 if( pRet ) memset(pRet, 0, nByte);
178605 return pRet;
178606 }
178607
@@ -178678,11 +180105,11 @@
178678 sqlite3_int64 nByte; /* total space to allocate */
178679
178680 rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
178681 if( rc==SQLITE_OK ){
178682 nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
178683 pRet = (Fts3Expr *)fts3MallocZero(nByte);
178684 if( !pRet ){
178685 rc = SQLITE_NOMEM;
178686 }else{
178687 pRet->eType = FTSQUERY_PHRASE;
178688 pRet->pPhrase = (Fts3Phrase *)&pRet[1];
@@ -178933,11 +180360,11 @@
178933 */
178934 cNext = zInput[nKey];
178935 if( fts3isspace(cNext)
178936 || cNext=='"' || cNext=='(' || cNext==')' || cNext==0
178937 ){
178938 pRet = (Fts3Expr *)fts3MallocZero(sizeof(Fts3Expr));
178939 if( !pRet ){
178940 return SQLITE_NOMEM;
178941 }
178942 pRet->eType = pKey->eType;
178943 pRet->nNear = nNear;
@@ -179112,11 +180539,11 @@
179112
179113 if( !sqlite3_fts3_enable_parentheses
179114 && p->eType==FTSQUERY_PHRASE && pParse->isNot
179115 ){
179116 /* Create an implicit NOT operator. */
179117 Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr));
179118 if( !pNot ){
179119 sqlite3Fts3ExprFree(p);
179120 rc = SQLITE_NOMEM;
179121 goto exprparse_out;
179122 }
@@ -179146,11 +180573,11 @@
179146
179147 if( isPhrase && !isRequirePhrase ){
179148 /* Insert an implicit AND operator. */
179149 Fts3Expr *pAnd;
179150 assert( pRet && pPrev );
179151 pAnd = fts3MallocZero(sizeof(Fts3Expr));
179152 if( !pAnd ){
179153 sqlite3Fts3ExprFree(p);
179154 rc = SQLITE_NOMEM;
179155 goto exprparse_out;
179156 }
@@ -183376,12 +184803,22 @@
183376 pReader->aNode = 0;
183377 if( pElem ){
183378 char *aCopy;
183379 PendingList *pList = (PendingList *)fts3HashData(pElem);
183380 int nCopy = pList->nData+1;
183381 pReader->zTerm = (char *)fts3HashKey(pElem);
183382 pReader->nTerm = fts3HashKeysize(pElem);
 
 
 
 
 
 
 
 
 
 
183383 aCopy = (char*)sqlite3_malloc(nCopy);
183384 if( !aCopy ) return SQLITE_NOMEM;
183385 memcpy(aCopy, pList->aData, nCopy);
183386 pReader->nNode = pReader->nDoclist = nCopy;
183387 pReader->aNode = pReader->aDoclist = aCopy;
@@ -183630,13 +185067,11 @@
183630 ** Free all allocations associated with the iterator passed as the
183631 ** second argument.
183632 */
183633 SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
183634 if( pReader ){
183635 if( !fts3SegReaderIsPending(pReader) ){
183636 sqlite3_free(pReader->zTerm);
183637 }
183638 if( !fts3SegReaderIsRootOnly(pReader) ){
183639 sqlite3_free(pReader->aNode);
183640 }
183641 sqlite3_blob_close(pReader->pBlob);
183642 }
@@ -185824,11 +187259,11 @@
185824
185825 if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
185826 return FTS_CORRUPT_VTAB;
185827 }
185828 blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
185829 if( rc==SQLITE_OK ){
185830 memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
185831 p->term.n = nPrefix+nSuffix;
185832 p->iOff += nSuffix;
185833 if( p->iChild==0 ){
185834 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
@@ -186218,11 +187653,15 @@
186218 const char *zRhs, int nRhs /* RHS of comparison */
186219 ){
186220 int nCmp = MIN(nLhs, nRhs);
186221 int res;
186222
186223 res = (nCmp ? memcmp(zLhs, zRhs, nCmp) : 0);
 
 
 
 
186224 if( res==0 ) res = nLhs - nRhs;
186225
186226 return res;
186227 }
186228
@@ -186862,11 +188301,11 @@
186862 const char *aHint = sqlite3_column_blob(pSelect, 0);
186863 int nHint = sqlite3_column_bytes(pSelect, 0);
186864 if( aHint ){
186865 blobGrowBuffer(pHint, nHint, &rc);
186866 if( rc==SQLITE_OK ){
186867 memcpy(pHint->a, aHint, nHint);
186868 pHint->n = nHint;
186869 }
186870 }
186871 }
186872 rc2 = sqlite3_reset(pSelect);
@@ -187979,13 +189418,12 @@
187979 MatchinfoBuffer *pRet;
187980 sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
187981 + sizeof(MatchinfoBuffer);
187982 sqlite3_int64 nStr = strlen(zMatchinfo);
187983
187984 pRet = sqlite3_malloc64(nByte + nStr+1);
187985 if( pRet ){
187986 memset(pRet, 0, nByte);
187987 pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
187988 pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
187989 + sizeof(u32)*((int)nElem+1);
187990 pRet->nElem = (int)nElem;
187991 pRet->zMatchinfo = ((char*)pRet) + nByte;
@@ -188385,15 +189823,14 @@
188385
188386 /* Now that it is known how many phrases there are, allocate and zero
188387 ** the required space using malloc().
188388 */
188389 nByte = sizeof(SnippetPhrase) * nList;
188390 sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte);
188391 if( !sIter.aPhrase ){
188392 return SQLITE_NOMEM;
188393 }
188394 memset(sIter.aPhrase, 0, nByte);
188395
188396 /* Initialize the contents of the SnippetIter object. Then iterate through
188397 ** the set of phrases in the expression to populate the aPhrase[] array.
188398 */
188399 sIter.pCsr = pCsr;
@@ -188953,14 +190390,16 @@
188953 ** Advance the iterator passed as an argument to the next position. Return
188954 ** 1 if the iterator is at EOF or if it now points to the start of the
188955 ** position list for the next column.
188956 */
188957 static int fts3LcsIteratorAdvance(LcsIterator *pIter){
188958 char *pRead = pIter->pRead;
188959 sqlite3_int64 iRead;
188960 int rc = 0;
188961
 
 
188962 pRead += sqlite3Fts3GetVarint(pRead, &iRead);
188963 if( iRead==0 || iRead==1 ){
188964 pRead = 0;
188965 rc = 1;
188966 }else{
@@ -188990,13 +190429,12 @@
188990 int rc = SQLITE_OK;
188991
188992 /* Allocate and populate the array of LcsIterator objects. The array
188993 ** contains one element for each matchable phrase in the query.
188994 **/
188995 aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase);
188996 if( !aIter ) return SQLITE_NOMEM;
188997 memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase);
188998 (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
188999
189000 for(i=0; i<pInfo->nPhrase; i++){
189001 LcsIterator *pIter = &aIter[i];
189002 nToken -= pIter->pExpr->pPhrase->nToken;
@@ -189453,11 +190891,11 @@
189453 /* Count the number of terms in the query */
189454 rc = fts3ExprLoadDoclists(pCsr, 0, &nToken);
189455 if( rc!=SQLITE_OK ) goto offsets_out;
189456
189457 /* Allocate the array of TermOffset iterators. */
189458 sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken);
189459 if( 0==sCtx.aTerm ){
189460 rc = SQLITE_NOMEM;
189461 goto offsets_out;
189462 }
189463 sCtx.iDocid = pCsr->iPrevId;
@@ -189474,17 +190912,17 @@
189474 int iEnd = 0;
189475 int iCurrent = 0;
189476 const char *zDoc;
189477 int nDoc;
189478
189479 /* Initialize the contents of sCtx.aTerm[] for column iCol. There is
189480 ** no way that this operation can fail, so the return code from
189481 ** fts3ExprIterate() can be discarded.
189482 */
189483 sCtx.iCol = iCol;
189484 sCtx.iTerm = 0;
189485 (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
 
189486
189487 /* Retreive the text stored in column iCol. If an SQL NULL is stored
189488 ** in column iCol, jump immediately to the next iteration of the loop.
189489 ** If an OOM occurs while retrieving the data (this can happen if SQLite
189490 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -190478,11 +191916,38 @@
190478 ** but the definitions need to be repeated for separate compilation. */
190479 typedef sqlite3_uint64 u64;
190480 typedef unsigned int u32;
190481 typedef unsigned short int u16;
190482 typedef unsigned char u8;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190483 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
190484
190485 /* Objects */
190486 typedef struct JsonString JsonString;
190487 typedef struct JsonNode JsonNode;
190488 typedef struct JsonParse JsonParse;
@@ -190536,17 +192001,18 @@
190536 /* A single node of parsed JSON
190537 */
190538 struct JsonNode {
190539 u8 eType; /* One of the JSON_ type values */
190540 u8 jnFlags; /* JNODE flags */
 
190541 u32 n; /* Bytes of content, or number of sub-nodes */
190542 union {
190543 const char *zJContent; /* Content for INT, REAL, and STRING */
190544 u32 iAppend; /* More terms for ARRAY and OBJECT */
190545 u32 iKey; /* Key for ARRAY objects in json_tree() */
190546 u32 iReplace; /* Replacement content for JNODE_REPLACE */
190547 JsonNode *pPatch; /* Node chain of patch for JNODE_PATCH */
190548 } u;
190549 };
190550
190551 /* A completely parsed JSON string
190552 */
@@ -190820,15 +192286,18 @@
190820 static void jsonRenderNode(
190821 JsonNode *pNode, /* The node to render */
190822 JsonString *pOut, /* Write JSON here */
190823 sqlite3_value **aReplace /* Replacement values */
190824 ){
 
190825 if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
190826 if( pNode->jnFlags & JNODE_REPLACE ){
 
190827 jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
190828 return;
190829 }
 
190830 pNode = pNode->u.pPatch;
190831 }
190832 switch( pNode->eType ){
190833 default: {
190834 assert( pNode->eType==JSON_NULL );
@@ -190843,17 +192312,19 @@
190843 jsonAppendRaw(pOut, "false", 5);
190844 break;
190845 }
190846 case JSON_STRING: {
190847 if( pNode->jnFlags & JNODE_RAW ){
 
190848 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
190849 break;
190850 }
190851 /* no break */ deliberate_fall_through
190852 }
190853 case JSON_REAL:
190854 case JSON_INT: {
 
190855 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
190856 break;
190857 }
190858 case JSON_ARRAY: {
190859 u32 j = 1;
@@ -190865,10 +192336,11 @@
190865 jsonRenderNode(&pNode[j], pOut, aReplace);
190866 }
190867 j += jsonNodeSize(&pNode[j]);
190868 }
190869 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
 
190870 pNode = &pNode[pNode->u.iAppend];
190871 j = 1;
190872 }
190873 jsonAppendChar(pOut, ']');
190874 break;
@@ -190885,10 +192357,11 @@
190885 jsonRenderNode(&pNode[j+1], pOut, aReplace);
190886 }
190887 j += 1 + jsonNodeSize(&pNode[j+1]);
190888 }
190889 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
 
190890 pNode = &pNode[pNode->u.iAppend];
190891 j = 1;
190892 }
190893 jsonAppendChar(pOut, '}');
190894 break;
@@ -190964,11 +192437,13 @@
190964 sqlite3_result_int(pCtx, 0);
190965 break;
190966 }
190967 case JSON_INT: {
190968 sqlite3_int64 i = 0;
190969 const char *z = pNode->u.zJContent;
 
 
190970 if( z[0]=='-' ){ z++; }
190971 while( z[0]>='0' && z[0]<='9' ){
190972 unsigned v = *(z++) - '0';
190973 if( i>=LARGEST_INT64/10 ){
190974 if( i>LARGEST_INT64/10 ) goto int_as_real;
@@ -190992,13 +192467,16 @@
190992 int_as_real: ; /* no break */ deliberate_fall_through
190993 }
190994 case JSON_REAL: {
190995 double r;
190996 #ifdef SQLITE_AMALGAMATION
190997 const char *z = pNode->u.zJContent;
 
 
190998 sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
190999 #else
 
191000 r = strtod(pNode->u.zJContent, 0);
191001 #endif
191002 sqlite3_result_double(pCtx, r);
191003 break;
191004 }
@@ -191005,26 +192483,30 @@
191005 case JSON_STRING: {
191006 #if 0 /* Never happens because JNODE_RAW is only set by json_set(),
191007 ** json_insert() and json_replace() and those routines do not
191008 ** call jsonReturn() */
191009 if( pNode->jnFlags & JNODE_RAW ){
 
191010 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
191011 SQLITE_TRANSIENT);
191012 }else
191013 #endif
191014 assert( (pNode->jnFlags & JNODE_RAW)==0 );
191015 if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
191016 /* JSON formatted without any backslash-escapes */
 
191017 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
191018 SQLITE_TRANSIENT);
191019 }else{
191020 /* Translate JSON formatted string into raw text */
191021 u32 i;
191022 u32 n = pNode->n;
191023 const char *z = pNode->u.zJContent;
191024 char *zOut;
191025 u32 j;
 
 
191026 zOut = sqlite3_malloc( n+1 );
191027 if( zOut==0 ){
191028 sqlite3_result_error_nomem(pCtx);
191029 break;
191030 }
@@ -191141,16 +192623,17 @@
191141 u32 eType, /* Node type */
191142 u32 n, /* Content size or sub-node count */
191143 const char *zContent /* Content */
191144 ){
191145 JsonNode *p;
191146 if( pParse->nNode>=pParse->nAlloc ){
191147 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
191148 }
191149 p = &pParse->aNode[pParse->nNode];
191150 p->eType = (u8)eType;
191151 p->jnFlags = 0;
 
191152 p->n = n;
191153 p->u.zJContent = zContent;
191154 return pParse->nNode++;
191155 }
191156
@@ -191214,10 +192697,11 @@
191214 return j+1;
191215 }else if( c=='[' ){
191216 /* Parse array */
191217 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
191218 if( iThis<0 ) return -1;
 
191219 for(j=i+1;;j++){
191220 while( safe_isspace(z[j]) ){ j++; }
191221 if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
191222 x = jsonParseValue(pParse, j);
191223 pParse->iDepth--;
@@ -191478,10 +192962,11 @@
191478 /*
191479 ** Compare the OBJECT label at pNode against zKey,nKey. Return true on
191480 ** a match.
191481 */
191482 static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
 
191483 if( pNode->jnFlags & JNODE_RAW ){
191484 if( pNode->n!=nKey ) return 0;
191485 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
191486 }else{
191487 if( pNode->n!=nKey+2 ) return 0;
@@ -191543,10 +193028,11 @@
191543 }
191544 j++;
191545 j += jsonNodeSize(&pRoot[j]);
191546 }
191547 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
 
191548 iRoot += pRoot->u.iAppend;
191549 pRoot = &pParse->aNode[iRoot];
191550 j = 1;
191551 }
191552 if( pApnd ){
@@ -191557,12 +193043,14 @@
191557 zPath += i;
191558 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
191559 if( pParse->oom ) return 0;
191560 if( pNode ){
191561 pRoot = &pParse->aNode[iRoot];
 
191562 pRoot->u.iAppend = iStart - iRoot;
191563 pRoot->jnFlags |= JNODE_APPEND;
 
191564 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
191565 }
191566 return pNode;
191567 }
191568 }else if( zPath[0]=='[' ){
@@ -191581,10 +193069,11 @@
191581 while( j<=pBase->n ){
191582 if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
191583 j += jsonNodeSize(&pBase[j]);
191584 }
191585 if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
 
191586 iBase += pBase->u.iAppend;
191587 pBase = &pParse->aNode[iBase];
191588 j = 1;
191589 }
191590 j = 2;
@@ -191614,10 +193103,11 @@
191614 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
191615 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
191616 j += jsonNodeSize(&pRoot[j]);
191617 }
191618 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
 
191619 iRoot += pRoot->u.iAppend;
191620 pRoot = &pParse->aNode[iRoot];
191621 j = 1;
191622 }
191623 if( j<=pRoot->n ){
@@ -191629,12 +193119,14 @@
191629 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
191630 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
191631 if( pParse->oom ) return 0;
191632 if( pNode ){
191633 pRoot = &pParse->aNode[iRoot];
 
191634 pRoot->u.iAppend = iStart - iRoot;
191635 pRoot->jnFlags |= JNODE_APPEND;
 
191636 }
191637 return pNode;
191638 }
191639 }else{
191640 *pzErr = zPath;
@@ -191784,13 +193276,17 @@
191784 }else{
191785 zType = jsonType[x.aNode[i].eType];
191786 }
191787 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
191788 i, zType, x.aNode[i].n, x.aUp[i]);
 
191789 if( x.aNode[i].u.zJContent!=0 ){
 
191790 jsonAppendRaw(&s, " ", 1);
191791 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
 
 
191792 }
191793 jsonAppendRaw(&s, "\n", 1);
191794 }
191795 jsonParseReset(&x);
191796 jsonResult(&s);
@@ -191969,10 +193465,11 @@
191969 for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
191970 u32 nKey;
191971 const char *zKey;
191972 assert( pPatch[i].eType==JSON_STRING );
191973 assert( pPatch[i].jnFlags & JNODE_LABEL );
 
191974 nKey = pPatch[i].n;
191975 zKey = pPatch[i].u.zJContent;
191976 assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
191977 for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
191978 assert( pTarget[j].eType==JSON_STRING );
@@ -191985,10 +193482,16 @@
191985 }else{
191986 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
191987 if( pNew==0 ) return 0;
191988 pTarget = &pParse->aNode[iTarget];
191989 if( pNew!=&pTarget[j+1] ){
 
 
 
 
 
 
191990 pTarget[j+1].u.pPatch = pNew;
191991 pTarget[j+1].jnFlags |= JNODE_PATCH;
191992 }
191993 }
191994 break;
@@ -192000,13 +193503,18 @@
192000 jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
192001 iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
192002 if( pParse->oom ) return 0;
192003 jsonRemoveAllNulls(pPatch);
192004 pTarget = &pParse->aNode[iTarget];
 
 
192005 pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
 
192006 pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
192007 iRoot = iStart;
 
 
192008 pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
192009 pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
192010 }
192011 }
192012 return pTarget;
@@ -192144,15 +193652,19 @@
192144 for(i=1; i<(u32)argc; i+=2){
192145 zPath = (const char*)sqlite3_value_text(argv[i]);
192146 pNode = jsonLookup(&x, zPath, 0, ctx);
192147 if( x.nErr ) goto replace_err;
192148 if( pNode ){
 
 
192149 pNode->jnFlags |= (u8)JNODE_REPLACE;
 
192150 pNode->u.iReplace = i + 1;
192151 }
192152 }
192153 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
 
192154 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
192155 }else{
192156 jsonReturnJson(x.aNode, ctx, argv);
192157 }
192158 replace_err:
@@ -192198,15 +193710,19 @@
192198 sqlite3_result_error_nomem(ctx);
192199 goto jsonSetDone;
192200 }else if( x.nErr ){
192201 goto jsonSetDone;
192202 }else if( pNode && (bApnd || bIsSet) ){
 
 
 
192203 pNode->jnFlags |= (u8)JNODE_REPLACE;
192204 pNode->u.iReplace = i + 1;
192205 }
192206 }
192207 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
 
192208 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
192209 }else{
192210 jsonReturnJson(x.aNode, ctx, argv);
192211 }
192212 jsonSetDone:
@@ -192553,10 +194069,13 @@
192553 if( p->i<p->iEnd ){
192554 u32 iUp = p->sParse.aUp[p->i];
192555 JsonNode *pUp = &p->sParse.aNode[iUp];
192556 p->eType = pUp->eType;
192557 if( pUp->eType==JSON_ARRAY ){
 
 
 
192558 if( iUp==p->i-1 ){
192559 pUp->u.iKey = 0;
192560 }else{
192561 pUp->u.iKey++;
192562 }
@@ -192599,16 +194118,19 @@
192599 iUp = p->sParse.aUp[i];
192600 jsonEachComputePath(p, pStr, iUp);
192601 pNode = &p->sParse.aNode[i];
192602 pUp = &p->sParse.aNode[iUp];
192603 if( pUp->eType==JSON_ARRAY ){
 
 
192604 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
192605 }else{
192606 assert( pUp->eType==JSON_OBJECT );
192607 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
192608 assert( pNode->eType==JSON_STRING );
192609 assert( pNode->jnFlags & JNODE_LABEL );
 
192610 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
192611 }
192612 }
192613
192614 /* Return the value of a column */
@@ -192626,10 +194148,11 @@
192626 jsonReturn(pThis, ctx, 0);
192627 }else if( p->eType==JSON_ARRAY ){
192628 u32 iKey;
192629 if( p->bRecursive ){
192630 if( p->iRowid==0 ) break;
 
192631 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
192632 }else{
192633 iKey = p->iRowid;
192634 }
192635 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
@@ -192675,10 +194198,11 @@
192675 jsonAppendChar(&x, '$');
192676 }
192677 if( p->eType==JSON_ARRAY ){
192678 jsonPrintf(30, &x, "[%d]", p->iRowid);
192679 }else if( p->eType==JSON_OBJECT ){
 
192680 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
192681 }
192682 }
192683 jsonResult(&x);
192684 break;
@@ -192742,10 +194266,11 @@
192742 int iCol;
192743 int iMask;
192744 if( pConstraint->iColumn < JEACH_JSON ) continue;
192745 iCol = pConstraint->iColumn - JEACH_JSON;
192746 assert( iCol==0 || iCol==1 );
 
192747 iMask = 1 << iCol;
192748 if( pConstraint->usable==0 ){
192749 unusableMask |= iMask;
192750 }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
192751 aIdx[iCol] = i;
@@ -192839,10 +194364,12 @@
192839 pNode = p->sParse.aNode;
192840 }
192841 p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
192842 p->eType = pNode->eType;
192843 if( p->eType>=JSON_ARRAY ){
 
 
192844 pNode->u.iKey = 0;
192845 p->iEnd = p->i + pNode->n + 1;
192846 if( p->bRecursive ){
192847 p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
192848 if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
@@ -193099,10 +194626,13 @@
193099 #endif
193100 #if defined(NDEBUG) && defined(SQLITE_DEBUG)
193101 # undef NDEBUG
193102 #endif
193103 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
 
 
 
193104 # define ALWAYS(X) (1)
193105 # define NEVER(X) (0)
193106 #elif !defined(NDEBUG)
193107 # define ALWAYS(X) ((X)?1:(assert(0),0))
193108 # define NEVER(X) ((X)?(assert(0),1):0)
@@ -193450,11 +194980,16 @@
193450
193451 /* The testcase() macro should already be defined in the amalgamation. If
193452 ** it is not, make it a no-op.
193453 */
193454 #ifndef SQLITE_AMALGAMATION
193455 # define testcase(X)
 
 
 
 
 
193456 #endif
193457
193458 /*
193459 ** Make sure that the compiler intrinsics we desire are enabled when
193460 ** compiling with an appropriate version of MSVC unless prevented by
@@ -194296,24 +195831,33 @@
194296 || p->op==RTREE_FALSE );
194297 assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
194298 switch( p->op ){
194299 case RTREE_TRUE: return; /* Always satisfied */
194300 case RTREE_FALSE: break; /* Never satisfied */
194301 case RTREE_LE:
194302 case RTREE_LT:
194303 case RTREE_EQ:
194304 RTREE_DECODE_COORD(eInt, pCellData, val);
194305 /* val now holds the lower bound of the coordinate pair */
 
 
 
 
 
 
 
 
 
 
 
194306 if( p->u.rValue>=val ) return;
194307 if( p->op!=RTREE_EQ ) break; /* RTREE_LE and RTREE_LT end here */
194308 /* Fall through for the RTREE_EQ case */
194309
194310 default: /* RTREE_GT or RTREE_GE, or fallthrough of RTREE_EQ */
194311 pCellData += 4;
194312 RTREE_DECODE_COORD(eInt, pCellData, val);
194313 /* val now holds the upper bound of the coordinate pair */
194314 if( p->u.rValue<=val ) return;
 
194315 }
194316 *peWithin = NOT_WITHIN;
194317 }
194318
194319 /*
@@ -195214,11 +196758,11 @@
195214 RtreeDValue fMinGrowth = RTREE_ZERO;
195215 RtreeDValue fMinArea = RTREE_ZERO;
195216
195217 int nCell = NCELL(pNode);
195218 RtreeCell cell;
195219 RtreeNode *pChild;
195220
195221 RtreeCell *aCell = 0;
195222
195223 /* Select the child node which will be enlarged the least if pCell
195224 ** is inserted into it. Resolve ties by choosing the entry with
@@ -195572,10 +197116,11 @@
195572 nodeRelease(pRtree, pChild->pParent);
195573 nodeReference(pNode);
195574 pChild->pParent = pNode;
195575 }
195576 }
 
195577 return xSetMapping(pRtree, iRowid, pNode->iNode);
195578 }
195579
195580 static int SplitNode(
195581 Rtree *pRtree,
@@ -196876,10 +198421,11 @@
196876 tree.nDim = (u8)sqlite3_value_int(apArg[0]);
196877 if( tree.nDim<1 || tree.nDim>5 ) return;
196878 tree.nDim2 = tree.nDim*2;
196879 tree.nBytesPerCell = 8 + 8 * tree.nDim;
196880 node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
 
196881 nData = sqlite3_value_bytes(apArg[1]);
196882 if( nData<4 ) return;
196883 if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
196884
196885 pOut = sqlite3_str_new(0);
@@ -197707,17 +199253,18 @@
197707 sqlite3_value *pVal, /* The value to decode */
197708 int *pRc /* Write error here */
197709 ){
197710 GeoPoly *p = 0;
197711 int nByte;
 
197712 if( sqlite3_value_type(pVal)==SQLITE_BLOB
197713 && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
197714 ){
197715 const unsigned char *a = sqlite3_value_blob(pVal);
197716 int nVertex;
197717 if( a==0 ){
197718 sqlite3_result_error_nomem(pCtx);
197719 return 0;
197720 }
197721 nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
197722 if( (a[0]==0 || a[0]==1)
197723 && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
@@ -198540,15 +200087,15 @@
198540 pActive = pSeg;
198541 needSort = 1;
198542 }else{
198543 /* Remove a segment */
198544 if( pActive==pThisEvent->pSeg ){
198545 pActive = pActive->pNext;
198546 }else{
198547 for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
198548 if( pSeg->pNext==pThisEvent->pSeg ){
198549 pSeg->pNext = pSeg->pNext->pNext;
198550 break;
198551 }
198552 }
198553 }
198554 }
@@ -198788,10 +200335,11 @@
198788 rc = nodeAcquire(pRtree, 1, 0, &pRoot);
198789 if( rc==SQLITE_OK && idxNum<=3 ){
198790 RtreeCoord bbox[4];
198791 RtreeConstraint *p;
198792 assert( argc==1 );
 
198793 geopolyBBox(0, argv[0], bbox, &rc);
198794 if( rc ){
198795 goto geopoly_filter_end;
198796 }
198797 pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
@@ -199015,10 +200563,11 @@
199015 if( nData>1 /* not a DELETE */
199016 && (!oldRowidValid /* INSERT */
199017 || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */
199018 || oldRowid!=newRowid) /* Rowid change */
199019 ){
 
199020 geopolyBBox(0, aData[2], cell.aCoord, &rc);
199021 if( rc ){
199022 if( rc==SQLITE_ERROR ){
199023 pVtab->zErrMsg =
199024 sqlite3_mprintf("_shape does not contain a valid polygon");
@@ -200941,10 +202490,17 @@
200941 ** Swap two objects of type TYPE.
200942 */
200943 #if !defined(SQLITE_AMALGAMATION)
200944 # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
200945 #endif
 
 
 
 
 
 
 
200946
200947 /*
200948 ** The rbu_state table is used to save the state of a partially applied
200949 ** update so that it can be resumed later. The table consists of integer
200950 ** keys mapped to values as follows:
@@ -202388,11 +203944,11 @@
202388 **
202389 ** If the expression cannot be created, NULL is returned. In this case,
202390 ** the caller has to use an OFFSET clause to extract only the required
202391 ** rows from the sourct table, just as it does for an RBU update operation.
202392 */
202393 char *rbuVacuumIndexStart(
202394 sqlite3rbu *p, /* RBU handle */
202395 RbuObjIter *pIter /* RBU iterator object */
202396 ){
202397 char *zOrder = 0;
202398 char *zLhs = 0;
@@ -203588,17 +205144,23 @@
203588
203589
203590 /*
203591 ** Open the database handle and attach the RBU database as "rbu". If an
203592 ** error occurs, leave an error code and message in the RBU handle.
 
 
 
 
203593 */
203594 static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){
203595 assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
203596 assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
 
203597
203598 /* Open the RBU database */
203599 p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
 
203600
203601 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
203602 sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
203603 if( p->zState==0 ){
203604 const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -203960,19 +205522,35 @@
203960 p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
203961 }
203962
203963
203964 /*
203965 ** Take an EXCLUSIVE lock on the database file.
 
203966 */
203967 static void rbuLockDatabase(sqlite3rbu *p){
203968 sqlite3_file *pReal = p->pTargetFd->pReal;
203969 assert( p->rc==SQLITE_OK );
203970 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
203971 if( p->rc==SQLITE_OK ){
203972 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
 
 
 
 
203973 }
 
 
 
 
 
 
 
 
 
 
 
203974 }
203975
203976 #if defined(_WIN32_WCE)
203977 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
203978 int nChar;
@@ -204026,22 +205604,28 @@
204026 ** in WAL mode). So no other connection may be writing the db.
204027 **
204028 ** In order to ensure that there are no database readers, an EXCLUSIVE
204029 ** lock is obtained here before the *-oal is moved to *-wal.
204030 */
204031 rbuLockDatabase(p);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204032 if( p->rc==SQLITE_OK ){
204033 rbuFileSuffix3(zBase, zWal);
204034 rbuFileSuffix3(zBase, zOal);
204035
204036 /* Re-open the databases. */
204037 rbuObjIterFinalize(&p->objiter);
204038 sqlite3_close(p->dbRbu);
204039 sqlite3_close(p->dbMain);
204040 p->dbMain = 0;
204041 p->dbRbu = 0;
204042
204043 #if defined(_WIN32_WCE)
204044 {
204045 LPWSTR zWideOal;
204046 LPWSTR zWideWal;
204047
@@ -204064,15 +205648,23 @@
204064 }
204065 }
204066 #else
204067 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
204068 #endif
 
204069
204070 if( p->rc==SQLITE_OK ){
204071 rbuOpenDatabase(p, 0);
204072 rbuSetupCheckpoint(p, 0);
204073 }
 
 
 
 
 
 
 
204074 }
204075 }
204076
204077 sqlite3_free(zWal);
204078 sqlite3_free(zOal);
@@ -204819,13 +206411,13 @@
204819 ** to be a wal-mode db. But, this may have happened due to an earlier
204820 ** RBU vacuum operation leaving an old wal file in the directory.
204821 ** If this is the case, it will have been checkpointed and deleted
204822 ** when the handle was closed and a second attempt to open the
204823 ** database may succeed. */
204824 rbuOpenDatabase(p, &bRetry);
204825 if( bRetry ){
204826 rbuOpenDatabase(p, 0);
204827 }
204828 }
204829
204830 if( p->rc==SQLITE_OK ){
204831 pState = rbuLoadState(p);
@@ -204916,10 +206508,18 @@
204916 }
204917 }
204918 }else if( p->eStage==RBU_STAGE_MOVE ){
204919 /* no-op */
204920 }else if( p->eStage==RBU_STAGE_CKPT ){
 
 
 
 
 
 
 
 
204921 rbuSetupCheckpoint(p, pState);
204922 }else if( p->eStage==RBU_STAGE_DONE ){
204923 p->rc = SQLITE_DONE;
204924 }else{
204925 p->rc = SQLITE_CORRUPT;
@@ -204953,11 +206553,10 @@
204953 const char *zTarget,
204954 const char *zRbu,
204955 const char *zState
204956 ){
204957 if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
204958 /* TODO: Check that zTarget and zRbu are non-NULL */
204959 return openRbuHandle(zTarget, zRbu, zState);
204960 }
204961
204962 /*
204963 ** Open a handle to begin or resume an RBU VACUUM operation.
@@ -207873,11 +209472,11 @@
207873 if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
207874 nVarint = sessionVarintLen(n);
207875
207876 if( aBuf ){
207877 sessionVarintPut(&aBuf[1], n);
207878 if( n ) memcpy(&aBuf[nVarint + 1], z, n);
207879 }
207880
207881 nByte = 1 + nVarint + n;
207882 break;
207883 }
@@ -208478,20 +210077,36 @@
208478 "SELECT 2, 'stat', '', 0, '', 0"
208479 );
208480 }else if( rc==SQLITE_ERROR ){
208481 zPragma = sqlite3_mprintf("");
208482 }else{
 
 
 
 
208483 return rc;
208484 }
208485 }else{
208486 zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
208487 }
208488 if( !zPragma ) return SQLITE_NOMEM;
 
 
 
 
 
 
208489
208490 rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
208491 sqlite3_free(zPragma);
208492 if( rc!=SQLITE_OK ) return rc;
 
 
 
 
 
 
208493
208494 nByte = nThis + 1;
208495 while( SQLITE_ROW==sqlite3_step(pStmt) ){
208496 nByte += sqlite3_column_bytes(pStmt, 1);
208497 nDbCol++;
@@ -208905,11 +210520,15 @@
208905 if( pSession->xTableFilter==0
208906 || pSession->xTableFilter(pSession->pFilterCtx, zName)
208907 ){
208908 rc = sqlite3session_attach(pSession, zName);
208909 if( rc==SQLITE_OK ){
208910 for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext);
 
 
 
 
208911 assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
208912 }
208913 }
208914 }
208915
@@ -209678,10 +211297,11 @@
209678 int bNoop = 1; /* Set to zero if any values are modified */
209679 int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
209680 int i; /* Used to iterate through columns */
209681 u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
209682
 
209683 sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
209684 sessionAppendByte(pBuf, p->bIndirect, &rc);
209685 for(i=0; i<sqlite3_column_count(pStmt); i++){
209686 int bChanged = 0;
209687 int nAdvance;
@@ -209982,16 +211602,18 @@
209982 sqlite3 *db = pSession->db; /* Source database handle */
209983 SessionTable *pTab; /* Used to iterate through attached tables */
209984 SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
209985 int rc; /* Return code */
209986
209987 assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) );
 
209988
209989 /* Zero the output variables in case an error occurs. If this session
209990 ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
209991 ** this call will be a no-op. */
209992 if( xOutput==0 ){
 
209993 *pnChangeset = 0;
209994 *ppChangeset = 0;
209995 }
209996
209997 if( pSession->rc ) return pSession->rc;
@@ -210001,12 +211623,12 @@
210001 sqlite3_mutex_enter(sqlite3_db_mutex(db));
210002
210003 for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
210004 if( pTab->nEntry ){
210005 const char *zName = pTab->zName;
210006 int nCol; /* Number of columns in table */
210007 u8 *abPK; /* Primary key array */
210008 const char **azCol = 0; /* Table columns */
210009 int i; /* Used to iterate through hash buckets */
210010 sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
210011 int nRewind = buf.nBuf; /* Initial size of write buffer */
210012 int nNoop; /* Size of buffer after writing tbl header */
@@ -210040,10 +211662,11 @@
210040 sessionAppendByte(&buf, p->bIndirect, &rc);
210041 for(iCol=0; iCol<nCol; iCol++){
210042 sessionAppendCol(&buf, pSel, iCol, &rc);
210043 }
210044 }else{
 
210045 rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
210046 }
210047 }else if( p->op!=SQLITE_INSERT ){
210048 rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
210049 }
@@ -210100,11 +211723,14 @@
210100 SQLITE_API int sqlite3session_changeset(
210101 sqlite3_session *pSession, /* Session object */
210102 int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
210103 void **ppChangeset /* OUT: Buffer containing changeset */
210104 ){
210105 int rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset);
 
 
 
210106 assert( rc || pnChangeset==0
210107 || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
210108 );
210109 return rc;
210110 }
@@ -210115,10 +211741,11 @@
210115 SQLITE_API int sqlite3session_changeset_strm(
210116 sqlite3_session *pSession,
210117 int (*xOutput)(void *pOut, const void *pData, int nData),
210118 void *pOut
210119 ){
 
210120 return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
210121 }
210122
210123 /*
210124 ** Streaming version of sqlite3session_patchset().
@@ -210126,10 +211753,11 @@
210126 SQLITE_API int sqlite3session_patchset_strm(
210127 sqlite3_session *pSession,
210128 int (*xOutput)(void *pOut, const void *pData, int nData),
210129 void *pOut
210130 ){
 
210131 return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
210132 }
210133
210134 /*
210135 ** Obtain a patchset object containing all changes recorded by the
@@ -210141,10 +211769,11 @@
210141 SQLITE_API int sqlite3session_patchset(
210142 sqlite3_session *pSession, /* Session object */
210143 int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
210144 void **ppPatchset /* OUT: Buffer containing changeset */
210145 ){
 
210146 return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
210147 }
210148
210149 /*
210150 ** Enable or disable the session object passed as the first argument.
@@ -211104,15 +212733,15 @@
211104 if( rc!=SQLITE_OK ) goto finished_invert;
211105 }
211106 }
211107
211108 assert( rc==SQLITE_OK );
211109 if( pnInverted ){
211110 *pnInverted = sOut.nBuf;
211111 *ppInverted = sOut.aBuf;
211112 sOut.aBuf = 0;
211113 }else if( sOut.nBuf>0 ){
211114 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
211115 }
211116
211117 finished_invert:
211118 sqlite3_free(sOut.aBuf);
@@ -211564,11 +213193,11 @@
211564 ** in the code below. */
211565 assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
211566
211567 for(i=0; rc==SQLITE_OK && i<nCol; i++){
211568 if( !abPK || abPK[i] ){
211569 sqlite3_value *pVal;
211570 (void)xValue(pIter, i, &pVal);
211571 if( pVal==0 ){
211572 /* The value in the changeset was "undefined". This indicates a
211573 ** corrupt changeset blob. */
211574 rc = SQLITE_CORRUPT_BKPT;
@@ -212707,13 +214336,13 @@
212707 }
212708
212709 if( rc==SQLITE_OK ){
212710 if( xOutput ){
212711 if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
212712 }else{
212713 *ppOut = buf.aBuf;
212714 *pnOut = buf.nBuf;
212715 buf.aBuf = 0;
212716 }
212717 }
212718 sqlite3_free(buf.aBuf);
212719
@@ -213109,11 +214738,11 @@
213109 if( rc==SQLITE_OK ){
213110 if( xOutput ){
213111 if( sOut.nBuf>0 ){
213112 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
213113 }
213114 }else{
213115 *ppOut = (void*)sOut.aBuf;
213116 *pnOut = sOut.nBuf;
213117 sOut.aBuf = 0;
213118 }
213119 }
@@ -213852,12 +215481,24 @@
213852 #ifndef ArraySize
213853 # define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
213854 #endif
213855
213856 #define testcase(x)
213857 #define ALWAYS(x) 1
213858 #define NEVER(x) 0
 
 
 
 
 
 
 
 
 
 
 
 
213859
213860 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
213861 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
213862
213863 /*
@@ -213913,11 +215554,11 @@
213913
213914 /*
213915 ** A version of memcmp() that does not cause asan errors if one of the pointer
213916 ** parameters is NULL and the number of bytes to compare is zero.
213917 */
213918 #define fts5Memcmp(s1, s2, n) ((n)==0 ? 0 : memcmp((s1), (s2), (n)))
213919
213920 /* Mark a function parameter as unused, to suppress nuisance compiler
213921 ** warnings. */
213922 #ifndef UNUSED_PARAM
213923 # define UNUSED_PARAM(X) (void)(X)
@@ -215032,13 +216673,13 @@
215032 fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
215033 #endif
215034 };
215035 typedef struct fts5yyParser fts5yyParser;
215036
215037 #ifndef NDEBUG
215038 /* #include <stdio.h> */
215039 /* #include <assert.h> */
 
 
215040 static FILE *fts5yyTraceFILE = 0;
215041 static char *fts5yyTracePrompt = 0;
215042 #endif /* NDEBUG */
215043
215044 #ifndef NDEBUG
@@ -215971,12 +217612,12 @@
215971 assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
215972 assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
215973 fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
215974 if( fts5yyact >= fts5YY_MIN_REDUCE ){
215975 unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
215976 assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
215977 #ifndef NDEBUG
 
215978 if( fts5yyTraceFILE ){
215979 int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
215980 if( fts5yysize ){
215981 fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
215982 fts5yyTracePrompt,
@@ -216939,11 +218580,10 @@
216939 int *pRc,
216940 Fts5Buffer *pBuf,
216941 u32 nData,
216942 const u8 *pData
216943 ){
216944 assert_nc( *pRc || nData>=0 );
216945 if( nData ){
216946 if( fts5BufferGrow(pRc, pBuf, nData) ) return;
216947 memcpy(&pBuf->p[pBuf->n], pData, nData);
216948 pBuf->n += nData;
216949 }
@@ -217051,11 +218691,10 @@
217051 return 1;
217052 }else{
217053 i64 iOff = *piOff;
217054 u32 iVal;
217055 fts5FastGetVarint32(a, i, iVal);
217056 assert( iVal>=0 );
217057 if( iVal<=1 ){
217058 if( iVal==0 ){
217059 *pi = i;
217060 return 0;
217061 }
@@ -217846,10 +219485,11 @@
217846
217847 z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
217848 z = fts5ConfigSkipWhitespace(z);
217849 if( z && *z=='=' ){
217850 bOption = 1;
 
217851 z++;
217852 if( bMustBeCol ) z = 0;
217853 }
217854 z = fts5ConfigSkipWhitespace(z);
217855 if( z && z[0] ){
@@ -217862,11 +219502,15 @@
217862 if( z==0 ){
217863 *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
217864 rc = SQLITE_ERROR;
217865 }else{
217866 if( bOption ){
217867 rc = fts5ConfigParseSpecial(pGlobal, pRet, zOne, zTwo?zTwo:"", pzErr);
 
 
 
 
217868 }else{
217869 rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
217870 zOne = 0;
217871 }
217872 }
@@ -218679,10 +220323,11 @@
218679 static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
218680 i64 iRet = 0;
218681 int bRetValid = 0;
218682 Fts5ExprTerm *p;
218683
 
218684 assert( pTerm->pSynonym );
218685 assert( bDesc==0 || bDesc==1 );
218686 for(p=pTerm; p; p=p->pSynonym){
218687 if( 0==sqlite3Fts5IterEof(p->pIter) ){
218688 i64 iRowid = p->pIter->iRowid;
@@ -220119,11 +221764,11 @@
220119 /* This happens when parsing a token or quoted phrase that contains
220120 ** no token characters at all. (e.g ... MATCH '""'). */
220121 sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
220122 }
220123
220124 if( rc==SQLITE_OK ){
220125 /* All the allocations succeeded. Put the expression object together. */
220126 pNew->pIndex = pExpr->pIndex;
220127 pNew->pConfig = pExpr->pConfig;
220128 pNew->nPhrase = 1;
220129 pNew->apExprPhrase[0] = sCtx.pPhrase;
@@ -221100,20 +222745,29 @@
221100 Fts5PoslistWriter writer;
221101 int bOk; /* True if ok to populate */
221102 int bMiss;
221103 };
221104
 
 
 
 
 
 
 
 
 
221105 static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
221106 Fts5PoslistPopulator *pRet;
221107 pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221108 if( pRet ){
221109 int i;
221110 memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
221111 for(i=0; i<pExpr->nPhrase; i++){
221112 Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
221113 Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
221114 assert( pExpr->apExprPhrase[i]->nTerm==1 );
221115 if( bLive &&
221116 (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
221117 ){
221118 pRet[i].bMiss = 1;
221119 }else{
@@ -221660,11 +223314,11 @@
221660 if( iCol>=0 ){
221661 if( pHash->eDetail==FTS5_DETAIL_NONE ){
221662 p->bContent = 1;
221663 }else{
221664 /* Append a new column value, if necessary */
221665 assert( iCol>=p->iCol );
221666 if( iCol!=p->iCol ){
221667 if( pHash->eDetail==FTS5_DETAIL_FULL ){
221668 pPtr[p->nData++] = 0x01;
221669 p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
221670 p->iCol = (i16)iCol;
@@ -222465,12 +224119,15 @@
222465 ** +ve if pRight is smaller than pLeft. In other words:
222466 **
222467 ** res = *pLeft - *pRight
222468 */
222469 static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
222470 int nCmp = MIN(pLeft->n, pRight->n);
222471 int res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
 
 
 
222472 return (res==0 ? (pLeft->n - pRight->n) : res);
222473 }
222474
222475 static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
222476 int ret;
@@ -222712,11 +224369,11 @@
222712 ** an error occurs, (*pRc) is set to an SQLite error code before returning.
222713 */
222714 static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
222715 Fts5Structure *p = *pp;
222716 if( *pRc==SQLITE_OK && p->nRef>1 ){
222717 int nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
222718 Fts5Structure *pNew;
222719 pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
222720 if( pNew ){
222721 int i;
222722 memcpy(pNew, p, nByte);
@@ -223638,10 +225295,11 @@
223638 fts5SegIterNextPage(p, pIter);
223639 }
223640
223641 if( p->rc==SQLITE_OK ){
223642 pIter->iLeafOffset = 4;
 
223643 assert_nc( pIter->pLeaf->nn>4 );
223644 assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
223645 pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
223646 fts5SegIterLoadTerm(p, pIter, 0);
223647 fts5SegIterLoadNPos(p, pIter);
@@ -223740,12 +225398,16 @@
223740 }
223741 }else{
223742 int iRowidOff;
223743 iRowidOff = fts5LeafFirstRowidOff(pNew);
223744 if( iRowidOff ){
223745 pIter->pLeaf = pNew;
223746 pIter->iLeafOffset = iRowidOff;
 
 
 
 
223747 }
223748 }
223749
223750 if( pIter->pLeaf ){
223751 u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
@@ -224142,25 +225804,24 @@
224142 Fts5Index *p, /* Leave any error code here */
224143 int bGe, /* True for a >= search */
224144 Fts5SegIter *pIter, /* Iterator to seek */
224145 const u8 *pTerm, int nTerm /* Term to search for */
224146 ){
224147 int iOff;
224148 const u8 *a = pIter->pLeaf->p;
224149 int szLeaf = pIter->pLeaf->szLeaf;
224150 int n = pIter->pLeaf->nn;
224151
224152 u32 nMatch = 0;
224153 u32 nKeep = 0;
224154 u32 nNew = 0;
224155 u32 iTermOff;
224156 int iPgidx; /* Current offset in pgidx */
224157 int bEndOfPage = 0;
224158
224159 assert( p->rc==SQLITE_OK );
224160
224161 iPgidx = szLeaf;
224162 iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
224163 iOff = iTermOff;
224164 if( iOff>n ){
224165 p->rc = FTS5_CORRUPT;
224166 return;
@@ -224222,19 +225883,19 @@
224222 do {
224223 fts5SegIterNextPage(p, pIter);
224224 if( pIter->pLeaf==0 ) return;
224225 a = pIter->pLeaf->p;
224226 if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
224227 iPgidx = pIter->pLeaf->szLeaf;
224228 iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
224229 if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
224230 p->rc = FTS5_CORRUPT;
224231 return;
224232 }else{
224233 nKeep = 0;
224234 iTermOff = iOff;
224235 n = pIter->pLeaf->nn;
224236 iOff += fts5GetVarint32(&a[iOff], nNew);
224237 break;
224238 }
224239 }
224240 }while( 1 );
@@ -224598,11 +226259,11 @@
224598 pIter->pNextLeaf = 0;
224599 pIter->iLeafPgno = iLeafPgno-1;
224600 fts5SegIterNextPage(p, pIter);
224601 assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
224602
224603 if( p->rc==SQLITE_OK ){
224604 int iOff;
224605 u8 *a = pIter->pLeaf->p;
224606 int n = pIter->pLeaf->szLeaf;
224607
224608 iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
@@ -225030,11 +226691,15 @@
225030 Fts5Index *p,
225031 Fts5SegIter *pSeg,
225032 Fts5Colset *pColset,
225033 Fts5Buffer *pBuf
225034 ){
 
 
225035 if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
 
 
225036 memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
225037 if( pColset==0 ){
225038 fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
225039 }else{
225040 if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){
@@ -225254,10 +226919,11 @@
225254 pIter->base.nData = pIter->poslist.n;
225255 }
225256 }
225257
225258 static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
 
225259 if( *pRc==SQLITE_OK ){
225260 Fts5Config *pConfig = pIter->pIndex->pConfig;
225261 if( pConfig->eDetail==FTS5_DETAIL_NONE ){
225262 pIter->xSetOutputs = fts5IterSetOutputs_None;
225263 }
@@ -225325,11 +226991,14 @@
225325 }else{
225326 nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
225327 }
225328 }
225329 *ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
225330 if( pNew==0 ) return;
 
 
 
225331 pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
225332 pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
225333 pNew->pColset = pColset;
225334 if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
225335 fts5IterSetOutputCb(&p->rc, pNew);
@@ -225389,10 +227058,14 @@
225389
225390 }else{
225391 fts5MultiIterFree(pNew);
225392 *ppOut = 0;
225393 }
 
 
 
 
225394 }
225395
225396 /*
225397 ** Create an Fts5Iter that iterates through the doclist provided
225398 ** as the second argument.
@@ -225436,11 +227109,12 @@
225436 /*
225437 ** Return true if the iterator is at EOF or if an error has occurred.
225438 ** False otherwise.
225439 */
225440 static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
225441 assert( p->rc
 
225442 || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof
225443 );
225444 return (p->rc || pIter->base.bEof);
225445 }
225446
@@ -226240,10 +227914,11 @@
226240
226241 /* Flush the last leaf page to disk. Set the output segment b-tree height
226242 ** and last leaf page number at the same time. */
226243 fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
226244
 
226245 if( fts5MultiIterEof(p, pIter) ){
226246 int i;
226247
226248 /* Remove the redundant segments from the %_data table */
226249 for(i=0; i<nInput; i++){
@@ -226340,11 +228015,11 @@
226340 static void fts5IndexAutomerge(
226341 Fts5Index *p, /* FTS5 backend object */
226342 Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
226343 int nLeaf /* Number of output leaves just written */
226344 ){
226345 if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 ){
226346 Fts5Structure *pStruct = *ppStruct;
226347 u64 nWrite; /* Initial value of write-counter */
226348 int nWork; /* Number of work-quanta to perform */
226349 int nRem; /* Number of leaf pages left to write */
226350
@@ -227450,15 +229125,19 @@
227450 }
227451 }else{
227452 /* Scan multiple terms in the main index */
227453 int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
227454 fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
227455 assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
227456 fts5IterSetOutputCb(&p->rc, pRet);
227457 if( p->rc==SQLITE_OK ){
227458 Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
227459 if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
 
 
 
 
227460 }
227461 }
227462
227463 if( p->rc ){
227464 sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
@@ -227702,11 +229381,11 @@
227702 int eDetail = p->pConfig->eDetail;
227703 u64 cksum = *pCksum;
227704 Fts5IndexIter *pIter = 0;
227705 int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
227706
227707 while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
227708 i64 rowid = pIter->iRowid;
227709
227710 if( eDetail==FTS5_DETAIL_NONE ){
227711 cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
227712 }else{
@@ -228067,10 +229746,11 @@
228067 int eDetail = p->pConfig->eDetail;
228068 u64 cksum2 = 0; /* Checksum based on contents of indexes */
228069 Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
228070 Fts5Iter *pIter; /* Used to iterate through entire index */
228071 Fts5Structure *pStruct; /* Index structure */
 
228072
228073 #ifdef SQLITE_DEBUG
228074 /* Used by extra internal tests only run if NDEBUG is not defined */
228075 u64 cksum3 = 0; /* Checksum based on contents of indexes */
228076 Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
@@ -228077,19 +229757,20 @@
228077 #endif
228078 const int flags = FTS5INDEX_QUERY_NOOUTPUT;
228079
228080 /* Load the FTS index structure */
228081 pStruct = fts5StructureRead(p);
 
 
 
 
228082
228083 /* Check that the internal nodes of each segment match the leaves */
228084 if( pStruct ){
228085 int iLvl, iSeg;
228086 for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
228087 for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
228088 Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
228089 fts5IndexIntegrityCheckSegment(p, pSeg);
228090 }
228091 }
228092 }
228093
228094 /* The cksum argument passed to this function is a checksum calculated
228095 ** based on all expected entries in the FTS index (including prefix index
@@ -230032,11 +231713,12 @@
230032 pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
230033 rc = sqlite3Fts5StorageStmt(
230034 pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
230035 );
230036 if( rc==SQLITE_OK ){
230037 if( pCsr->ePlan==FTS5_PLAN_ROWID ){
 
230038 sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
230039 }else{
230040 sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
230041 sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
230042 }
@@ -231450,11 +233132,11 @@
231450 int nArg, /* Number of args */
231451 sqlite3_value **apUnused /* Function arguments */
231452 ){
231453 assert( nArg==0 );
231454 UNUSED_PARAM2(nArg, apUnused);
231455 sqlite3_result_text(pCtx, "fts5: 2021-10-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813", -1, SQLITE_TRANSIENT);
231456 }
231457
231458 /*
231459 ** Return true if zName is the extension on one of the shadow tables used
231460 ** by this module.
@@ -232001,16 +233683,20 @@
232001 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
232002 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
232003 if( pConfig->abUnindexed[iCol-1]==0 ){
232004 const char *zText;
232005 int nText;
 
 
232006 if( pSeek ){
232007 zText = (const char*)sqlite3_column_text(pSeek, iCol);
232008 nText = sqlite3_column_bytes(pSeek, iCol);
232009 }else{
232010 zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
232011 nText = sqlite3_value_bytes(apVal[iCol-1]);
 
 
232012 }
232013 ctx.szCol = 0;
232014 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
232015 zText, nText, (void*)&ctx, fts5StorageInsertCallback
232016 );
@@ -232642,12 +234328,13 @@
232642 sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
232643 int rc; /* Return Code */
232644
232645 assert( p->pConfig->bColumnsize );
232646 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
232647 if( rc==SQLITE_OK ){
232648 int bCorrupt = 1;
 
232649 sqlite3_bind_int64(pLookup, 1, iRowid);
232650 if( SQLITE_ROW==sqlite3_step(pLookup) ){
232651 const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
232652 int nBlob = sqlite3_column_bytes(pLookup, 0);
232653 if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
@@ -232656,10 +234343,12 @@
232656 }
232657 rc = sqlite3_reset(pLookup);
232658 if( bCorrupt && rc==SQLITE_OK ){
232659 rc = FTS5_CORRUPT;
232660 }
 
 
232661 }
232662
232663 return rc;
232664 }
232665
@@ -235660,11 +237349,11 @@
235660 rc = sqlite3Fts5FlushToDisk(pFts5);
235661 }
235662 }
235663
235664 if( rc==SQLITE_OK ){
235665 int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
235666 pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
235667 }
235668
235669 if( pCsr ){
235670 pCsr->pFts5 = pFts5;
235671
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -1,8 +1,8 @@
1 /******************************************************************************
2 ** This file is an amalgamation of many separate C source files from SQLite
3 ** version 3.38.0. By combining all the individual C code files into this
4 ** single large file, the entire code can be compiled as a single translation
5 ** unit. This allows many compilers to do optimizations that would not be
6 ** possible if the files were compiled separately. Performance improvements
7 ** of 5% or more are commonly seen when SQLite is compiled as a single
8 ** translation unit.
@@ -450,13 +450,13 @@
450 **
451 ** See also: [sqlite3_libversion()],
452 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
453 ** [sqlite_version()] and [sqlite_source_id()].
454 */
455 #define SQLITE_VERSION "3.38.0"
456 #define SQLITE_VERSION_NUMBER 3038000
457 #define SQLITE_SOURCE_ID "2021-12-09 20:06:18 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882"
458
459 /*
460 ** CAPI3REF: Run-Time Library Version Numbers
461 ** KEYWORDS: sqlite3_version sqlite3_sourceid
462 **
@@ -843,11 +843,10 @@
843 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
844 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
845 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
846 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
847 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
 
848 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
849 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
850 #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
851 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
852 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -879,10 +878,23 @@
878 ** CAPI3REF: Flags For File Open Operations
879 **
880 ** These bit values are intended for use in the
881 ** 3rd parameter to the [sqlite3_open_v2()] interface and
882 ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
883 **
884 ** Only those flags marked as "Ok for sqlite3_open_v2()" may be
885 ** used as the third argument to the [sqlite3_open_v2()] interface.
886 ** The other flags have historically been ignored by sqlite3_open_v2(),
887 ** though future versions of SQLite might change so that an error is
888 ** raised if any of the disallowed bits are passed into sqlite3_open_v2().
889 ** Applications should not depend on the historical behavior.
890 **
891 ** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into
892 ** [sqlite3_open_v2()] does *not* cause the underlying database file
893 ** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into
894 ** [sqlite3_open_v2()] has historically be a no-op and might become an
895 ** error in future versions of SQLite.
896 */
897 #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
898 #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
899 #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
900 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
@@ -901,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
@@ -3720,25 +3733,35 @@
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 **
3751 ** If the 3rd parameter to sqlite3_open_v2() is not one of the
3752 ** required combinations shown above optionally combined with other
3753 ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
3754 ** then the behavior is undefined. Historic versions of SQLite
3755 ** have silently ignored surplus bits in the flags parameter to
3756 ** sqlite3_open_v2(), however that behavior might not be carried through
3757 ** into future versions of SQLite and so applications should not rely
3758 ** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op
3759 ** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause
3760 ** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE
3761 ** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not
3762 ** by sqlite3_open_v2().
3763 **
3764 ** ^The fourth parameter to sqlite3_open_v2() is the name of the
3765 ** [sqlite3_vfs] object that defines the operating system interface that
3766 ** the new database connection should use. ^If the fourth parameter is
3767 ** a NULL pointer then the default [sqlite3_vfs] object is used.
@@ -6695,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 **
@@ -8159,11 +8248,12 @@
8248 #define SQLITE_TESTCTRL_PRNG_SEED 28
8249 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
8250 #define SQLITE_TESTCTRL_SEEK_COUNT 30
8251 #define SQLITE_TESTCTRL_TRACEFLAGS 31
8252 #define SQLITE_TESTCTRL_TUNE 32
8253 #define SQLITE_TESTCTRL_LOGEST 33
8254 #define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */
8255
8256 /*
8257 ** CAPI3REF: SQL Keyword Checking
8258 **
8259 ** These routines provide access to the set of SQL language keywords
@@ -8681,10 +8771,20 @@
8771 ** <dd>^This is the number of times that the prepared statement has
8772 ** been run. A single "run" for the purposes of this counter is one
8773 ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
8774 ** The counter is incremented on the first [sqlite3_step()] call of each
8775 ** cycle.
8776 **
8777 ** [[SQLITE_STMTSTATUS_FILTER_MISS]]
8778 ** [[SQLITE_STMTSTATUS_FILTER HIT]]
8779 ** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br>
8780 ** SQLITE_STMTSTATUS_FILTER_MISS</dt>
8781 ** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join
8782 ** step was bypassed because a Bloom filter returned not-found. The
8783 ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of
8784 ** times that the Bloom filter returned a find, and thus the join step
8785 ** had to be processed as normal.
8786 **
8787 ** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
8788 ** <dd>^This is the approximate number of bytes of heap memory
8789 ** used to store the prepared statement. ^This value is not actually
8790 ** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -8696,10 +8796,12 @@
8796 #define SQLITE_STMTSTATUS_SORT 2
8797 #define SQLITE_STMTSTATUS_AUTOINDEX 3
8798 #define SQLITE_STMTSTATUS_VM_STEP 4
8799 #define SQLITE_STMTSTATUS_REPREPARE 5
8800 #define SQLITE_STMTSTATUS_RUN 6
8801 #define SQLITE_STMTSTATUS_FILTER_MISS 7
8802 #define SQLITE_STMTSTATUS_FILTER_HIT 8
8803 #define SQLITE_STMTSTATUS_MEMUSED 99
8804
8805 /*
8806 ** CAPI3REF: Custom Page Cache Object
8807 **
@@ -13160,15 +13262,16 @@
13262 ** can be used to make sure boundary values are tested. For
13263 ** bitmask tests, testcase() can be used to make sure each bit
13264 ** is significant and used at least once. On switch statements
13265 ** where multiple cases go to the same block of code, testcase()
13266 ** can insure that all cases are evaluated.
 
13267 */
13268 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
13269 # ifndef SQLITE_AMALGAMATION
13270 extern unsigned int sqlite3CoverageCounter;
13271 # endif
13272 # define testcase(X) if( X ){ sqlite3CoverageCounter += (unsigned)__LINE__; }
13273 #else
13274 # define testcase(X)
13275 #endif
13276
13277 /*
@@ -13194,10 +13297,18 @@
13297 # define VVA_ONLY(X) X
13298 #else
13299 # define VVA_ONLY(X)
13300 #endif
13301
13302 /*
13303 ** Disable ALWAYS() and NEVER() (make them pass-throughs) for coverage
13304 ** and mutation testing
13305 */
13306 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
13307 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
13308 #endif
13309
13310 /*
13311 ** The ALWAYS and NEVER macros surround boolean expressions which
13312 ** are intended to always be true or false, respectively. Such
13313 ** expressions could be omitted from the code completely. But they
13314 ** are included in a few cases in order to enhance the resilience
@@ -13209,11 +13320,11 @@
13320 **
13321 ** When doing coverage testing ALWAYS and NEVER are hard-coded to
13322 ** be true and false so that the unreachable code they specify will
13323 ** not be counted as untested code.
13324 */
13325 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
13326 # define ALWAYS(X) (1)
13327 # define NEVER(X) (0)
13328 #elif !defined(NDEBUG)
13329 # define ALWAYS(X) ((X)?1:(assert(0),0))
13330 # define NEVER(X) ((X)?(assert(0),1):0)
@@ -13220,30 +13331,10 @@
13331 #else
13332 # define ALWAYS(X) (X)
13333 # define NEVER(X) (X)
13334 #endif
13335
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13336 /*
13337 ** Some conditionals are optimizations only. In other words, if the
13338 ** conditionals are replaced with a constant 1 (true) or 0 (false) then
13339 ** the correct answer is still obtained, though perhaps not as quickly.
13340 **
@@ -13422,11 +13513,11 @@
13513 /* #define sqliteHashKeysize(E) ((E)->nKey) // NOT USED */
13514
13515 /*
13516 ** Number of entries in a hash table
13517 */
13518 #define sqliteHashCount(H) ((H)->count)
13519
13520 #endif /* SQLITE_HASH_H */
13521
13522 /************** End of hash.h ************************************************/
13523 /************** Continuing where we left off in sqliteInt.h ******************/
@@ -13474,14 +13565,14 @@
13565 #define TK_DETACH 40
13566 #define TK_EACH 41
13567 #define TK_FAIL 42
13568 #define TK_OR 43
13569 #define TK_AND 44
13570 #define TK_MATCH 45
13571 #define TK_LIKE_KW 46
13572 #define TK_BETWEEN 47
13573 #define TK_IS 48
13574 #define TK_IN 49
13575 #define TK_ISNULL 50
13576 #define TK_NOTNULL 51
13577 #define TK_NE 52
13578 #define TK_EQ 53
@@ -13718,11 +13809,11 @@
13809 ** The default initial allocation for the pagecache when using separate
13810 ** pagecaches for each database connection. A positive number is the
13811 ** number of pages. A negative number N translations means that a buffer
13812 ** of -1024*N bytes is allocated and used for as many pages as it will hold.
13813 **
13814 ** The default value of "20" was chosen to minimize the run-time of the
13815 ** speedtest1 test program with options: --shrink-memory --reprepare
13816 */
13817 #ifndef SQLITE_DEFAULT_PCACHE_INITSZ
13818 # define SQLITE_DEFAULT_PCACHE_INITSZ 20
13819 #endif
@@ -14075,15 +14166,29 @@
14166 int nBusy; /* Incremented with each busy call */
14167 };
14168
14169 /*
14170 ** Name of table that holds the database schema.
14171 **
14172 ** The PREFERRED names are used whereever possible. But LEGACY is also
14173 ** used for backwards compatibility.
14174 **
14175 ** 1. Queries can use either the PREFERRED or the LEGACY names
14176 ** 2. The sqlite3_set_authorizer() callback uses the LEGACY name
14177 ** 3. The PRAGMA table_list statement uses the PREFERRED name
14178 **
14179 ** The LEGACY names are stored in the internal symbol hash table
14180 ** in support of (2). Names are translated using sqlite3PreferredTableName()
14181 ** for (3). The sqlite3FindTable() function takes care of translating
14182 ** names for (1).
14183 **
14184 ** Note that "sqlite_temp_schema" can also be called "temp.sqlite_schema".
14185 */
14186 #define LEGACY_SCHEMA_TABLE "sqlite_master"
14187 #define LEGACY_TEMP_SCHEMA_TABLE "sqlite_temp_master"
14188 #define PREFERRED_SCHEMA_TABLE "sqlite_schema"
14189 #define PREFERRED_TEMP_SCHEMA_TABLE "sqlite_temp_schema"
14190
14191
14192 /*
14193 ** The root-page of the schema table.
14194 */
@@ -14091,11 +14196,11 @@
14196
14197 /*
14198 ** The name of the schema table. The name is different for TEMP.
14199 */
14200 #define SCHEMA_TABLE(x) \
14201 ((!OMIT_TEMPDB)&&(x==1)?LEGACY_TEMP_SCHEMA_TABLE:LEGACY_SCHEMA_TABLE)
14202
14203 /*
14204 ** A convenience macro that returns the number of elements in
14205 ** an array.
14206 */
@@ -15159,49 +15264,49 @@
15264 #define OP_ElseEq 58 /* jump, same as TK_ESCAPE */
15265 #define OP_IfNotZero 59 /* jump, synopsis: if r[P1]!=0 then r[P1]--, goto P2 */
15266 #define OP_DecrJumpZero 60 /* jump, synopsis: if (--r[P1])==0 goto P2 */
15267 #define OP_IncrVacuum 61 /* jump */
15268 #define OP_VNext 62 /* jump */
15269 #define OP_Filter 63 /* jump, synopsis: if key(P3@P4) not in filter(P1) goto P2 */
15270 #define OP_Init 64 /* jump, synopsis: Start at P2 */
15271 #define OP_PureFunc 65 /* synopsis: r[P3]=func(r[P2@NP]) */
15272 #define OP_Function 66 /* synopsis: r[P3]=func(r[P2@NP]) */
15273 #define OP_Return 67
15274 #define OP_EndCoroutine 68
15275 #define OP_HaltIfNull 69 /* synopsis: if r[P3]=null halt */
15276 #define OP_Halt 70
15277 #define OP_Integer 71 /* synopsis: r[P2]=P1 */
15278 #define OP_Int64 72 /* synopsis: r[P2]=P4 */
15279 #define OP_String 73 /* synopsis: r[P2]='P4' (len=P1) */
15280 #define OP_Null 74 /* synopsis: r[P2..P3]=NULL */
15281 #define OP_SoftNull 75 /* synopsis: r[P1]=NULL */
15282 #define OP_Blob 76 /* synopsis: r[P2]=P4 (len=P1) */
15283 #define OP_Variable 77 /* synopsis: r[P2]=parameter(P1,P4) */
15284 #define OP_Move 78 /* synopsis: r[P2@P3]=r[P1@P3] */
15285 #define OP_Copy 79 /* synopsis: r[P2@P3+1]=r[P1@P3+1] */
15286 #define OP_SCopy 80 /* synopsis: r[P2]=r[P1] */
15287 #define OP_IntCopy 81 /* synopsis: r[P2]=r[P1] */
15288 #define OP_FkCheck 82
15289 #define OP_ResultRow 83 /* synopsis: output=r[P1@P2] */
15290 #define OP_CollSeq 84
15291 #define OP_AddImm 85 /* synopsis: r[P1]=r[P1]+P2 */
15292 #define OP_RealAffinity 86
15293 #define OP_Cast 87 /* synopsis: affinity(r[P1]) */
15294 #define OP_Permutation 88
15295 #define OP_Compare 89 /* synopsis: r[P1@P3] <-> r[P2@P3] */
15296 #define OP_IsTrue 90 /* synopsis: r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4 */
15297 #define OP_ZeroOrNull 91 /* synopsis: r[P2] = 0 OR NULL */
15298 #define OP_Offset 92 /* synopsis: r[P3] = sqlite_offset(P1) */
15299 #define OP_Column 93 /* synopsis: r[P3]=PX */
15300 #define OP_TypeCheck 94 /* synopsis: typecheck(r[P1@P2]) */
15301 #define OP_Affinity 95 /* synopsis: affinity(r[P1@P2]) */
15302 #define OP_MakeRecord 96 /* synopsis: r[P3]=mkrec(r[P1@P2]) */
15303 #define OP_Count 97 /* synopsis: r[P2]=count() */
15304 #define OP_ReadCookie 98
15305 #define OP_SetCookie 99
15306 #define OP_ReopenIdx 100 /* synopsis: root=P2 iDb=P3 */
15307 #define OP_OpenRead 101 /* synopsis: root=P2 iDb=P3 */
15308 #define OP_BitAnd 102 /* same as TK_BITAND, synopsis: r[P3]=r[P1]&r[P2] */
15309 #define OP_BitOr 103 /* same as TK_BITOR, synopsis: r[P3]=r[P1]|r[P2] */
15310 #define OP_ShiftLeft 104 /* same as TK_LSHIFT, synopsis: r[P3]=r[P2]<<r[P1] */
15311 #define OP_ShiftRight 105 /* same as TK_RSHIFT, synopsis: r[P3]=r[P2]>>r[P1] */
15312 #define OP_Add 106 /* same as TK_PLUS, synopsis: r[P3]=r[P1]+r[P2] */
@@ -15208,80 +15313,82 @@
15313 #define OP_Subtract 107 /* same as TK_MINUS, synopsis: r[P3]=r[P2]-r[P1] */
15314 #define OP_Multiply 108 /* same as TK_STAR, synopsis: r[P3]=r[P1]*r[P2] */
15315 #define OP_Divide 109 /* same as TK_SLASH, synopsis: r[P3]=r[P2]/r[P1] */
15316 #define OP_Remainder 110 /* same as TK_REM, synopsis: r[P3]=r[P2]%r[P1] */
15317 #define OP_Concat 111 /* same as TK_CONCAT, synopsis: r[P3]=r[P2]+r[P1] */
15318 #define OP_OpenWrite 112 /* synopsis: root=P2 iDb=P3 */
15319 #define OP_BitNot 113 /* same as TK_BITNOT, synopsis: r[P2]= ~r[P1] */
15320 #define OP_OpenDup 114
15321 #define OP_OpenAutoindex 115 /* synopsis: nColumn=P2 */
15322 #define OP_String8 116 /* same as TK_STRING, synopsis: r[P2]='P4' */
15323 #define OP_OpenEphemeral 117 /* synopsis: nColumn=P2 */
15324 #define OP_SorterOpen 118
15325 #define OP_SequenceTest 119 /* synopsis: if( cursor[P1].ctr++ ) pc = P2 */
15326 #define OP_OpenPseudo 120 /* synopsis: P3 columns in r[P2] */
15327 #define OP_Close 121
15328 #define OP_ColumnsUsed 122
15329 #define OP_SeekScan 123 /* synopsis: Scan-ahead up to P1 rows */
15330 #define OP_SeekHit 124 /* synopsis: set P2<=seekHit<=P3 */
15331 #define OP_Sequence 125 /* synopsis: r[P2]=cursor[P1].ctr++ */
15332 #define OP_NewRowid 126 /* synopsis: r[P2]=rowid */
15333 #define OP_Insert 127 /* synopsis: intkey=r[P3] data=r[P2] */
15334 #define OP_RowCell 128
15335 #define OP_Delete 129
15336 #define OP_ResetCount 130
15337 #define OP_SorterCompare 131 /* synopsis: if key(P1)!=trim(r[P3],P4) goto P2 */
15338 #define OP_SorterData 132 /* synopsis: r[P2]=data */
15339 #define OP_RowData 133 /* synopsis: r[P2]=data */
15340 #define OP_Rowid 134 /* synopsis: r[P2]=rowid */
15341 #define OP_NullRow 135
15342 #define OP_SeekEnd 136
15343 #define OP_IdxInsert 137 /* synopsis: key=r[P2] */
15344 #define OP_SorterInsert 138 /* synopsis: key=r[P2] */
15345 #define OP_IdxDelete 139 /* synopsis: key=r[P2@P3] */
15346 #define OP_DeferredSeek 140 /* synopsis: Move P3 to P1.rowid if needed */
15347 #define OP_IdxRowid 141 /* synopsis: r[P2]=rowid */
15348 #define OP_FinishSeek 142
15349 #define OP_Destroy 143
15350 #define OP_Clear 144
15351 #define OP_ResetSorter 145
15352 #define OP_CreateBtree 146 /* synopsis: r[P2]=root iDb=P1 flags=P3 */
15353 #define OP_SqlExec 147
15354 #define OP_ParseSchema 148
15355 #define OP_LoadAnalysis 149
15356 #define OP_DropTable 150
15357 #define OP_DropIndex 151
15358 #define OP_Real 152 /* same as TK_FLOAT, synopsis: r[P2]=P4 */
15359 #define OP_DropTrigger 153
15360 #define OP_IntegrityCk 154
15361 #define OP_RowSetAdd 155 /* synopsis: rowset(P1)=r[P2] */
15362 #define OP_Param 156
15363 #define OP_FkCounter 157 /* synopsis: fkctr[P1]+=P2 */
15364 #define OP_MemMax 158 /* synopsis: r[P1]=max(r[P1],r[P2]) */
15365 #define OP_OffsetLimit 159 /* synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1) */
15366 #define OP_AggInverse 160 /* synopsis: accum=r[P3] inverse(r[P2@P5]) */
15367 #define OP_AggStep 161 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15368 #define OP_AggStep1 162 /* synopsis: accum=r[P3] step(r[P2@P5]) */
15369 #define OP_AggValue 163 /* synopsis: r[P3]=value N=P2 */
15370 #define OP_AggFinal 164 /* synopsis: accum=r[P1] N=P2 */
15371 #define OP_Expire 165
15372 #define OP_CursorLock 166
15373 #define OP_CursorUnlock 167
15374 #define OP_TableLock 168 /* synopsis: iDb=P1 root=P2 write=P3 */
15375 #define OP_VBegin 169
15376 #define OP_VCreate 170
15377 #define OP_VDestroy 171
15378 #define OP_VOpen 172
15379 #define OP_VColumn 173 /* synopsis: r[P3]=vcolumn(P2) */
15380 #define OP_VRename 174
15381 #define OP_Pagecount 175
15382 #define OP_MaxPgcnt 176
15383 #define OP_FilterAdd 177 /* synopsis: filter(P1) += key(P3@P4) */
15384 #define OP_Trace 178
15385 #define OP_CursorHint 179
15386 #define OP_ReleaseReg 180 /* synopsis: release r[P1@P2] mask P3 */
15387 #define OP_Noop 181
15388 #define OP_Explain 182
15389 #define OP_Abortable 183
15390
15391 /* Properties such as "out2" or "jump" that are specified in
15392 ** comments following the "case" for each opcode in the vdbe.c
15393 ** are encoded into bitvectors as follows:
15394 */
@@ -15298,33 +15405,34 @@
15405 /* 24 */ 0x09, 0x09, 0x09, 0x01, 0x09, 0x09, 0x09, 0x09,\
15406 /* 32 */ 0x09, 0x09, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,\
15407 /* 40 */ 0x01, 0x01, 0x01, 0x26, 0x26, 0x23, 0x0b, 0x01,\
15408 /* 48 */ 0x01, 0x03, 0x03, 0x03, 0x0b, 0x0b, 0x0b, 0x0b,\
15409 /* 56 */ 0x0b, 0x0b, 0x01, 0x03, 0x03, 0x01, 0x01, 0x01,\
15410 /* 64 */ 0x01, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x10,\
15411 /* 72 */ 0x10, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x00,\
15412 /* 80 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x02, 0x02, 0x02,\
15413 /* 88 */ 0x00, 0x00, 0x12, 0x1e, 0x20, 0x00, 0x00, 0x00,\
15414 /* 96 */ 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x26, 0x26,\
15415 /* 104 */ 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,\
15416 /* 112 */ 0x00, 0x12, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,\
15417 /* 120 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00,\
15418 /* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,\
15419 /* 136 */ 0x00, 0x04, 0x04, 0x00, 0x00, 0x10, 0x00, 0x10,\
15420 /* 144 */ 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,\
15421 /* 152 */ 0x10, 0x00, 0x00, 0x06, 0x10, 0x00, 0x04, 0x1a,\
15422 /* 160 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15423 /* 168 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,\
15424 /* 176 */ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
15425 }
15426
15427 /* The resolve3P2Values() routine is able to run faster if it knows
15428 ** the value of the largest JUMP opcode. The smaller the maximum
15429 ** JUMP opcode the better, so the mkopcodeh.tcl script that
15430 ** generated this include file strives to group all JUMP opcodes
15431 ** together near the beginning of the list.
15432 */
15433 #define SQLITE_MX_JUMP_OPCODE 64 /* Maximum JUMP opcode */
15434
15435 /************** End of opcodes.h *********************************************/
15436 /************** Continuing where we left off in vdbe.h ***********************/
15437
15438 /*
@@ -16420,14 +16528,14 @@
16528 int nVdbeExec; /* Number of nested calls to VdbeExec() */
16529 int nVDestroy; /* Number of active OP_VDestroy operations */
16530 int nExtension; /* Number of loaded extensions */
16531 void **aExtension; /* Array of shared library handles */
16532 union {
16533 void (*xLegacy)(void*,const char*); /* mTrace==SQLITE_TRACE_LEGACY */
16534 int (*xV2)(u32,void*,void*,void*); /* All other mTrace values */
16535 } trace;
16536 void *pTraceArg; /* Argument to the trace function */
16537 #ifndef SQLITE_OMIT_DEPRECATED
16538 void (*xProfile)(void*,const char*,u64); /* Profiling function */
16539 void *pProfileArg; /* Argument to profile function */
16540 #endif
16541 void *pCommitArg; /* Argument to xCommitCallback() */
@@ -16434,10 +16542,13 @@
16542 int (*xCommitCallback)(void*); /* Invoked at every commit. */
16543 void *pRollbackArg; /* Argument to xRollbackCallback() */
16544 void (*xRollbackCallback)(void*); /* Invoked at every commit. */
16545 void *pUpdateArg;
16546 void (*xUpdateCallback)(void*,int, const char*,const char*,sqlite_int64);
16547 void *pAutovacPagesArg; /* Client argument to autovac_pages */
16548 void (*xAutovacDestr)(void*); /* Destructor for pAutovacPAgesArg */
16549 unsigned int (*xAutovacPages)(void*,const char*,u32,u32,u32);
16550 Parse *pParse; /* Current parse */
16551 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
16552 void *pPreUpdateArg; /* First argument to xPreUpdateCallback */
16553 void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */
16554 void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64
@@ -16563,10 +16674,11 @@
16674 #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/
16675 #define SQLITE_EnableView 0x80000000 /* Enable the use of views */
16676 #define SQLITE_CountRows HI(0x00001) /* Count rows changed by INSERT, */
16677 /* DELETE, or UPDATE and return */
16678 /* the count using a callback. */
16679 #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */
16680
16681 /* Flags used only if debugging */
16682 #ifdef SQLITE_DEBUG
16683 #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */
16684 #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */
@@ -16611,10 +16723,12 @@
16723 #define SQLITE_PropagateConst 0x00008000 /* The constant propagation opt */
16724 #define SQLITE_MinMaxOpt 0x00010000 /* The min/max optimization */
16725 #define SQLITE_SeekScan 0x00020000 /* The OP_SeekScan optimization */
16726 #define SQLITE_OmitOrderBy 0x00040000 /* Omit pointless ORDER BY */
16727 /* TH3 expects this value ^^^^^^^^^^ to be 0x40000. Coordinate any change */
16728 #define SQLITE_BloomFilter 0x00080000 /* Use a Bloom filter on searches */
16729 #define SQLITE_BloomPulldown 0x00100000 /* Run Bloom filters early */
16730 #define SQLITE_AllOpts 0xffffffff /* All optimizations */
16731
16732 /*
16733 ** Macros for testing whether or not optimizations are enabled or disabled.
16734 */
@@ -16659,11 +16773,11 @@
16773 void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */
16774 const char *zName; /* SQL name of the function. */
16775 union {
16776 FuncDef *pHash; /* Next with a different name but the same hash */
16777 FuncDestructor *pDestructor; /* Reference counted destructor function */
16778 } u; /* pHash if SQLITE_FUNC_BUILTIN, pDestructor otherwise */
16779 };
16780
16781 /*
16782 ** This structure encapsulates a user-function destructor callback (as
16783 ** configured using create_function_v2()) and a reference counter. When
@@ -16720,10 +16834,11 @@
16834 #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
16835 #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */
16836 #define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */
16837 #define SQLITE_FUNC_UNSAFE 0x00200000 /* Function has side effects */
16838 #define SQLITE_FUNC_INLINE 0x00400000 /* Functions implemented in-line */
16839 #define SQLITE_FUNC_BUILTIN 0x00800000 /* This is a built-in function */
16840 #define SQLITE_FUNC_ANYORDER 0x08000000 /* count/min/max aggregate */
16841
16842 /* Identifier numbers for each in-line function */
16843 #define INLINEFUNC_coalesce 0
16844 #define INLINEFUNC_implies_nonnull_row 1
@@ -16798,48 +16913,55 @@
16913 ** available as the function user-data (sqlite3_user_data()). The
16914 ** FuncDef.flags variable is set to the value passed as the flags
16915 ** parameter.
16916 */
16917 #define FUNCTION(zName, nArg, iArg, bNC, xFunc) \
16918 {nArg, SQLITE_FUNC_BUILTIN|\
16919 SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16920 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16921 #define VFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16922 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16923 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16924 #define SFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16925 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_DIRECTONLY|SQLITE_FUNC_UNSAFE, \
16926 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16927 #define MFUNCTION(zName, nArg, xPtr, xFunc) \
16928 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8, \
16929 xPtr, 0, xFunc, 0, 0, 0, #zName, {0} }
16930 #define INLINE_FUNC(zName, nArg, iArg, mFlags) \
16931 {nArg, SQLITE_FUNC_BUILTIN|\
16932 SQLITE_UTF8|SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
16933 SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
16934 #define TEST_FUNC(zName, nArg, iArg, mFlags) \
16935 {nArg, SQLITE_FUNC_BUILTIN|\
16936 SQLITE_UTF8|SQLITE_FUNC_INTERNAL|SQLITE_FUNC_TEST| \
16937 SQLITE_FUNC_INLINE|SQLITE_FUNC_CONSTANT|(mFlags), \
16938 SQLITE_INT_TO_PTR(iArg), 0, noopFunc, 0, 0, 0, #zName, {0} }
16939 #define DFUNCTION(zName, nArg, iArg, bNC, xFunc) \
16940 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_SLOCHNG|SQLITE_UTF8, \
16941 0, 0, xFunc, 0, 0, 0, #zName, {0} }
16942 #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \
16943 {nArg, SQLITE_FUNC_BUILTIN|\
16944 SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
16945 (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} }
16946 #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \
16947 {nArg, SQLITE_FUNC_BUILTIN|\
16948 SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\
16949 SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} }
16950 #define STR_FUNCTION(zName, nArg, pArg, bNC, xFunc) \
16951 {nArg, SQLITE_FUNC_BUILTIN|\
16952 SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL), \
16953 pArg, 0, xFunc, 0, 0, 0, #zName, }
16954 #define LIKEFUNC(zName, nArg, arg, flags) \
16955 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_FUNC_CONSTANT|SQLITE_UTF8|flags, \
16956 (void *)arg, 0, likeFunc, 0, 0, 0, #zName, {0} }
16957 #define WAGGREGATE(zName, nArg, arg, nc, xStep, xFinal, xValue, xInverse, f) \
16958 {nArg, SQLITE_FUNC_BUILTIN|SQLITE_UTF8|(nc*SQLITE_FUNC_NEEDCOLL)|f, \
16959 SQLITE_INT_TO_PTR(arg), 0, xStep,xFinal,xValue,xInverse,#zName, {0}}
16960 #define INTERNAL_FUNCTION(zName, nArg, xFunc) \
16961 {nArg, SQLITE_FUNC_BUILTIN|\
16962 SQLITE_FUNC_INTERNAL|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \
16963 0, 0, xFunc, 0, 0, 0, #zName, {0} }
16964
16965
16966 /*
16967 ** All current savepoints are stored in a linked list starting at
@@ -17558,14 +17680,14 @@
17680 ** code representing the ">=" operator. This same integer code is reused
17681 ** to represent the greater-than-or-equal-to operator in the expression
17682 ** tree.
17683 **
17684 ** If the expression is an SQL literal (TK_INTEGER, TK_FLOAT, TK_BLOB,
17685 ** or TK_STRING), then Expr.u.zToken contains the text of the SQL literal. If
17686 ** the expression is a variable (TK_VARIABLE), then Expr.u.zToken contains the
17687 ** variable name. Finally, if the expression is an SQL function (TK_FUNCTION),
17688 ** then Expr.u.zToken contains the name of the function.
17689 **
17690 ** Expr.pRight and Expr.pLeft are the left and right subexpressions of a
17691 ** binary operator. Either or both may be NULL.
17692 **
17693 ** Expr.x.pList is a list of arguments if the expression is an SQL function,
@@ -17601,11 +17723,11 @@
17723 **
17724 ** Expr objects can use a lot of memory space in database schema. To
17725 ** help reduce memory requirements, sometimes an Expr object will be
17726 ** truncated. And to reduce the number of memory allocations, sometimes
17727 ** two or more Expr objects will be stored in a single memory allocation,
17728 ** together with Expr.u.zToken strings.
17729 **
17730 ** If the EP_Reduced and EP_TokenOnly flags are set when
17731 ** an Expr object is truncated. When EP_Reduced is set, then all
17732 ** the child Expr objects in the Expr.pLeft and Expr.pRight subtrees
17733 ** are contained within the same memory allocation. Note, however, that
@@ -17670,12 +17792,11 @@
17792 int regReturn; /* Register used to hold return address */
17793 } sub;
17794 } y;
17795 };
17796
17797 /* The following are the meanings of bits in the Expr.flags field.
 
17798 ** Value restrictions:
17799 **
17800 ** EP_Agg == NC_HasAgg == SF_HasAgg
17801 ** EP_Win == NC_HasWin
17802 */
@@ -17710,27 +17831,35 @@
17831 #define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */
17832 #define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */
17833 #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
17834 /* 0x80000000 // Available */
17835
17836 /* The EP_Propagate mask is a set of properties that automatically propagate
 
17837 ** upwards into parent nodes.
17838 */
17839 #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
17840
17841 /* Macros can be used to test, set, or clear bits in the
 
17842 ** Expr.flags field.
17843 */
17844 #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
17845 #define ExprHasAllProperty(E,P) (((E)->flags&(P))==(P))
17846 #define ExprSetProperty(E,P) (E)->flags|=(P)
17847 #define ExprClearProperty(E,P) (E)->flags&=~(P)
17848 #define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
17849 #define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
17850
17851 /* Macros used to ensure that the correct members of unions are accessed
17852 ** in Expr.
17853 */
17854 #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
17855 #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0)
17856 #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0)
17857 #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0)
17858 #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0)
17859 #define ExprUseYWin(E) (((E)->flags&EP_WinFunc)!=0)
17860 #define ExprUseYSub(E) (((E)->flags&EP_Subrtn)!=0)
17861
17862 /* Flags for use with Expr.vvaFlags
17863 */
17864 #define EP_NoReduce 0x01 /* Cannot EXPRDUP_REDUCE this Expr */
17865 #define EP_Immutable 0x02 /* Do not change this Expr node */
@@ -17809,15 +17938,16 @@
17938 unsigned done :1; /* A flag to indicate when processing is finished */
17939 unsigned reusable :1; /* Constant expression is reusable */
17940 unsigned bSorterRef :1; /* Defer evaluation until after sorting */
17941 unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */
17942 union {
17943 struct { /* Used by any ExprList other than Parse.pConsExpr */
17944 u16 iOrderByCol; /* For ORDER BY, column number in result set */
17945 u16 iAlias; /* Index into Parse.aAlias[] for zName */
17946 } x;
17947 int iConstExprReg; /* Register in which Expr value is cached. Used only
17948 ** by Parse.pConstExpr */
17949 } u;
17950 } a[1]; /* One slot for each expression in the list */
17951 };
17952
17953 /*
@@ -17851,10 +17981,17 @@
17981 };
17982
17983 /*
17984 ** The SrcItem object represents a single term in the FROM clause of a query.
17985 ** The SrcList object is mostly an array of SrcItems.
17986 **
17987 ** Union member validity:
17988 **
17989 ** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
17990 ** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
17991 ** u2.pIBIndex fg.isIndexedBy && !fg.isCte
17992 ** u2.pCteUse fg.isCte && !fg.isIndexedBy
17993 */
17994 struct SrcItem {
17995 Schema *pSchema; /* Schema to which this item is fixed */
17996 char *zDatabase; /* Name of database holding this table */
17997 char *zName; /* Name of the table */
@@ -18382,11 +18519,10 @@
18519 TableLock *aTableLock; /* Required table locks for shared-cache mode */
18520 #endif
18521 AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */
18522 Parse *pToplevel; /* Parse structure for main program (or NULL) */
18523 Table *pTriggerTab; /* Table triggers are being coded for */
 
18524 union {
18525 int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */
18526 Returning *pReturning; /* The RETURNING clause */
18527 } u1;
18528 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
@@ -18445,10 +18581,12 @@
18581 #ifndef SQLITE_OMIT_ALTERTABLE
18582 RenameToken *pRename; /* Tokens subject to renaming by ALTER TABLE */
18583 #endif
18584 };
18585
18586 /* Allowed values for Parse.eParseMode
18587 */
18588 #define PARSE_MODE_NORMAL 0
18589 #define PARSE_MODE_DECLARE_VTAB 1
18590 #define PARSE_MODE_RENAME 2
18591 #define PARSE_MODE_UNMAP 3
18592
@@ -18666,12 +18804,14 @@
18804 } InitData;
18805
18806 /*
18807 ** Allowed values for mInitFlags
18808 */
18809 #define INITFLAG_AlterMask 0x0003 /* Types of ALTER */
18810 #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */
18811 #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */
18812 #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */
18813
18814 /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled
18815 ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning
18816 ** parameters are for temporary use during development, to help find
18817 ** optimial values for parameters in the query planner. The should not
@@ -18788,12 +18928,12 @@
18928 union { /* Extra data for callback */
18929 NameContext *pNC; /* Naming context */
18930 int n; /* A counter */
18931 int iCur; /* A cursor number */
18932 SrcList *pSrcList; /* FROM clause */
 
18933 struct CCurHint *pCCurHint; /* Used by codeCursorHint() */
18934 struct RefSrcList *pRefSrcList; /* sqlite3ReferencesSrcList() */
18935 int *aiCol; /* array of column indexes */
18936 struct IdxCover *pIdxCover; /* Check for index coverage */
18937 struct IdxExprTrans *pIdxTrans; /* Convert idxed expr to column */
18938 ExprList *pGroupBy; /* GROUP BY clause */
18939 Select *pSelect; /* HAVING to WHERE clause ctx */
@@ -19387,10 +19527,11 @@
19527 SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int);
19528 SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int);
19529 #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY)
19530 SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*);
19531 #endif
19532 SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe*,int,const char*);
19533 SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*);
19534 SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*,
19535 Upsert*);
19536 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int);
19537 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
@@ -19430,10 +19571,11 @@
19571 SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int);
19572 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*);
19573 #define LOCATE_VIEW 0x01
19574 #define LOCATE_NOERR 0x02
19575 SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
19576 SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char*);
19577 SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
19578 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
19579 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
19580 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
19581 SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*);
@@ -19446,11 +19588,11 @@
19588 SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int);
19589 SQLITE_PRIVATE void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
19590 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
19591 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
19592 SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
19593 SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse*, Expr*, SrcList*);
19594 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
19595 #ifndef SQLITE_UNTESTABLE
19596 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
19597 SQLITE_PRIVATE void sqlite3PrngRestoreState(void);
19598 #endif
@@ -19596,18 +19738,12 @@
19738 #endif
19739 SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte);
19740 SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**);
19741 SQLITE_PRIVATE LogEst sqlite3LogEst(u64);
19742 SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst);
 
19743 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double);
 
 
 
 
19744 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst);
 
19745 SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int);
19746 SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int);
19747 SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int);
19748
19749 /*
@@ -19888,13 +20024,15 @@
20024 #endif
20025 SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db);
20026 #ifndef SQLITE_OMIT_VIRTUALTABLE
20027 SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName);
20028 SQLITE_PRIVATE int sqlite3IsShadowTableOf(sqlite3*,Table*,const char*);
20029 SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3*, Table*);
20030 #else
20031 # define sqlite3ShadowTableName(A,B) 0
20032 # define sqlite3IsShadowTableOf(A,B,C) 0
20033 # define sqlite3MarkAllShadowTablesOf(A,B)
20034 #endif
20035 SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*);
20036 SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*);
20037 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
20038 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int);
@@ -19933,11 +20071,11 @@
20071 #else
20072 # define sqlite3CteNew(P,T,E,S) ((void*)0)
20073 # define sqlite3CteDelete(D,C)
20074 # define sqlite3CteWithAdd(P,W,C) ((void*)0)
20075 # define sqlite3WithDelete(x,y)
20076 # define sqlite3WithPush(x,y,z) ((void*)0)
20077 #endif
20078 #ifndef SQLITE_OMIT_UPSERT
20079 SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*,Upsert*);
20080 SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*);
20081 SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*);
@@ -20101,12 +20239,12 @@
20239 ** All of this is no-op for a production build. It only comes into
20240 ** play when the SQLITE_MEMDEBUG compile-time option is used.
20241 */
20242 #ifdef SQLITE_MEMDEBUG
20243 SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8);
20244 SQLITE_PRIVATE int sqlite3MemdebugHasType(const void*,u8);
20245 SQLITE_PRIVATE int sqlite3MemdebugNoType(const void*,u8);
20246 #else
20247 # define sqlite3MemdebugSetType(X,Y) /* no-op */
20248 # define sqlite3MemdebugHasType(X,Y) 1
20249 # define sqlite3MemdebugNoType(X,Y) 1
20250 #endif
@@ -21425,10 +21563,22 @@
21563 ** database connections. After initialization, this table is
21564 ** read-only.
21565 */
21566 SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions;
21567
21568 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
21569 /*
21570 ** Counter used for coverage testing. Does not come into play for
21571 ** release builds.
21572 **
21573 ** Access to this global variable is not mutex protected. This might
21574 ** result in TSAN warnings. But as the variable does not exist in
21575 ** release builds, that should not be a concern.
21576 */
21577 SQLITE_PRIVATE unsigned int sqlite3CoverageCounter;
21578 #endif /* SQLITE_COVERAGE_TEST || SQLITE_DEBUG */
21579
21580 #ifdef VDBE_PROFILE
21581 /*
21582 ** The following performance counter can be used in place of
21583 ** sqlite3Hwtime() for profiling. This is a no-op on standard builds.
21584 */
@@ -21969,11 +22119,11 @@
22119 bft usesStmtJournal:1; /* True if uses a statement journal */
22120 bft readOnly:1; /* True for statements that do not write */
22121 bft bIsReader:1; /* True for statements that read */
22122 yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */
22123 yDbMask lockMask; /* Subset of btreeMask that requires a lock */
22124 u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */
22125 char *zSql; /* Text of the SQL statement that generated this */
22126 #ifdef SQLITE_ENABLE_NORMALIZE
22127 char *zNormSql; /* Normalization of the associated SQL statement */
22128 DblquoteStr *pDblStr; /* List of double-quoted string literals */
22129 #endif
@@ -22065,19 +22215,23 @@
22215 SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double);
22216 #endif
22217 SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*));
22218 SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16);
22219 SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*);
22220 #ifndef SQLITE_OMIT_INCRBLOB
22221 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int);
22222 #else
22223 SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem*,int);
22224 #endif
22225 #ifdef SQLITE_DEBUG
22226 SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*);
22227 #endif
22228 SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*);
22229 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*);
22230 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8);
22231 SQLITE_PRIVATE int sqlite3IntFloatCompare(i64,double);
22232 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem*);
22233 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*);
22234 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*);
22235 SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull);
22236 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*);
22237 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*);
@@ -23071,11 +23225,13 @@
23225 pX = localtime(t);
23226 #ifndef SQLITE_UNTESTABLE
23227 if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0;
23228 #endif
23229 if( pX ) *pTm = *pX;
23230 #if SQLITE_THREADSAFE>0
23231 sqlite3_mutex_leave(mutex);
23232 #endif
23233 rc = pX==0;
23234 #else
23235 #ifndef SQLITE_UNTESTABLE
23236 if( sqlite3GlobalConfig.bLocaltimeFault ) return 1;
23237 #endif
@@ -23210,10 +23366,49 @@
23366 DateTime *p /* The date/time value to be modified */
23367 ){
23368 int rc = 1;
23369 double r;
23370 switch(sqlite3UpperToLower[(u8)z[0]] ){
23371 case 'a': {
23372 /*
23373 ** auto
23374 **
23375 ** If rawS is available, then interpret as a julian day number, or
23376 ** a unix timestamp, depending on its magnitude.
23377 */
23378 if( sqlite3_stricmp(z, "auto")==0 ){
23379 if( !p->rawS || p->validJD ){
23380 rc = 0;
23381 p->rawS = 0;
23382 }else if( p->s>=-210866760000 && p->s<=253402300799 ){
23383 r = p->s*1000.0 + 210866760000000.0;
23384 clearYMD_HMS_TZ(p);
23385 p->iJD = (sqlite3_int64)(r + 0.5);
23386 p->validJD = 1;
23387 p->rawS = 0;
23388 rc = 0;
23389 }
23390 }
23391 break;
23392 }
23393 case 'j': {
23394 /*
23395 ** julianday
23396 **
23397 ** Always interpret the prior number as a julian-day value. If this
23398 ** is not the first modifier, or if the prior argument is not a numeric
23399 ** value in the allowed range of julian day numbers understood by
23400 ** SQLite (0..5373484.5) then the result will be NULL.
23401 */
23402 if( sqlite3_stricmp(z, "julianday")==0 ){
23403 if( p->validJD && p->rawS ){
23404 rc = 0;
23405 p->rawS = 0;
23406 }
23407 }
23408 break;
23409 }
23410 #ifndef SQLITE_OMIT_LOCALTIME
23411 case 'l': {
23412 /* localtime
23413 **
23414 ** Assuming the current time value is UTC (a.k.a. GMT), shift it to
@@ -23473,10 +23668,28 @@
23668 if( isDate(context, argc, argv, &x)==0 ){
23669 computeJD(&x);
23670 sqlite3_result_double(context, x.iJD/86400000.0);
23671 }
23672 }
23673
23674 /*
23675 ** unixepoch( TIMESTRING, MOD, MOD, ...)
23676 **
23677 ** Return the number of seconds (including fractional seconds) since
23678 ** the unix epoch of 1970-01-01 00:00:00 GMT.
23679 */
23680 static void unixepochFunc(
23681 sqlite3_context *context,
23682 int argc,
23683 sqlite3_value **argv
23684 ){
23685 DateTime x;
23686 if( isDate(context, argc, argv, &x)==0 ){
23687 computeJD(&x);
23688 sqlite3_result_int64(context, x.iJD/1000 - 21086676*(i64)10000);
23689 }
23690 }
23691
23692 /*
23693 ** datetime( TIMESTRING, MOD, MOD, ...)
23694 **
23695 ** Return YYYY-MM-DD HH:MM:SS
@@ -23573,11 +23786,11 @@
23786
23787 computeJD(&x);
23788 computeYMD_HMS(&x);
23789 for(i=j=0; zFmt[i]; i++){
23790 if( zFmt[i]!='%' ) continue;
23791 if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j));
23792 i++;
23793 j = i + 1;
23794 switch( zFmt[i] ){
23795 case 'd': {
23796 sqlite3_str_appendf(&sRes, "%02d", x.D);
@@ -23649,11 +23862,11 @@
23862 sqlite3_str_reset(&sRes);
23863 return;
23864 }
23865 }
23866 }
23867 if( j<i ) sqlite3_str_append(&sRes, zFmt+j, (int)(i-j));
23868 sqlite3ResultStrAccum(context, &sRes);
23869 }
23870
23871 /*
23872 ** current_time()
@@ -23750,10 +23963,11 @@
23963 */
23964 SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){
23965 static FuncDef aDateTimeFuncs[] = {
23966 #ifndef SQLITE_OMIT_DATETIME_FUNCS
23967 PURE_DATE(julianday, -1, 0, 0, juliandayFunc ),
23968 PURE_DATE(unixepoch, -1, 0, 0, unixepochFunc ),
23969 PURE_DATE(date, -1, 0, 0, dateFunc ),
23970 PURE_DATE(time, -1, 0, 0, timeFunc ),
23971 PURE_DATE(datetime, -1, 0, 0, datetimeFunc ),
23972 PURE_DATE(strftime, -1, 0, 0, strftimeFunc ),
23973 DFUNCTION(current_time, 0, 0, 0, ctimeFunc ),
@@ -24086,16 +24300,19 @@
24300 pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
24301 if( pFile ){
24302 rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
24303 if( rc!=SQLITE_OK ){
24304 sqlite3_free(pFile);
24305 *ppFile = 0;
24306 }else{
24307 *ppFile = pFile;
24308 }
24309 }else{
24310 *ppFile = 0;
24311 rc = SQLITE_NOMEM_BKPT;
24312 }
24313 assert( *ppFile!=0 || rc!=SQLITE_OK );
24314 return rc;
24315 }
24316 SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){
24317 assert( pFile );
24318 sqlite3OsClose(pFile);
@@ -24809,11 +25026,11 @@
25026 ** Given an allocation, find the MemBlockHdr for that allocation.
25027 **
25028 ** This routine checks the guards at either end of the allocation and
25029 ** if they are incorrect it asserts.
25030 */
25031 static struct MemBlockHdr *sqlite3MemsysGetHeader(const void *pAllocation){
25032 struct MemBlockHdr *p;
25033 int *pInt;
25034 u8 *pU8;
25035 int nReserve;
25036
@@ -25056,11 +25273,11 @@
25273 ** This routine is designed for use within an assert() statement, to
25274 ** verify the type of an allocation. For example:
25275 **
25276 ** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
25277 */
25278 SQLITE_PRIVATE int sqlite3MemdebugHasType(const void *p, u8 eType){
25279 int rc = 1;
25280 if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
25281 struct MemBlockHdr *pHdr;
25282 pHdr = sqlite3MemsysGetHeader(p);
25283 assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
@@ -25078,11 +25295,11 @@
25295 ** This routine is designed for use within an assert() statement, to
25296 ** verify the type of an allocation. For example:
25297 **
25298 ** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) );
25299 */
25300 SQLITE_PRIVATE int sqlite3MemdebugNoType(const void *p, u8 eType){
25301 int rc = 1;
25302 if( p && sqlite3GlobalConfig.m.xFree==sqlite3MemFree ){
25303 struct MemBlockHdr *pHdr;
25304 pHdr = sqlite3MemsysGetHeader(p);
25305 assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */
@@ -30543,10 +30760,11 @@
30760 zOp2[0] = 0;
30761 }
30762 sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s",
30763 pExpr->iColumn, zFlgs, zOp2);
30764 }else{
30765 assert( ExprUseYTab(pExpr) );
30766 sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s",
30767 pExpr->iTable, pExpr->iColumn,
30768 pExpr->y.pTab, zFlgs);
30769 }
30770 if( ExprHasProperty(pExpr, EP_FixedCol) ){
@@ -30562,15 +30780,17 @@
30780 }
30781 break;
30782 }
30783 #ifndef SQLITE_OMIT_FLOATING_POINT
30784 case TK_FLOAT: {
30785 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30786 sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
30787 break;
30788 }
30789 #endif
30790 case TK_STRING: {
30791 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30792 sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken);
30793 break;
30794 }
30795 case TK_NULL: {
30796 sqlite3TreeViewLine(pView,"NULL");
@@ -30581,30 +30801,34 @@
30801 sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE", zFlgs);
30802 break;
30803 }
30804 #ifndef SQLITE_OMIT_BLOB_LITERAL
30805 case TK_BLOB: {
30806 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30807 sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken);
30808 break;
30809 }
30810 #endif
30811 case TK_VARIABLE: {
30812 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30813 sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)",
30814 pExpr->u.zToken, pExpr->iColumn);
30815 break;
30816 }
30817 case TK_REGISTER: {
30818 sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable);
30819 break;
30820 }
30821 case TK_ID: {
30822 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30823 sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken);
30824 break;
30825 }
30826 #ifndef SQLITE_OMIT_CAST
30827 case TK_CAST: {
30828 /* Expressions of the form: CAST(pLeft AS token) */
30829 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30830 sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken);
30831 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
30832 break;
30833 }
30834 #endif /* SQLITE_OMIT_CAST */
@@ -30650,10 +30874,11 @@
30874 zUniOp = azOp[x];
30875 break;
30876 }
30877
30878 case TK_SPAN: {
30879 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30880 sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
30881 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
30882 break;
30883 }
30884
@@ -30661,10 +30886,11 @@
30886 /* COLLATE operators without the EP_Collate flag are intended to
30887 ** emulate collation associated with a table column. These show
30888 ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE
30889 ** operators that appear in the original SQL always have the
30890 ** EP_Collate bit set and appear in treeview output as just "COLLATE" */
30891 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30892 sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s",
30893 !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "",
30894 pExpr->u.zToken, zFlgs);
30895 sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
30896 break;
@@ -30676,17 +30902,19 @@
30902 Window *pWin;
30903 if( ExprHasProperty(pExpr, EP_TokenOnly) ){
30904 pFarg = 0;
30905 pWin = 0;
30906 }else{
30907 assert( ExprUseXList(pExpr) );
30908 pFarg = pExpr->x.pList;
30909 #ifndef SQLITE_OMIT_WINDOWFUNC
30910 pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0;
30911 #else
30912 pWin = 0;
30913 #endif
30914 }
30915 assert( !ExprHasProperty(pExpr, EP_IntValue) );
30916 if( pExpr->op==TK_AGG_FUNCTION ){
30917 sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s agg=%d[%d]/%p",
30918 pExpr->op2, pExpr->u.zToken, zFlgs,
30919 pExpr->pAggInfo ? pExpr->pAggInfo->selId : 0,
30920 pExpr->iAgg, pExpr->pAggInfo);
@@ -30714,23 +30942,25 @@
30942 #endif
30943 break;
30944 }
30945 #ifndef SQLITE_OMIT_SUBQUERY
30946 case TK_EXISTS: {
30947 assert( ExprUseXSelect(pExpr) );
30948 sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags);
30949 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
30950 break;
30951 }
30952 case TK_SELECT: {
30953 assert( ExprUseXSelect(pExpr) );
30954 sqlite3TreeViewLine(pView, "subquery-expr flags=0x%x", pExpr->flags);
30955 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
30956 break;
30957 }
30958 case TK_IN: {
30959 sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags);
30960 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
30961 if( ExprUseXSelect(pExpr) ){
30962 sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0);
30963 }else{
30964 sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
30965 }
30966 break;
@@ -30747,13 +30977,16 @@
30977 ** X is stored in pExpr->pLeft.
30978 ** Y is stored in pExpr->pList->a[0].pExpr.
30979 ** Z is stored in pExpr->pList->a[1].pExpr.
30980 */
30981 case TK_BETWEEN: {
30982 const Expr *pX, *pY, *pZ;
30983 pX = pExpr->pLeft;
30984 assert( ExprUseXList(pExpr) );
30985 assert( pExpr->x.pList->nExpr==2 );
30986 pY = pExpr->x.pList->a[0].pExpr;
30987 pZ = pExpr->x.pList->a[1].pExpr;
30988 sqlite3TreeViewLine(pView, "BETWEEN");
30989 sqlite3TreeViewExpr(pView, pX, 1);
30990 sqlite3TreeViewExpr(pView, pY, 1);
30991 sqlite3TreeViewExpr(pView, pZ, 0);
30992 break;
@@ -30771,10 +31004,11 @@
31004 break;
31005 }
31006 case TK_CASE: {
31007 sqlite3TreeViewLine(pView, "CASE");
31008 sqlite3TreeViewExpr(pView, pExpr->pLeft, 1);
31009 assert( ExprUseXList(pExpr) );
31010 sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0);
31011 break;
31012 }
31013 #ifndef SQLITE_OMIT_TRIGGER
31014 case TK_RAISE: {
@@ -30783,10 +31017,11 @@
31017 case OE_Rollback: zType = "rollback"; break;
31018 case OE_Abort: zType = "abort"; break;
31019 case OE_Fail: zType = "fail"; break;
31020 case OE_Ignore: zType = "ignore"; break;
31021 }
31022 assert( !ExprHasProperty(pExpr, EP_IntValue) );
31023 sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken);
31024 break;
31025 }
31026 #endif
31027 case TK_MATCH: {
@@ -30795,18 +31030,20 @@
31030 sqlite3TreeViewExpr(pView, pExpr->pRight, 0);
31031 break;
31032 }
31033 case TK_VECTOR: {
31034 char *z = sqlite3_mprintf("VECTOR%s",zFlgs);
31035 assert( ExprUseXList(pExpr) );
31036 sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z);
31037 sqlite3_free(z);
31038 break;
31039 }
31040 case TK_SELECT_COLUMN: {
31041 sqlite3TreeViewLine(pView, "SELECT-COLUMN %d of [0..%d]%s",
31042 pExpr->iColumn, pExpr->iTable-1,
31043 pExpr->pRight==pExpr->pLeft ? " (SELECT-owner)" : "");
31044 assert( ExprUseXSelect(pExpr->pLeft) );
31045 sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0);
31046 break;
31047 }
31048 case TK_IF_NULL_ROW: {
31049 sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable);
@@ -31879,20 +32116,10 @@
32116 /* #include <stdarg.h> */
32117 #ifndef SQLITE_OMIT_FLOATING_POINT
32118 #include <math.h>
32119 #endif
32120
 
 
 
 
 
 
 
 
 
 
32121 /*
32122 ** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
32123 ** or to bypass normal error detection during testing in order to let
32124 ** execute proceed futher downstream.
32125 **
@@ -32135,10 +32362,11 @@
32362 }
32363 }
32364 z[j] = 0;
32365 }
32366 SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){
32367 assert( !ExprHasProperty(p, EP_IntValue) );
32368 assert( sqlite3Isquote(p->u.zToken[0]) );
32369 p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted;
32370 sqlite3Dequote(p->u.zToken);
32371 }
32372
@@ -33453,11 +33681,10 @@
33681 #endif
33682 }
33683 return a[x&7] + y - 10;
33684 }
33685
 
33686 /*
33687 ** Convert a double into a LogEst
33688 ** In other words, compute an approximation for 10*log2(x).
33689 */
33690 SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){
@@ -33468,38 +33695,23 @@
33695 if( x<=2000000000 ) return sqlite3LogEst((u64)x);
33696 memcpy(&a, &x, 8);
33697 e = (a>>52) - 1022;
33698 return e*10;
33699 }
 
33700
 
 
 
33701 /*
33702 ** Convert a LogEst into an integer.
 
 
 
33703 */
33704 SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){
33705 u64 n;
33706 n = x%10;
33707 x /= 10;
33708 if( n>=5 ) n -= 2;
33709 else if( n>=1 ) n -= 1;
 
 
33710 if( x>60 ) return (u64)LARGEST_INT64;
 
 
 
 
 
33711 return x>=3 ? (n+8)<<(x-3) : (n+8)>>(3-x);
33712 }
 
33713
33714 /*
33715 ** Add a new name/number pair to a VList. This might require that the
33716 ** VList object be reallocated, so return the new VList. If an OOM
33717 ** error occurs, the original VList returned and the
@@ -33949,49 +34161,49 @@
34161 /* 58 */ "ElseEq" OpHelp(""),
34162 /* 59 */ "IfNotZero" OpHelp("if r[P1]!=0 then r[P1]--, goto P2"),
34163 /* 60 */ "DecrJumpZero" OpHelp("if (--r[P1])==0 goto P2"),
34164 /* 61 */ "IncrVacuum" OpHelp(""),
34165 /* 62 */ "VNext" OpHelp(""),
34166 /* 63 */ "Filter" OpHelp("if key(P3@P4) not in filter(P1) goto P2"),
34167 /* 64 */ "Init" OpHelp("Start at P2"),
34168 /* 65 */ "PureFunc" OpHelp("r[P3]=func(r[P2@NP])"),
34169 /* 66 */ "Function" OpHelp("r[P3]=func(r[P2@NP])"),
34170 /* 67 */ "Return" OpHelp(""),
34171 /* 68 */ "EndCoroutine" OpHelp(""),
34172 /* 69 */ "HaltIfNull" OpHelp("if r[P3]=null halt"),
34173 /* 70 */ "Halt" OpHelp(""),
34174 /* 71 */ "Integer" OpHelp("r[P2]=P1"),
34175 /* 72 */ "Int64" OpHelp("r[P2]=P4"),
34176 /* 73 */ "String" OpHelp("r[P2]='P4' (len=P1)"),
34177 /* 74 */ "Null" OpHelp("r[P2..P3]=NULL"),
34178 /* 75 */ "SoftNull" OpHelp("r[P1]=NULL"),
34179 /* 76 */ "Blob" OpHelp("r[P2]=P4 (len=P1)"),
34180 /* 77 */ "Variable" OpHelp("r[P2]=parameter(P1,P4)"),
34181 /* 78 */ "Move" OpHelp("r[P2@P3]=r[P1@P3]"),
34182 /* 79 */ "Copy" OpHelp("r[P2@P3+1]=r[P1@P3+1]"),
34183 /* 80 */ "SCopy" OpHelp("r[P2]=r[P1]"),
34184 /* 81 */ "IntCopy" OpHelp("r[P2]=r[P1]"),
34185 /* 82 */ "FkCheck" OpHelp(""),
34186 /* 83 */ "ResultRow" OpHelp("output=r[P1@P2]"),
34187 /* 84 */ "CollSeq" OpHelp(""),
34188 /* 85 */ "AddImm" OpHelp("r[P1]=r[P1]+P2"),
34189 /* 86 */ "RealAffinity" OpHelp(""),
34190 /* 87 */ "Cast" OpHelp("affinity(r[P1])"),
34191 /* 88 */ "Permutation" OpHelp(""),
34192 /* 89 */ "Compare" OpHelp("r[P1@P3] <-> r[P2@P3]"),
34193 /* 90 */ "IsTrue" OpHelp("r[P2] = coalesce(r[P1]==TRUE,P3) ^ P4"),
34194 /* 91 */ "ZeroOrNull" OpHelp("r[P2] = 0 OR NULL"),
34195 /* 92 */ "Offset" OpHelp("r[P3] = sqlite_offset(P1)"),
34196 /* 93 */ "Column" OpHelp("r[P3]=PX"),
34197 /* 94 */ "TypeCheck" OpHelp("typecheck(r[P1@P2])"),
34198 /* 95 */ "Affinity" OpHelp("affinity(r[P1@P2])"),
34199 /* 96 */ "MakeRecord" OpHelp("r[P3]=mkrec(r[P1@P2])"),
34200 /* 97 */ "Count" OpHelp("r[P2]=count()"),
34201 /* 98 */ "ReadCookie" OpHelp(""),
34202 /* 99 */ "SetCookie" OpHelp(""),
34203 /* 100 */ "ReopenIdx" OpHelp("root=P2 iDb=P3"),
34204 /* 101 */ "OpenRead" OpHelp("root=P2 iDb=P3"),
34205 /* 102 */ "BitAnd" OpHelp("r[P3]=r[P1]&r[P2]"),
34206 /* 103 */ "BitOr" OpHelp("r[P3]=r[P1]|r[P2]"),
34207 /* 104 */ "ShiftLeft" OpHelp("r[P3]=r[P2]<<r[P1]"),
34208 /* 105 */ "ShiftRight" OpHelp("r[P3]=r[P2]>>r[P1]"),
34209 /* 106 */ "Add" OpHelp("r[P3]=r[P1]+r[P2]"),
@@ -33998,80 +34210,82 @@
34210 /* 107 */ "Subtract" OpHelp("r[P3]=r[P2]-r[P1]"),
34211 /* 108 */ "Multiply" OpHelp("r[P3]=r[P1]*r[P2]"),
34212 /* 109 */ "Divide" OpHelp("r[P3]=r[P2]/r[P1]"),
34213 /* 110 */ "Remainder" OpHelp("r[P3]=r[P2]%r[P1]"),
34214 /* 111 */ "Concat" OpHelp("r[P3]=r[P2]+r[P1]"),
34215 /* 112 */ "OpenWrite" OpHelp("root=P2 iDb=P3"),
34216 /* 113 */ "BitNot" OpHelp("r[P2]= ~r[P1]"),
34217 /* 114 */ "OpenDup" OpHelp(""),
34218 /* 115 */ "OpenAutoindex" OpHelp("nColumn=P2"),
34219 /* 116 */ "String8" OpHelp("r[P2]='P4'"),
34220 /* 117 */ "OpenEphemeral" OpHelp("nColumn=P2"),
34221 /* 118 */ "SorterOpen" OpHelp(""),
34222 /* 119 */ "SequenceTest" OpHelp("if( cursor[P1].ctr++ ) pc = P2"),
34223 /* 120 */ "OpenPseudo" OpHelp("P3 columns in r[P2]"),
34224 /* 121 */ "Close" OpHelp(""),
34225 /* 122 */ "ColumnsUsed" OpHelp(""),
34226 /* 123 */ "SeekScan" OpHelp("Scan-ahead up to P1 rows"),
34227 /* 124 */ "SeekHit" OpHelp("set P2<=seekHit<=P3"),
34228 /* 125 */ "Sequence" OpHelp("r[P2]=cursor[P1].ctr++"),
34229 /* 126 */ "NewRowid" OpHelp("r[P2]=rowid"),
34230 /* 127 */ "Insert" OpHelp("intkey=r[P3] data=r[P2]"),
34231 /* 128 */ "RowCell" OpHelp(""),
34232 /* 129 */ "Delete" OpHelp(""),
34233 /* 130 */ "ResetCount" OpHelp(""),
34234 /* 131 */ "SorterCompare" OpHelp("if key(P1)!=trim(r[P3],P4) goto P2"),
34235 /* 132 */ "SorterData" OpHelp("r[P2]=data"),
34236 /* 133 */ "RowData" OpHelp("r[P2]=data"),
34237 /* 134 */ "Rowid" OpHelp("r[P2]=rowid"),
34238 /* 135 */ "NullRow" OpHelp(""),
34239 /* 136 */ "SeekEnd" OpHelp(""),
34240 /* 137 */ "IdxInsert" OpHelp("key=r[P2]"),
34241 /* 138 */ "SorterInsert" OpHelp("key=r[P2]"),
34242 /* 139 */ "IdxDelete" OpHelp("key=r[P2@P3]"),
34243 /* 140 */ "DeferredSeek" OpHelp("Move P3 to P1.rowid if needed"),
34244 /* 141 */ "IdxRowid" OpHelp("r[P2]=rowid"),
34245 /* 142 */ "FinishSeek" OpHelp(""),
34246 /* 143 */ "Destroy" OpHelp(""),
34247 /* 144 */ "Clear" OpHelp(""),
34248 /* 145 */ "ResetSorter" OpHelp(""),
34249 /* 146 */ "CreateBtree" OpHelp("r[P2]=root iDb=P1 flags=P3"),
34250 /* 147 */ "SqlExec" OpHelp(""),
34251 /* 148 */ "ParseSchema" OpHelp(""),
34252 /* 149 */ "LoadAnalysis" OpHelp(""),
34253 /* 150 */ "DropTable" OpHelp(""),
34254 /* 151 */ "DropIndex" OpHelp(""),
34255 /* 152 */ "Real" OpHelp("r[P2]=P4"),
34256 /* 153 */ "DropTrigger" OpHelp(""),
34257 /* 154 */ "IntegrityCk" OpHelp(""),
34258 /* 155 */ "RowSetAdd" OpHelp("rowset(P1)=r[P2]"),
34259 /* 156 */ "Param" OpHelp(""),
34260 /* 157 */ "FkCounter" OpHelp("fkctr[P1]+=P2"),
34261 /* 158 */ "MemMax" OpHelp("r[P1]=max(r[P1],r[P2])"),
34262 /* 159 */ "OffsetLimit" OpHelp("if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)"),
34263 /* 160 */ "AggInverse" OpHelp("accum=r[P3] inverse(r[P2@P5])"),
34264 /* 161 */ "AggStep" OpHelp("accum=r[P3] step(r[P2@P5])"),
34265 /* 162 */ "AggStep1" OpHelp("accum=r[P3] step(r[P2@P5])"),
34266 /* 163 */ "AggValue" OpHelp("r[P3]=value N=P2"),
34267 /* 164 */ "AggFinal" OpHelp("accum=r[P1] N=P2"),
34268 /* 165 */ "Expire" OpHelp(""),
34269 /* 166 */ "CursorLock" OpHelp(""),
34270 /* 167 */ "CursorUnlock" OpHelp(""),
34271 /* 168 */ "TableLock" OpHelp("iDb=P1 root=P2 write=P3"),
34272 /* 169 */ "VBegin" OpHelp(""),
34273 /* 170 */ "VCreate" OpHelp(""),
34274 /* 171 */ "VDestroy" OpHelp(""),
34275 /* 172 */ "VOpen" OpHelp(""),
34276 /* 173 */ "VColumn" OpHelp("r[P3]=vcolumn(P2)"),
34277 /* 174 */ "VRename" OpHelp(""),
34278 /* 175 */ "Pagecount" OpHelp(""),
34279 /* 176 */ "MaxPgcnt" OpHelp(""),
34280 /* 177 */ "FilterAdd" OpHelp("filter(P1) += key(P3@P4)"),
34281 /* 178 */ "Trace" OpHelp(""),
34282 /* 179 */ "CursorHint" OpHelp(""),
34283 /* 180 */ "ReleaseReg" OpHelp("release r[P1@P2] mask P3"),
34284 /* 181 */ "Noop" OpHelp(""),
34285 /* 182 */ "Explain" OpHelp(""),
34286 /* 183 */ "Abortable" OpHelp(""),
34287 };
34288 return azName[i];
34289 }
34290 #endif
34291
@@ -38028,11 +38242,13 @@
38242 }
38243 }
38244
38245 /* Forward declaration */
38246 static int unixGetTempname(int nBuf, char *zBuf);
38247 #ifndef SQLITE_OMIT_WAL
38248 static int unixFcntlExternalReader(unixFile*, int*);
38249 #endif
38250
38251 /*
38252 ** Information and control of an open file handle.
38253 */
38254 static int unixFileControl(sqlite3_file *id, int op, void *pArg){
@@ -38147,11 +38363,16 @@
38363 return proxyFileControl(id,op,pArg);
38364 }
38365 #endif /* SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) */
38366
38367 case SQLITE_FCNTL_EXTERNAL_READER: {
38368 #ifndef SQLITE_OMIT_WAL
38369 return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
38370 #else
38371 *(int*)pArg = 0;
38372 return SQLITE_OK;
38373 #endif
38374 }
38375 }
38376 return SQLITE_NOTFOUND;
38377 }
38378
@@ -39867,40 +40088,50 @@
40088 OpenCounter(+1);
40089 verifyDbFile(pNew);
40090 }
40091 return rc;
40092 }
40093
40094 /*
40095 ** Directories to consider for temp files.
40096 */
40097 static const char *azTempDirs[] = {
40098 0,
40099 0,
40100 "/var/tmp",
40101 "/usr/tmp",
40102 "/tmp",
40103 "."
40104 };
40105
40106 /*
40107 ** Initialize first two members of azTempDirs[] array.
40108 */
40109 static void unixTempFileInit(void){
40110 azTempDirs[0] = getenv("SQLITE_TMPDIR");
40111 azTempDirs[1] = getenv("TMPDIR");
40112 }
40113
40114 /*
40115 ** Return the name of a directory in which to put temporary files.
40116 ** If no suitable temporary file directory can be found, return NULL.
40117 */
40118 static const char *unixTempFileDir(void){
 
 
 
 
 
 
 
 
40119 unsigned int i = 0;
40120 struct stat buf;
40121 const char *zDir = sqlite3_temp_directory;
40122
 
 
40123 while(1){
40124 if( zDir!=0
40125 && osStat(zDir, &buf)==0
40126 && S_ISDIR(buf.st_mode)
40127 && osAccess(zDir, 03)==0
40128 ){
40129 return zDir;
40130 }
40131 if( i>=sizeof(azTempDirs)/sizeof(azTempDirs[0]) ) break;
40132 zDir = azTempDirs[i++];
40133 }
40134 return 0;
40135 }
40136
40137 /*
@@ -40201,10 +40432,15 @@
40432 if( randomnessPid!=osGetpid(0) ){
40433 randomnessPid = osGetpid(0);
40434 sqlite3_randomness(0,0);
40435 }
40436 memset(p, 0, sizeof(unixFile));
40437
40438 #ifdef SQLITE_ASSERT_NO_FILES
40439 /* Applications that never read or write a persistent disk files */
40440 assert( zName==0 );
40441 #endif
40442
40443 if( eType==SQLITE_OPEN_MAIN_DB ){
40444 UnixUnusedFd *pUnused;
40445 pUnused = findReusableFd(zName, flags);
40446 if( pUnused ){
@@ -40262,12 +40498,10 @@
40498 if( fd<0 ){
40499 if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
40500 /* If unable to create a journal because the directory is not
40501 ** writable, change the error code to indicate that. */
40502 rc = SQLITE_READONLY_DIRECTORY;
 
 
40503 }else if( errno!=EISDIR && isReadWrite ){
40504 /* Failed to open the file for read/write access. Try read-only. */
40505 flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
40506 openFlags &= ~(O_RDWR|O_CREAT);
40507 flags |= SQLITE_OPEN_READONLY;
@@ -42164,10 +42398,13 @@
42398 ** READ-4 UNIX_SHM_BASE+7 127
42399 ** DMS UNIX_SHM_BASE+8 128
42400 */
42401 assert( UNIX_SHM_DMS==128 ); /* Byte offset of the deadman-switch */
42402 #endif
42403
42404 /* Initialize temp file dir array. */
42405 unixTempFileInit();
42406
42407 return SQLITE_OK;
42408 }
42409
42410 /*
@@ -48615,11 +48852,11 @@
48852 /*
48853 ** Try to enlarge the memory allocation to hold at least sz bytes
48854 */
48855 static int memdbEnlarge(MemStore *p, sqlite3_int64 newSz){
48856 unsigned char *pNew;
48857 if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || NEVER(p->nMmap>0) ){
48858 return SQLITE_FULL;
48859 }
48860 if( newSz>p->szMax ){
48861 return SQLITE_FULL;
48862 }
@@ -48674,12 +48911,13 @@
48911 */
48912 static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){
48913 MemStore *p = ((MemFile*)pFile)->pStore;
48914 int rc = SQLITE_OK;
48915 memdbEnter(p);
48916 if( size>p->sz ){
48917 /* This can only happen with a corrupt wal mode db */
48918 rc = SQLITE_CORRUPT;
48919 }else{
48920 p->sz = size;
48921 }
48922 memdbLeave(p);
48923 return rc;
@@ -48814,11 +49052,11 @@
49052 int iAmt,
49053 void **pp
49054 ){
49055 MemStore *p = ((MemFile*)pFile)->pStore;
49056 memdbEnter(p);
49057 if( iOfst+iAmt>p->sz || (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)!=0 ){
49058 *pp = 0;
49059 }else{
49060 p->nMmap++;
49061 *pp = (void*)(p->aData + iOfst);
49062 }
@@ -48848,13 +49086,12 @@
49086 int *pOutFlags
49087 ){
49088 MemFile *pFile = (MemFile*)pFd;
49089 MemStore *p = 0;
49090 int szName;
49091 UNUSED_PARAMETER(pVfs);
49092
 
49093 memset(pFile, 0, sizeof(*pFile));
49094 szName = sqlite3Strlen30(zName);
49095 if( szName>1 && zName[0]=='/' ){
49096 int i;
49097 #ifndef SQLITE_MUTEX_OMIT
@@ -48910,12 +49147,13 @@
49147 memset(p, 0, sizeof(*p));
49148 p->mFlags = SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE;
49149 p->szMax = sqlite3GlobalConfig.mxMemdbSize;
49150 }
49151 pFile->pStore = p;
49152 if( pOutFlags!=0 ){
49153 *pOutFlags = flags | SQLITE_OPEN_MEMORY;
49154 }
49155 pFd->pMethods = &memdb_io_methods;
49156 memdbLeave(p);
49157 return SQLITE_OK;
49158 }
49159
@@ -49576,11 +49814,11 @@
49814 /* NULL pBitvec tests */
49815 sqlite3BitvecSet(0, 1);
49816 sqlite3BitvecClear(0, 1, pTmpSpace);
49817
49818 /* Run the program */
49819 pc = i = 0;
49820 while( (op = aOp[pc])!=0 ){
49821 switch( op ){
49822 case 1:
49823 case 2:
49824 case 5: {
@@ -53106,10 +53344,11 @@
53344 u8 walSyncFlags; /* See description above */
53345 u8 tempFile; /* zFilename is a temporary or immutable file */
53346 u8 noLock; /* Do not lock (except in WAL mode) */
53347 u8 readOnly; /* True for a read-only database */
53348 u8 memDb; /* True to inhibit all file I/O */
53349 u8 memVfs; /* VFS-implemented memory database */
53350
53351 /**************************************************************************
53352 ** The following block contains those class members that change during
53353 ** routine operation. Class members not in this block are either fixed
53354 ** when the pager is first created or else only change when there is a
@@ -55500,10 +55739,11 @@
55739 ** routine which only updates the change-counter if the update is actually
55740 ** needed, as determined by the pPager->changeCountDone state variable.
55741 */
55742 static void pager_write_changecounter(PgHdr *pPg){
55743 u32 change_counter;
55744 if( NEVER(pPg==0) ) return;
55745
55746 /* Increment the value just read and write it back to byte 24. */
55747 change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1;
55748 put32bits(((char*)pPg->pData)+24, change_counter);
55749
@@ -57347,11 +57587,11 @@
57587 if( zFilename && zFilename[0] ){
57588 int fout = 0; /* VFS flags returned by xOpen() */
57589 rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout);
57590 assert( !memDb );
57591 #ifndef SQLITE_OMIT_DESERIALIZE
57592 pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0;
57593 #endif
57594 readOnly = (fout&SQLITE_OPEN_READONLY)!=0;
57595
57596 /* If the file was successfully opened for read/write access,
57597 ** choose a default page size in case we have to create the
@@ -59284,11 +59524,11 @@
59524
59525 /*
59526 ** Return true if this is an in-memory or temp-file backed pager.
59527 */
59528 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
59529 return pPager->tempFile || pPager->memVfs;
59530 }
59531
59532 /*
59533 ** Check that there are at least nSavepoint savepoints open. If there are
59534 ** currently less than nSavepoints open, then open one or more savepoints
@@ -59604,11 +59844,11 @@
59844 */
59845 pPg->flags &= ~PGHDR_NEED_SYNC;
59846 pPgOld = sqlite3PagerLookup(pPager, pgno);
59847 assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB );
59848 if( pPgOld ){
59849 if( NEVER(pPgOld->nRef>1) ){
59850 sqlite3PagerUnrefNotNull(pPgOld);
59851 return SQLITE_CORRUPT_BKPT;
59852 }
59853 pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC);
59854 if( pPager->tempFile ){
@@ -60809,13 +61049,17 @@
61049 ** If the wal-index is currently smaller the iPage pages then the size
61050 ** of the wal-index might be increased, but only if it is safe to do
61051 ** so. It is safe to enlarge the wal-index if pWal->writeLock is true
61052 ** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
61053 **
61054 ** Three possible result scenarios:
61055 **
61056 ** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page
61057 ** (2) rc>=SQLITE_ERROR and *ppPage==NULL
61058 ** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0
61059 **
61060 ** Scenario (3) can only occur when pWal->writeLock is false and iPage==0
61061 */
61062 static SQLITE_NOINLINE int walIndexPageRealloc(
61063 Wal *pWal, /* The WAL context */
61064 int iPage, /* The page we seek */
61065 volatile u32 **ppPage /* Write the page pointer here */
@@ -60844,11 +61088,13 @@
61088 if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
61089 }else{
61090 rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ,
61091 pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
61092 );
61093 assert( pWal->apWiData[iPage]!=0
61094 || rc!=SQLITE_OK
61095 || (pWal->writeLock==0 && iPage==0) );
61096 testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
61097 if( rc==SQLITE_OK ){
61098 if( iPage>0 && sqlite3FaultSim(600) ) rc = SQLITE_NOMEM;
61099 }else if( (rc&0xff)==SQLITE_READONLY ){
61100 pWal->readOnly |= WAL_SHM_RDONLY;
@@ -61183,12 +61429,12 @@
61429 ** in the wal-index file. Set pLoc->iZero to one less than the frame
61430 ** number of the first frame indexed by this hash table. If a
61431 ** slot in the hash table is set to N, it refers to frame number
61432 ** (pLoc->iZero+N) in the log.
61433 **
61434 ** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the
61435 ** first frame indexed by the hash table, frame (pLoc->iZero).
61436 */
61437 static int walHashGet(
61438 Wal *pWal, /* WAL handle */
61439 int iHash, /* Find the iHash'th table */
61440 WalHashLoc *pLoc /* OUT: Hash table location */
@@ -61196,19 +61442,20 @@
61442 int rc; /* Return code */
61443
61444 rc = walIndexPage(pWal, iHash, &pLoc->aPgno);
61445 assert( rc==SQLITE_OK || iHash>0 );
61446
61447 if( pLoc->aPgno ){
61448 pLoc->aHash = (volatile ht_slot *)&pLoc->aPgno[HASHTABLE_NPAGE];
61449 if( iHash==0 ){
61450 pLoc->aPgno = &pLoc->aPgno[WALINDEX_HDR_SIZE/sizeof(u32)];
61451 pLoc->iZero = 0;
61452 }else{
61453 pLoc->iZero = HASHTABLE_NPAGE_ONE + (iHash-1)*HASHTABLE_NPAGE;
61454 }
61455 }else if( NEVER(rc==SQLITE_OK) ){
61456 rc = SQLITE_ERROR;
61457 }
61458 return rc;
61459 }
61460
61461 /*
@@ -61286,25 +61533,26 @@
61533 }
61534
61535 /* Zero the entries in the aPgno array that correspond to frames with
61536 ** frame numbers greater than pWal->hdr.mxFrame.
61537 */
61538 nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]);
61539 assert( nByte>=0 );
61540 memset((void *)&sLoc.aPgno[iLimit], 0, nByte);
61541
61542 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61543 /* Verify that the every entry in the mapping region is still reachable
61544 ** via the hash table even after the cleanup.
61545 */
61546 if( iLimit ){
61547 int j; /* Loop counter */
61548 int iKey; /* Hash key */
61549 for(j=0; j<iLimit; j++){
61550 for(iKey=walHash(sLoc.aPgno[j]);sLoc.aHash[iKey];iKey=walNextHash(iKey)){
61551 if( sLoc.aHash[iKey]==j+1 ) break;
61552 }
61553 assert( sLoc.aHash[iKey]==j+1 );
61554 }
61555 }
61556 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61557 }
61558
@@ -61332,32 +61580,32 @@
61580
61581 /* If this is the first entry to be added to this hash-table, zero the
61582 ** entire hash table and aPgno[] array before proceeding.
61583 */
61584 if( idx==1 ){
61585 int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno);
61586 assert( nByte>=0 );
61587 memset((void*)sLoc.aPgno, 0, nByte);
61588 }
61589
61590 /* If the entry in aPgno[] is already set, then the previous writer
61591 ** must have exited unexpectedly in the middle of a transaction (after
61592 ** writing one or more dirty pages to the WAL to free up memory).
61593 ** Remove the remnants of that writers uncommitted transaction from
61594 ** the hash-table before writing any new entries.
61595 */
61596 if( sLoc.aPgno[idx-1] ){
61597 walCleanupHash(pWal);
61598 assert( !sLoc.aPgno[idx-1] );
61599 }
61600
61601 /* Write the aPgno[] array entry and the hash-table slot. */
61602 nCollide = idx;
61603 for(iKey=walHash(iPage); sLoc.aHash[iKey]; iKey=walNextHash(iKey)){
61604 if( (nCollide--)==0 ) return SQLITE_CORRUPT_BKPT;
61605 }
61606 sLoc.aPgno[idx-1] = iPage;
61607 AtomicStore(&sLoc.aHash[iKey], (ht_slot)idx);
61608
61609 #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
61610 /* Verify that the number of entries in the hash table exactly equals
61611 ** the number of entries in the mapping region.
@@ -61374,22 +61622,21 @@
61622 ** thing to check, so only do this occasionally - not on every
61623 ** iteration.
61624 */
61625 if( (idx&0x3ff)==0 ){
61626 int i; /* Loop counter */
61627 for(i=0; i<idx; i++){
61628 for(iKey=walHash(sLoc.aPgno[i]);
61629 sLoc.aHash[iKey];
61630 iKey=walNextHash(iKey)){
61631 if( sLoc.aHash[iKey]==i+1 ) break;
61632 }
61633 assert( sLoc.aHash[iKey]==i+1 );
61634 }
61635 }
61636 #endif /* SQLITE_ENABLE_EXPENSIVE_ASSERT */
61637 }
 
61638
61639 return rc;
61640 }
61641
61642
@@ -61507,11 +61754,12 @@
61754 u32 iFrame; /* Index of last frame read */
61755 u32 iLast = MIN(iLastFrame, HASHTABLE_NPAGE_ONE+iPg*HASHTABLE_NPAGE);
61756 u32 iFirst = 1 + (iPg==0?0:HASHTABLE_NPAGE_ONE+(iPg-1)*HASHTABLE_NPAGE);
61757 u32 nHdr, nHdr32;
61758 rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare);
61759 assert( aShare!=0 || rc!=SQLITE_OK );
61760 if( aShare==0 ) break;
61761 pWal->apWiData[iPg] = aPrivate;
61762
61763 for(iFrame=iFirst; iFrame<=iLast; iFrame++){
61764 i64 iOffset = walFrameOffset(iFrame, szPage);
61765 u32 pgno; /* Database page number for frame */
@@ -62004,11 +62252,10 @@
62252 if( rc==SQLITE_OK ){
62253 int j; /* Counter variable */
62254 int nEntry; /* Number of entries in this segment */
62255 ht_slot *aIndex; /* Sorted index for this segment */
62256
 
62257 if( (i+1)==nSegment ){
62258 nEntry = (int)(iLast - sLoc.iZero);
62259 }else{
62260 nEntry = (int)((u32*)sLoc.aHash - (u32*)sLoc.aPgno);
62261 }
@@ -63143,11 +63390,12 @@
63390 i64 iDbOff; /* Offset of db file entry */
63391 i64 iWalOff; /* Offset of wal file entry */
63392
63393 rc = walHashGet(pWal, walFramePage(i), &sLoc);
63394 if( rc!=SQLITE_OK ) break;
63395 assert( i - sLoc.iZero - 1 >=0 );
63396 pgno = sLoc.aPgno[i-sLoc.iZero-1];
63397 iDbOff = (i64)(pgno-1) * szPage;
63398
63399 if( iDbOff+szPage<=szDb ){
63400 iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE;
63401 rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff);
@@ -63376,11 +63624,11 @@
63624 }
63625 nCollide = HASHTABLE_NSLOT;
63626 iKey = walHash(pgno);
63627 while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){
63628 u32 iFrame = iH + sLoc.iZero;
63629 if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){
63630 assert( iFrame>iRead || CORRUPT_DB );
63631 iRead = iFrame;
63632 }
63633 if( (nCollide--)==0 ){
63634 return SQLITE_CORRUPT_BKPT;
@@ -64628,11 +64876,10 @@
64876 ** Access to all fields of this structure is controlled by the mutex
64877 ** stored in MemPage.pBt->mutex.
64878 */
64879 struct MemPage {
64880 u8 isInit; /* True if previously initialized. MUST BE FIRST! */
 
64881 u8 intKey; /* True if table b-trees. False for index b-trees */
64882 u8 intKeyLeaf; /* True if the leaf of an intKey table */
64883 Pgno pgno; /* Page number for this page */
64884 /* Only the first 8 bytes (above) are zeroed by pager.c when a new page
64885 ** is allocated. All fields that follow must be initialized before use */
@@ -66870,11 +67117,11 @@
67117 if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
67118 sz2 = get2byte(&data[iFree2+2]);
67119 if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
67120 memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
67121 sz += sz2;
67122 }else if( NEVER(iFree+sz>usableSize) ){
67123 return SQLITE_CORRUPT_PAGE(pPage);
67124 }
67125
67126 cbrk = top+sz;
67127 assert( cbrk+(iFree-top) <= usableSize );
@@ -68075,34 +68322,42 @@
68322 /*
68323 ** Make sure pBt->pTmpSpace points to an allocation of
68324 ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child
68325 ** pointer.
68326 */
68327 static SQLITE_NOINLINE int allocateTempSpace(BtShared *pBt){
68328 assert( pBt!=0 );
68329 assert( pBt->pTmpSpace==0 );
68330 /* This routine is called only by btreeCursor() when allocating the
68331 ** first write cursor for the BtShared object */
68332 assert( pBt->pCursor!=0 && (pBt->pCursor->curFlags & BTCF_WriteFlag)!=0 );
68333 pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
68334 if( pBt->pTmpSpace==0 ){
68335 BtCursor *pCur = pBt->pCursor;
68336 pBt->pCursor = pCur->pNext; /* Unlink the cursor */
68337 memset(pCur, 0, sizeof(*pCur));
68338 return SQLITE_NOMEM_BKPT;
68339 }
68340
68341 /* One of the uses of pBt->pTmpSpace is to format cells before
68342 ** inserting them into a leaf page (function fillInCell()). If
68343 ** a cell is less than 4 bytes in size, it is rounded up to 4 bytes
68344 ** by the various routines that manipulate binary cells. Which
68345 ** can mean that fillInCell() only initializes the first 2 or 3
68346 ** bytes of pTmpSpace, but that the first 4 bytes are copied from
68347 ** it into a database page. This is not actually a problem, but it
68348 ** does cause a valgrind error when the 1 or 2 bytes of unitialized
68349 ** data is passed to system call write(). So to avoid this error,
68350 ** zero the first 4 bytes of temp space here.
68351 **
68352 ** Also: Provide four bytes of initialized space before the
68353 ** beginning of pTmpSpace as an area available to prepend the
68354 ** left-child pointer to the beginning of a cell.
68355 */
68356 memset(pBt->pTmpSpace, 0, 8);
68357 pBt->pTmpSpace += 4;
68358 return SQLITE_OK;
68359 }
68360
68361 /*
68362 ** Free the pBt->pTmpSpace allocation
68363 */
@@ -68477,11 +68732,10 @@
68732 static int lockBtree(BtShared *pBt){
68733 int rc; /* Result code from subfunctions */
68734 MemPage *pPage1; /* Page 1 of the database file */
68735 u32 nPage; /* Number of pages in the database */
68736 u32 nPageFile = 0; /* Number of pages in the database file */
 
68737
68738 assert( sqlite3_mutex_held(pBt->mutex) );
68739 assert( pBt->pPage1==0 );
68740 rc = sqlite3PagerSharedLock(pBt->pPager);
68741 if( rc!=SQLITE_OK ) return rc;
@@ -68489,11 +68743,11 @@
68743 if( rc!=SQLITE_OK ) return rc;
68744
68745 /* Do some checking to help insure the file we opened really is
68746 ** a valid database file.
68747 */
68748 nPage = get4byte(28+(u8*)pPage1->aData);
68749 sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile);
68750 if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){
68751 nPage = nPageFile;
68752 }
68753 if( (pBt->db->flags & SQLITE_ResetDatabase)!=0 ){
@@ -69322,27 +69576,30 @@
69576 }
69577
69578 /*
69579 ** This routine is called prior to sqlite3PagerCommit when a transaction
69580 ** is committed for an auto-vacuum database.
 
 
 
 
 
69581 */
69582 static int autoVacuumCommit(Btree *p){
69583 int rc = SQLITE_OK;
69584 Pager *pPager;
69585 BtShared *pBt;
69586 sqlite3 *db;
69587 VVA_ONLY( int nRef );
69588
69589 assert( p!=0 );
69590 pBt = p->pBt;
69591 pPager = pBt->pPager;
69592 VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); )
69593
69594 assert( sqlite3_mutex_held(pBt->mutex) );
69595 invalidateAllOverflowCache(pBt);
69596 assert(pBt->autoVacuum);
69597 if( !pBt->incrVacuum ){
69598 Pgno nFin; /* Number of pages in database after autovacuuming */
69599 Pgno nFree; /* Number of pages on the freelist initially */
69600 Pgno nVac; /* Number of pages to vacuum */
69601 Pgno iFree; /* The next page to be freed */
69602 Pgno nOrig; /* Database size before freeing */
69603
69604 nOrig = btreePagecount(pBt);
69605 if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){
@@ -69352,22 +69609,46 @@
69609 */
69610 return SQLITE_CORRUPT_BKPT;
69611 }
69612
69613 nFree = get4byte(&pBt->pPage1->aData[36]);
69614 db = p->db;
69615 if( db->xAutovacPages ){
69616 int iDb;
69617 for(iDb=0; ALWAYS(iDb<db->nDb); iDb++){
69618 if( db->aDb[iDb].pBt==p ) break;
69619 }
69620 nVac = db->xAutovacPages(
69621 db->pAutovacPagesArg,
69622 db->aDb[iDb].zDbSName,
69623 nOrig,
69624 nFree,
69625 pBt->pageSize
69626 );
69627 if( nVac>nFree ){
69628 nVac = nFree;
69629 }
69630 if( nVac==0 ){
69631 return SQLITE_OK;
69632 }
69633 }else{
69634 nVac = nFree;
69635 }
69636 nFin = finalDbSize(pBt, nOrig, nVac);
69637 if( nFin>nOrig ) return SQLITE_CORRUPT_BKPT;
69638 if( nFin<nOrig ){
69639 rc = saveAllCursors(pBt, 0, 0);
69640 }
69641 for(iFree=nOrig; iFree>nFin && rc==SQLITE_OK; iFree--){
69642 rc = incrVacuumStep(pBt, nFin, iFree, nVac==nFree);
69643 }
69644 if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){
69645 rc = sqlite3PagerWrite(pBt->pPage1->pDbPage);
69646 if( nVac==nFree ){
69647 put4byte(&pBt->pPage1->aData[32], 0);
69648 put4byte(&pBt->pPage1->aData[36], 0);
69649 }
69650 put4byte(&pBt->pPage1->aData[28], nFin);
69651 pBt->bDoTruncate = 1;
69652 pBt->nPage = nFin;
69653 }
69654 if( rc!=SQLITE_OK ){
@@ -69414,11 +69695,11 @@
69695 if( p->inTrans==TRANS_WRITE ){
69696 BtShared *pBt = p->pBt;
69697 sqlite3BtreeEnter(p);
69698 #ifndef SQLITE_OMIT_AUTOVACUUM
69699 if( pBt->autoVacuum ){
69700 rc = autoVacuumCommit(p);
69701 if( rc!=SQLITE_OK ){
69702 sqlite3BtreeLeave(p);
69703 return rc;
69704 }
69705 }
@@ -69813,14 +70094,10 @@
70094 assert( p->inTrans>TRANS_NONE );
70095 assert( wrFlag==0 || p->inTrans==TRANS_WRITE );
70096 assert( pBt->pPage1 && pBt->pPage1->aData );
70097 assert( wrFlag==0 || (pBt->btsFlags & BTS_READ_ONLY)==0 );
70098
 
 
 
 
70099 if( iTable<=1 ){
70100 if( iTable<1 ){
70101 return SQLITE_CORRUPT_BKPT;
70102 }else if( btreePagecount(pBt)==0 ){
70103 assert( wrFlag==0 );
@@ -69833,23 +70110,29 @@
70110 pCur->pgnoRoot = iTable;
70111 pCur->iPage = -1;
70112 pCur->pKeyInfo = pKeyInfo;
70113 pCur->pBtree = p;
70114 pCur->pBt = pBt;
70115 pCur->curFlags = 0;
 
70116 /* If there are two or more cursors on the same btree, then all such
70117 ** cursors *must* have the BTCF_Multiple flag set. */
70118 for(pX=pBt->pCursor; pX; pX=pX->pNext){
70119 if( pX->pgnoRoot==iTable ){
70120 pX->curFlags |= BTCF_Multiple;
70121 pCur->curFlags = BTCF_Multiple;
70122 }
70123 }
70124 pCur->eState = CURSOR_INVALID;
70125 pCur->pNext = pBt->pCursor;
70126 pBt->pCursor = pCur;
70127 if( wrFlag ){
70128 pCur->curFlags |= BTCF_WriteFlag;
70129 pCur->curPagerFlags = 0;
70130 if( pBt->pTmpSpace==0 ) return allocateTempSpace(pBt);
70131 }else{
70132 pCur->curPagerFlags = PAGER_GET_READONLY;
70133 }
70134 return SQLITE_OK;
70135 }
70136 static int btreeCursorWithLock(
70137 Btree *p, /* The btree */
70138 Pgno iTable, /* Root page of table to open */
@@ -70219,11 +70502,13 @@
70502 #endif
70503
70504 assert( pPage );
70505 assert( eOp==0 || eOp==1 );
70506 assert( pCur->eState==CURSOR_VALID );
70507 if( pCur->ix>=pPage->nCell ){
70508 return SQLITE_CORRUPT_PAGE(pPage);
70509 }
70510 assert( cursorHoldsMutex(pCur) );
70511
70512 getCellInfo(pCur);
70513 aPayload = pCur->info.pPayload;
70514 assert( offset+amt <= pCur->info.nPayload );
@@ -70406,11 +70691,10 @@
70691 */
70692 SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
70693 assert( cursorHoldsMutex(pCur) );
70694 assert( pCur->eState==CURSOR_VALID );
70695 assert( pCur->iPage>=0 && pCur->pPage );
 
70696 return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0);
70697 }
70698
70699 /*
70700 ** This variant of sqlite3BtreePayload() works even if the cursor has not
@@ -70468,11 +70752,11 @@
70752 int amt;
70753 assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
70754 assert( pCur->eState==CURSOR_VALID );
70755 assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
70756 assert( cursorOwnsBtShared(pCur) );
70757 assert( pCur->ix<pCur->pPage->nCell || CORRUPT_DB );
70758 assert( pCur->info.nSize>0 );
70759 assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
70760 assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
70761 amt = pCur->info.nLocal;
70762 if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
@@ -71254,20 +71538,10 @@
71538 ** module cov1/btree78.test testcase 220 (2018-06-08) for an
71539 ** example. */
71540 return SQLITE_CORRUPT_BKPT;
71541 }
71542
 
 
 
 
 
 
 
 
 
 
71543 if( idx>=pPage->nCell ){
71544 if( !pPage->leaf ){
71545 rc = moveToChild(pCur, get4byte(&pPage->aData[pPage->hdrOffset+8]));
71546 if( rc ) return rc;
71547 return moveToLeftmost(pCur);
@@ -71751,11 +72025,11 @@
72025
72026 assert( sqlite3_mutex_held(pBt->mutex) );
72027 assert( CORRUPT_DB || iPage>1 );
72028 assert( !pMemPage || pMemPage->pgno==iPage );
72029
72030 if( NEVER(iPage<2) || iPage>pBt->nPage ){
72031 return SQLITE_CORRUPT_BKPT;
72032 }
72033 if( pMemPage ){
72034 pPage = pMemPage;
72035 sqlite3PagerRef(pPage->pDbPage);
@@ -73069,15 +73343,14 @@
73343 Pgno pgno; /* Temp var to store a page number in */
73344 u8 abDone[NB+2]; /* True after i'th new page is populated */
73345 Pgno aPgno[NB+2]; /* Page numbers of new pages before shuffling */
73346 Pgno aPgOrder[NB+2]; /* Copy of aPgno[] used for sorting pages */
73347 u16 aPgFlags[NB+2]; /* flags field of new pages before shuffling */
73348 CellArray b; /* Parsed information on cells being balanced */
73349
73350 memset(abDone, 0, sizeof(abDone));
73351 memset(&b, 0, sizeof(b));
 
73352 pBt = pParent->pBt;
73353 assert( sqlite3_mutex_held(pBt->mutex) );
73354 assert( sqlite3PagerIswriteable(pParent->pDbPage) );
73355
73356 /* At this point pParent may have at most one overflow cell. And if
@@ -73884,11 +74157,11 @@
74157
74158 /*
74159 ** Return SQLITE_CORRUPT if any cursor other than pCur is currently valid
74160 ** on the same B-tree as pCur.
74161 **
74162 ** This can occur if a database is corrupt with two or more SQL tables
74163 ** pointing to the same b-tree. If an insert occurs on one SQL table
74164 ** and causes a BEFORE TRIGGER to do a secondary insert on the other SQL
74165 ** table linked to the same b-tree. If the secondary insert causes a
74166 ** rebalance, that can change content out from under the cursor on the
74167 ** first SQL table, violating invariants on the first insert.
@@ -74353,11 +74626,14 @@
74626 assert( szNew==pPage->xCellSize(pPage, newCell) );
74627 assert( szNew <= MX_CELL_SIZE(pBt) );
74628 idx = pCur->ix;
74629 if( loc==0 ){
74630 CellInfo info;
74631 assert( idx>=0 );
74632 if( idx>=pPage->nCell ){
74633 return SQLITE_CORRUPT_BKPT;
74634 }
74635 rc = sqlite3PagerWrite(pPage->pDbPage);
74636 if( rc ){
74637 goto end_insert;
74638 }
74639 oldCell = findCell(pPage, idx);
@@ -74939,15 +75215,16 @@
75215 if( pgno>btreePagecount(pBt) ){
75216 return SQLITE_CORRUPT_BKPT;
75217 }
75218 rc = getAndInitPage(pBt, pgno, &pPage, 0, 0);
75219 if( rc ) return rc;
75220 if( (pBt->openFlags & BTREE_SINGLE)==0
75221 && sqlite3PagerPageRefcount(pPage->pDbPage)!=1
75222 ){
75223 rc = SQLITE_CORRUPT_BKPT;
75224 goto cleardatabasepage_out;
75225 }
 
75226 hdr = pPage->hdrOffset;
75227 for(i=0; i<pPage->nCell; i++){
75228 pCell = findCell(pPage, i);
75229 if( !pPage->leaf ){
75230 rc = clearDatabasePage(pBt, get4byte(pCell), 1, pnChange);
@@ -74970,11 +75247,10 @@
75247 }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
75248 zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF);
75249 }
75250
75251 cleardatabasepage_out:
 
75252 releasePage(pPage);
75253 return rc;
75254 }
75255
75256 /*
@@ -75049,14 +75325,14 @@
75325 assert( iTable>=2 );
75326 if( iTable>btreePagecount(pBt) ){
75327 return SQLITE_CORRUPT_BKPT;
75328 }
75329
 
 
75330 rc = sqlite3BtreeClearTable(p, iTable, 0);
75331 if( rc ) return rc;
75332 rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0);
75333 if( NEVER(rc) ){
75334 releasePage(pPage);
75335 return rc;
75336 }
75337
75338 *piMoved = 0;
@@ -77209,10 +77485,11 @@
77485 */
77486 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){
77487 #ifndef SQLITE_OMIT_UTF16
77488 int rc;
77489 #endif
77490 assert( pMem!=0 );
77491 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77492 assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE
77493 || desiredEnc==SQLITE_UTF16BE );
77494 if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){
77495 return SQLITE_OK;
@@ -77341,10 +77618,11 @@
77618 ** MEM.zMalloc, where it can be safely written.
77619 **
77620 ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails.
77621 */
77622 SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){
77623 assert( pMem!=0 );
77624 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77625 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77626 if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){
77627 if( ExpandBlob(pMem) ) return SQLITE_NOMEM;
77628 if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){
@@ -77365,10 +77643,11 @@
77643 ** blob stored in dynamically allocated space.
77644 */
77645 #ifndef SQLITE_OMIT_INCRBLOB
77646 SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){
77647 int nByte;
77648 assert( pMem!=0 );
77649 assert( pMem->flags & MEM_Zero );
77650 assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
77651 testcase( sqlite3_value_nochange(pMem) );
77652 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77653 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -77380,10 +77659,12 @@
77659 nByte = 1;
77660 }
77661 if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
77662 return SQLITE_NOMEM_BKPT;
77663 }
77664 assert( pMem->z!=0 );
77665 assert( sqlite3DbMallocSize(pMem->db,pMem->z) >= nByte );
77666
77667 memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
77668 pMem->n += pMem->u.nZero;
77669 pMem->flags &= ~(MEM_Zero|MEM_Term);
77670 return SQLITE_OK;
@@ -77392,10 +77673,11 @@
77673
77674 /*
77675 ** Make sure the given Mem is \u0000 terminated.
77676 */
77677 SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){
77678 assert( pMem!=0 );
77679 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77680 testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) );
77681 testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 );
77682 if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){
77683 return SQLITE_OK; /* Nothing to do */
@@ -77419,10 +77701,11 @@
77701 ** user and the latter is an internal programming error.
77702 */
77703 SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){
77704 const int nByte = 32;
77705
77706 assert( pMem!=0 );
77707 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77708 assert( !(pMem->flags&MEM_Zero) );
77709 assert( !(pMem->flags&(MEM_Str|MEM_Blob)) );
77710 assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) );
77711 assert( !sqlite3VdbeMemIsRowSet(pMem) );
@@ -77454,10 +77737,11 @@
77737 */
77738 SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
77739 sqlite3_context ctx;
77740 Mem t;
77741 assert( pFunc!=0 );
77742 assert( pMem!=0 );
77743 assert( pFunc->xFinalize!=0 );
77744 assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef );
77745 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77746 memset(&ctx, 0, sizeof(ctx));
77747 memset(&t, 0, sizeof(t));
@@ -77597,17 +77881,18 @@
77881 ** it into an integer and return that. If pMem represents an
77882 ** an SQL-NULL value, return 0.
77883 **
77884 ** If pMem represents a string value, its encoding might be changed.
77885 */
77886 static SQLITE_NOINLINE i64 memIntValue(const Mem *pMem){
77887 i64 value = 0;
77888 sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc);
77889 return value;
77890 }
77891 SQLITE_PRIVATE i64 sqlite3VdbeIntValue(const Mem *pMem){
77892 int flags;
77893 assert( pMem!=0 );
77894 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77895 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77896 flags = pMem->flags;
77897 if( flags & (MEM_Int|MEM_IntReal) ){
77898 testcase( flags & MEM_IntReal );
@@ -77632,10 +77917,11 @@
77917 double val = (double)0;
77918 sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc);
77919 return val;
77920 }
77921 SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){
77922 assert( pMem!=0 );
77923 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77924 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77925 if( pMem->flags & MEM_Real ){
77926 return pMem->u.r;
77927 }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){
@@ -77664,10 +77950,11 @@
77950 ** The MEM structure is already a MEM_Real. Try to also make it a
77951 ** MEM_Int if we can.
77952 */
77953 SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){
77954 i64 ix;
77955 assert( pMem!=0 );
77956 assert( pMem->flags & MEM_Real );
77957 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77958 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77959 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77960
@@ -77691,10 +77978,11 @@
77978
77979 /*
77980 ** Convert pMem to type integer. Invalidate any prior representations.
77981 */
77982 SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){
77983 assert( pMem!=0 );
77984 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
77985 assert( !sqlite3VdbeMemIsRowSet(pMem) );
77986 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
77987
77988 pMem->u.i = sqlite3VdbeIntValue(pMem);
@@ -77705,10 +77993,11 @@
77993 /*
77994 ** Convert pMem so that it is of type MEM_Real.
77995 ** Invalidate any prior representations.
77996 */
77997 SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){
77998 assert( pMem!=0 );
77999 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
78000 assert( EIGHT_BYTE_ALIGNMENT(pMem) );
78001
78002 pMem->u.r = sqlite3VdbeRealValue(pMem);
78003 MemSetTypeFlag(pMem, MEM_Real);
@@ -77738,10 +78027,11 @@
78027 ** Every effort is made to force the conversion, even if the input
78028 ** is a string that does not look completely like a number. Convert
78029 ** as much of the string as we can and ignore the rest.
78030 */
78031 SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){
78032 assert( pMem!=0 );
78033 testcase( pMem->flags & MEM_Int );
78034 testcase( pMem->flags & MEM_Real );
78035 testcase( pMem->flags & MEM_IntReal );
78036 testcase( pMem->flags & MEM_Null );
78037 if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){
@@ -77847,19 +78137,35 @@
78137
78138 /*
78139 ** Delete any previous value and set the value to be a BLOB of length
78140 ** n containing all zeros.
78141 */
78142 #ifndef SQLITE_OMIT_INCRBLOB
78143 SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78144 sqlite3VdbeMemRelease(pMem);
78145 pMem->flags = MEM_Blob|MEM_Zero;
78146 pMem->n = 0;
78147 if( n<0 ) n = 0;
78148 pMem->u.nZero = n;
78149 pMem->enc = SQLITE_UTF8;
78150 pMem->z = 0;
78151 }
78152 #else
78153 SQLITE_PRIVATE int sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){
78154 int nByte = n>0?n:1;
78155 if( sqlite3VdbeMemGrow(pMem, nByte, 0) ){
78156 return SQLITE_NOMEM_BKPT;
78157 }
78158 assert( pMem->z!=0 );
78159 assert( sqlite3DbMallocSize(pMem->db, pMem->z)>=nByte );
78160 memset(pMem->z, 0, nByte);
78161 pMem->n = n>0?n:0;
78162 pMem->flags = MEM_Blob;
78163 pMem->enc = SQLITE_UTF8;
78164 return SQLITE_OK;
78165 }
78166 #endif
78167
78168 /*
78169 ** The pMem is known to contain content that needs to be destroyed prior
78170 ** to a value change. So invoke the destructor, then set the value to
78171 ** a 64-bit integer.
@@ -78089,10 +78395,11 @@
78395 ){
78396 i64 nByte = n; /* New value for pMem->n */
78397 int iLimit; /* Maximum allowed string or blob size */
78398 u16 flags = 0; /* New value for pMem->flags */
78399
78400 assert( pMem!=0 );
78401 assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
78402 assert( !sqlite3VdbeMemIsRowSet(pMem) );
78403
78404 /* If z is a NULL pointer, set pMem to contain an SQL NULL. */
78405 if( !z ){
@@ -78414,12 +78721,14 @@
78721 ExprList *pList = 0; /* Function arguments */
78722 int i; /* Iterator variable */
78723
78724 assert( pCtx!=0 );
78725 assert( (p->flags & EP_TokenOnly)==0 );
78726 assert( ExprUseXList(p) );
78727 pList = p->x.pList;
78728 if( pList ) nVal = pList->nExpr;
78729 assert( !ExprHasProperty(p, EP_IntValue) );
78730 pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0);
78731 assert( pFunc );
78732 if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
78733 || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
78734 ){
@@ -78519,11 +78828,13 @@
78828 ** check ensures that an EP_TokenOnly expression is never passed down
78829 ** into valueFromFunction(). */
78830 assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );
78831
78832 if( op==TK_CAST ){
78833 u8 aff;
78834 assert( !ExprHasProperty(pExpr, EP_IntValue) );
78835 aff = sqlite3AffinityType(pExpr->u.zToken,0);
78836 rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx);
78837 testcase( rc!=SQLITE_OK );
78838 if( *ppVal ){
78839 sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8);
78840 sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8);
@@ -78592,10 +78903,11 @@
78903 sqlite3VdbeMemSetNull(pVal);
78904 }
78905 #ifndef SQLITE_OMIT_BLOB_LITERAL
78906 else if( op==TK_BLOB ){
78907 int nVal;
78908 assert( !ExprHasProperty(pExpr, EP_IntValue) );
78909 assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' );
78910 assert( pExpr->u.zToken[1]=='\'' );
78911 pVal = valueNew(db, pCtx);
78912 if( !pVal ) goto no_mem;
78913 zVal = &pExpr->u.zToken[2];
@@ -78609,10 +78921,11 @@
78921 else if( op==TK_FUNCTION && pCtx!=0 ){
78922 rc = valueFromFunction(db, pExpr, enc, affinity, &pVal, pCtx);
78923 }
78924 #endif
78925 else if( op==TK_TRUEFALSE ){
78926 assert( !ExprHasProperty(pExpr, EP_IntValue) );
78927 pVal = valueNew(db, pCtx);
78928 if( pVal ){
78929 pVal->flags = MEM_Int;
78930 pVal->u.i = pExpr->u.zToken[4]==0;
78931 }
@@ -79162,12 +79475,14 @@
79475 assert( p->iVdbeMagic==VDBE_MAGIC_INIT );
79476 assert( op>=0 && op<0xff );
79477 if( p->nOpAlloc<=i ){
79478 return growOp3(p, op, p1, p2, p3);
79479 }
79480 assert( p->aOp!=0 );
79481 p->nOp++;
79482 pOp = &p->aOp[i];
79483 assert( pOp!=0 );
79484 pOp->opcode = (u8)op;
79485 pOp->p5 = 0;
79486 pOp->p1 = p1;
79487 pOp->p2 = p2;
79488 pOp->p3 = p3;
@@ -80406,11 +80721,11 @@
80721 zOpName = sqlite3OpcodeName(pOp->opcode);
80722 nOpName = sqlite3Strlen30(zOpName);
80723 if( zOpName[nOpName+1] ){
80724 int seenCom = 0;
80725 char c;
80726 zSynopsis = zOpName + nOpName + 1;
80727 if( strncmp(zSynopsis,"IF ",3)==0 ){
80728 sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3);
80729 zSynopsis = zAlt;
80730 }
80731 for(ii=0; (c = zSynopsis[ii])!=0; ii++){
@@ -80479,10 +80794,11 @@
80794 */
80795 static void displayP4Expr(StrAccum *p, Expr *pExpr){
80796 const char *zOp = 0;
80797 switch( pExpr->op ){
80798 case TK_STRING:
80799 assert( !ExprHasProperty(pExpr, EP_IntValue) );
80800 sqlite3_str_appendf(p, "%Q", pExpr->u.zToken);
80801 break;
80802 case TK_INTEGER:
80803 sqlite3_str_appendf(p, "%d", pExpr->u.iValue);
80804 break;
@@ -80825,12 +81141,12 @@
81141 ** with no indexes using a single prepared INSERT statement, bind()
81142 ** and reset(). Inserts are grouped into a transaction.
81143 */
81144 testcase( p->flags & MEM_Agg );
81145 testcase( p->flags & MEM_Dyn );
 
81146 if( p->flags&(MEM_Agg|MEM_Dyn) ){
81147 testcase( (p->flags & MEM_Dyn)!=0 && p->xDel==sqlite3VdbeFrameMemDel );
81148 sqlite3VdbeMemRelease(p);
81149 }else if( p->szMalloc ){
81150 sqlite3DbFreeNN(db, p->zMalloc);
81151 p->szMalloc = 0;
81152 }
@@ -81974,13 +82290,19 @@
82290
82291 /* Lock all btrees used by the statement */
82292 sqlite3VdbeEnter(p);
82293
82294 /* Check for one of the special errors */
82295 if( p->rc ){
82296 mrc = p->rc & 0xff;
82297 isSpecialError = mrc==SQLITE_NOMEM
82298 || mrc==SQLITE_IOERR
82299 || mrc==SQLITE_INTERRUPT
82300 || mrc==SQLITE_FULL;
82301 }else{
82302 mrc = isSpecialError = 0;
82303 }
82304 if( isSpecialError ){
82305 /* If the query was read-only and the error code is SQLITE_INTERRUPT,
82306 ** no rollback is necessary. Otherwise, at least a savepoint
82307 ** transaction must be rolled back to restore the database to a
82308 ** consistent state.
@@ -82028,10 +82350,13 @@
82350 if( NEVER(p->readOnly) ){
82351 sqlite3VdbeLeave(p);
82352 return SQLITE_ERROR;
82353 }
82354 rc = SQLITE_CONSTRAINT_FOREIGNKEY;
82355 }else if( db->flags & SQLITE_CorruptRdOnly ){
82356 rc = SQLITE_CORRUPT;
82357 db->flags &= ~SQLITE_CorruptRdOnly;
82358 }else{
82359 /* The auto-commit flag is true, the vdbe program was successful
82360 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
82361 ** key constraints to hold up the transaction. This means a commit
82362 ** is required. */
@@ -84132,10 +84457,12 @@
84457 }else{
84458 iKey2 = iKey1;
84459 }
84460 }
84461
84462 assert( pCsr!=0 );
84463 assert( pCsr->eCurType==CURTYPE_BTREE );
84464 assert( pCsr->nField==pTab->nCol
84465 || (pCsr->nField==pTab->nCol+1 && op==SQLITE_DELETE && iReg==-1)
84466 );
84467
84468 preupdate.v = v;
@@ -84531,12 +84858,12 @@
84858 /**************************** sqlite3_result_ *******************************
84859 ** The following routines are used by user-defined functions to specify
84860 ** the function result.
84861 **
84862 ** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the
84863 ** result as a string or blob. Appropriate errors are set if the string/blob
84864 ** is too big or if an OOM occurs.
84865 **
84866 ** The invokeValueDestructor(P,X) routine invokes destructor function X()
84867 ** on value P is not going to be used and need to be destroyed.
84868 */
84869 static void setResultStrOrError(
@@ -84544,12 +84871,20 @@
84871 const char *z, /* String pointer */
84872 int n, /* Bytes in string, or negative */
84873 u8 enc, /* Encoding of z. 0 for BLOBs */
84874 void (*xDel)(void*) /* Destructor function */
84875 ){
84876 int rc = sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel);
84877 if( rc ){
84878 if( rc==SQLITE_TOOBIG ){
84879 sqlite3_result_error_toobig(pCtx);
84880 }else{
84881 /* The only errors possible from sqlite3VdbeMemSetStr are
84882 ** SQLITE_TOOBIG and SQLITE_NOMEM */
84883 assert( rc==SQLITE_NOMEM );
84884 sqlite3_result_error_nomem(pCtx);
84885 }
84886 }
84887 }
84888 static int invokeValueDestructor(
84889 const void *p, /* Value to destroy */
84890 void (*xDel)(void*), /* The destructor */
@@ -84702,12 +85037,16 @@
85037 Mem *pOut = pCtx->pOut;
85038 assert( sqlite3_mutex_held(pOut->db->mutex) );
85039 if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
85040 return SQLITE_TOOBIG;
85041 }
85042 #ifndef SQLITE_OMIT_INCRBLOB
85043 sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
85044 return SQLITE_OK;
85045 #else
85046 return sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
85047 #endif
85048 }
85049 SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
85050 pCtx->isError = errCode ? errCode : -1;
85051 #ifdef SQLITE_DEBUG
85052 if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
@@ -85715,11 +86054,15 @@
86054 SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){
86055 int rc;
86056 Vdbe *p = (Vdbe *)pStmt;
86057 rc = vdbeUnbind(p, i);
86058 if( rc==SQLITE_OK ){
86059 #ifndef SQLITE_OMIT_INCRBLOB
86060 sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
86061 #else
86062 rc = sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n);
86063 #endif
86064 sqlite3_mutex_leave(p->db->mutex);
86065 }
86066 return rc;
86067 }
86068 SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){
@@ -86003,10 +86346,11 @@
86346 /* If the old.* record has not yet been loaded into memory, do so now. */
86347 if( p->pUnpacked==0 ){
86348 u32 nRec;
86349 u8 *aRec;
86350
86351 assert( p->pCsr->eCurType==CURTYPE_BTREE );
86352 nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor);
86353 aRec = sqlite3DbMallocRaw(db, nRec);
86354 if( !aRec ) goto preupdate_old_out;
86355 rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec);
86356 if( rc==SQLITE_OK ){
@@ -87091,10 +87435,35 @@
87435 }else{
87436 pOut->flags = MEM_Int;
87437 return pOut;
87438 }
87439 }
87440
87441 /*
87442 ** Compute a bloom filter hash using pOp->p4.i registers from aMem[] beginning
87443 ** with pOp->p3. Return the hash.
87444 */
87445 static u64 filterHash(const Mem *aMem, const Op *pOp){
87446 int i, mx;
87447 u64 h = 0;
87448
87449 i = pOp->p3;
87450 assert( pOp->p4type==P4_INT32 );
87451 mx = i + pOp->p4.i;
87452 for(i=pOp->p3, mx=i+pOp->p4.i; i<mx; i++){
87453 const Mem *p = &aMem[i];
87454 if( p->flags & (MEM_Int|MEM_IntReal) ){
87455 h += p->u.i;
87456 }else if( p->flags & MEM_Real ){
87457 h += sqlite3VdbeIntValue(p);
87458 }else if( p->flags & (MEM_Str|MEM_Blob) ){
87459 h += p->n;
87460 if( p->flags & MEM_Zero ) h += p->u.nZero;
87461 }
87462 }
87463 return h;
87464 }
87465
87466 /*
87467 ** Return the symbolic name for the data type of a pMem
87468 */
87469 static const char *vdbeMemTypeName(Mem *pMem){
@@ -87746,16 +88115,22 @@
88115
88116 /* Opcode: Blob P1 P2 * P4 *
88117 ** Synopsis: r[P2]=P4 (len=P1)
88118 **
88119 ** P4 points to a blob of data P1 bytes long. Store this
88120 ** blob in register P2. If P4 is a NULL pointer, then construct
88121 ** a zero-filled blob that is P1 bytes long in P2.
88122 */
88123 case OP_Blob: { /* out2 */
88124 assert( pOp->p1 <= SQLITE_MAX_LENGTH );
88125 pOut = out2Prerelease(p, pOp);
88126 if( pOp->p4.z==0 ){
88127 sqlite3VdbeMemSetZeroBlob(pOut, pOp->p1);
88128 if( sqlite3VdbeMemExpandBlob(pOut) ) goto no_mem;
88129 }else{
88130 sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0);
88131 }
88132 pOut->enc = encoding;
88133 UPDATE_MAX_BLOBSIZE(pOut);
88134 break;
88135 }
88136
@@ -87900,28 +88275,26 @@
88275 pOut = &aMem[pOp->p2];
88276 sqlite3VdbeMemSetInt64(pOut, pIn1->u.i);
88277 break;
88278 }
88279
88280 /* Opcode: FkCheck * * * * *
88281 **
88282 ** Halt with an SQLITE_CONSTRAINT error if there are any unresolved
88283 ** foreign key constraint violations. If there are no foreign key
88284 ** constraint violations, this is a no-op.
88285 **
88286 ** FK constraint violations are also checked when the prepared statement
88287 ** exits. This opcode is used to raise foreign key constraint errors prior
88288 ** to returning results such as a row change count or the result of a
88289 ** RETURNING clause.
88290 */
88291 case OP_FkCheck: {
 
88292 if( (rc = sqlite3VdbeCheckFk(p,0))!=SQLITE_OK ){
88293 goto abort_due_to_error;
88294 }
88295 break;
 
88296 }
88297
88298 /* Opcode: ResultRow P1 P2 * * *
88299 ** Synopsis: output=r[P1@P2]
88300 **
@@ -89320,20 +89693,25 @@
89693 rc = SQLITE_CORRUPT_BKPT;
89694 goto abort_due_to_error;
89695 }
89696 }
89697
89698 /* Opcode: TypeCheck P1 P2 P3 P4 *
89699 ** Synopsis: typecheck(r[P1@P2])
89700 **
89701 ** Apply affinities to the range of P2 registers beginning with P1.
89702 ** Take the affinities from the Table object in P4. If any value
89703 ** cannot be coerced into the correct type, then raise an error.
89704 **
89705 ** This opcode is similar to OP_Affinity except that this opcode
89706 ** forces the register type to the Table column type. This is used
89707 ** to implement "strict affinity".
89708 **
89709 ** GENERATED ALWAYS AS ... STATIC columns are only checked if P3
89710 ** is zero. When P3 is non-zero, no type checking occurs for
89711 ** static generated columns. Virtual columns are computed at query time
89712 ** and so they are never checked.
89713 **
89714 ** Preconditions:
89715 **
89716 ** <ul>
89717 ** <li> P2 should be the number of non-virtual columns in the
@@ -89353,11 +89731,14 @@
89731 assert( pTab->tabFlags & TF_Strict );
89732 assert( pTab->nNVCol==pOp->p2 );
89733 aCol = pTab->aCol;
89734 pIn1 = &aMem[pOp->p1];
89735 for(i=0; i<pTab->nCol; i++){
89736 if( aCol[i].colFlags & COLFLAG_GENERATED ){
89737 if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
89738 if( pOp->p3 ){ pIn1++; continue; }
89739 }
89740 assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
89741 applyAffinity(pIn1, aCol[i].affinity, encoding);
89742 if( (pIn1->flags & MEM_Null)==0 ){
89743 switch( aCol[i].eCType ){
89744 case COLTYPE_BLOB: {
@@ -89756,11 +90137,11 @@
90137 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
90138 REGISTER_TRACE(pOp->p3, pOut);
90139 break;
90140 }
90141
90142 /* Opcode: Count P1 P2 P3 * *
90143 ** Synopsis: r[P2]=count()
90144 **
90145 ** Store the number of entries (an integer value) in the table or index
90146 ** opened by cursor P1 in register P2.
90147 **
@@ -90077,12 +90458,20 @@
90458 assert( p->bIsReader );
90459 assert( p->readOnly==0 || pOp->p2==0 );
90460 assert( pOp->p2>=0 && pOp->p2<=2 );
90461 assert( pOp->p1>=0 && pOp->p1<db->nDb );
90462 assert( DbMaskTest(p->btreeMask, pOp->p1) );
90463 assert( rc==SQLITE_OK );
90464 if( pOp->p2 && (db->flags & (SQLITE_QueryOnly|SQLITE_CorruptRdOnly))!=0 ){
90465 if( db->flags & SQLITE_QueryOnly ){
90466 /* Writes prohibited by the "PRAGMA query_only=TRUE" statement */
90467 rc = SQLITE_READONLY;
90468 }else{
90469 /* Writes prohibited due to a prior SQLITE_CORRUPT in the current
90470 ** transaction */
90471 rc = SQLITE_CORRUPT;
90472 }
90473 goto abort_due_to_error;
90474 }
90475 pBt = db->aDb[pOp->p1].pBt;
90476
90477 if( pBt ){
@@ -90120,11 +90509,12 @@
90509 p->nStmtDefCons = db->nDeferredCons;
90510 p->nStmtDefImmCons = db->nDeferredImmCons;
90511 }
90512 }
90513 assert( pOp->p5==0 || pOp->p4type==P4_INT32 );
90514 if( rc==SQLITE_OK
90515 && pOp->p5
90516 && (iMeta!=pOp->p3
90517 || db->aDb[pOp->p1].pSchema->iGeneration!=pOp->p4.i)
90518 ){
90519 /*
90520 ** IMPLEMENTATION-OF: R-03189-51135 As each SQL statement runs, the schema
@@ -90514,11 +90904,11 @@
90904 assert( aMem[pOp->p3].flags & MEM_Null );
90905 aMem[pOp->p3].n = 0;
90906 aMem[pOp->p3].z = "";
90907 }
90908 pCx = p->apCsr[pOp->p1];
90909 if( pCx && !pCx->hasBeenDuped && ALWAYS(pOp->p2<=pCx->nField) ){
90910 /* If the ephermeral table is already open and has no duplicates from
90911 ** OP_OpenDup, then erase all existing content so that the table is
90912 ** empty again, rather than creating a new table. */
90913 assert( pCx->isEphemeral );
90914 pCx->seqCount = 0;
@@ -91677,11 +92067,11 @@
92067 zDb = db->aDb[pC->iDb].zDbSName;
92068 pTab = pOp->p4.pTab;
92069 assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
92070 }else{
92071 pTab = 0;
92072 zDb = 0;
92073 }
92074
92075 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
92076 /* Invoke the pre-update hook, if any */
92077 if( pTab ){
@@ -91830,17 +92220,18 @@
92220 pTab = pOp->p4.pTab;
92221 if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){
92222 pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor);
92223 }
92224 }else{
92225 zDb = 0;
92226 pTab = 0;
92227 }
92228
92229 #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
92230 /* Invoke the pre-update-hook if required. */
92231 assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab );
92232 if( db->xPreUpdateCallback && pTab ){
92233 assert( !(opflags & OPFLAG_ISUPDATE)
92234 || HasRowid(pTab)==0
92235 || (aMem[pOp->p3].flags & MEM_Int)
92236 );
92237 sqlite3VdbePreUpdateHook(p, pC,
@@ -91877,11 +92268,11 @@
92268 if( rc ) goto abort_due_to_error;
92269
92270 /* Invoke the update-hook if required. */
92271 if( opflags & OPFLAG_NCHANGE ){
92272 p->nChange++;
92273 if( db->xUpdateCallback && ALWAYS(pTab!=0) && HasRowid(pTab) ){
92274 db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, pTab->zName,
92275 pC->movetoTarget);
92276 assert( pC->iDb>=0 );
92277 }
92278 }
@@ -92925,11 +93316,11 @@
93316 db->mDbFlags |= DBFLAG_SchemaChange;
93317 p->expired = 0;
93318 }else
93319 #endif
93320 {
93321 zSchema = LEGACY_SCHEMA_TABLE;
93322 initData.db = db;
93323 initData.iDb = iDb;
93324 initData.pzErrMsg = &p->zErrMsg;
93325 initData.mInitFlags = 0;
93326 initData.mxPage = sqlite3BtreeLastPage(db->aDb[iDb].pBt);
@@ -94145,10 +94536,11 @@
94536 pQuery = &aMem[pOp->p3];
94537 pArgc = &pQuery[1];
94538 pCur = p->apCsr[pOp->p1];
94539 assert( memIsValid(pQuery) );
94540 REGISTER_TRACE(pOp->p3, pQuery);
94541 assert( pCur!=0 );
94542 assert( pCur->eCurType==CURTYPE_VTAB );
94543 pVCur = pCur->uc.pVCur;
94544 pVtab = pVCur->pVtab;
94545 pModule = pVtab->pModule;
94546
@@ -94193,10 +94585,11 @@
94585 const sqlite3_module *pModule;
94586 Mem *pDest;
94587 sqlite3_context sContext;
94588
94589 VdbeCursor *pCur = p->apCsr[pOp->p1];
94590 assert( pCur!=0 );
94591 assert( pCur->eCurType==CURTYPE_VTAB );
94592 assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
94593 pDest = &aMem[pOp->p3];
94594 memAboutToChange(p, pDest);
94595 if( pCur->nullRow ){
@@ -94246,10 +94639,11 @@
94639 const sqlite3_module *pModule;
94640 int res;
94641 VdbeCursor *pCur;
94642
94643 pCur = p->apCsr[pOp->p1];
94644 assert( pCur!=0 );
94645 assert( pCur->eCurType==CURTYPE_VTAB );
94646 if( pCur->nullRow ){
94647 break;
94648 }
94649 pVtab = pCur->uc.pVCur->pVtab;
@@ -94341,11 +94735,11 @@
94735 case OP_VUpdate: {
94736 sqlite3_vtab *pVtab;
94737 const sqlite3_module *pModule;
94738 int nArg;
94739 int i;
94740 sqlite_int64 rowid = 0;
94741 Mem **apArg;
94742 Mem *pX;
94743
94744 assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback
94745 || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace
@@ -94528,10 +94922,81 @@
94922
94923 REGISTER_TRACE(pOp->p3, pOut);
94924 UPDATE_MAX_BLOBSIZE(pOut);
94925 break;
94926 }
94927
94928 /* Opcode: FilterAdd P1 * P3 P4 *
94929 ** Synopsis: filter(P1) += key(P3@P4)
94930 **
94931 ** Compute a hash on the P4 registers starting with r[P3] and
94932 ** add that hash to the bloom filter contained in r[P1].
94933 */
94934 case OP_FilterAdd: {
94935 u64 h;
94936
94937 assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
94938 pIn1 = &aMem[pOp->p1];
94939 assert( pIn1->flags & MEM_Blob );
94940 assert( pIn1->n>0 );
94941 h = filterHash(aMem, pOp);
94942 #ifdef SQLITE_DEBUG
94943 if( db->flags&SQLITE_VdbeTrace ){
94944 int ii;
94945 for(ii=pOp->p3; ii<pOp->p3+pOp->p4.i; ii++){
94946 registerTrace(ii, &aMem[ii]);
94947 }
94948 printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n));
94949 }
94950 #endif
94951 h %= pIn1->n;
94952 pIn1->z[h/8] |= 1<<(h&7);
94953 break;
94954 }
94955
94956 /* Opcode: Filter P1 P2 P3 P4 *
94957 ** Synopsis: if key(P3@P4) not in filter(P1) goto P2
94958 **
94959 ** Compute a hash on the key contained in the P4 registers starting
94960 ** with r[P3]. Check to see if that hash is found in the
94961 ** bloom filter hosted by register P1. If it is not present then
94962 ** maybe jump to P2. Otherwise fall through.
94963 **
94964 ** False negatives are harmless. It is always safe to fall through,
94965 ** even if the value is in the bloom filter. A false negative causes
94966 ** more CPU cycles to be used, but it should still yield the correct
94967 ** answer. However, an incorrect answer may well arise from a
94968 ** false positive - if the jump is taken when it should fall through.
94969 */
94970 case OP_Filter: { /* jump */
94971 u64 h;
94972
94973 assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
94974 pIn1 = &aMem[pOp->p1];
94975 assert( (pIn1->flags & MEM_Blob)!=0 );
94976 assert( pIn1->n >= 1 );
94977 h = filterHash(aMem, pOp);
94978 #ifdef SQLITE_DEBUG
94979 if( db->flags&SQLITE_VdbeTrace ){
94980 int ii;
94981 for(ii=pOp->p3; ii<pOp->p3+pOp->p4.i; ii++){
94982 registerTrace(ii, &aMem[ii]);
94983 }
94984 printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n));
94985 }
94986 #endif
94987 h %= pIn1->n;
94988 if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){
94989 VdbeBranchTaken(1, 2);
94990 p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++;
94991 goto jump_to_p2;
94992 }else{
94993 p->aCounter[SQLITE_STMTSTATUS_FILTER_MISS]++;
94994 VdbeBranchTaken(0, 2);
94995 }
94996 break;
94997 }
94998
94999 /* Opcode: Trace P1 P2 * P4 *
95000 **
95001 ** Write P4 on the statement trace output if statement tracing is
95002 ** enabled.
@@ -94788,11 +95253,18 @@
95253 rc = SQLITE_CORRUPT_BKPT;
95254 }
95255 assert( rc );
95256 #ifdef SQLITE_DEBUG
95257 if( db->flags & SQLITE_VdbeTrace ){
95258 const char *zTrace = p->zSql;
95259 if( zTrace==0 ){
95260 if( aOp[0].opcode==OP_Trace ){
95261 zTrace = aOp[0].p4.z;
95262 }
95263 if( zTrace==0 ) zTrace = "???";
95264 }
95265 printf("ABORT-due-to-error (rc=%d): %s\n", rc, zTrace);
95266 }
95267 #endif
95268 if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
95269 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
95270 }
@@ -94801,10 +95273,13 @@
95273 testcase( sqlite3GlobalConfig.xLog!=0 );
95274 sqlite3_log(rc, "statement aborts at %d: [%s] %s",
95275 (int)(pOp - aOp), p->zSql, p->zErrMsg);
95276 sqlite3VdbeHalt(p);
95277 if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db);
95278 if( rc==SQLITE_CORRUPT && db->autoCommit==0 ){
95279 db->flags |= SQLITE_CorruptRdOnly;
95280 }
95281 rc = SQLITE_ERROR;
95282 if( resetSchemaOnFault>0 ){
95283 sqlite3ResetOneSchema(db, resetSchemaOnFault-1);
95284 }
95285
@@ -94932,11 +95407,14 @@
95407 }else{
95408 rc = sqlite3_step(p->pStmt);
95409 }
95410 if( rc==SQLITE_ROW ){
95411 VdbeCursor *pC = v->apCsr[0];
95412 u32 type;
95413 assert( pC!=0 );
95414 assert( pC->eCurType==CURTYPE_BTREE );
95415 type = pC->nHdrParsed>p->iCol ? pC->aType[p->iCol] : 0;
95416 testcase( pC->nHdrParsed==p->iCol );
95417 testcase( pC->nHdrParsed==p->iCol+1 );
95418 if( type<12 ){
95419 zErr = sqlite3MPrintf(p->db, "cannot open value of type %s",
95420 type==0?"null": type==7?"real": "integer"
@@ -95069,11 +95547,11 @@
95547 /* Check that the column is not part of an FK child key definition. It
95548 ** is not necessary to check if it is part of a parent key, as parent
95549 ** key columns must be indexed. The check below will pick up this
95550 ** case. */
95551 FKey *pFKey;
95552 assert( IsOrdinaryTable(pTab) );
95553 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
95554 int j;
95555 for(j=0; j<pFKey->nCol; j++){
95556 if( pFKey->aCol[j].iFrom==iCol ){
95557 zFault = "foreign key";
@@ -95277,10 +95755,12 @@
95755 ** using the incremental-blob API, this works. For the sessions module
95756 ** anyhow.
95757 */
95758 sqlite3_int64 iKey;
95759 iKey = sqlite3BtreeIntegerKey(p->pCsr);
95760 assert( v->apCsr[0]!=0 );
95761 assert( v->apCsr[0]->eCurType==CURTYPE_BTREE );
95762 sqlite3VdbePreUpdateHook(
95763 v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1, p->iCol
95764 );
95765 }
95766 #endif
@@ -96659,11 +97139,11 @@
97139 void *p = 0;
97140 int chunksize = 4*1024;
97141 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize);
97142 sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte);
97143 sqlite3OsFetch(pFd, 0, (int)nByte, &p);
97144 if( p ) sqlite3OsUnfetch(pFd, 0, p);
97145 }
97146 }
97147 #else
97148 # define vdbeSorterExtendFile(x,y,z)
97149 #endif
@@ -97377,10 +97857,11 @@
97857 pTask->file2.iEof += pIncr->mxSz;
97858 }else{
97859 vdbeMergeEngineFree(pMerger);
97860 rc = SQLITE_NOMEM_BKPT;
97861 }
97862 assert( *ppOut!=0 || rc!=SQLITE_OK );
97863 return rc;
97864 }
97865
97866 #if SQLITE_MAX_WORKER_THREADS>0
97867 /*
@@ -99078,11 +99559,11 @@
99559 if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort;
99560 if( pExpr->pRight ){
99561 assert( !ExprHasProperty(pExpr, EP_WinFunc) );
99562 pExpr = pExpr->pRight;
99563 continue;
99564 }else if( ExprUseXSelect(pExpr) ){
99565 assert( !ExprHasProperty(pExpr, EP_WinFunc) );
99566 if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort;
99567 }else{
99568 if( pExpr->x.pList ){
99569 if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort;
@@ -99350,10 +99831,11 @@
99831 sqlite3ExprDelete(db, pDup);
99832 pDup = 0;
99833 }else{
99834 incrAggFunctionDepth(pDup, nSubquery);
99835 if( pExpr->op==TK_COLLATE ){
99836 assert( !ExprHasProperty(pExpr, EP_IntValue) );
99837 pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
99838 }
99839
99840 /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This
99841 ** prevents ExprDelete() from deleting the Expr structure itself,
@@ -99453,10 +99935,11 @@
99935 SQLITE_PRIVATE Bitmask sqlite3ExprColUsed(Expr *pExpr){
99936 int n;
99937 Table *pExTab;
99938
99939 n = pExpr->iColumn;
99940 assert( ExprUseYTab(pExpr) );
99941 pExTab = pExpr->y.pTab;
99942 assert( pExTab!=0 );
99943 if( (pExTab->tabFlags & TF_HasGenerated)!=0
99944 && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0
99945 ){
@@ -99590,10 +100073,11 @@
100073 const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName;
100074 assert( zTabName!=0 );
100075 if( sqlite3StrICmp(zTabName, zTab)!=0 ){
100076 continue;
100077 }
100078 assert( ExprUseYTab(pExpr) );
100079 if( IN_RENAME_OBJECT && pItem->zAlias ){
100080 sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
100081 }
100082 }
100083 hCol = sqlite3StrIHash(zCol);
@@ -99621,10 +100105,11 @@
100105 pMatch = pItem;
100106 }
100107 }
100108 if( pMatch ){
100109 pExpr->iTable = pMatch->iCursor;
100110 assert( ExprUseYTab(pExpr) );
100111 pExpr->y.pTab = pMatch->pTab;
100112 /* RIGHT JOIN not (yet) supported */
100113 assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
100114 if( (pMatch->fg.jointype & JT_LEFT)!=0 ){
100115 ExprSetProperty(pExpr, EP_CanBeNull);
@@ -99694,10 +100179,11 @@
100179 cnt++;
100180 pMatch = 0;
100181 #ifndef SQLITE_OMIT_UPSERT
100182 if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
100183 testcase( iCol==(-1) );
100184 assert( ExprUseYTab(pExpr) );
100185 if( IN_RENAME_OBJECT ){
100186 pExpr->iColumn = iCol;
100187 pExpr->y.pTab = pTab;
100188 eNewExprOp = TK_COLUMN;
100189 }else{
@@ -99706,10 +100192,11 @@
100192 eNewExprOp = TK_REGISTER;
100193 }
100194 }else
100195 #endif /* SQLITE_OMIT_UPSERT */
100196 {
100197 assert( ExprUseYTab(pExpr) );
100198 pExpr->y.pTab = pTab;
100199 if( pParse->bReturning ){
100200 eNewExprOp = TK_REGISTER;
100201 pExpr->iTable = pNC->uNC.iBaseReg + (pTab->nCol+1)*pExpr->iTable +
100202 sqlite3TableColumnToStorage(pTab, iCol) + 1;
@@ -99780,12 +100267,12 @@
100267 if( pEList->a[j].eEName==ENAME_NAME
100268 && sqlite3_stricmp(zAs, zCol)==0
100269 ){
100270 Expr *pOrig;
100271 assert( pExpr->pLeft==0 && pExpr->pRight==0 );
100272 assert( ExprUseXList(pExpr)==0 || pExpr->x.pList==0 );
100273 assert( ExprUseXSelect(pExpr)==0 || pExpr->x.pSelect==0 );
100274 pOrig = pEList->a[j].pExpr;
100275 if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
100276 sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
100277 return WRC_Abort;
100278 }
@@ -99853,11 +100340,11 @@
100340 "double-quoted string literal: \"%w\"", zCol);
100341 #ifdef SQLITE_ENABLE_NORMALIZE
100342 sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
100343 #endif
100344 pExpr->op = TK_STRING;
100345 memset(&pExpr->y, 0, sizeof(pExpr->y));
100346 return WRC_Prune;
100347 }
100348 if( sqlite3ExprIdToTrueFalse(pExpr) ){
100349 return WRC_Prune;
100350 }
@@ -99939,11 +100426,13 @@
100426 */
100427 SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
100428 Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
100429 if( p ){
100430 SrcItem *pItem = &pSrc->a[iSrc];
100431 Table *pTab;
100432 assert( ExprUseYTab(p) );
100433 pTab = p->y.pTab = pItem->pTab;
100434 p->iTable = pItem->iCursor;
100435 if( p->y.pTab->iPKey==iCol ){
100436 p->iColumn = -1;
100437 }else{
100438 p->iColumn = (ynVar)iCol;
@@ -100006,10 +100495,11 @@
100495 ** value between 1.0 and 0.0.
100496 */
100497 static int exprProbability(Expr *p){
100498 double r = -1.0;
100499 if( p->op!=TK_FLOAT ) return -1;
100500 assert( !ExprHasProperty(p, EP_IntValue) );
100501 sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8);
100502 assert( r>=0.0 );
100503 if( r>1.0 ) return -1;
100504 return (int)(r*134217728.0);
100505 }
@@ -100054,10 +100544,11 @@
100544 SrcList *pSrcList = pNC->pSrcList;
100545 SrcItem *pItem;
100546 assert( pSrcList && pSrcList->nSrc>=1 );
100547 pItem = pSrcList->a;
100548 pExpr->op = TK_COLUMN;
100549 assert( ExprUseYTab(pExpr) );
100550 pExpr->y.pTab = pItem->pTab;
100551 pExpr->iTable = pItem->iCursor;
100552 pExpr->iColumn--;
100553 pExpr->affExpr = SQLITE_AFF_INTEGER;
100554 break;
@@ -100086,10 +100577,11 @@
100577 anRef[i] = p->nRef;
100578 }
100579 sqlite3WalkExpr(pWalker, pExpr->pLeft);
100580 if( 0==sqlite3ExprCanBeNull(pExpr->pLeft) && !IN_RENAME_OBJECT ){
100581 testcase( ExprHasProperty(pExpr, EP_FromJoin) );
100582 assert( !ExprHasProperty(pExpr, EP_IntValue) );
100583 if( pExpr->op==TK_NOTNULL ){
100584 pExpr->u.zToken = "true";
100585 ExprSetProperty(pExpr, EP_IsTrue);
100586 }else{
100587 pExpr->u.zToken = "false";
@@ -100121,10 +100613,11 @@
100613 Expr *pRight;
100614
100615 if( pExpr->op==TK_ID ){
100616 zDb = 0;
100617 zTable = 0;
100618 assert( !ExprHasProperty(pExpr, EP_IntValue) );
100619 zColumn = pExpr->u.zToken;
100620 }else{
100621 Expr *pLeft = pExpr->pLeft;
100622 testcase( pNC->ncFlags & NC_IdxExpr );
100623 testcase( pNC->ncFlags & NC_GenCol );
@@ -100133,16 +100626,19 @@
100626 pRight = pExpr->pRight;
100627 if( pRight->op==TK_ID ){
100628 zDb = 0;
100629 }else{
100630 assert( pRight->op==TK_DOT );
100631 assert( !ExprHasProperty(pRight, EP_IntValue) );
100632 zDb = pLeft->u.zToken;
100633 pLeft = pRight->pLeft;
100634 pRight = pRight->pRight;
100635 }
100636 assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) );
100637 zTable = pLeft->u.zToken;
100638 zColumn = pRight->u.zToken;
100639 assert( ExprUseYTab(pExpr) );
100640 if( IN_RENAME_OBJECT ){
100641 sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
100642 sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
100643 }
100644 }
@@ -100163,11 +100659,11 @@
100659 u8 enc = ENC(pParse->db); /* The database encoding */
100660 int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
100661 #ifndef SQLITE_OMIT_WINDOWFUNC
100662 Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0);
100663 #endif
100664 assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) );
100665 zId = pExpr->u.zToken;
100666 nId = sqlite3Strlen30(zId);
100667 pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
100668 if( pDef==0 ){
100669 pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
@@ -100327,11 +100823,11 @@
100823 sqlite3WalkExprList(pWalker, pList);
100824 if( is_agg ){
100825 #ifndef SQLITE_OMIT_WINDOWFUNC
100826 if( pWin ){
100827 Select *pSel = pNC->pWinSelect;
100828 assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
100829 if( IN_RENAME_OBJECT==0 ){
100830 sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
100831 if( pParse->db->mallocFailed ) break;
100832 }
100833 sqlite3WalkExprList(pWalker, pWin->pPartition);
@@ -100340,19 +100836,22 @@
100836 sqlite3WindowLink(pSel, pWin);
100837 pNC->ncFlags |= NC_HasWin;
100838 }else
100839 #endif /* SQLITE_OMIT_WINDOWFUNC */
100840 {
100841 NameContext *pNC2; /* For looping up thru outer contexts */
100842 pExpr->op = TK_AGG_FUNCTION;
100843 pExpr->op2 = 0;
100844 #ifndef SQLITE_OMIT_WINDOWFUNC
100845 if( ExprHasProperty(pExpr, EP_WinFunc) ){
100846 sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
100847 }
100848 #endif
100849 pNC2 = pNC;
100850 while( pNC2
100851 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
100852 ){
100853 pExpr->op2++;
100854 pNC2 = pNC2->pNext;
100855 }
100856 assert( pDef!=0 || IN_RENAME_OBJECT );
100857 if( pNC2 && pDef ){
@@ -100376,11 +100875,11 @@
100875 case TK_SELECT:
100876 case TK_EXISTS: testcase( pExpr->op==TK_EXISTS );
100877 #endif
100878 case TK_IN: {
100879 testcase( pExpr->op==TK_IN );
100880 if( ExprUseXSelect(pExpr) ){
100881 int nRef = pNC->nRef;
100882 testcase( pNC->ncFlags & NC_IsCheck );
100883 testcase( pNC->ncFlags & NC_PartIdx );
100884 testcase( pNC->ncFlags & NC_IdxExpr );
100885 testcase( pNC->ncFlags & NC_GenCol );
@@ -100433,10 +100932,11 @@
100932 int nLeft, nRight;
100933 if( pParse->db->mallocFailed ) break;
100934 assert( pExpr->pLeft!=0 );
100935 nLeft = sqlite3ExprVectorSize(pExpr->pLeft);
100936 if( pExpr->op==TK_BETWEEN ){
100937 assert( ExprUseXList(pExpr) );
100938 nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr);
100939 if( nRight==nLeft ){
100940 nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr);
100941 }
100942 }else{
@@ -100481,11 +100981,13 @@
100981 int i; /* Loop counter */
100982
100983 UNUSED_PARAMETER(pParse);
100984
100985 if( pE->op==TK_ID ){
100986 const char *zCol;
100987 assert( !ExprHasProperty(pE, EP_IntValue) );
100988 zCol = pE->u.zToken;
100989 for(i=0; i<pEList->nExpr; i++){
100990 if( pEList->a[i].eEName==ENAME_NAME
100991 && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0
100992 ){
100993 return i+1;
@@ -101315,12 +101817,12 @@
101817
101818 /*
101819 ** Return the affinity character for a single column of a table.
101820 */
101821 SQLITE_PRIVATE char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
101822 if( iCol<0 || NEVER(iCol>=pTab->nCol) ) return SQLITE_AFF_INTEGER;
101823 return pTab->aCol[iCol].affinity;
101824 }
101825
101826 /*
101827 ** Return the 'affinity' of the expression pExpr if any.
101828 **
@@ -101346,15 +101848,18 @@
101848 pExpr = pExpr->pLeft;
101849 assert( pExpr!=0 );
101850 }
101851 op = pExpr->op;
101852 if( op==TK_REGISTER ) op = pExpr->op2;
101853 if( op==TK_COLUMN || op==TK_AGG_COLUMN ){
101854 assert( ExprUseYTab(pExpr) );
101855 if( pExpr->y.pTab ){
101856 return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
101857 }
101858 }
101859 if( op==TK_SELECT ){
101860 assert( ExprUseXSelect(pExpr) );
101861 assert( pExpr->x.pSelect!=0 );
101862 assert( pExpr->x.pSelect->pEList!=0 );
101863 assert( pExpr->x.pSelect->pEList->a[0].pExpr!=0 );
101864 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
101865 }
@@ -101363,18 +101868,19 @@
101868 assert( !ExprHasProperty(pExpr, EP_IntValue) );
101869 return sqlite3AffinityType(pExpr->u.zToken, 0);
101870 }
101871 #endif
101872 if( op==TK_SELECT_COLUMN ){
101873 assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) );
101874 assert( pExpr->iColumn < pExpr->iTable );
101875 assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr );
101876 return sqlite3ExprAffinity(
101877 pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr
101878 );
101879 }
101880 if( op==TK_VECTOR ){
101881 assert( ExprUseXList(pExpr) );
101882 return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr);
101883 }
101884 return pExpr->affExpr;
101885 }
101886
@@ -101430,11 +101936,11 @@
101936 ** expression.
101937 */
101938 SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){
101939 while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){
101940 if( ExprHasProperty(pExpr, EP_Unlikely) ){
101941 assert( ExprUseXList(pExpr) );
101942 assert( pExpr->x.pList->nExpr>0 );
101943 assert( pExpr->op==TK_FUNCTION );
101944 pExpr = pExpr->x.pList->a[0].pExpr;
101945 }else{
101946 assert( pExpr->op==TK_COLLATE );
@@ -101463,45 +101969,46 @@
101969 CollSeq *pColl = 0;
101970 const Expr *p = pExpr;
101971 while( p ){
101972 int op = p->op;
101973 if( op==TK_REGISTER ) op = p->op2;
101974 if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){
101975 assert( ExprUseYTab(p) );
101976 if( p->y.pTab!=0 ){
101977 /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
101978 ** a TK_COLUMN but was previously evaluated and cached in a register */
101979 int j = p->iColumn;
101980 if( j>=0 ){
101981 const char *zColl = sqlite3ColumnColl(&p->y.pTab->aCol[j]);
101982 pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0);
101983 }
101984 break;
101985 }
101986 }
101987 if( op==TK_CAST || op==TK_UPLUS ){
101988 p = p->pLeft;
101989 continue;
101990 }
101991 if( op==TK_VECTOR ){
101992 assert( ExprUseXList(p) );
101993 p = p->x.pList->a[0].pExpr;
101994 continue;
101995 }
101996 if( op==TK_COLLATE ){
101997 assert( !ExprHasProperty(p, EP_IntValue) );
101998 pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
101999 break;
102000 }
102001 if( p->flags & EP_Collate ){
102002 if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
102003 p = p->pLeft;
102004 }else{
102005 Expr *pNext = p->pRight;
102006 /* The Expr.x union is never used at the same time as Expr.pRight */
102007 assert( ExprUseXList(p) );
102008 assert( p->x.pList==0 || p->pRight==0 );
102009 if( p->x.pList!=0 && !db->mallocFailed ){
 
 
 
102010 int i;
102011 for(i=0; ALWAYS(i<p->x.pList->nExpr); i++){
102012 if( ExprHasProperty(p->x.pList->a[i].pExpr, EP_Collate) ){
102013 pNext = p->x.pList->a[i].pExpr;
102014 break;
@@ -101580,11 +102087,11 @@
102087 pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT );
102088 assert( pExpr->pLeft );
102089 aff = sqlite3ExprAffinity(pExpr->pLeft);
102090 if( pExpr->pRight ){
102091 aff = sqlite3CompareAffinity(pExpr->pRight, aff);
102092 }else if( ExprUseXSelect(pExpr) ){
102093 aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff);
102094 }else if( aff==0 ){
102095 aff = SQLITE_AFF_BLOB;
102096 }
102097 return aff;
@@ -101720,12 +102227,14 @@
102227 */
102228 SQLITE_PRIVATE int sqlite3ExprVectorSize(const Expr *pExpr){
102229 u8 op = pExpr->op;
102230 if( op==TK_REGISTER ) op = pExpr->op2;
102231 if( op==TK_VECTOR ){
102232 assert( ExprUseXList(pExpr) );
102233 return pExpr->x.pList->nExpr;
102234 }else if( op==TK_SELECT ){
102235 assert( ExprUseXSelect(pExpr) );
102236 return pExpr->x.pSelect->pEList->nExpr;
102237 }else{
102238 return 1;
102239 }
102240 }
@@ -101748,12 +102257,14 @@
102257 SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr *pVector, int i){
102258 assert( i<sqlite3ExprVectorSize(pVector) || pVector->op==TK_ERROR );
102259 if( sqlite3ExprIsVector(pVector) ){
102260 assert( pVector->op2==0 || pVector->op==TK_REGISTER );
102261 if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){
102262 assert( ExprUseXSelect(pVector) );
102263 return pVector->x.pSelect->pEList->a[i].pExpr;
102264 }else{
102265 assert( ExprUseXList(pVector) );
102266 return pVector->x.pList->a[i].pExpr;
102267 }
102268 }
102269 return pVector;
102270 }
@@ -101785,11 +102296,11 @@
102296 int iField, /* Which column of the vector to return */
102297 int nField /* Total number of columns in the vector */
102298 ){
102299 Expr *pRet;
102300 if( pVector->op==TK_SELECT ){
102301 assert( ExprUseXSelect(pVector) );
102302 /* The TK_SELECT_COLUMN Expr node:
102303 **
102304 ** pLeft: pVector containing TK_SELECT. Not deleted.
102305 ** pRight: not used. But recursively deleted.
102306 ** iColumn: Index of a column in pVector
@@ -101810,11 +102321,13 @@
102321 pRet->iColumn = iField;
102322 pRet->pLeft = pVector;
102323 }
102324 }else{
102325 if( pVector->op==TK_VECTOR ){
102326 Expr **ppVector;
102327 assert( ExprUseXList(pVector) );
102328 ppVector = &pVector->x.pList->a[iField].pExpr;
102329 pVector = *ppVector;
102330 if( IN_RENAME_OBJECT ){
102331 /* This must be a vector UPDATE inside a trigger */
102332 *ppVector = 0;
102333 return pVector;
@@ -101874,14 +102387,16 @@
102387 if( op==TK_REGISTER ){
102388 *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField);
102389 return pVector->iTable+iField;
102390 }
102391 if( op==TK_SELECT ){
102392 assert( ExprUseXSelect(pVector) );
102393 *ppExpr = pVector->x.pSelect->pEList->a[iField].pExpr;
102394 return regSelect+iField;
102395 }
102396 if( op==TK_VECTOR ){
102397 assert( ExprUseXList(pVector) );
102398 *ppExpr = pVector->x.pList->a[iField].pExpr;
102399 return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree);
102400 }
102401 return 0;
102402 }
@@ -102052,11 +102567,11 @@
102567 */
102568 static void exprSetHeight(Expr *p){
102569 int nHeight = 0;
102570 heightOfExpr(p->pLeft, &nHeight);
102571 heightOfExpr(p->pRight, &nHeight);
102572 if( ExprUseXSelect(p) ){
102573 heightOfSelect(p->x.pSelect, &nHeight);
102574 }else if( p->x.pList ){
102575 heightOfExprList(p->x.pList, &nHeight);
102576 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
102577 }
@@ -102091,11 +102606,11 @@
102606 ** Propagate all EP_Propagate flags from the Expr.x.pList into
102607 ** Expr.flags.
102608 */
102609 SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){
102610 if( pParse->nErr ) return;
102611 if( p && ExprUseXList(p) && p->x.pList ){
102612 p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList);
102613 }
102614 }
102615 #define exprSetHeight(y)
102616 #endif /* SQLITE_MAX_EXPR_DEPTH>0 */
@@ -102275,17 +102790,24 @@
102790 Select *pRet = 0;
102791 assert( nElem>1 );
102792 for(ii=0; ii<pEList->nExpr; ii++){
102793 Select *pSel;
102794 Expr *pExpr = pEList->a[ii].pExpr;
102795 int nExprElem;
102796 if( pExpr->op==TK_VECTOR ){
102797 assert( ExprUseXList(pExpr) );
102798 nExprElem = pExpr->x.pList->nExpr;
102799 }else{
102800 nExprElem = 1;
102801 }
102802 if( nExprElem!=nElem ){
102803 sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d",
102804 nExprElem, nExprElem>1?"s":"", nElem
102805 );
102806 break;
102807 }
102808 assert( ExprUseXList(pExpr) );
102809 pSel = sqlite3SelectNew(pParse, pExpr->x.pList, 0, 0, 0, 0, 0, SF_Values,0);
102810 pExpr->x.pList = 0;
102811 if( pSel ){
102812 if( pRet ){
102813 pSel->op = TK_ALL;
@@ -102351,11 +102873,11 @@
102873 ){
102874 sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken);
102875 }
102876 pNew->x.pList = pList;
102877 ExprSetProperty(pNew, EP_HasFunc);
102878 assert( ExprUseXList(pNew) );
102879 sqlite3ExprSetHeightAndFlags(pParse, pNew);
102880 if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct);
102881 return pNew;
102882 }
102883
@@ -102477,31 +102999,30 @@
102999 /*
103000 ** Recursively delete an expression tree.
103001 */
103002 static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
103003 assert( p!=0 );
103004 assert( !ExprUseUValue(p) || p->u.iValue>=0 );
103005 assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
103006 assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
103007 assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) );
 
 
103008 #ifdef SQLITE_DEBUG
103009 if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
103010 assert( p->pLeft==0 );
103011 assert( p->pRight==0 );
103012 assert( !ExprUseXSelect(p) || p->x.pSelect==0 );
103013 assert( !ExprUseXList(p) || p->x.pList==0 );
103014 }
103015 #endif
103016 if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){
103017 /* The Expr.x union is never used at the same time as Expr.pRight */
103018 assert( (ExprUseXList(p) && p->x.pList==0) || p->pRight==0 );
103019 if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft);
103020 if( p->pRight ){
103021 assert( !ExprHasProperty(p, EP_WinFunc) );
103022 sqlite3ExprDeleteNN(db, p->pRight);
103023 }else if( ExprUseXSelect(p) ){
103024 assert( !ExprHasProperty(p, EP_WinFunc) );
103025 sqlite3SelectDelete(db, p->x.pSelect);
103026 }else{
103027 sqlite3ExprListDelete(db, p->x.pList);
103028 #ifndef SQLITE_OMIT_WINDOWFUNC
@@ -102509,11 +103030,14 @@
103030 sqlite3WindowDelete(db, p->y.pWin);
103031 }
103032 #endif
103033 }
103034 }
103035 if( ExprHasProperty(p, EP_MemToken) ){
103036 assert( !ExprHasProperty(p, EP_IntValue) );
103037 sqlite3DbFree(db, p->u.zToken);
103038 }
103039 if( !ExprHasProperty(p, EP_Static) ){
103040 sqlite3DbFreeNN(db, p);
103041 }
103042 }
103043 SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){
@@ -102725,11 +103249,11 @@
103249 memcpy(zToken, p->u.zToken, nToken);
103250 }
103251
103252 if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){
103253 /* Fill in the pNew->x.pSelect or pNew->x.pList member. */
103254 if( ExprUseXSelect(p) ){
103255 pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags);
103256 }else{
103257 pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags);
103258 }
103259 }
@@ -103019,11 +103543,11 @@
103543 }
103544
103545 return pRet;
103546 }
103547 #else
103548 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, const Select *p, int flags){
103549 assert( p==0 );
103550 return 0;
103551 }
103552 #endif
103553
@@ -103352,11 +103876,11 @@
103876 ** the conversion happened, and zero if the expression is unaltered.
103877 */
103878 SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){
103879 u32 v;
103880 assert( pExpr->op==TK_ID || pExpr->op==TK_STRING );
103881 if( !ExprHasProperty(pExpr, EP_Quoted|EP_IntValue)
103882 && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0
103883 ){
103884 pExpr->op = TK_TRUEFALSE;
103885 ExprSetProperty(pExpr, v);
103886 return 1;
@@ -103369,10 +103893,11 @@
103893 ** and 0 if it is FALSE.
103894 */
103895 SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){
103896 pExpr = sqlite3ExprSkipCollate((Expr*)pExpr);
103897 assert( pExpr->op==TK_TRUEFALSE );
103898 assert( !ExprHasProperty(pExpr, EP_IntValue) );
103899 assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0
103900 || sqlite3StrICmp(pExpr->u.zToken,"false")==0 );
103901 return pExpr->u.zToken[4]==0;
103902 }
103903
@@ -103573,11 +104098,11 @@
104098 }
104099 }
104100 }
104101
104102 /* Check if pExpr is a sub-select. If so, consider it variable. */
104103 if( ExprUseXSelect(pExpr) ){
104104 pWalker->eCode = 0;
104105 return WRC_Abort;
104106 }
104107
104108 return exprNodeIsConstant(pWalker, pExpr);
@@ -103680,13 +104205,13 @@
104205 case TK_UPLUS: {
104206 rc = sqlite3ExprIsInteger(p->pLeft, pValue);
104207 break;
104208 }
104209 case TK_UMINUS: {
104210 int v = 0;
104211 if( sqlite3ExprIsInteger(p->pLeft, &v) ){
104212 assert( ((unsigned int)v)!=0x80000000 );
104213 *pValue = -v;
104214 rc = 1;
104215 }
104216 break;
104217 }
@@ -103723,14 +104248,15 @@
104248 case TK_STRING:
104249 case TK_FLOAT:
104250 case TK_BLOB:
104251 return 0;
104252 case TK_COLUMN:
104253 assert( ExprUseYTab(p) );
104254 return ExprHasProperty(p, EP_CanBeNull) ||
104255 p->y.pTab==0 || /* Reference to column of index on expression */
104256 (p->iColumn>=0
104257 && p->y.pTab->aCol!=0 /* Possible due to prior error */
104258 && p->y.pTab->aCol[p->iColumn].notNull==0);
104259 default:
104260 return 1;
104261 }
104262 }
@@ -103800,11 +104326,11 @@
104326 Select *p;
104327 SrcList *pSrc;
104328 ExprList *pEList;
104329 Table *pTab;
104330 int i;
104331 if( !ExprUseXSelect(pX) ) return 0; /* Not a subquery */
104332 if( ExprHasProperty(pX, EP_VarSelect) ) return 0; /* Correlated subq */
104333 p = pX->x.pSelect;
104334 if( p->pPrior ) return 0; /* Not a compound SELECT */
104335 if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
104336 testcase( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
@@ -103971,11 +104497,11 @@
104497 /* If the RHS of this IN(...) operator is a SELECT, and if it matters
104498 ** whether or not the SELECT result contains NULL values, check whether
104499 ** or not NULL is actually possible (it may not be, for example, due
104500 ** to NOT NULL constraints in the schema). If no NULL values are possible,
104501 ** set prRhsHasNull to 0 before continuing. */
104502 if( prRhsHasNull && ExprUseXSelect(pX) ){
104503 int i;
104504 ExprList *pEList = pX->x.pSelect->pEList;
104505 for(i=0; i<pEList->nExpr; i++){
104506 if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break;
104507 }
@@ -104072,11 +104598,12 @@
104598 Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i);
104599 Expr *pRhs = pEList->a[i].pExpr;
104600 CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs);
104601 int j;
104602
104603 assert( pReq!=0 || pRhs->iColumn==XN_ROWID
104604 || pParse->nErr || db->mallocFailed );
104605 for(j=0; j<nExpr; j++){
104606 if( pIdx->aiColumn[j]!=pRhs->iColumn ) continue;
104607 assert( pIdx->azColl[j] );
104608 if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){
104609 continue;
@@ -104127,11 +104654,11 @@
104654 ** then it is not worth creating an ephemeral table to evaluate
104655 ** the IN operator so return IN_INDEX_NOOP.
104656 */
104657 if( eType==0
104658 && (inFlags & IN_INDEX_NOOP_OK)
104659 && ExprUseXList(pX)
104660 && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
104661 ){
104662 eType = IN_INDEX_NOOP;
104663 }
104664
@@ -104175,11 +104702,11 @@
104702 ** string is eventually freed using sqlite3DbFree().
104703 */
104704 static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
104705 Expr *pLeft = pExpr->pLeft;
104706 int nVal = sqlite3ExprVectorSize(pLeft);
104707 Select *pSelect = ExprUseXSelect(pExpr) ? pExpr->x.pSelect : 0;
104708 char *zRet;
104709
104710 assert( pExpr->op==TK_IN );
104711 zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
104712 if( zRet ){
@@ -104225,11 +104752,11 @@
104752 **
104753 ** "row value misused"
104754 */
104755 SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){
104756 #ifndef SQLITE_OMIT_SUBQUERY
104757 if( ExprUseXSelect(pExpr) ){
104758 sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1);
104759 }else
104760 #endif
104761 {
104762 sqlite3ErrorMsg(pParse, "row value misused");
@@ -104289,22 +104816,24 @@
104816 /* If this routine has already been coded, but the previous code
104817 ** might not have been invoked yet, so invoke it now as a subroutine.
104818 */
104819 if( ExprHasProperty(pExpr, EP_Subrtn) ){
104820 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
104821 if( ExprUseXSelect(pExpr) ){
104822 ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
104823 pExpr->x.pSelect->selId));
104824 }
104825 assert( ExprUseYSub(pExpr) );
104826 sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
104827 pExpr->y.sub.iAddr);
104828 sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
104829 sqlite3VdbeJumpHere(v, addrOnce);
104830 return;
104831 }
104832
104833 /* Begin coding the subroutine */
104834 assert( !ExprUseYWin(pExpr) );
104835 ExprSetProperty(pExpr, EP_Subrtn);
104836 assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
104837 pExpr->y.sub.regReturn = ++pParse->nMem;
104838 pExpr->y.sub.iAddr =
104839 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
@@ -104321,19 +104850,19 @@
104850 ** RHS of the IN operator.
104851 */
104852 pExpr->iTable = iTab;
104853 addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
104854 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
104855 if( ExprUseXSelect(pExpr) ){
104856 VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
104857 }else{
104858 VdbeComment((v, "RHS of IN operator"));
104859 }
104860 #endif
104861 pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
104862
104863 if( ExprUseXSelect(pExpr) ){
104864 /* Case 1: expr IN (SELECT ...)
104865 **
104866 ** Generate code to write the results of the select into the temporary
104867 ** table allocated and opened above.
104868 */
@@ -104427,10 +104956,11 @@
104956 sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
104957 }
104958 if( addrOnce ){
104959 sqlite3VdbeJumpHere(v, addrOnce);
104960 /* Subroutine return */
104961 assert( ExprUseYSub(pExpr) );
104962 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
104963 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
104964 sqlite3ClearTempRegCache(pParse);
104965 }
104966 }
@@ -104463,23 +104993,26 @@
104993 assert( v!=0 );
104994 if( pParse->nErr ) return 0;
104995 testcase( pExpr->op==TK_EXISTS );
104996 testcase( pExpr->op==TK_SELECT );
104997 assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
104998 assert( ExprUseXSelect(pExpr) );
104999 pSel = pExpr->x.pSelect;
105000
105001 /* If this routine has already been coded, then invoke it as a
105002 ** subroutine. */
105003 if( ExprHasProperty(pExpr, EP_Subrtn) ){
105004 ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
105005 assert( ExprUseYSub(pExpr) );
105006 sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
105007 pExpr->y.sub.iAddr);
105008 return pExpr->iTable;
105009 }
105010
105011 /* Begin coding the subroutine */
105012 assert( !ExprUseYWin(pExpr) );
105013 assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
105014 ExprSetProperty(pExpr, EP_Subrtn);
105015 pExpr->y.sub.regReturn = ++pParse->nMem;
105016 pExpr->y.sub.iAddr =
105017 sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
105018 VdbeComment((v, "return address"));
@@ -104555,10 +105088,11 @@
105088 if( addrOnce ){
105089 sqlite3VdbeJumpHere(v, addrOnce);
105090 }
105091
105092 /* Subroutine return */
105093 assert( ExprUseYSub(pExpr) );
105094 sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
105095 sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
105096 sqlite3ClearTempRegCache(pParse);
105097 return rReg;
105098 }
@@ -104571,11 +105105,11 @@
105105 ** columns as the vector on the LHS. Or, if the RHS of the IN() is not
105106 ** a sub-query, that the LHS is a vector of size 1.
105107 */
105108 SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){
105109 int nVector = sqlite3ExprVectorSize(pIn->pLeft);
105110 if( ExprUseXSelect(pIn) && !pParse->db->mallocFailed ){
105111 if( nVector!=pIn->x.pSelect->pEList->nExpr ){
105112 sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector);
105113 return 1;
105114 }
105115 }else if( nVector!=1 ){
@@ -104705,17 +105239,19 @@
105239 ** sequence of comparisons.
105240 **
105241 ** This is step (1) in the in-operator.md optimized algorithm.
105242 */
105243 if( eType==IN_INDEX_NOOP ){
105244 ExprList *pList;
105245 CollSeq *pColl;
105246 int labelOk = sqlite3VdbeMakeLabel(pParse);
105247 int r2, regToFree;
105248 int regCkNull = 0;
105249 int ii;
105250 assert( ExprUseXList(pExpr) );
105251 pList = pExpr->x.pList;
105252 pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
105253 if( destIfNull!=destIfFalse ){
105254 regCkNull = sqlite3GetTempReg(pParse);
105255 sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
105256 }
105257 for(ii=0; ii<pList->nExpr; ii++){
@@ -105097,10 +105633,11 @@
105633 #endif
105634 }else{
105635 int i;
105636 iResult = pParse->nMem+1;
105637 pParse->nMem += nResult;
105638 assert( ExprUseXList(p) );
105639 for(i=0; i<nResult; i++){
105640 sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
105641 }
105642 }
105643 }
@@ -105295,10 +105832,11 @@
105832 ** datatype by applying the Affinity of the table column to the
105833 ** constant.
105834 */
105835 int aff;
105836 iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
105837 assert( ExprUseYTab(pExpr) );
105838 if( pExpr->y.pTab ){
105839 aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
105840 }else{
105841 aff = pExpr->affExpr;
105842 }
@@ -105318,13 +105856,15 @@
105856 ** The row is unpacked into registers beginning at
105857 ** 0-(pParse->iSelfTab). The rowid (if any) is in a register
105858 ** immediately prior to the first column.
105859 */
105860 Column *pCol;
105861 Table *pTab;
105862 int iSrc;
105863 int iCol = pExpr->iColumn;
105864 assert( ExprUseYTab(pExpr) );
105865 pTab = pExpr->y.pTab;
105866 assert( pTab!=0 );
105867 assert( iCol>=XN_ROWID );
105868 assert( iCol<pTab->nCol );
105869 if( iCol<0 ){
105870 return -1-pParse->iSelfTab;
@@ -105358,10 +105898,11 @@
105898 /* Coding an expression that is part of an index where column names
105899 ** in the index refer to the table to which the index belongs */
105900 iTab = pParse->iSelfTab - 1;
105901 }
105902 }
105903 assert( ExprUseYTab(pExpr) );
105904 iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
105905 pExpr->iColumn, iTab, target,
105906 pExpr->op2);
105907 if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){
105908 sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
@@ -105435,10 +105976,11 @@
105976 inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
105977 if( inReg!=target ){
105978 sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target);
105979 inReg = target;
105980 }
105981 assert( !ExprHasProperty(pExpr, EP_IntValue) );
105982 sqlite3VdbeAddOp2(v, OP_Cast, target,
105983 sqlite3AffinityType(pExpr->u.zToken, 0));
105984 return inReg;
105985 }
105986 #endif /* SQLITE_OMIT_CAST */
@@ -105602,12 +106144,12 @@
106144 if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
106145 /* SQL functions can be expensive. So try to avoid running them
106146 ** multiple times if we know they always give the same result */
106147 return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
106148 }
 
106149 assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
106150 assert( ExprUseXList(pExpr) );
106151 pFarg = pExpr->x.pList;
106152 nFarg = pFarg ? pFarg->nExpr : 0;
106153 assert( !ExprHasProperty(pExpr, EP_IntValue) );
106154 zId = pExpr->u.zToken;
106155 pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0);
@@ -105692,11 +106234,11 @@
106234 if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){
106235 if( !pColl ) pColl = db->pDfltColl;
106236 sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ);
106237 }
106238 #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
106239 if( (pDef->funcFlags & SQLITE_FUNC_OFFSET)!=0 && ALWAYS(pFarg!=0) ){
106240 Expr *pArg = pFarg->a[0].pExpr;
106241 if( pArg->op==TK_COLUMN ){
106242 sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target);
106243 }else{
106244 sqlite3VdbeAddOp2(v, OP_Null, 0, target);
@@ -105722,11 +106264,14 @@
106264 int nCol;
106265 testcase( op==TK_EXISTS );
106266 testcase( op==TK_SELECT );
106267 if( pParse->db->mallocFailed ){
106268 return 0;
106269 }else if( op==TK_SELECT
106270 && ALWAYS( ExprUseXSelect(pExpr) )
106271 && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1
106272 ){
106273 sqlite3SubselectError(pParse, nCol, 1);
106274 }else{
106275 return sqlite3CodeSubselect(pParse, pExpr);
106276 }
106277 break;
@@ -105804,13 +106349,18 @@
106349 **
106350 ** p1==0 -> old.rowid p1==3 -> new.rowid
106351 ** p1==1 -> old.a p1==4 -> new.a
106352 ** p1==2 -> old.b p1==5 -> new.b
106353 */
106354 Table *pTab;
106355 int iCol;
106356 int p1;
106357
106358 assert( ExprUseYTab(pExpr) );
106359 pTab = pExpr->y.pTab;
106360 iCol = pExpr->iColumn;
106361 p1 = pExpr->iTable * (pTab->nCol+1) + 1
106362 + sqlite3TableColumnToStorage(pTab, iCol);
106363
106364 assert( pExpr->iTable==0 || pExpr->iTable==1 );
106365 assert( iCol>=-1 && iCol<pTab->nCol );
106366 assert( pTab->iPKey<0 || iCol!=pTab->iPKey );
@@ -105894,11 +106444,11 @@
106444 Expr *pX; /* The X expression */
106445 Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */
106446 Expr *pDel = 0;
106447 sqlite3 *db = pParse->db;
106448
106449 assert( ExprUseXList(pExpr) && pExpr->x.pList!=0 );
106450 assert(pExpr->x.pList->nExpr > 0);
106451 pEList = pExpr->x.pList;
106452 aListelem = pEList->a;
106453 nExpr = pEList->nExpr;
106454 endLabel = sqlite3VdbeMakeLabel(pParse);
@@ -106239,11 +106789,11 @@
106789
106790 memset(&compLeft, 0, sizeof(Expr));
106791 memset(&compRight, 0, sizeof(Expr));
106792 memset(&exprAnd, 0, sizeof(Expr));
106793
106794 assert( ExprUseXList(pExpr) );
106795 pDel = sqlite3ExprDup(db, pExpr->pLeft, 0);
106796 if( db->mallocFailed==0 ){
106797 exprAnd.op = TK_AND;
106798 exprAnd.pLeft = &compLeft;
106799 exprAnd.pRight = &compRight;
@@ -106714,11 +107264,13 @@
107264 if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
107265 return 1;
107266 }
107267 return 2;
107268 }
107269 assert( !ExprHasProperty(pA, EP_IntValue) );
107270 assert( !ExprHasProperty(pB, EP_IntValue) );
107271 if( pA->u.zToken ){
107272 if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){
107273 if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
107274 #ifndef SQLITE_OMIT_WINDOWFUNC
107275 assert( pA->op==pB->op );
107276 if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){
@@ -106732,11 +107284,16 @@
107284 #endif
107285 }else if( pA->op==TK_NULL ){
107286 return 0;
107287 }else if( pA->op==TK_COLLATE ){
107288 if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
107289 }else
107290 if( pB->u.zToken!=0
107291 && pA->op!=TK_COLUMN
107292 && pA->op!=TK_AGG_COLUMN
107293 && strcmp(pA->u.zToken,pB->u.zToken)!=0
107294 ){
107295 return 2;
107296 }
107297 }
107298 if( (pA->flags & (EP_Distinct|EP_Commuted))
107299 != (pB->flags & (EP_Distinct|EP_Commuted)) ) return 2;
@@ -106821,16 +107378,17 @@
107378 return pNN->op!=TK_NULL;
107379 }
107380 switch( p->op ){
107381 case TK_IN: {
107382 if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0;
107383 assert( ExprUseXSelect(p) || (p->x.pList!=0 && p->x.pList->nExpr>0) );
 
107384 return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1);
107385 }
107386 case TK_BETWEEN: {
107387 ExprList *pList;
107388 assert( ExprUseXList(p) );
107389 pList = p->x.pList;
107390 assert( pList!=0 );
107391 assert( pList->nExpr==2 );
107392 if( seenNot ) return 0;
107393 if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1)
107394 || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1)
@@ -107003,14 +107561,18 @@
107561 testcase( pExpr->op==TK_LE );
107562 testcase( pExpr->op==TK_GT );
107563 testcase( pExpr->op==TK_GE );
107564 /* The y.pTab=0 assignment in wherecode.c always happens after the
107565 ** impliesNotNullRow() test */
107566 assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
107567 assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
107568 if( (pLeft->op==TK_COLUMN
107569 && pLeft->y.pTab!=0
107570 && IsVirtual(pLeft->y.pTab))
107571 || (pRight->op==TK_COLUMN
107572 && pRight->y.pTab!=0
107573 && IsVirtual(pRight->y.pTab))
107574 ){
107575 return WRC_Prune;
107576 }
107577 /* no break */ deliberate_fall_through
107578 }
@@ -107115,92 +107677,129 @@
107677 sqlite3WalkExpr(&w, pExpr);
107678 return !w.eCode;
107679 }
107680
107681
107682 /* Structure used to pass information throught the Walker in order to
107683 ** implement sqlite3ReferencesSrcList().
 
 
 
107684 */
107685 struct RefSrcList {
107686 sqlite3 *db; /* Database connection used for sqlite3DbRealloc() */
107687 SrcList *pRef; /* Looking for references to these tables */
107688 i64 nExclude; /* Number of tables to exclude from the search */
107689 int *aiExclude; /* Cursor IDs for tables to exclude from the search */
107690 };
107691
107692 /*
107693 ** Walker SELECT callbacks for sqlite3ReferencesSrcList().
107694 **
107695 ** When entering a new subquery on the pExpr argument, add all FROM clause
107696 ** entries for that subquery to the exclude list.
107697 **
107698 ** When leaving the subquery, remove those entries from the exclude list.
107699 */
107700 static int selectRefEnter(Walker *pWalker, Select *pSelect){
107701 struct RefSrcList *p = pWalker->u.pRefSrcList;
107702 SrcList *pSrc = pSelect->pSrc;
107703 i64 i, j;
107704 int *piNew;
107705 if( pSrc->nSrc==0 ) return WRC_Continue;
107706 j = p->nExclude;
107707 p->nExclude += pSrc->nSrc;
107708 piNew = sqlite3DbRealloc(p->db, p->aiExclude, p->nExclude*sizeof(int));
107709 if( piNew==0 ){
107710 p->nExclude = 0;
107711 return WRC_Abort;
107712 }else{
107713 p->aiExclude = piNew;
107714 }
107715 for(i=0; i<pSrc->nSrc; i++, j++){
107716 p->aiExclude[j] = pSrc->a[i].iCursor;
107717 }
107718 return WRC_Continue;
107719 }
107720 static void selectRefLeave(Walker *pWalker, Select *pSelect){
107721 struct RefSrcList *p = pWalker->u.pRefSrcList;
107722 SrcList *pSrc = pSelect->pSrc;
107723 if( p->nExclude ){
107724 assert( p->nExclude>=pSrc->nSrc );
107725 p->nExclude -= pSrc->nSrc;
107726 }
107727 }
107728
107729 /* This is the Walker EXPR callback for sqlite3ReferencesSrcList().
107730 **
107731 ** Set the 0x01 bit of pWalker->eCode if there is a reference to any
107732 ** of the tables shown in RefSrcList.pRef.
107733 **
107734 ** Set the 0x02 bit of pWalker->eCode if there is a reference to a
107735 ** table is in neither RefSrcList.pRef nor RefSrcList.aiExclude.
107736 */
107737 static int exprRefToSrcList(Walker *pWalker, Expr *pExpr){
107738 if( pExpr->op==TK_COLUMN
107739 || pExpr->op==TK_AGG_COLUMN
107740 ){
107741 int i;
107742 struct RefSrcList *p = pWalker->u.pRefSrcList;
107743 SrcList *pSrc = p->pRef;
107744 int nSrc = pSrc ? pSrc->nSrc : 0;
107745 for(i=0; i<nSrc; i++){
107746 if( pExpr->iTable==pSrc->a[i].iCursor ){
107747 pWalker->eCode |= 1;
107748 return WRC_Continue;
107749 }
107750 }
107751 for(i=0; i<p->nExclude && p->aiExclude[i]!=pExpr->iTable; i++){}
107752 if( i>=p->nExclude ){
107753 pWalker->eCode |= 2;
 
107754 }
107755 }
107756 return WRC_Continue;
107757 }
107758
107759 /*
107760 ** Check to see if pExpr references any tables in pSrcList.
107761 ** Possible return values:
107762 **
107763 ** 1 pExpr does references a table in pSrcList.
107764 **
107765 ** 0 pExpr references some table that is not defined in either
107766 ** pSrcList or in subqueries of pExpr itself.
107767 **
107768 ** -1 pExpr only references no tables at all, or it only
107769 ** references tables defined in subqueries of pExpr itself.
107770 **
107771 ** As currently used, pExpr is always an aggregate function call. That
107772 ** fact is exploited for efficiency.
107773 */
107774 SQLITE_PRIVATE int sqlite3ReferencesSrcList(Parse *pParse, Expr *pExpr, SrcList *pSrcList){
107775 Walker w;
107776 struct RefSrcList x;
107777 memset(&w, 0, sizeof(w));
107778 memset(&x, 0, sizeof(x));
107779 w.xExprCallback = exprRefToSrcList;
107780 w.xSelectCallback = selectRefEnter;
107781 w.xSelectCallback2 = selectRefLeave;
107782 w.u.pRefSrcList = &x;
107783 x.db = pParse->db;
107784 x.pRef = pSrcList;
107785 assert( pExpr->op==TK_AGG_FUNCTION );
107786 assert( ExprUseXList(pExpr) );
 
 
 
 
 
 
 
107787 sqlite3WalkExprList(&w, pExpr->x.pList);
107788 #ifndef SQLITE_OMIT_WINDOWFUNC
107789 if( ExprHasProperty(pExpr, EP_WinFunc) ){
107790 sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter);
107791 }
107792 #endif
107793 sqlite3DbFree(pParse->db, x.aiExclude);
107794 if( w.eCode & 0x01 ){
107795 return 1;
107796 }else if( w.eCode ){
107797 return 0;
107798 }else{
107799 return -1;
107800 }
107801 }
107802
107803 /*
107804 ** This is a Walker expression node callback.
107805 **
@@ -107331,10 +107930,11 @@
107930 }
107931 if( (k>=pAggInfo->nColumn)
107932 && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
107933 ){
107934 pCol = &pAggInfo->aCol[k];
107935 assert( ExprUseYTab(pExpr) );
107936 pCol->pTab = pExpr->y.pTab;
107937 pCol->iTable = pExpr->iTable;
107938 pCol->iColumn = pExpr->iColumn;
107939 pCol->iMem = ++pParse->nMem;
107940 pCol->iSorterColumn = -1;
@@ -107394,11 +107994,11 @@
107994 if( i>=0 ){
107995 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
107996 pItem = &pAggInfo->aFunc[i];
107997 pItem->pFExpr = pExpr;
107998 pItem->iMem = ++pParse->nMem;
107999 assert( ExprUseUToken(pExpr) );
108000 pItem->pFunc = sqlite3FindFunction(pParse->db,
108001 pExpr->u.zToken,
108002 pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0);
108003 if( pExpr->flags & EP_Distinct ){
108004 pItem->iDistinct = pParse->nTab++;
@@ -107609,11 +108209,11 @@
108209 int bNoDQS /* Do not allow DQS in the schema */
108210 ){
108211 pParse->colNamesSet = 1;
108212 sqlite3NestedParse(pParse,
108213 "SELECT 1 "
108214 "FROM \"%w\"." LEGACY_SCHEMA_TABLE " "
108215 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108216 " AND sql NOT LIKE 'create virtual%%'"
108217 " AND sqlite_rename_test(%Q, sql, type, name, %d, %Q, %d)=NULL ",
108218 zDb,
108219 zDb, bTemp, zWhen, bNoDQS
@@ -107620,11 +108220,11 @@
108220 );
108221
108222 if( bTemp==0 ){
108223 sqlite3NestedParse(pParse,
108224 "SELECT 1 "
108225 "FROM temp." LEGACY_SCHEMA_TABLE " "
108226 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108227 " AND sql NOT LIKE 'create virtual%%'"
108228 " AND sqlite_rename_test(%Q, sql, type, name, 1, %Q, %d)=NULL ",
108229 zDb, zWhen, bNoDQS
108230 );
@@ -107638,18 +108238,18 @@
108238 ** not true, similarly update all SQL statements in the sqlite_schema table
108239 ** of the temp db.
108240 */
108241 static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){
108242 sqlite3NestedParse(pParse,
108243 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE
108244 " SET sql = sqlite_rename_quotefix(%Q, sql)"
108245 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108246 " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb
108247 );
108248 if( bTemp==0 ){
108249 sqlite3NestedParse(pParse,
108250 "UPDATE temp." LEGACY_SCHEMA_TABLE
108251 " SET sql = sqlite_rename_quotefix('temp', sql)"
108252 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108253 " AND sql NOT LIKE 'create virtual%%'"
108254 );
108255 }
@@ -107763,21 +108363,21 @@
108363 nTabName = sqlite3Utf8CharLen(zTabName, -1);
108364
108365 /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in
108366 ** the schema to use the new table name. */
108367 sqlite3NestedParse(pParse,
108368 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108369 "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) "
108370 "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)"
108371 "AND name NOT LIKE 'sqliteX_%%' ESCAPE 'X'"
108372 , zDb, zDb, zTabName, zName, (iDb==1), zTabName
108373 );
108374
108375 /* Update the tbl_name and name columns of the sqlite_schema table
108376 ** as required. */
108377 sqlite3NestedParse(pParse,
108378 "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET "
108379 "tbl_name = %Q, "
108380 "name = CASE "
108381 "WHEN type='table' THEN %Q "
108382 "WHEN name LIKE 'sqliteX_autoindex%%' ESCAPE 'X' "
108383 " AND type='index' THEN "
@@ -107916,10 +108516,11 @@
108516 */
108517 assert( pDflt==0 || pDflt->op==TK_SPAN );
108518 if( pDflt && pDflt->pLeft->op==TK_NULL ){
108519 pDflt = 0;
108520 }
108521 assert( IsOrdinaryTable(pNew) );
108522 if( (db->flags&SQLITE_ForeignKeys) && pNew->u.tab.pFKey && pDflt ){
108523 sqlite3ErrorIfNotEmpty(pParse, zDb, zTab,
108524 "Cannot add a REFERENCES column with non-NULL default value");
108525 }
108526 if( pCol->notNull && !pDflt ){
@@ -107958,13 +108559,14 @@
108559 while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){
108560 *zEnd-- = '\0';
108561 }
108562 /* substr() operations on characters, but addColOffset is in bytes. So we
108563 ** have to use printf() to translate between these units: */
108564 assert( IsOrdinaryTable(pTab) );
108565 assert( IsOrdinaryTable(pNew) );
108566 sqlite3NestedParse(pParse,
108567 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108568 "sql = printf('%%.%ds, ',sql) || %Q"
108569 " || substr(sql,1+length(printf('%%.%ds',sql))) "
108570 "WHERE type = 'table' AND name = %Q",
108571 zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset,
108572 zTab
@@ -107986,11 +108588,11 @@
108588 VdbeCoverage(v);
108589 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3);
108590 sqlite3ReleaseTempReg(pParse, r1);
108591
108592 /* Reload the table definition */
108593 renameReloadSchema(pParse, iDb, INITFLAG_AlterAdd);
108594
108595 /* Verify that constraints are still satisfied */
108596 if( pNew->pCheck!=0
108597 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0)
108598 ){
@@ -108052,10 +108654,11 @@
108654 if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
108655 goto exit_begin_add_column;
108656 }
108657
108658 sqlite3MayAbort(pParse);
108659 assert( IsOrdinaryTable(pTab) );
108660 assert( pTab->u.tab.addColOffset>0 );
108661 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
108662
108663 /* Put a copy of the Table struct in Parse.pNewTable for the
108664 ** sqlite3AddColumn() function and friends to modify. But modify
@@ -108082,11 +108685,11 @@
108685 for(i=0; i<pNew->nCol; i++){
108686 Column *pCol = &pNew->aCol[i];
108687 pCol->zCnName = sqlite3DbStrDup(db, pCol->zCnName);
108688 pCol->hName = sqlite3StrIHash(pCol->zCnName);
108689 }
108690 assert( IsOrdinaryTable(pNew) );
108691 pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0);
108692 pNew->pSchema = db->aDb[iDb].pSchema;
108693 pNew->u.tab.addColOffset = pTab->u.tab.addColOffset;
108694 pNew->nTabRef = 1;
108695
@@ -108193,21 +108796,21 @@
108796 zNew = sqlite3NameFromToken(db, pNew);
108797 if( !zNew ) goto exit_rename_column;
108798 assert( pNew->n>0 );
108799 bQuote = sqlite3Isquote(pNew->z[0]);
108800 sqlite3NestedParse(pParse,
108801 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
108802 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
108803 "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
108804 " AND (type != 'index' OR tbl_name = %Q)",
108805 zDb,
108806 zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
108807 pTab->zName
108808 );
108809
108810 sqlite3NestedParse(pParse,
108811 "UPDATE temp." LEGACY_SCHEMA_TABLE " SET "
108812 "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) "
108813 "WHERE type IN ('trigger', 'view')",
108814 zDb, pTab->zName, iCol, zNew, bQuote
108815 );
108816
@@ -108351,11 +108954,13 @@
108954 ** Walker callback used by sqlite3RenameExprUnmap().
108955 */
108956 static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
108957 Parse *pParse = pWalker->pParse;
108958 sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr);
108959 if( ExprUseYTab(pExpr) ){
108960 sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);
108961 }
108962 return WRC_Continue;
108963 }
108964
108965 /*
108966 ** Iterate through the Select objects that are part of WITH clauses attached
@@ -108413,11 +109018,13 @@
109018 */
109019 static int renameUnmapSelectCb(Walker *pWalker, Select *p){
109020 Parse *pParse = pWalker->pParse;
109021 int i;
109022 if( pParse->nErr ) return WRC_Abort;
109023 testcase( p->selFlags & SF_View );
109024 testcase( p->selFlags & SF_CopyCte );
109025 if( p->selFlags & (SF_View|SF_CopyCte) ){
109026 return WRC_Prune;
109027 }
109028 if( ALWAYS(p->pEList) ){
109029 ExprList *pList = p->pEList;
109030 for(i=0; i<pList->nExpr; i++){
@@ -108550,10 +109157,11 @@
109157 && pWalker->pParse->pTriggerTab==p->pTab
109158 ){
109159 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
109160 }else if( pExpr->op==TK_COLUMN
109161 && pExpr->iColumn==p->iCol
109162 && ALWAYS(ExprUseYTab(pExpr))
109163 && p->pTab==pExpr->y.pTab
109164 ){
109165 renameTokenFind(pWalker->pParse, p, (void*)pExpr);
109166 }
109167 return WRC_Continue;
@@ -108874,10 +109482,13 @@
109482 p->pTab->nTabRef++;
109483 rc = sqlite3ViewGetColumnNames(pParse, p->pTab);
109484 }
109485 }
109486 }
109487 if( rc==SQLITE_OK && db->mallocFailed ){
109488 rc = SQLITE_NOMEM;
109489 }
109490 sNC.pSrcList = pSrc;
109491 if( rc==SQLITE_OK && pStep->pWhere ){
109492 rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere);
109493 }
109494 if( rc==SQLITE_OK ){
@@ -109080,11 +109691,11 @@
109691 sqlite3WalkExpr(&sWalker, pExpr);
109692 }
109693 #endif
109694 }
109695
109696 assert( IsOrdinaryTable(sParse.pNewTable) );
109697 for(pFKey=sParse.pNewTable->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
109698 for(i=0; i<pFKey->nCol; i++){
109699 if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){
109700 renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]);
109701 }
@@ -109152,11 +109763,14 @@
109763 /*
109764 ** Walker expression callback used by "RENAME TABLE".
109765 */
109766 static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
109767 RenameCtx *p = pWalker->u.pRename;
109768 if( pExpr->op==TK_COLUMN
109769 && ALWAYS(ExprUseYTab(pExpr))
109770 && p->pTab==pExpr->y.pTab
109771 ){
109772 renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
109773 }
109774 return WRC_Continue;
109775 }
109776
@@ -109270,11 +109884,11 @@
109884 #ifndef SQLITE_OMIT_FOREIGN_KEY
109885 if( (isLegacy==0 || (db->flags & SQLITE_ForeignKeys))
109886 && !IsVirtual(pTab)
109887 ){
109888 FKey *pFKey;
109889 assert( IsOrdinaryTable(pTab) );
109890 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
109891 if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){
109892 renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo);
109893 }
109894 }
@@ -109591,11 +110205,11 @@
110205 if( iCol<pTab->nCol-1 ){
110206 RenameToken *pEnd;
110207 pEnd = renameTokenFind(&sParse, 0, (void*)pTab->aCol[iCol+1].zCnName);
110208 zEnd = (const char*)pEnd->t.z;
110209 }else{
110210 assert( IsOrdinaryTable(pTab) );
110211 zEnd = (const char*)&zSql[pTab->u.tab.addColOffset];
110212 while( ALWAYS(pCol->t.z[0]!=0) && pCol->t.z[0]!=',' ) pCol->t.z--;
110213 }
110214
110215 zNew = sqlite3MPrintf(db, "%.*s%s", pCol->t.z-zSql, zSql, zEnd);
@@ -109673,11 +110287,11 @@
110287 assert( iDb>=0 );
110288 zDb = db->aDb[iDb].zDbSName;
110289 renameTestSchema(pParse, zDb, iDb==1, "", 0);
110290 renameFixQuotes(pParse, zDb, iDb==1);
110291 sqlite3NestedParse(pParse,
110292 "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
110293 "sql = sqlite_drop_column(%d, sql, %d) "
110294 "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)"
110295 , zDb, iDb, iCol, pTab->zName
110296 );
110297
@@ -110766,11 +111380,11 @@
111380 pParse->nMem = MAX(pParse->nMem, iMem);
111381 v = sqlite3GetVdbe(pParse);
111382 if( v==0 || NEVER(pTab==0) ){
111383 return;
111384 }
111385 if( !IsOrdinaryTable(pTab) ){
111386 /* Do not gather statistics on views or virtual tables */
111387 return;
111388 }
111389 if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){
111390 /* Do not gather statistics on system tables */
@@ -112049,21 +112663,22 @@
112663 if( pParse->nErr ) goto attach_end;
112664 memset(&sName, 0, sizeof(NameContext));
112665 sName.pParse = pParse;
112666
112667 if(
112668 SQLITE_OK!=resolveAttachExpr(&sName, pFilename) ||
112669 SQLITE_OK!=resolveAttachExpr(&sName, pDbname) ||
112670 SQLITE_OK!=resolveAttachExpr(&sName, pKey)
112671 ){
112672 goto attach_end;
112673 }
112674
112675 #ifndef SQLITE_OMIT_AUTHORIZATION
112676 if( pAuthArg ){
112677 char *zAuthArg;
112678 if( pAuthArg->op==TK_STRING ){
112679 assert( !ExprHasProperty(pAuthArg, EP_IntValue) );
112680 zAuthArg = pAuthArg->u.zToken;
112681 }else{
112682 zAuthArg = 0;
112683 }
112684 rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0);
@@ -112744,21 +113359,26 @@
113359 Returning *pReturning = pParse->u1.pReturning;
113360 int addrRewind;
113361 int i;
113362 int reg;
113363
113364 if( pReturning->nRetCol==0 ){
113365 assert( CORRUPT_DB );
113366 }else{
113367 sqlite3VdbeAddOp0(v, OP_FkCheck);
113368 addrRewind =
113369 sqlite3VdbeAddOp1(v, OP_Rewind, pReturning->iRetCur);
113370 VdbeCoverage(v);
113371 reg = pReturning->iRetReg;
113372 for(i=0; i<pReturning->nRetCol; i++){
113373 sqlite3VdbeAddOp3(v, OP_Column, pReturning->iRetCur, i, reg+i);
113374 }
113375 sqlite3VdbeAddOp2(v, OP_ResultRow, reg, i);
113376 sqlite3VdbeAddOp2(v, OP_Next, pReturning->iRetCur, addrRewind+1);
113377 VdbeCoverage(v);
113378 sqlite3VdbeJumpHere(v, addrRewind);
113379 }
113380 }
113381 sqlite3VdbeAddOp0(v, OP_Halt);
113382
113383 #if SQLITE_USER_AUTHENTICATION
113384 if( pParse->nTableLock>0 && db->init.busy==0 ){
@@ -112835,11 +113455,15 @@
113455 }
113456 }
113457
113458 if( pParse->bReturning ){
113459 Returning *pRet = pParse->u1.pReturning;
113460 if( pRet->nRetCol==0 ){
113461 assert( CORRUPT_DB );
113462 }else{
113463 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pRet->iRetCur, pRet->nRetCol);
113464 }
113465 }
113466
113467 /* Finally, jump back to the beginning of the executable code. */
113468 sqlite3VdbeGoto(v, 1);
113469 }
@@ -112953,21 +113577,21 @@
113577 }
113578 }
113579 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113580 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113581 if( i==1 ){
113582 if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0
113583 || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0
113584 || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0
113585 ){
113586 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113587 LEGACY_TEMP_SCHEMA_TABLE);
113588 }
113589 }else{
113590 if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113591 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash,
113592 LEGACY_SCHEMA_TABLE);
113593 }
113594 }
113595 }
113596 }else{
113597 /* Match against TEMP first */
@@ -112981,15 +113605,15 @@
113605 assert( sqlite3SchemaMutexHeld(db, i, 0) );
113606 p = sqlite3HashFind(&db->aDb[i].pSchema->tblHash, zName);
113607 if( p ) break;
113608 }
113609 if( p==0 && sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113610 if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){
113611 p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE);
113612 }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){
113613 p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash,
113614 LEGACY_TEMP_SCHEMA_TABLE);
113615 }
113616 }
113617 }
113618 return p;
113619 }
@@ -113080,10 +113704,26 @@
113704 }else{
113705 zDb = p->zDatabase;
113706 }
113707 return sqlite3LocateTable(pParse, flags, p->zName, zDb);
113708 }
113709
113710 /*
113711 ** Return the preferred table name for system tables. Translate legacy
113712 ** names into the new preferred names, as appropriate.
113713 */
113714 SQLITE_PRIVATE const char *sqlite3PreferredTableName(const char *zName){
113715 if( sqlite3StrNICmp(zName, "sqlite_", 7)==0 ){
113716 if( sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){
113717 return PREFERRED_SCHEMA_TABLE;
113718 }
113719 if( sqlite3StrICmp(zName+7, &LEGACY_TEMP_SCHEMA_TABLE[7])==0 ){
113720 return PREFERRED_TEMP_SCHEMA_TABLE;
113721 }
113722 }
113723 return zName;
113724 }
113725
113726 /*
113727 ** Locate the in-memory structure that describes
113728 ** a particular index given the name of that index
113729 ** and the name of the database that contains the index.
@@ -113257,11 +113897,11 @@
113897 Table *pTab, /* The table containing the column */
113898 Column *pCol, /* The column to receive the new DEFAULT expression */
113899 Expr *pExpr /* The new default expression */
113900 ){
113901 ExprList *pList;
113902 assert( IsOrdinaryTable(pTab) );
113903 pList = pTab->u.tab.pDfltList;
113904 if( pCol->iDflt==0
113905 || NEVER(pList==0)
113906 || NEVER(pList->nExpr<pCol->iDflt)
113907 ){
@@ -113278,11 +113918,11 @@
113918 ** the DEFAULT clause or the AS clause of a generated column.
113919 ** Return NULL if the column has no associated expression.
113920 */
113921 SQLITE_PRIVATE Expr *sqlite3ColumnExpr(Table *pTab, Column *pCol){
113922 if( pCol->iDflt==0 ) return 0;
113923 if( NEVER(!IsOrdinaryTable(pTab)) ) return 0;
113924 if( NEVER(pTab->u.tab.pDfltList==0) ) return 0;
113925 if( NEVER(pTab->u.tab.pDfltList->nExpr<pCol->iDflt) ) return 0;
113926 return pTab->u.tab.pDfltList->a[pCol->iDflt-1].pExpr;
113927 }
113928
@@ -113292,12 +113932,12 @@
113932 SQLITE_PRIVATE void sqlite3ColumnSetColl(
113933 sqlite3 *db,
113934 Column *pCol,
113935 const char *zColl
113936 ){
113937 i64 nColl;
113938 i64 n;
113939 char *zNew;
113940 assert( zColl!=0 );
113941 n = sqlite3Strlen30(pCol->zCnName) + 1;
113942 if( pCol->colFlags & COLFLAG_HASTYPE ){
113943 n += sqlite3Strlen30(pCol->zCnName+n) + 1;
@@ -113337,17 +113977,17 @@
113977 for(i=0; i<pTable->nCol; i++, pCol++){
113978 assert( pCol->zCnName==0 || pCol->hName==sqlite3StrIHash(pCol->zCnName) );
113979 sqlite3DbFree(db, pCol->zCnName);
113980 }
113981 sqlite3DbFree(db, pTable->aCol);
113982 if( IsOrdinaryTable(pTable) ){
113983 sqlite3ExprListDelete(db, pTable->u.tab.pDfltList);
113984 }
113985 if( db==0 || db->pnBytesFreed==0 ){
113986 pTable->aCol = 0;
113987 pTable->nCol = 0;
113988 if( IsOrdinaryTable(pTable) ){
113989 pTable->u.tab.pDfltList = 0;
113990 }
113991 }
113992 }
113993 }
@@ -113479,11 +114119,11 @@
114119 ** Open the sqlite_schema table stored in database number iDb for
114120 ** writing. The table is opened using cursor 0.
114121 */
114122 SQLITE_PRIVATE void sqlite3OpenSchemaTable(Parse *p, int iDb){
114123 Vdbe *v = sqlite3GetVdbe(p);
114124 sqlite3TableLock(p, iDb, SCHEMA_ROOT, 1, LEGACY_SCHEMA_TABLE);
114125 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, SCHEMA_ROOT, iDb, 5);
114126 if( p->nTab==0 ){
114127 p->nTab = 1;
114128 }
114129 }
@@ -114098,11 +114738,11 @@
114738 break;
114739 }
114740 }
114741 }
114742
114743 z = sqlite3DbMallocRaw(db, (i64)sName.n + 1 + (i64)sType.n + (sType.n>0) );
114744 if( z==0 ) return;
114745 if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, &sName);
114746 memcpy(z, sName.z, sName.n);
114747 z[sName.n] = 0;
114748 sqlite3Dequote(z);
@@ -114112,11 +114752,11 @@
114752 sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
114753 sqlite3DbFree(db, z);
114754 return;
114755 }
114756 }
114757 aNew = sqlite3DbRealloc(db,p->aCol,((i64)p->nCol+1)*sizeof(p->aCol[0]));
114758 if( aNew==0 ){
114759 sqlite3DbFree(db, z);
114760 return;
114761 }
114762 p->aCol = aNew;
@@ -114410,11 +115050,13 @@
115050 for(i=0; i<nTerm; i++){
115051 Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
115052 assert( pCExpr!=0 );
115053 sqlite3StringToId(pCExpr);
115054 if( pCExpr->op==TK_ID ){
115055 const char *zCName;
115056 assert( !ExprHasProperty(pCExpr, EP_IntValue) );
115057 zCName = pCExpr->u.zToken;
115058 for(iCol=0; iCol<pTab->nCol; iCol++){
115059 if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zCnName)==0 ){
115060 pCol = &pTab->aCol[iCol];
115061 makeColumnPartOfPrimaryKey(pParse, pCol);
115062 break;
@@ -114782,11 +115424,10 @@
115424 ** This is used to determine if the column number x appears in any of the
115425 ** first nCol entries of an index.
115426 */
115427 static int hasColumn(const i16 *aiCol, int nCol, int x){
115428 while( nCol-- > 0 ){
 
115429 if( x==*(aiCol++) ){
115430 return 1;
115431 }
115432 }
115433 return 0;
@@ -115057,10 +115698,45 @@
115698 if( pMod->pModule->xShadowName==0 ) return 0;
115699 return pMod->pModule->xShadowName(zName+nName+1);
115700 }
115701 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115702
115703 #ifndef SQLITE_OMIT_VIRTUALTABLE
115704 /*
115705 ** Table pTab is a virtual table. If it the virtual table implementation
115706 ** exists and has an xShadowName method, then loop over all other ordinary
115707 ** tables within the same schema looking for shadow tables of pTab, and mark
115708 ** any shadow tables seen using the TF_Shadow flag.
115709 */
115710 SQLITE_PRIVATE void sqlite3MarkAllShadowTablesOf(sqlite3 *db, Table *pTab){
115711 int nName; /* Length of pTab->zName */
115712 Module *pMod; /* Module for the virtual table */
115713 HashElem *k; /* For looping through the symbol table */
115714
115715 assert( IsVirtual(pTab) );
115716 pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->u.vtab.azArg[0]);
115717 if( pMod==0 ) return;
115718 if( NEVER(pMod->pModule==0) ) return;
115719 if( pMod->pModule->iVersion<3 ) return;
115720 if( pMod->pModule->xShadowName==0 ) return;
115721 assert( pTab->zName!=0 );
115722 nName = sqlite3Strlen30(pTab->zName);
115723 for(k=sqliteHashFirst(&pTab->pSchema->tblHash); k; k=sqliteHashNext(k)){
115724 Table *pOther = sqliteHashData(k);
115725 assert( pOther->zName!=0 );
115726 if( !IsOrdinaryTable(pOther) ) continue;
115727 if( pOther->tabFlags & TF_Shadow ) continue;
115728 if( sqlite3StrNICmp(pOther->zName, pTab->zName, nName)==0
115729 && pOther->zName[nName]=='_'
115730 && pMod->pModule->xShadowName(pOther->zName+nName+1)
115731 ){
115732 pOther->tabFlags |= TF_Shadow;
115733 }
115734 }
115735 }
115736 #endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
115737
115738 #ifndef SQLITE_OMIT_VIRTUALTABLE
115739 /*
115740 ** Return true if zName is a shadow table name in the current database
115741 ** connection.
115742 **
@@ -115158,11 +115834,11 @@
115834 **
115835 ** If the root page number is 1, that means this is the sqlite_schema
115836 ** table itself. So mark it read-only.
115837 */
115838 if( db->init.busy ){
115839 if( pSelect || (!IsOrdinaryTable(p) && db->init.newTnum) ){
115840 sqlite3ErrorMsg(pParse, "");
115841 return;
115842 }
115843 p->tnum = db->init.newTnum;
115844 if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
@@ -115385,11 +116061,11 @@
116061 /* A slot for the record has already been allocated in the
116062 ** schema table. We just need to update that slot with all
116063 ** the information we've collected.
116064 */
116065 sqlite3NestedParse(pParse,
116066 "UPDATE %Q." LEGACY_SCHEMA_TABLE
116067 " SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q"
116068 " WHERE rowid=#%d",
116069 db->aDb[iDb].zDbSName,
116070 zType,
116071 p->zName,
@@ -115571,17 +116247,16 @@
116247 #endif
116248
116249 assert( pTable );
116250
116251 #ifndef SQLITE_OMIT_VIRTUALTABLE
116252 if( IsVirtual(pTable) ){
116253 db->nSchemaLock++;
116254 rc = sqlite3VtabCallConnect(pParse, pTable);
116255 db->nSchemaLock--;
116256 return rc;
116257 }
 
116258 #endif
116259
116260 #ifndef SQLITE_OMIT_VIEW
116261 /* A positive nCol means the columns names for this view are
116262 ** already known.
@@ -115765,11 +116440,11 @@
116440 ** The "#NNN" in the SQL is a special constant that means whatever value
116441 ** is in register NNN. See grammar rules associated with the TK_REGISTER
116442 ** token for additional information.
116443 */
116444 sqlite3NestedParse(pParse,
116445 "UPDATE %Q." LEGACY_SCHEMA_TABLE
116446 " SET rootpage=%d WHERE #%d AND rootpage=#%d",
116447 pParse->db->aDb[iDb].zDbSName, iTable, r1, r1);
116448 #endif
116449 sqlite3ReleaseTempReg(pParse, r1);
116450 }
@@ -115900,11 +116575,11 @@
116575 ** dropped. Triggers are handled separately because a trigger can be
116576 ** created in the temp database that refers to a table in another
116577 ** database.
116578 */
116579 sqlite3NestedParse(pParse,
116580 "DELETE FROM %Q." LEGACY_SCHEMA_TABLE
116581 " WHERE tbl_name=%Q and type!='trigger'",
116582 pDb->zDbSName, pTab->zName);
116583 if( !isView && !IsVirtual(pTab) ){
116584 destroyTable(pParse, pTab);
116585 }
@@ -115947,10 +116622,13 @@
116622 if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0;
116623 return 1;
116624 }
116625 if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){
116626 return 1;
116627 }
116628 if( pTab->tabFlags & TF_Eponymous ){
116629 return 1;
116630 }
116631 return 0;
116632 }
116633
116634 /*
@@ -116087,11 +116765,11 @@
116765 sqlite3 *db = pParse->db;
116766 #ifndef SQLITE_OMIT_FOREIGN_KEY
116767 FKey *pFKey = 0;
116768 FKey *pNextTo;
116769 Table *p = pParse->pNewTable;
116770 i64 nByte;
116771 int i;
116772 int nCol;
116773 char *z;
116774
116775 assert( pTo!=0 );
@@ -116123,10 +116801,11 @@
116801 pFKey = sqlite3DbMallocZero(db, nByte );
116802 if( pFKey==0 ){
116803 goto fk_end;
116804 }
116805 pFKey->pFrom = p;
116806 assert( IsOrdinaryTable(p) );
116807 pFKey->pNextFrom = p->u.tab.pFKey;
116808 z = (char*)&pFKey->aCol[nCol];
116809 pFKey->zTo = z;
116810 if( IN_RENAME_OBJECT ){
116811 sqlite3RenameTokenMap(pParse, (void*)z, pTo);
@@ -116188,11 +116867,11 @@
116867 pNextTo->pPrevTo = pFKey;
116868 }
116869
116870 /* Link the foreign key to the table as the last step.
116871 */
116872 assert( IsOrdinaryTable(p) );
116873 p->u.tab.pFKey = pFKey;
116874 pFKey = 0;
116875
116876 fk_end:
116877 sqlite3DbFree(db, pFKey);
@@ -116211,11 +116890,11 @@
116890 SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){
116891 #ifndef SQLITE_OMIT_FOREIGN_KEY
116892 Table *pTab;
116893 FKey *pFKey;
116894 if( (pTab = pParse->pNewTable)==0 ) return;
116895 if( NEVER(!IsOrdinaryTable(pTab)) ) return;
116896 if( (pFKey = pTab->u.tab.pFKey)==0 ) return;
116897 assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */
116898 pFKey->isDeferred = (u8)isDeferred;
116899 #endif
116900 }
@@ -116613,10 +117292,11 @@
117292 */
117293 for(i=0; i<pList->nExpr; i++){
117294 Expr *pExpr = pList->a[i].pExpr;
117295 assert( pExpr!=0 );
117296 if( pExpr->op==TK_COLLATE ){
117297 assert( !ExprHasProperty(pExpr, EP_IntValue) );
117298 nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken));
117299 }
117300 }
117301
117302 /*
@@ -116708,10 +117388,11 @@
117388 pIndex->aiColumn[i] = (i16)j;
117389 }
117390 zColl = 0;
117391 if( pListItem->pExpr->op==TK_COLLATE ){
117392 int nColl;
117393 assert( !ExprHasProperty(pListItem->pExpr, EP_IntValue) );
117394 zColl = pListItem->pExpr->u.zToken;
117395 nColl = sqlite3Strlen30(zColl) + 1;
117396 assert( nExtra>=nColl );
117397 memcpy(zExtra, zColl, nColl);
117398 zColl = zExtra;
@@ -116914,17 +117595,17 @@
117595 }
117596
117597 /* Add an entry in sqlite_schema for this index
117598 */
117599 sqlite3NestedParse(pParse,
117600 "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);",
117601 db->aDb[iDb].zDbSName,
117602 pIndex->zName,
117603 pTab->zName,
117604 iMem,
117605 zStmt
117606 );
117607 sqlite3DbFree(db, zStmt);
117608
117609 /* Fill the index with data and reparse the schema. Code an OP_Expire
117610 ** to invalidate all pre-compiled statements.
117611 */
@@ -117100,11 +117781,11 @@
117781 /* Generate code to remove the index and from the schema table */
117782 v = sqlite3GetVdbe(pParse);
117783 if( v ){
117784 sqlite3BeginWriteOperation(pParse, 1, iDb);
117785 sqlite3NestedParse(pParse,
117786 "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='index'",
117787 db->aDb[iDb].zDbSName, pIndex->zName
117788 );
117789 sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName);
117790 sqlite3ChangeCookie(pParse, iDb);
117791 destroyRootPage(pParse, pIndex->tnum, iDb);
@@ -117468,11 +118149,11 @@
118149 pItem->pSelect = pSubquery;
118150 pItem->pOn = pOn;
118151 pItem->pUsing = pUsing;
118152 return p;
118153
118154 append_from_error:
118155 assert( p==0 );
118156 sqlite3ExprDelete(db, pOn);
118157 sqlite3IdListDelete(db, pUsing);
118158 sqlite3SelectDelete(db, pSubquery);
118159 return 0;
@@ -117496,10 +118177,11 @@
118177 ** construct "indexed_opt" for details. */
118178 pItem->fg.notIndexed = 1;
118179 }else{
118180 pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy);
118181 pItem->fg.isIndexedBy = 1;
118182 assert( pItem->fg.isCte==0 ); /* No collision on union u2 */
118183 }
118184 }
118185 }
118186
118187 /*
@@ -118476,10 +119158,11 @@
119158 int h, /* Hash of the name */
119159 const char *zFunc /* Name of function */
119160 ){
119161 FuncDef *p;
119162 for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){
119163 assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
119164 if( sqlite3StrICmp(p->zName, zFunc)==0 ){
119165 return p;
119166 }
119167 }
119168 return 0;
@@ -118497,10 +119180,11 @@
119180 FuncDef *pOther;
119181 const char *zName = aDef[i].zName;
119182 int nName = sqlite3Strlen30(zName);
119183 int h = SQLITE_FUNC_HASH(zName[0], nName);
119184 assert( zName[0]>='a' && zName[0]<='z' );
119185 assert( aDef[i].funcFlags & SQLITE_FUNC_BUILTIN );
119186 pOther = sqlite3FunctionSearch(h, zName);
119187 if( pOther ){
119188 assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] );
119189 aDef[i].pNext = pOther->pNext;
119190 pOther->pNext = &aDef[i];
@@ -118721,10 +119405,20 @@
119405 pTab = 0;
119406 }
119407 }
119408 return pTab;
119409 }
119410
119411 /* Generate byte-code that will report the number of rows modified
119412 ** by a DELETE, INSERT, or UPDATE statement.
119413 */
119414 SQLITE_PRIVATE void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){
119415 sqlite3VdbeAddOp0(v, OP_FkCheck);
119416 sqlite3VdbeAddOp2(v, OP_ResultRow, regCounter, 1);
119417 sqlite3VdbeSetNumCols(v, 1);
119418 sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zColName, SQLITE_STATIC);
119419 }
119420
119421 /* Return true if table pTab is read-only.
119422 **
119423 ** A table is read-only if any of the following are true:
119424 **
@@ -118888,10 +119582,11 @@
119582 ** and the SELECT subtree. */
119583 pSrc->a[0].pTab = 0;
119584 pSelectSrc = sqlite3SrcListDup(db, pSrc, 0);
119585 pSrc->a[0].pTab = pTab;
119586 if( pSrc->a[0].fg.isIndexedBy ){
119587 assert( pSrc->a[0].fg.isCte==0 );
119588 pSrc->a[0].u2.pIBIndex = 0;
119589 pSrc->a[0].fg.isIndexedBy = 0;
119590 sqlite3DbFree(db, pSrc->a[0].u1.zIndexedBy);
119591 }else if( pSrc->a[0].fg.isCte ){
119592 pSrc->a[0].u2.pCteUse->nUse++;
@@ -119296,13 +119991,11 @@
119991 /* Return the number of rows that were deleted. If this routine is
119992 ** generating code because of a call to sqlite3NestedParse(), do not
119993 ** invoke the callback function.
119994 */
119995 if( memCnt ){
119996 sqlite3CodeChangeCount(v, memCnt, "rows deleted");
 
 
119997 }
119998
119999 delete_from_cleanup:
120000 sqlite3AuthContextPop(&sContext);
120001 sqlite3SrcListDelete(db, pTabList);
@@ -121472,11 +122165,15 @@
122165 if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
122166 pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
122167 /* pGCC is always non-NULL since groupConcatStep() will have always
122168 ** run frist to initialize it */
122169 if( ALWAYS(pGCC) ){
122170 int nVS;
122171 /* Must call sqlite3_value_text() to convert the argument into text prior
122172 ** to invoking sqlite3_value_bytes(), in case the text encoding is UTF16 */
122173 (void)sqlite3_value_text(argv[0]);
122174 nVS = sqlite3_value_bytes(argv[0]);
122175 pGCC->nAccum -= 1;
122176 if( pGCC->pnSepLengths!=0 ){
122177 assert(pGCC->nAccum >= 0);
122178 if( pGCC->nAccum>0 ){
122179 nVS += *pGCC->pnSepLengths;
@@ -121587,15 +122284,16 @@
122284 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){
122285 FuncDef *pDef;
122286 int nExpr;
122287 assert( pExpr!=0 );
122288 assert( pExpr->op==TK_FUNCTION );
122289 assert( ExprUseXList(pExpr) );
122290 if( !pExpr->x.pList ){
122291 return 0;
122292 }
 
122293 nExpr = pExpr->x.pList->nExpr;
122294 assert( !ExprHasProperty(pExpr, EP_IntValue) );
122295 pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0);
122296 #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
122297 if( pDef==0 ) return 0;
122298 #endif
122299 if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){
@@ -121615,10 +122313,11 @@
122313 aWc[3] = 0;
122314 }else{
122315 Expr *pEscape = pExpr->x.pList->a[2].pExpr;
122316 char *zEscape;
122317 if( pEscape->op!=TK_STRING ) return 0;
122318 assert( !ExprHasProperty(pEscape, EP_IntValue) );
122319 zEscape = pEscape->u.zToken;
122320 if( zEscape[0]==0 || zEscape[1]!=0 ) return 0;
122321 if( zEscape[0]==aWc[0] ) return 0;
122322 if( zEscape[0]==aWc[1] ) return 0;
122323 aWc[3] = zEscape[0];
@@ -121996,10 +122695,11 @@
122695 for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
122696 printf("FUNC-HASH %02d:", i);
122697 for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){
122698 int n = sqlite3Strlen30(p->zName);
122699 int h = p->zName[0] + n;
122700 assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
122701 printf(" %s(%d)", p->zName, h);
122702 }
122703 printf("\n");
122704 }
122705 }
@@ -122518,10 +123218,11 @@
123218 int iCursor, /* The open cursor on the table */
123219 i16 iCol /* The column that is wanted */
123220 ){
123221 Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
123222 if( pExpr ){
123223 assert( ExprUseYTab(pExpr) );
123224 pExpr->y.pTab = pTab;
123225 pExpr->iTable = iCursor;
123226 pExpr->iColumn = iCol;
123227 }
123228 return pExpr;
@@ -122728,17 +123429,16 @@
123429 ** the table from the database. Triggers are disabled while running this
123430 ** DELETE, but foreign key actions are not.
123431 */
123432 SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){
123433 sqlite3 *db = pParse->db;
123434 if( (db->flags&SQLITE_ForeignKeys) && IsOrdinaryTable(pTab) ){
123435 int iSkip = 0;
123436 Vdbe *v = sqlite3GetVdbe(pParse);
123437
123438 assert( v ); /* VDBE has already been allocated */
123439 assert( IsOrdinaryTable(pTab) );
 
123440 if( sqlite3FkReferences(pTab)==0 ){
123441 /* Search for a deferred foreign key constraint for which this table
123442 ** is the child table. If one cannot be found, return without
123443 ** generating any VDBE code. If one can be found, then jump over
123444 ** the entire DELETE if there are no outstanding deferred constraints
@@ -122898,17 +123598,17 @@
123598 /* Exactly one of regOld and regNew should be non-zero. */
123599 assert( (regOld==0)!=(regNew==0) );
123600
123601 /* If foreign-keys are disabled, this function is a no-op. */
123602 if( (db->flags&SQLITE_ForeignKeys)==0 ) return;
123603 if( !IsOrdinaryTable(pTab) ) return;
123604
123605 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
123606 zDb = db->aDb[iDb].zDbSName;
123607
123608 /* Loop through all the foreign key constraints for which pTab is the
123609 ** child table (the table that the foreign key definition is part of). */
 
123610 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){
123611 Table *pTo; /* Parent table of foreign key pFKey */
123612 Index *pIdx = 0; /* Index on key columns in pTo */
123613 int *aiFree = 0;
123614 int *aiCol;
@@ -123087,14 +123787,13 @@
123787 SQLITE_PRIVATE u32 sqlite3FkOldmask(
123788 Parse *pParse, /* Parse context */
123789 Table *pTab /* Table being modified */
123790 ){
123791 u32 mask = 0;
123792 if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){
123793 FKey *p;
123794 int i;
 
123795 for(p=pTab->u.tab.pFKey; p; p=p->pNextFrom){
123796 for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
123797 }
123798 for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
123799 Index *pIdx = 0;
@@ -123141,11 +123840,11 @@
123840 int *aChange, /* Non-NULL for UPDATE operations */
123841 int chngRowid /* True for UPDATE that affects rowid */
123842 ){
123843 int eRet = 1; /* Value to return if bHaveFK is true */
123844 int bHaveFK = 0; /* If FK processing is required */
123845 if( pParse->db->flags&SQLITE_ForeignKeys && IsOrdinaryTable(pTab) ){
123846 if( !aChange ){
123847 /* A DELETE operation. Foreign key processing is required if the
123848 ** table in question is either the child or parent table for any
123849 ** foreign key constraint. */
123850 bHaveFK = (sqlite3FkReferences(pTab) || pTab->u.tab.pFKey);
@@ -123429,11 +124128,11 @@
124128 */
124129 SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){
124130 FKey *pFKey; /* Iterator variable */
124131 FKey *pNext; /* Copy of pFKey->pNextFrom */
124132
124133 assert( IsOrdinaryTable(pTab) );
124134 for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pNext){
124135 assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) );
124136
124137 /* Remove the FK from the fkeyHash hash table. */
124138 if( !db || db->pnBytesFreed==0 ){
@@ -123750,28 +124449,34 @@
124449
124450 /* Before computing generated columns, first go through and make sure
124451 ** that appropriate affinity has been applied to the regular columns
124452 */
124453 sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore);
124454 if( (pTab->tabFlags & TF_HasStored)!=0 ){
124455 pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1);
124456 if( pOp->opcode==OP_Affinity ){
124457 /* Change the OP_Affinity argument to '@' (NONE) for all stored
124458 ** columns. '@' is the no-op affinity and those columns have not
124459 ** yet been computed. */
124460 int ii, jj;
124461 char *zP4 = pOp->p4.z;
124462 assert( zP4!=0 );
124463 assert( pOp->p4type==P4_DYNAMIC );
124464 for(ii=jj=0; zP4[jj]; ii++){
124465 if( pTab->aCol[ii].colFlags & COLFLAG_VIRTUAL ){
124466 continue;
124467 }
124468 if( pTab->aCol[ii].colFlags & COLFLAG_STORED ){
124469 zP4[jj] = SQLITE_AFF_NONE;
124470 }
124471 jj++;
124472 }
124473 }else if( pOp->opcode==OP_TypeCheck ){
124474 /* If an OP_TypeCheck was generated because the table is STRICT,
124475 ** then set the P3 operand to indicate that generated columns should
124476 ** not be checked */
124477 pOp->p3 = 1;
124478 }
124479 }
124480
124481 /* Because there can be multiple generated columns that refer to one another,
124482 ** this is a two-pass algorithm. On the first pass, mark all generated
@@ -124844,13 +125549,11 @@
125549 ** Return the number of rows inserted. If this routine is
125550 ** generating code because of a call to sqlite3NestedParse(), do not
125551 ** invoke the callback function.
125552 */
125553 if( regRowCount ){
125554 sqlite3CodeChangeCount(v, regRowCount, "rows inserted");
 
 
125555 }
125556
125557 insert_cleanup:
125558 sqlite3SrcListDelete(db, pTabList);
125559 sqlite3ExprListDelete(db, pList);
@@ -125688,10 +126391,11 @@
126391 ** (5) No FK constraint counters need to be updated if a conflict occurs.
126392 **
126393 ** This is not possible for ENABLE_PREUPDATE_HOOK builds, as the row
126394 ** must be explicitly deleted in order to ensure any pre-update hook
126395 ** is invoked. */
126396 assert( IsOrdinaryTable(pTab) );
126397 #ifndef SQLITE_ENABLE_PREUPDATE_HOOK
126398 if( (ix==0 && pIdx->pNext==0) /* Condition 3 */
126399 && pPk==pIdx /* Condition 2 */
126400 && onError==OE_Replace /* Condition 1 */
126401 && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */
@@ -125794,11 +126498,12 @@
126498 default: {
126499 int nConflictCk; /* Number of opcodes in conflict check logic */
126500
126501 assert( onError==OE_Replace );
126502 nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk;
126503 assert( nConflictCk>0 || db->mallocFailed );
126504 testcase( nConflictCk<=0 );
126505 testcase( nConflictCk>1 );
126506 if( regTrigCnt ){
126507 sqlite3MultiWrite(pParse);
126508 nReplaceTrig++;
126509 }
@@ -126080,12 +126785,13 @@
126785
126786 assert( op==OP_OpenRead || op==OP_OpenWrite );
126787 assert( op==OP_OpenWrite || p5==0 );
126788 if( IsVirtual(pTab) ){
126789 /* This routine is a no-op for virtual tables. Leave the output
126790 ** variables *piDataCur and *piIdxCur set to illegal cursor numbers
126791 ** for improved error detection. */
126792 *piDataCur = *piIdxCur = -999;
126793 return 0;
126794 }
126795 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
126796 v = pParse->pVdbe;
126797 assert( v!=0 );
@@ -126368,11 +127074,13 @@
127074 /* Default values for second and subsequent columns need to match. */
127075 if( (pDestCol->colFlags & COLFLAG_GENERATED)==0 && i>0 ){
127076 Expr *pDestExpr = sqlite3ColumnExpr(pDest, pDestCol);
127077 Expr *pSrcExpr = sqlite3ColumnExpr(pSrc, pSrcCol);
127078 assert( pDestExpr==0 || pDestExpr->op==TK_SPAN );
127079 assert( pDestExpr==0 || !ExprHasProperty(pDestExpr, EP_IntValue) );
127080 assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN );
127081 assert( pSrcExpr==0 || !ExprHasProperty(pSrcExpr, EP_IntValue) );
127082 if( (pDestExpr==0)!=(pSrcExpr==0)
127083 || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken,
127084 pSrcExpr->u.zToken)!=0)
127085 ){
127086 return 0; /* Default values must be the same for all columns */
@@ -126408,10 +127116,11 @@
127116 ** But the main beneficiary of the transfer optimization is the VACUUM
127117 ** command, and the VACUUM command disables foreign key constraints. So
127118 ** the extra complication to make this rule less restrictive is probably
127119 ** not worth the effort. Ticket [6284df89debdfa61db8073e062908af0c9b6118e]
127120 */
127121 assert( IsOrdinaryTable(pDest) );
127122 if( (db->flags & SQLITE_ForeignKeys)!=0 && pDest->u.tab.pFKey!=0 ){
127123 return 0;
127124 }
127125 #endif
127126 if( (db->flags & SQLITE_CountRows)!=0 ){
@@ -127089,10 +127798,14 @@
127798 /* Version 3.34.0 and later */
127799 int (*txn_state)(sqlite3*,const char*);
127800 /* Version 3.36.1 and later */
127801 sqlite3_int64 (*changes64)(sqlite3*);
127802 sqlite3_int64 (*total_changes64)(sqlite3*);
127803 /* Version 3.37.0 and later */
127804 int (*autovacuum_pages)(sqlite3*,
127805 unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
127806 void*, void(*)(void*));
127807 };
127808
127809 /*
127810 ** This is the function signature used for all extension entry points. It
127811 ** is also defined in the file "loadext.c".
@@ -127395,10 +128108,15 @@
128108 #define sqlite3_create_filename sqlite3_api->create_filename
128109 #define sqlite3_free_filename sqlite3_api->free_filename
128110 #define sqlite3_database_file_object sqlite3_api->database_file_object
128111 /* Version 3.34.0 and later */
128112 #define sqlite3_txn_state sqlite3_api->txn_state
128113 /* Version 3.36.1 and later */
128114 #define sqlite3_changes64 sqlite3_api->changes64
128115 #define sqlite3_total_changes64 sqlite3_api->total_changes64
128116 /* Version 3.37.0 and later */
128117 #define sqlite3_autovacuum_pages sqlite3_api->autovacuum_pages
128118 #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
128119
128120 #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
128121 /* This case when the file really is being compiled as a loadable
128122 ** extension */
@@ -127882,10 +128600,12 @@
128600 /* Version 3.34.0 and later */
128601 sqlite3_txn_state,
128602 /* Version 3.36.1 and later */
128603 sqlite3_changes64,
128604 sqlite3_total_changes64,
128605 /* Version 3.37.0 and later */
128606 sqlite3_autovacuum_pages,
128607 };
128608
128609 /* True if x is the directory separator character
128610 */
128611 #if SQLITE_OS_WIN
@@ -128871,11 +129591,11 @@
129591 /* iArg: */ 0 },
129592 {/* zName: */ "table_list",
129593 /* ePragTyp: */ PragTyp_TABLE_LIST,
129594 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1,
129595 /* ColNames: */ 15, 6,
129596 /* iArg: */ 0 },
129597 {/* zName: */ "table_xinfo",
129598 /* ePragTyp: */ PragTyp_TABLE_INFO,
129599 /* ePragFlg: */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
129600 /* ColNames: */ 8, 7,
129601 /* iArg: */ 1 },
@@ -129400,11 +130120,15 @@
130120 goto pragma_out;
130121 }
130122
130123 /* Locate the pragma in the lookup table */
130124 pPragma = pragmaLocate(zLeft);
130125 if( pPragma==0 ){
130126 /* IMP: R-43042-22504 No error messages are generated if an
130127 ** unknown pragma is issued. */
130128 goto pragma_out;
130129 }
130130
130131 /* Make sure the database schema is loaded if the pragma requires that */
130132 if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){
130133 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
130134 }
@@ -130050,10 +130774,18 @@
130774 if( sqlite3GetBoolean(zRight, 0) ){
130775 db->flags |= mask;
130776 }else{
130777 db->flags &= ~mask;
130778 if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
130779 if( (mask & SQLITE_WriteSchema)!=0
130780 && sqlite3_stricmp(zRight, "reset")==0
130781 ){
130782 /* IMP: R-60817-01178 If the argument is "RESET" then schema
130783 ** writing is disabled (as with "PRAGMA writable_schema=OFF") and,
130784 ** in addition, the schema is reloaded. */
130785 sqlite3ResetAllSchemasOfConnection(db);
130786 }
130787 }
130788
130789 /* Many of the flag-pragmas modify the code generated by the SQL
130790 ** compiler (eg. count_changes). So add an opcode to expire all
130791 ** compiled SQL statements after modifying a pragma value.
@@ -130090,10 +130822,11 @@
130822 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
130823 pParse->nMem = 7;
130824 sqlite3ViewGetColumnNames(pParse, pTab);
130825 for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
130826 int isHidden = 0;
130827 const Expr *pColExpr;
130828 if( pCol->colFlags & COLFLAG_NOINSERT ){
130829 if( pPragma->iArg==0 ){
130830 nHidden++;
130831 continue;
130832 }
@@ -130110,20 +130843,20 @@
130843 }else if( pPk==0 ){
130844 k = 1;
130845 }else{
130846 for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
130847 }
130848 pColExpr = sqlite3ColumnExpr(pTab,pCol);
130849 assert( pColExpr==0 || pColExpr->op==TK_SPAN || isHidden>=2 );
130850 assert( pColExpr==0 || !ExprHasProperty(pColExpr, EP_IntValue)
130851 || isHidden>=2 );
130852 sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi",
130853 i-nHidden,
130854 pCol->zCnName,
130855 sqlite3ColumnType(pCol,""),
130856 pCol->notNull ? 1 : 0,
130857 (isHidden>=2 || pColExpr==0) ? 0 : pColExpr->u.zToken,
 
130858 k,
130859 isHidden);
130860 }
130861 }
130862 }
@@ -130147,12 +130880,39 @@
130880 pParse->nMem = 6;
130881 sqlite3CodeVerifyNamedSchema(pParse, zDb);
130882 for(ii=0; ii<db->nDb; ii++){
130883 HashElem *k;
130884 Hash *pHash;
130885 int initNCol;
130886 if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue;
130887
130888 /* Ensure that the Table.nCol field is initialized for all views
130889 ** and virtual tables. Each time we initialize a Table.nCol value
130890 ** for a table, that can potentially disrupt the hash table, so restart
130891 ** the initialization scan.
130892 */
130893 pHash = &db->aDb[ii].pSchema->tblHash;
130894 initNCol = sqliteHashCount(pHash);
130895 while( initNCol-- ){
130896 for(k=sqliteHashFirst(pHash); 1; k=sqliteHashNext(k) ){
130897 Table *pTab;
130898 if( k==0 ){ initNCol = 0; break; }
130899 pTab = sqliteHashData(k);
130900 if( pTab->nCol==0 ){
130901 char *zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\"", pTab->zName);
130902 if( zSql ){
130903 sqlite3_stmt *pDummy = 0;
130904 (void)sqlite3_prepare(db, zSql, -1, &pDummy, 0);
130905 (void)sqlite3_finalize(pDummy);
130906 sqlite3DbFree(db, zSql);
130907 }
130908 pHash = &db->aDb[ii].pSchema->tblHash;
130909 break;
130910 }
130911 }
130912 }
130913
130914 for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){
130915 Table *pTab = sqliteHashData(k);
130916 const char *zType;
130917 if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue;
130918 if( IsView(pTab) ){
@@ -130164,11 +130924,11 @@
130924 }else{
130925 zType = "table";
130926 }
130927 sqlite3VdbeMultiLoad(v, 1, "sssiii",
130928 db->aDb[ii].zDbSName,
130929 sqlite3PreferredTableName(pTab->zName),
130930 zType,
130931 pTab->nCol,
130932 (pTab->tabFlags & TF_WithoutRowid)!=0,
130933 (pTab->tabFlags & TF_Strict)!=0
130934 );
@@ -130184,11 +130944,11 @@
130944 pParse->nMem = 5;
130945 sqlite3CodeVerifySchema(pParse, iDb);
130946 for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
130947 Table *pTab = sqliteHashData(i);
130948 sqlite3VdbeMultiLoad(v, 1, "ssiii",
130949 sqlite3PreferredTableName(pTab->zName),
130950 0,
130951 pTab->szTabRow,
130952 pTab->nRowLogEst,
130953 pTab->tabFlags);
130954 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
@@ -130303,15 +131063,17 @@
131063 FuncDef *p;
131064 int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0;
131065 pParse->nMem = 6;
131066 for(i=0; i<SQLITE_FUNC_HASH_SZ; i++){
131067 for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){
131068 assert( p->funcFlags & SQLITE_FUNC_BUILTIN );
131069 pragmaFunclistLine(v, p, 1, showInternFunc);
131070 }
131071 }
131072 for(j=sqliteHashFirst(&db->aFunc); j; j=sqliteHashNext(j)){
131073 p = (FuncDef*)sqliteHashData(j);
131074 assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 );
131075 pragmaFunclistLine(v, p, 0, showInternFunc);
131076 }
131077 }
131078 break;
131079
@@ -130341,11 +131103,11 @@
131103 #ifndef SQLITE_OMIT_FOREIGN_KEY
131104 case PragTyp_FOREIGN_KEY_LIST: if( zRight ){
131105 FKey *pFK;
131106 Table *pTab;
131107 pTab = sqlite3FindTable(db, zRight, zDb);
131108 if( pTab && IsOrdinaryTable(pTab) ){
131109 pFK = pTab->u.tab.pFKey;
131110 if( pFK ){
131111 int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema);
131112 int i = 0;
131113 pParse->nMem = 8;
@@ -130401,19 +131163,19 @@
131163 k = 0;
131164 }else{
131165 pTab = (Table*)sqliteHashData(k);
131166 k = sqliteHashNext(k);
131167 }
131168 if( pTab==0 || !IsOrdinaryTable(pTab) || pTab->u.tab.pFKey==0 ) continue;
131169 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
131170 zDb = db->aDb[iDb].zDbSName;
131171 sqlite3CodeVerifySchema(pParse, iDb);
131172 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
131173 if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow;
131174 sqlite3OpenTable(pParse, 0, iDb, pTab, OP_OpenRead);
131175 sqlite3VdbeLoadString(v, regResult, pTab->zName);
131176 assert( IsOrdinaryTable(pTab) );
131177 for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
131178 pParent = sqlite3FindTable(db, pFK->zTo, zDb);
131179 if( pParent==0 ) continue;
131180 pIdx = 0;
131181 sqlite3TableLock(pParse, iDb, pParent->tnum, 0, pParent->zName);
@@ -130432,11 +131194,11 @@
131194 }
131195 assert( pParse->nErr>0 || pFK==0 );
131196 if( pFK ) break;
131197 if( pParse->nTab<i ) pParse->nTab = i;
131198 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v);
131199 assert( IsOrdinaryTable(pTab) );
131200 for(i=1, pFK=pTab->u.tab.pFKey; pFK; i++, pFK=pFK->pNextFrom){
131201 pParent = sqlite3FindTable(db, pFK->zTo, zDb);
131202 pIdx = 0;
131203 aiCols = 0;
131204 if( pParent ){
@@ -130636,11 +131398,11 @@
131398 int loopTop;
131399 int iDataCur, iIdxCur;
131400 int r1 = -1;
131401 int bStrict;
131402
131403 if( !IsOrdinaryTable(pTab) ) continue;
131404 if( pObjTab && pObjTab!=pTab ) continue;
131405 pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
131406 sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
131407 1, 0, &iDataCur, &iIdxCur);
131408 /* reg[7] counts the number of entries in the table.
@@ -130677,11 +131439,11 @@
131439 if( pCol->notNull ){
131440 jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
131441 zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
131442 pCol->zCnName);
131443 sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
131444 if( bStrict && pCol->eCType!=COLTYPE_ANY ){
131445 sqlite3VdbeGoto(v, doError);
131446 }else{
131447 integrityCheckResultRow(v);
131448 }
131449 sqlite3VdbeJumpHere(v, jmp2);
@@ -131231,16 +131993,16 @@
131993 ** in each index that it looks at. Return the new limit.
131994 */
131995 case PragTyp_ANALYSIS_LIMIT: {
131996 sqlite3_int64 N;
131997 if( zRight
131998 && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK /* IMP: R-40975-20399 */
131999 && N>=0
132000 ){
132001 db->nAnalysisLimit = (int)(N&0x7fffffff);
132002 }
132003 returnSingleInt(v, db->nAnalysisLimit); /* IMP: R-57594-65522 */
132004 break;
132005 }
132006
132007 #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
132008 /*
@@ -131638,14 +132400,19 @@
132400 sqlite3 *db = pData->db;
132401 if( db->mallocFailed ){
132402 pData->rc = SQLITE_NOMEM_BKPT;
132403 }else if( pData->pzErrMsg[0]!=0 ){
132404 /* A error message has already been generated. Do not overwrite it */
132405 }else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
132406 static const char *azAlterType[] = {
132407 "rename",
132408 "drop column",
132409 "add column"
132410 };
132411 *pData->pzErrMsg = sqlite3MPrintf(db,
132412 "error in %s %s after %s: %s", azObj[0], azObj[1],
132413 azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1],
132414 zExtra
132415 );
132416 pData->rc = SQLITE_ERROR;
132417 }else if( db->flags & SQLITE_WriteSchema ){
132418 pData->rc = SQLITE_CORRUPT_BKPT;
@@ -132412,10 +133179,11 @@
133179 /* Make multiple attempts to compile the SQL, until it either succeeds
133180 ** or encounters a permanent error. A schema problem after one schema
133181 ** reset is considered a permanent error. */
133182 rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail);
133183 assert( rc==SQLITE_OK || *ppStmt==0 );
133184 if( rc==SQLITE_OK || db->mallocFailed ) break;
133185 }while( rc==SQLITE_ERROR_RETRY
133186 || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) );
133187 sqlite3BtreeLeaveAll(db);
133188 rc = sqlite3ApiExit(db, rc);
133189 assert( (rc&db->errMask)==rc );
@@ -133023,14 +133791,17 @@
133791 while( p ){
133792 ExprSetProperty(p, EP_FromJoin);
133793 assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
133794 ExprSetVVAProperty(p, EP_NoReduce);
133795 p->iRightJoinTable = iTable;
133796 if( p->op==TK_FUNCTION ){
133797 assert( ExprUseXList(p) );
133798 if( p->x.pList ){
133799 int i;
133800 for(i=0; i<p->x.pList->nExpr; i++){
133801 sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable);
133802 }
133803 }
133804 }
133805 sqlite3SetJoinExpr(p->pLeft, iTable);
133806 p = p->pRight;
133807 }
@@ -133049,14 +133820,17 @@
133820 ExprClearProperty(p, EP_FromJoin);
133821 }
133822 if( p->op==TK_COLUMN && p->iTable==iTable ){
133823 ExprClearProperty(p, EP_CanBeNull);
133824 }
133825 if( p->op==TK_FUNCTION ){
133826 assert( ExprUseXList(p) );
133827 if( p->x.pList ){
133828 int i;
133829 for(i=0; i<p->x.pList->nExpr; i++){
133830 unsetJoinExpr(p->x.pList->a[i].pExpr, iTable);
133831 }
133832 }
133833 }
133834 unsetJoinExpr(p->pLeft, iTable);
133835 p = p->pRight;
133836 }
@@ -133567,13 +134341,17 @@
134341 ExprList *pExtra = 0;
134342 for(i=0; i<pEList->nExpr; i++){
134343 struct ExprList_item *pItem = &pEList->a[i];
134344 if( pItem->u.x.iOrderByCol==0 ){
134345 Expr *pExpr = pItem->pExpr;
134346 Table *pTab;
134347 if( pExpr->op==TK_COLUMN
134348 && pExpr->iColumn>=0
134349 && ALWAYS( ExprUseYTab(pExpr) )
134350 && (pTab = pExpr->y.pTab)!=0
134351 && IsOrdinaryTable(pTab)
134352 && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)!=0
134353 ){
134354 int j;
134355 for(j=0; j<nDefer; j++){
134356 if( pSort->aDefer[j].iCsr==pExpr->iTable ) break;
134357 }
@@ -133590,10 +134368,11 @@
134368 }
134369 for(k=0; k<nKey; k++){
134370 Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
134371 if( pNew ){
134372 pNew->iTable = pExpr->iTable;
134373 assert( ExprUseYTab(pNew) );
134374 pNew->y.pTab = pExpr->y.pTab;
134375 pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
134376 pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
134377 }
134378 }
@@ -134438,11 +135217,11 @@
135217 ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT
135218 ** branch below. */
135219 break;
135220 }
135221
135222 assert( pTab && ExprUseYTab(pExpr) && pExpr->y.pTab==pTab );
135223 if( pS ){
135224 /* The "table" is actually a sub-select or a view in the FROM clause
135225 ** of the SELECT statement. Return the declaration type and origin
135226 ** data for the result-set column of the sub-select.
135227 */
@@ -134498,13 +135277,15 @@
135277 /* The expression is a sub-select. Return the declaration type and
135278 ** origin info for the single column in the result set of the SELECT
135279 ** statement.
135280 */
135281 NameContext sNC;
135282 Select *pS;
135283 Expr *p;
135284 assert( ExprUseXSelect(pExpr) );
135285 pS = pExpr->x.pSelect;
135286 p = pS->pEList->a[0].pExpr;
135287 sNC.pSrcList = pS->pSrc;
135288 sNC.pNext = pNC;
135289 sNC.pParse = pNC->pParse;
135290 zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol);
135291 break;
@@ -134629,11 +135410,12 @@
135410 for(i=0; i<pEList->nExpr; i++){
135411 Expr *p = pEList->a[i].pExpr;
135412
135413 assert( p!=0 );
135414 assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
135415 assert( p->op!=TK_COLUMN
135416 || (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */
135417 if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
135418 /* An AS clause always takes first priority */
135419 char *zName = pEList->a[i].zEName;
135420 sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT);
135421 }else if( srcName && p->op==TK_COLUMN ){
@@ -134725,11 +135507,14 @@
135507 Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr);
135508 while( ALWAYS(pColExpr!=0) && pColExpr->op==TK_DOT ){
135509 pColExpr = pColExpr->pRight;
135510 assert( pColExpr!=0 );
135511 }
135512 if( pColExpr->op==TK_COLUMN
135513 && ALWAYS( ExprUseYTab(pColExpr) )
135514 && (pTab = pColExpr->y.pTab)!=0
135515 ){
135516 /* For columns use the column name name */
135517 int iCol = pColExpr->iColumn;
135518 if( iCol<0 ) iCol = pTab->iPKey;
135519 zName = iCol>=0 ? pTab->aCol[iCol].zCnName : "rowid";
135520 }else if( pColExpr->op==TK_ID ){
@@ -134811,11 +135596,11 @@
135596 memset(&sNC, 0, sizeof(sNC));
135597 sNC.pSrcList = pSelect->pSrc;
135598 a = pSelect->pEList->a;
135599 for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
135600 const char *zType;
135601 i64 n, m;
135602 pTab->tabFlags |= (pCol->colFlags & COLFLAG_NOINSERT);
135603 p = a[i].pExpr;
135604 zType = columnType(&sNC, p, 0, 0, 0);
135605 /* pCol->szEst = ... // Column size est for SELECT tables never used */
135606 pCol->affinity = sqlite3ExprAffinity(p);
@@ -134824,10 +135609,13 @@
135609 n = sqlite3Strlen30(pCol->zCnName);
135610 pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+m+2);
135611 if( pCol->zCnName ){
135612 memcpy(&pCol->zCnName[n+1], zType, m+1);
135613 pCol->colFlags |= COLFLAG_HASTYPE;
135614 }else{
135615 testcase( pCol->colFlags & COLFLAG_HASTYPE );
135616 pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
135617 }
135618 }
135619 if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
135620 pColl = sqlite3ExprCollSeq(pParse, p);
135621 if( pColl ){
@@ -134994,11 +135782,11 @@
135782 ** function is responsible for ensuring that this structure is eventually
135783 ** freed.
135784 */
135785 static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){
135786 ExprList *pOrderBy = p->pOrderBy;
135787 int nOrderBy = ALWAYS(pOrderBy!=0) ? pOrderBy->nExpr : 0;
135788 sqlite3 *db = pParse->db;
135789 KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1);
135790 if( pRet ){
135791 int i;
135792 for(i=0; i<nOrderBy; i++){
@@ -135615,10 +136403,11 @@
136403 Select *pLoop; /* For looping through SELECT statements */
136404 CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
136405 int nCol; /* Number of columns in result set */
136406
136407 assert( p->pNext==0 );
136408 assert( p->pEList!=0 );
136409 nCol = p->pEList->nExpr;
136410 pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1);
136411 if( !pKeyInfo ){
136412 rc = SQLITE_NOMEM_BKPT;
136413 goto multi_select_end;
@@ -135966,10 +136755,11 @@
136755 */
136756 if( op!=TK_ALL ){
136757 for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
136758 struct ExprList_item *pItem;
136759 for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
136760 assert( pItem!=0 );
136761 assert( pItem->u.x.iOrderByCol>0 );
136762 if( pItem->u.x.iOrderByCol==i ) break;
136763 }
136764 if( j==nOrderBy ){
136765 Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
@@ -135992,10 +136782,11 @@
136782 aPermute = sqlite3DbMallocRawNN(db, sizeof(u32)*(nOrderBy + 1));
136783 if( aPermute ){
136784 struct ExprList_item *pItem;
136785 aPermute[0] = nOrderBy;
136786 for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
136787 assert( pItem!=0 );
136788 assert( pItem->u.x.iOrderByCol>0 );
136789 assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
136790 aPermute[i] = pItem->u.x.iOrderByCol - 1;
136791 }
136792 pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
@@ -136304,11 +137095,11 @@
137095 if( pExpr->op==TK_IF_NULL_ROW && pExpr->iTable==pSubst->iTable ){
137096 pExpr->iTable = pSubst->iNewTable;
137097 }
137098 pExpr->pLeft = substExpr(pSubst, pExpr->pLeft);
137099 pExpr->pRight = substExpr(pSubst, pExpr->pRight);
137100 if( ExprUseXSelect(pExpr) ){
137101 substSelect(pSubst, pExpr->x.pSelect, 1);
137102 }else{
137103 substExprList(pSubst, pExpr->x.pList);
137104 }
137105 #ifndef SQLITE_OMIT_WINDOWFUNC
@@ -136791,11 +137582,11 @@
137582 /* Restriction (23) */
137583 if( (p->selFlags & SF_Recursive) ) return 0;
137584
137585 if( pSrc->nSrc>1 ){
137586 if( pParse->nSelect>500 ) return 0;
137587 aCsrMap = sqlite3DbMallocZero(db, ((i64)pParse->nTab+1)*sizeof(int));
137588 if( aCsrMap ) aCsrMap[0] = pParse->nTab;
137589 }
137590 }
137591
137592 /***** If we reach this point, flattening is permitted. *****/
@@ -137515,25 +138306,28 @@
138306 ** located but before their arguments have been subjected to aggregate
138307 ** analysis.
138308 */
138309 static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){
138310 int eRet = WHERE_ORDERBY_NORMAL; /* Return value */
138311 ExprList *pEList; /* Arguments to agg function */
138312 const char *zFunc; /* Name of aggregate function pFunc */
138313 ExprList *pOrderBy;
138314 u8 sortFlags = 0;
138315
138316 assert( *ppMinMax==0 );
138317 assert( pFunc->op==TK_AGG_FUNCTION );
138318 assert( !IsWindowFunc(pFunc) );
138319 assert( ExprUseXList(pFunc) );
138320 pEList = pFunc->x.pList;
138321 if( pEList==0
138322 || pEList->nExpr!=1
138323 || ExprHasProperty(pFunc, EP_WinFunc)
138324 || OptimizationDisabled(db, SQLITE_MinMaxOpt)
138325 ){
138326 return eRet;
138327 }
138328 assert( !ExprHasProperty(pFunc, EP_IntValue) );
138329 zFunc = pFunc->u.zToken;
138330 if( sqlite3StrICmp(zFunc, "min")==0 ){
138331 eRet = WHERE_ORDERBY_MIN;
138332 if( sqlite3ExprCanBeNull(pEList->a[0].pExpr) ){
138333 sortFlags = KEYINFO_ORDER_BIGNULL;
@@ -137557,31 +138351,44 @@
138351 **
138352 ** SELECT count(*) FROM <tbl>
138353 **
138354 ** where table is a database table, not a sub-select or view. If the query
138355 ** does match this pattern, then a pointer to the Table object representing
138356 ** <tbl> is returned. Otherwise, NULL is returned.
138357 **
138358 ** This routine checks to see if it is safe to use the count optimization.
138359 ** A correct answer is still obtained (though perhaps more slowly) if
138360 ** this routine returns NULL when it could have returned a table pointer.
138361 ** But returning the pointer when NULL should have been returned can
138362 ** result in incorrect answers and/or crashes. So, when in doubt, return NULL.
138363 */
138364 static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){
138365 Table *pTab;
138366 Expr *pExpr;
138367
138368 assert( !p->pGroupBy );
138369
138370 if( p->pWhere
138371 || p->pEList->nExpr!=1
138372 || p->pSrc->nSrc!=1
138373 || p->pSrc->a[0].pSelect
138374 || pAggInfo->nFunc!=1
138375 ){
138376 return 0;
138377 }
138378 pTab = p->pSrc->a[0].pTab;
138379 assert( pTab!=0 );
138380 assert( !IsView(pTab) );
138381 if( !IsOrdinaryTable(pTab) ) return 0;
138382 pExpr = p->pEList->a[0].pExpr;
138383 assert( pExpr!=0 );
 
 
138384 if( pExpr->op!=TK_AGG_FUNCTION ) return 0;
138385 if( pExpr->pAggInfo!=pAggInfo ) return 0;
138386 if( (pAggInfo->aFunc[0].pFunc->funcFlags&SQLITE_FUNC_COUNT)==0 ) return 0;
138387 assert( pAggInfo->aFunc[0].pFExpr==pExpr );
138388 testcase( ExprHasProperty(pExpr, EP_Distinct) );
138389 testcase( ExprHasProperty(pExpr, EP_WinFunc) );
138390 if( ExprHasProperty(pExpr, EP_Distinct|EP_WinFunc) ) return 0;
138391
138392 return pTab;
138393 }
138394
@@ -137606,10 +138413,11 @@
138413 if( !pIdx ){
138414 sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0);
138415 pParse->checkSchema = 1;
138416 return SQLITE_ERROR;
138417 }
138418 assert( pFrom->fg.isCte==0 );
138419 pFrom->u2.pIBIndex = pIdx;
138420 return SQLITE_OK;
138421 }
138422
138423 /*
@@ -137863,10 +138671,14 @@
138671 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
138672 pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
138673 if( db->mallocFailed ) return 2;
138674 pFrom->pSelect->selFlags |= SF_CopyCte;
138675 assert( pFrom->pSelect );
138676 if( pFrom->fg.isIndexedBy ){
138677 sqlite3ErrorMsg(pParse, "no such index: \"%s\"", pFrom->u1.zIndexedBy);
138678 return 2;
138679 }
138680 pFrom->fg.isCte = 1;
138681 pFrom->u2.pCteUse = pCteUse;
138682 pCteUse->nUse++;
138683 if( pCteUse->nUse>=2 && pCteUse->eM10d==M10d_Any ){
138684 pCteUse->eM10d = M10d_Yes;
@@ -138498,11 +139310,11 @@
139310 #endif
139311 sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
139312 for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
139313 if( pFunc->iDistinct>=0 ){
139314 Expr *pE = pFunc->pFExpr;
139315 assert( ExprUseXList(pE) );
139316 if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){
139317 sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one "
139318 "argument");
139319 pFunc->iDistinct = -1;
139320 }else{
@@ -138523,12 +139335,13 @@
139335 static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){
139336 Vdbe *v = pParse->pVdbe;
139337 int i;
139338 struct AggInfo_func *pF;
139339 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
139340 ExprList *pList;
139341 assert( ExprUseXList(pF->pFExpr) );
139342 pList = pF->pFExpr->x.pList;
139343 sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0);
139344 sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF);
139345 }
139346 }
139347
@@ -138558,13 +139371,14 @@
139371 pAggInfo->directMode = 1;
139372 for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
139373 int nArg;
139374 int addrNext = 0;
139375 int regAgg;
139376 ExprList *pList;
139377 assert( ExprUseXList(pF->pFExpr) );
139378 assert( !IsWindowFunc(pF->pFExpr) );
139379 pList = pF->pFExpr->x.pList;
139380 if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){
139381 Expr *pFilter = pF->pFExpr->y.pWin->pFilter;
139382 if( pAggInfo->nAccumulator
139383 && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)
139384 && regAcc
@@ -138806,11 +139620,13 @@
139620 if( p->pEList->nExpr!=1 ) return 0; /* Single result column */
139621 if( p->pWhere ) return 0;
139622 if( p->pGroupBy ) return 0;
139623 pExpr = p->pEList->a[0].pExpr;
139624 if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */
139625 assert( ExprUseUToken(pExpr) );
139626 if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */
139627 assert( ExprUseXList(pExpr) );
139628 if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */
139629 if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */
139630 pSub = p->pSrc->a[0].pSelect;
139631 if( pSub==0 ) return 0; /* The FROM is a subquery */
139632 if( pSub->pPrior==0 ) return 0; /* Must be a compound ry */
@@ -139621,11 +140437,11 @@
140437 }else{
140438 minMaxFlag = WHERE_ORDERBY_NORMAL;
140439 }
140440 for(i=0; i<pAggInfo->nFunc; i++){
140441 Expr *pExpr = pAggInfo->aFunc[i].pFExpr;
140442 assert( ExprUseXList(pExpr) );
140443 sNC.ncFlags |= NC_InAggFunc;
140444 sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
140445 #ifndef SQLITE_OMIT_WINDOWFUNC
140446 assert( !IsWindowFunc(pExpr) );
140447 if( ExprHasProperty(pExpr, EP_WinFunc) ){
@@ -139676,11 +140492,13 @@
140492 u16 distFlag = 0;
140493 int eDist = WHERE_DISTINCT_NOOP;
140494
140495 if( pAggInfo->nFunc==1
140496 && pAggInfo->aFunc[0].iDistinct>=0
140497 && ALWAYS(pAggInfo->aFunc[0].pFExpr!=0)
140498 && ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr))
140499 && pAggInfo->aFunc[0].pFExpr->x.pList!=0
140500 ){
140501 Expr *pExpr = pAggInfo->aFunc[0].pFExpr->x.pList->a[0].pExpr;
140502 pExpr = sqlite3ExprDup(db, pExpr, 0);
140503 pDistinct = sqlite3ExprListDup(db, pGroupBy, 0);
140504 pDistinct = sqlite3ExprListAppend(pParse, pDistinct, pExpr);
@@ -139997,10 +140815,11 @@
140815 if( i==pAggInfo->nFunc ){
140816 regAcc = ++pParse->nMem;
140817 sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
140818 }
140819 }else if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 ){
140820 assert( ExprUseXList(pAggInfo->aFunc[0].pFExpr) );
140821 pDistinct = pAggInfo->aFunc[0].pFExpr->x.pList;
140822 distFlag = pDistinct ? (WHERE_WANT_DISTINCT|WHERE_AGG_DISTINCT) : 0;
140823 }
140824
140825 /* This case runs if the aggregate has no GROUP BY clause. The
@@ -140670,11 +141489,11 @@
141489 if( v==0 ) goto triggerfinish_cleanup;
141490 sqlite3BeginWriteOperation(pParse, 0, iDb);
141491 z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n);
141492 testcase( z==0 );
141493 sqlite3NestedParse(pParse,
141494 "INSERT INTO %Q." LEGACY_SCHEMA_TABLE
141495 " VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')",
141496 db->aDb[iDb].zDbSName, zName,
141497 pTrig->table, z);
141498 sqlite3DbFree(db, z);
141499 sqlite3ChangeCookie(pParse, iDb);
@@ -140984,11 +141803,11 @@
141803
141804 /* Generate code to destroy the database record of the trigger.
141805 */
141806 if( (v = sqlite3GetVdbe(pParse))!=0 ){
141807 sqlite3NestedParse(pParse,
141808 "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE name=%Q AND type='trigger'",
141809 db->aDb[iDb].zDbSName, pTrigger->zName
141810 );
141811 sqlite3ChangeCookie(pParse, iDb);
141812 sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0);
141813 }
@@ -142852,13 +143671,11 @@
143671 /*
143672 ** Return the number of rows that were changed, if we are tracking
143673 ** that information.
143674 */
143675 if( regRowCount ){
143676 sqlite3CodeChangeCount(v, regRowCount, "rows updated");
 
 
143677 }
143678
143679 update_cleanup:
143680 sqlite3AuthContextPop(&sContext);
143681 sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */
@@ -143637,11 +144454,13 @@
144454 rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0);
144455 if( rc!=SQLITE_OK ) goto end_of_vacuum;
144456
144457 /* Do not attempt to change the page size for a WAL database */
144458 if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain))
144459 ==PAGER_JOURNALMODE_WAL
144460 && pOut==0
144461 ){
144462 db->nextPagesize = 0;
144463 }
144464
144465 if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0)
144466 || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0))
@@ -144022,11 +144841,14 @@
144841 ** Except, if argument db is not NULL, then the entry associated with
144842 ** connection db is left in the p->u.vtab.p list.
144843 */
144844 static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){
144845 VTable *pRet = 0;
144846 VTable *pVTable;
144847
144848 assert( IsVirtual(p) );
144849 pVTable = p->u.vtab.p;
144850 p->u.vtab.p = 0;
144851
144852 /* Assert that the mutex (if any) associated with the BtShared database
144853 ** that contains table p is held by the caller. See header comments
144854 ** above function sqlite3VtabUnlockList() for an explanation of why
@@ -144130,10 +144952,11 @@
144952 ** structure being xDisconnected and free). Any other VTable structures
144953 ** in the list are moved to the sqlite3.pDisconnect list of the associated
144954 ** database connection.
144955 */
144956 SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){
144957 assert( IsVirtual(p) );
144958 if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p);
144959 if( p->u.vtab.azArg ){
144960 int i;
144961 for(i=0; i<p->u.vtab.nArg; i++){
144962 if( i!=1 ) sqlite3DbFree(db, p->u.vtab.azArg[i]);
@@ -144147,13 +144970,16 @@
144970 ** The string is not copied - the pointer is stored. The
144971 ** string will be freed automatically when the table is
144972 ** deleted.
144973 */
144974 static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
144975 sqlite3_int64 nBytes;
144976 char **azModuleArg;
144977 sqlite3 *db = pParse->db;
144978
144979 assert( IsVirtual(pTable) );
144980 nBytes = sizeof(char *)*(2+pTable->u.vtab.nArg);
144981 if( pTable->u.vtab.nArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
144982 sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
144983 }
144984 azModuleArg = sqlite3DbRealloc(db, pTable->u.vtab.azArg, nBytes);
144985 if( azModuleArg==0 ){
@@ -144236,10 +145062,11 @@
145062 SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){
145063 Table *pTab = pParse->pNewTable; /* The table being constructed */
145064 sqlite3 *db = pParse->db; /* The database connection */
145065
145066 if( pTab==0 ) return;
145067 assert( IsVirtual(pTab) );
145068 addArgumentToVtab(pParse);
145069 pParse->sArg.z = 0;
145070 if( pTab->u.vtab.nArg<1 ) return;
145071
145072 /* If the CREATE VIRTUAL TABLE statement is being entered for the
@@ -144271,11 +145098,11 @@
145098 ** entry in the sqlite_schema table tht was created for this vtab
145099 ** by sqlite3StartTable().
145100 */
145101 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
145102 sqlite3NestedParse(pParse,
145103 "UPDATE %Q." LEGACY_SCHEMA_TABLE " "
145104 "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q "
145105 "WHERE rowid=#%d",
145106 db->aDb[iDb].zDbSName,
145107 pTab->zName,
145108 pTab->zName,
@@ -144291,22 +145118,18 @@
145118 sqlite3DbFree(db, zStmt);
145119
145120 iReg = ++pParse->nMem;
145121 sqlite3VdbeLoadString(v, iReg, pTab->zName);
145122 sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg);
145123 }else{
145124 /* If we are rereading the sqlite_schema table create the in-memory
145125 ** record of the table. */
 
 
 
 
 
145126 Table *pOld;
145127 Schema *pSchema = pTab->pSchema;
145128 const char *zName = pTab->zName;
145129 assert( zName!=0 );
145130 sqlite3MarkAllShadowTablesOf(db, pTab);
145131 pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab);
145132 if( pOld ){
145133 sqlite3OomFault(db);
145134 assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */
145135 return;
@@ -144353,17 +145176,20 @@
145176 char **pzErr
145177 ){
145178 VtabCtx sCtx;
145179 VTable *pVTable;
145180 int rc;
145181 const char *const*azArg;
145182 int nArg = pTab->u.vtab.nArg;
145183 char *zErr = 0;
145184 char *zModuleName;
145185 int iDb;
145186 VtabCtx *pCtx;
145187
145188 assert( IsVirtual(pTab) );
145189 azArg = (const char *const*)pTab->u.vtab.azArg;
145190
145191 /* Check that the virtual-table is not already being initialized */
145192 for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){
145193 if( pCtx->pTab==pTab ){
145194 *pzErr = sqlite3MPrintf(db,
145195 "vtable constructor called recursively: %s", pTab->zName
@@ -144483,11 +145309,12 @@
145309 const char *zMod;
145310 Module *pMod;
145311 int rc;
145312
145313 assert( pTab );
145314 assert( IsVirtual(pTab) );
145315 if( sqlite3GetVTable(db, pTab) ){
145316 return SQLITE_OK;
145317 }
145318
145319 /* Locate the required virtual table module */
145320 zMod = pTab->u.vtab.azArg[0];
@@ -144687,11 +145514,14 @@
145514 SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){
145515 int rc = SQLITE_OK;
145516 Table *pTab;
145517
145518 pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName);
145519 if( ALWAYS(pTab!=0)
145520 && ALWAYS(IsVirtual(pTab))
145521 && ALWAYS(pTab->u.vtab.p!=0)
145522 ){
145523 VTable *p;
145524 int (*xDestroy)(sqlite3_vtab *);
145525 for(p=pTab->u.vtab.p; p; p=p->pNext){
145526 assert( p->pVtab );
145527 if( p->pVtab->nRef>0 ){
@@ -144920,10 +145750,11 @@
145750 int rc = 0;
145751
145752 /* Check to see the left operand is a column in a virtual table */
145753 if( NEVER(pExpr==0) ) return pDef;
145754 if( pExpr->op!=TK_COLUMN ) return pDef;
145755 assert( ExprUseYTab(pExpr) );
145756 pTab = pExpr->y.pTab;
145757 if( pTab==0 ) return pDef;
145758 if( !IsVirtual(pTab) ) return pDef;
145759 pVtab = sqlite3GetVTable(db, pTab)->pVtab;
145760 assert( pVtab!=0 );
@@ -145214,10 +146045,11 @@
146045 int addrBignull; /* Jump here for next part of big-null scan */
146046 #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS
146047 u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */
146048 int addrLikeRep; /* LIKE range processing address */
146049 #endif
146050 int regFilter; /* Bloom filter */
146051 u8 iFrom; /* Which entry in the FROM clause */
146052 u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */
146053 int p1, p2; /* Operands of the opcode used to end the loop */
146054 union { /* Information that depends on pWLoop->wsFlags */
146055 struct {
@@ -145228,11 +146060,11 @@
146060 int iBase; /* Base register of multi-key index record */
146061 int nPrefix; /* Number of prior entires in the key */
146062 u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
146063 } *aInLoop; /* Information about each nested IN operator */
146064 } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */
146065 Index *pCoveringIdx; /* Possible covering index for WHERE_MULTI_OR */
146066 } u;
146067 struct WhereLoop *pWLoop; /* The selected WhereLoop object */
146068 Bitmask notReady; /* FROM entries not usable at this level */
146069 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
146070 int addrVisit; /* Address at which row is visited */
@@ -145442,15 +146274,15 @@
146274 struct WhereScan {
146275 WhereClause *pOrigWC; /* Original, innermost WhereClause */
146276 WhereClause *pWC; /* WhereClause currently being scanned */
146277 const char *zCollName; /* Required collating sequence, if not NULL */
146278 Expr *pIdxExpr; /* Search for this index expression */
146279 int k; /* Resume scanning at this->pWC->a[this->k] */
 
 
146280 u32 opMask; /* Acceptable operators */
146281 char idxaff; /* Must match this affinity, if zCollName!=NULL */
146282 unsigned char iEquiv; /* Current slot in aiCur[] and aiColumn[] */
146283 unsigned char nEquiv; /* Number of entries in aiCur[] and aiColumn[] */
146284 int aiCur[11]; /* Cursors in the equivalence class */
146285 i16 aiColumn[11]; /* Corresponding column number in the eq-class */
146286 };
146287
146288 /*
@@ -145470,10 +146302,11 @@
146302 WhereClause *pOuter; /* Outer conjunction */
146303 u8 op; /* Split operator. TK_AND or TK_OR */
146304 u8 hasOr; /* True if any a[].eOperator is WO_OR */
146305 int nTerm; /* Number of terms */
146306 int nSlot; /* Number of entries in a[] */
146307 int nBase; /* Number of terms through the last non-Virtual */
146308 WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
146309 #if defined(SQLITE_SMALL_STACK)
146310 WhereTerm aStatic[1]; /* Initial static space for a[] */
146311 #else
146312 WhereTerm aStatic[8]; /* Initial static space for a[] */
@@ -145527,15 +146360,10 @@
146360 int bVarSelect; /* Used by sqlite3WhereExprUsage() */
146361 int n; /* Number of assigned cursor values */
146362 int ix[BMS]; /* Cursor assigned to each bit */
146363 };
146364
 
 
 
 
 
146365 /*
146366 ** This object is a convenience wrapper holding all information needed
146367 ** to construct WhereLoop objects for a particular query.
146368 */
146369 struct WhereLoopBuilder {
@@ -145660,12 +146488,18 @@
146488 Parse *pParse, /* Parse context */
146489 SrcList *pTabList, /* Table list this loop refers to */
146490 WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */
146491 u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */
146492 );
146493 SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter(
146494 const Parse *pParse, /* Parse context */
146495 const WhereInfo *pWInfo, /* WHERE clause */
146496 const WhereLevel *pLevel /* Bloom filter on this level */
146497 );
146498 #else
146499 # define sqlite3WhereExplainOneScan(u,v,w,x) 0
146500 # define sqlite3WhereExplainBloomFilter(u,v,w) 0
146501 #endif /* SQLITE_OMIT_EXPLAIN */
146502 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
146503 SQLITE_PRIVATE void sqlite3WhereAddScanStatus(
146504 Vdbe *v, /* Vdbe to add scanstatus entry to */
146505 SrcList *pSrclist, /* FROM clause pLvl reads data from */
@@ -145754,10 +146588,12 @@
146588 #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */
146589 #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */
146590 #define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */
146591 #define WHERE_IN_SEEKSCAN 0x00100000 /* Seek-scan optimization for IN */
146592 #define WHERE_TRANSCONS 0x00200000 /* Uses a transitive constraint */
146593 #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */
146594 #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */
146595
146596 #endif /* !defined(SQLITE_WHEREINT_H) */
146597
146598 /************** End of whereInt.h ********************************************/
146599 /************** Continuing where we left off in wherecode.c ******************/
@@ -145916,23 +146752,31 @@
146752 sqlite3_str_append(&str, " USING ", 7);
146753 sqlite3_str_appendf(&str, zFmt, pIdx->zName);
146754 explainIndexRange(&str, pLoop);
146755 }
146756 }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
146757 char cRangeOp;
146758 #if 0 /* Better output, but breaks many tests */
146759 const Table *pTab = pItem->pTab;
146760 const char *zRowid = pTab->iPKey>=0 ? pTab->aCol[pTab->iPKey].zCnName:
146761 "rowid";
146762 #else
146763 const char *zRowid = "rowid";
146764 #endif
146765 sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (%s", zRowid);
146766 if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
146767 cRangeOp = '=';
146768 }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
146769 sqlite3_str_appendf(&str, ">? AND %s", zRowid);
146770 cRangeOp = '<';
146771 }else if( flags&WHERE_BTM_LIMIT ){
146772 cRangeOp = '>';
146773 }else{
146774 assert( flags&WHERE_TOP_LIMIT);
146775 cRangeOp = '<';
146776 }
146777 sqlite3_str_appendf(&str, "%c?)", cRangeOp);
 
146778 }
146779 #ifndef SQLITE_OMIT_VIRTUALTABLE
146780 else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
146781 sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s",
146782 pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
@@ -145951,10 +146795,60 @@
146795 ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
146796 pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
146797 }
146798 return ret;
146799 }
146800
146801 /*
146802 ** Add a single OP_Explain opcode that describes a Bloom filter.
146803 **
146804 ** Or if not processing EXPLAIN QUERY PLAN and not in a SQLITE_DEBUG and/or
146805 ** SQLITE_ENABLE_STMT_SCANSTATUS build, then OP_Explain opcodes are not
146806 ** required and this routine is a no-op.
146807 **
146808 ** If an OP_Explain opcode is added to the VM, its address is returned.
146809 ** Otherwise, if no OP_Explain is coded, zero is returned.
146810 */
146811 SQLITE_PRIVATE int sqlite3WhereExplainBloomFilter(
146812 const Parse *pParse, /* Parse context */
146813 const WhereInfo *pWInfo, /* WHERE clause */
146814 const WhereLevel *pLevel /* Bloom filter on this level */
146815 ){
146816 int ret = 0;
146817 SrcItem *pItem = &pWInfo->pTabList->a[pLevel->iFrom];
146818 Vdbe *v = pParse->pVdbe; /* VM being constructed */
146819 sqlite3 *db = pParse->db; /* Database handle */
146820 char *zMsg; /* Text to add to EQP output */
146821 int i; /* Loop counter */
146822 WhereLoop *pLoop; /* The where loop */
146823 StrAccum str; /* EQP output string */
146824 char zBuf[100]; /* Initial space for EQP output string */
146825
146826 sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
146827 str.printfFlags = SQLITE_PRINTF_INTERNAL;
146828 sqlite3_str_appendf(&str, "BLOOM FILTER ON %S (", pItem);
146829 pLoop = pLevel->pWLoop;
146830 if( pLoop->wsFlags & WHERE_IPK ){
146831 const Table *pTab = pItem->pTab;
146832 if( pTab->iPKey>=0 ){
146833 sqlite3_str_appendf(&str, "%s=?", pTab->aCol[pTab->iPKey].zCnName);
146834 }else{
146835 sqlite3_str_appendf(&str, "rowid=?");
146836 }
146837 }else{
146838 for(i=pLoop->nSkip; i<pLoop->u.btree.nEq; i++){
146839 const char *z = explainIndexColumnName(pLoop->u.btree.pIndex, i);
146840 if( i>pLoop->nSkip ) sqlite3_str_append(&str, " AND ", 5);
146841 sqlite3_str_appendf(&str, "%s=?", z);
146842 }
146843 }
146844 sqlite3_str_append(&str, ")", 1);
146845 zMsg = sqlite3StrAccumFinish(&str);
146846 ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
146847 pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
146848 return ret;
146849 }
146850 #endif /* SQLITE_OMIT_EXPLAIN */
146851
146852 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
146853 /*
146854 ** Configure the VM passed as the first argument with an
@@ -146156,20 +147050,27 @@
147050 ){
147051 sqlite3 *db = pParse->db;
147052 Expr *pNew;
147053 pNew = sqlite3ExprDup(db, pX, 0);
147054 if( db->mallocFailed==0 ){
147055 ExprList *pOrigRhs; /* Original unmodified RHS */
147056 ExprList *pOrigLhs; /* Original unmodified LHS */
147057 ExprList *pRhs = 0; /* New RHS after modifications */
147058 ExprList *pLhs = 0; /* New LHS after mods */
147059 int i; /* Loop counter */
147060 Select *pSelect; /* Pointer to the SELECT on the RHS */
147061
147062 assert( ExprUseXSelect(pNew) );
147063 pOrigRhs = pNew->x.pSelect->pEList;
147064 assert( pNew->pLeft!=0 );
147065 assert( ExprUseXList(pNew->pLeft) );
147066 pOrigLhs = pNew->pLeft->x.pList;
147067 for(i=iEq; i<pLoop->nLTerm; i++){
147068 if( pLoop->aLTerm[i]->pExpr==pX ){
147069 int iField;
147070 assert( (pLoop->aLTerm[i]->eOperator & (WO_OR|WO_AND))==0 );
147071 iField = pLoop->aLTerm[i]->u.x.iField - 1;
147072 if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */
147073 pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr);
147074 pOrigRhs->a[iField].pExpr = 0;
147075 assert( pOrigLhs->a[iField].pExpr!=0 );
147076 pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr);
@@ -146280,11 +147181,11 @@
147181 assert( pLoop->aLTerm[i]!=0 );
147182 if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
147183 }
147184
147185 iTab = 0;
147186 if( !ExprUseXSelect(pX) || pX->x.pSelect->pEList->nExpr==1 ){
147187 eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
147188 }else{
147189 sqlite3 *db = pParse->db;
147190 pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);
147191
@@ -146302,12 +147203,12 @@
147203 bRev = !bRev;
147204 }
147205 sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
147206 VdbeCoverageIf(v, bRev);
147207 VdbeCoverageIf(v, !bRev);
147208
147209 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
 
147210 pLoop->wsFlags |= WHERE_IN_ABLE;
147211 if( pLevel->u.in.nIn==0 ){
147212 pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
147213 }
147214 if( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 ){
@@ -146703,11 +147604,11 @@
147604 sHint.pIdx = pLoop->u.btree.pIndex;
147605 memset(&sWalker, 0, sizeof(sWalker));
147606 sWalker.pParse = pParse;
147607 sWalker.u.pCCurHint = &sHint;
147608 pWC = &pWInfo->sWC;
147609 for(i=0; i<pWC->nBase; i++){
147610 pTerm = &pWC->a[i];
147611 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
147612 if( pTerm->prereqAll & pLevel->notReady ) continue;
147613
147614 /* Any terms specified as part of the ON(...) clause for any LEFT
@@ -146845,21 +147746,23 @@
147746 */
147747 static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
147748 assert( nReg>0 );
147749 if( p && sqlite3ExprIsVector(p) ){
147750 #ifndef SQLITE_OMIT_SUBQUERY
147751 if( ExprUseXSelect(p) ){
147752 Vdbe *v = pParse->pVdbe;
147753 int iSelect;
147754 assert( p->op==TK_SELECT );
147755 iSelect = sqlite3CodeSubselect(pParse, p);
147756 sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
147757 }else
147758 #endif
147759 {
147760 int i;
147761 const ExprList *pList;
147762 assert( ExprUseXList(p) );
147763 pList = p->x.pList;
147764 assert( nReg<=pList->nExpr );
147765 for(i=0; i<nReg; i++){
147766 sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i);
147767 }
147768 }
@@ -146908,14 +147811,14 @@
147811 preserveExpr(pX, pExpr);
147812 pExpr->affExpr = sqlite3ExprAffinity(pExpr);
147813 pExpr->op = TK_COLUMN;
147814 pExpr->iTable = pX->iIdxCur;
147815 pExpr->iColumn = pX->iIdxCol;
 
147816 testcase( ExprHasProperty(pExpr, EP_Skip) );
147817 testcase( ExprHasProperty(pExpr, EP_Unlikely) );
147818 ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn);
147819 pExpr->y.pTab = 0;
147820 return WRC_Prune;
147821 }else{
147822 return WRC_Continue;
147823 }
147824 }
@@ -146926,11 +147829,11 @@
147829 */
147830 static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){
147831 if( pExpr->op==TK_COLUMN ){
147832 IdxExprTrans *pX = p->u.pIdxTrans;
147833 if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){
147834 assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 );
147835 preserveExpr(pX, pExpr);
147836 pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn);
147837 pExpr->iTable = pX->iIdxCur;
147838 pExpr->iColumn = pX->iIdxCol;
147839 pExpr->y.pTab = 0;
@@ -146974,11 +147877,11 @@
147877 x.pWInfo = pWInfo;
147878 x.db = pWInfo->pParse->db;
147879 for(iIdxCol=0; iIdxCol<pIdx->nColumn; iIdxCol++){
147880 i16 iRef = pIdx->aiColumn[iIdxCol];
147881 if( iRef==XN_EXPR ){
147882 assert( aColExpr!=0 && aColExpr->a[iIdxCol].pExpr!=0 );
147883 x.pIdxExpr = aColExpr->a[iIdxCol].pExpr;
147884 if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue;
147885 w.xExprCallback = whereIndexExprTransNode;
147886 #ifndef SQLITE_OMIT_GENERATED_COLUMNS
147887 }else if( iRef>=0
@@ -147031,10 +147934,67 @@
147934 if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){
147935 pTerm->wtFlags |= TERM_CODED;
147936 }
147937 }
147938 }
147939
147940 /*
147941 ** This routine is called right after An OP_Filter has been generated and
147942 ** before the corresponding index search has been performed. This routine
147943 ** checks to see if there are additional Bloom filters in inner loops that
147944 ** can be checked prior to doing the index lookup. If there are available
147945 ** inner-loop Bloom filters, then evaluate those filters now, before the
147946 ** index lookup. The idea is that a Bloom filter check is way faster than
147947 ** an index lookup, and the Bloom filter might return false, meaning that
147948 ** the index lookup can be skipped.
147949 **
147950 ** We know that an inner loop uses a Bloom filter because it has the
147951 ** WhereLevel.regFilter set. If an inner-loop Bloom filter is checked,
147952 ** then clear the WhereLevel.regFilter value to prevent the Bloom filter
147953 ** from being checked a second time when the inner loop is evaluated.
147954 */
147955 static SQLITE_NOINLINE void filterPullDown(
147956 Parse *pParse, /* Parsing context */
147957 WhereInfo *pWInfo, /* Complete information about the WHERE clause */
147958 int iLevel, /* Which level of pWInfo->a[] should be coded */
147959 int addrNxt, /* Jump here to bypass inner loops */
147960 Bitmask notReady /* Loops that are not ready */
147961 ){
147962 while( ++iLevel < pWInfo->nLevel ){
147963 WhereLevel *pLevel = &pWInfo->a[iLevel];
147964 WhereLoop *pLoop = pLevel->pWLoop;
147965 if( pLevel->regFilter==0 ) continue;
147966 /* ,--- Because constructBloomFilter() has will not have set
147967 ** vvvvv--' pLevel->regFilter if this were true. */
147968 if( NEVER(pLoop->prereq & notReady) ) continue;
147969 if( pLoop->wsFlags & WHERE_IPK ){
147970 WhereTerm *pTerm = pLoop->aLTerm[0];
147971 int regRowid;
147972 assert( pTerm!=0 );
147973 assert( pTerm->pExpr!=0 );
147974 testcase( pTerm->wtFlags & TERM_VIRTUAL );
147975 regRowid = sqlite3GetTempReg(pParse);
147976 regRowid = codeEqualityTerm(pParse, pTerm, pLevel, 0, 0, regRowid);
147977 sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
147978 addrNxt, regRowid, 1);
147979 VdbeCoverage(pParse->pVdbe);
147980 }else{
147981 u16 nEq = pLoop->u.btree.nEq;
147982 int r1;
147983 char *zStartAff;
147984
147985 assert( pLoop->wsFlags & WHERE_INDEXED );
147986 r1 = codeAllEqualityTerms(pParse,pLevel,0,0,&zStartAff);
147987 codeApplyAffinity(pParse, r1, nEq, zStartAff);
147988 sqlite3DbFree(pParse->db, zStartAff);
147989 sqlite3VdbeAddOp4Int(pParse->pVdbe, OP_Filter, pLevel->regFilter,
147990 addrNxt, r1, nEq);
147991 VdbeCoverage(pParse->pVdbe);
147992 }
147993 pLevel->regFilter = 0;
147994 }
147995 }
147996
147997 /*
147998 ** Generate code for the start of the iLevel-th loop in the WHERE clause
147999 ** implementation described by pWInfo.
148000 */
@@ -147163,11 +148123,16 @@
148123 ** the u.vtab.idxStr. NULL it out to prevent a use-after-free */
148124 if( db->mallocFailed ) pLoop->u.vtab.idxStr = 0;
148125 pLevel->p1 = iCur;
148126 pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
148127 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148128 assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );
148129 if( pLoop->wsFlags & WHERE_IN_ABLE ){
148130 iIn = pLevel->u.in.nIn;
148131 }else{
148132 iIn = 0;
148133 }
148134 for(j=nConstraint-1; j>=0; j--){
148135 pTerm = pLoop->aLTerm[j];
148136 if( (pTerm->eOperator & WO_IN)!=0 ) iIn--;
148137 if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
148138 disableTerm(pLevel, pTerm);
@@ -147237,10 +148202,16 @@
148202 testcase( pTerm->wtFlags & TERM_VIRTUAL );
148203 iReleaseReg = ++pParse->nMem;
148204 iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
148205 if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
148206 addrNxt = pLevel->addrNxt;
148207 if( pLevel->regFilter ){
148208 sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt,
148209 iRowidReg, 1);
148210 VdbeCoverage(v);
148211 filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady);
148212 }
148213 sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
148214 VdbeCoverage(v);
148215 pLevel->op = OP_Noop;
148216 }else if( (pLoop->wsFlags & WHERE_IPK)!=0
148217 && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
@@ -147562,10 +148533,16 @@
148533 }else{
148534 if( regBignull ){
148535 sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull);
148536 VdbeComment((v, "NULL-scan pass ctr"));
148537 }
148538 if( pLevel->regFilter ){
148539 sqlite3VdbeAddOp4Int(v, OP_Filter, pLevel->regFilter, addrNxt,
148540 regBase, nEq);
148541 VdbeCoverage(v);
148542 filterPullDown(pParse, pWInfo, iLevel, addrNxt, notReady);
148543 }
148544
148545 op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev];
148546 assert( op!=0 );
148547 if( (pLoop->wsFlags & WHERE_IN_SEEKSCAN)!=0 && op==OP_SeekGE ){
148548 assert( regBignull==0 );
@@ -147610,12 +148587,23 @@
148587
148588 /* Load the value for the inequality constraint at the end of the
148589 ** range (if any).
148590 */
148591 nConstraint = nEq;
148592 assert( pLevel->p2==0 );
148593 if( pRangeEnd ){
148594 Expr *pRight = pRangeEnd->pExpr->pRight;
148595 if( addrSeekScan ){
148596 /* For a seek-scan that has a range on the lowest term of the index,
148597 ** we have to make the top of the loop be code that sets the end
148598 ** condition of the range. Otherwise, the OP_SeekScan might jump
148599 ** over that initialization, leaving the range-end value set to the
148600 ** range-start value, resulting in a wrong answer.
148601 ** See ticket 5981a8c041a3c2f3 (2021-11-02).
148602 */
148603 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148604 }
148605 codeExprOrVector(pParse, pRight, regBase+nEq, nTop);
148606 whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd);
148607 if( (pRangeEnd->wtFlags & TERM_VNULL)==0
148608 && sqlite3ExprCanBeNull(pRight)
148609 ){
@@ -147645,11 +148633,11 @@
148633 }
148634 sqlite3DbFree(db, zStartAff);
148635 sqlite3DbFree(db, zEndAff);
148636
148637 /* Top of the loop body */
148638 if( pLevel->p2==0 ) pLevel->p2 = sqlite3VdbeCurrentAddr(v);
148639
148640 /* Check if the index cursor is past the end of the range. */
148641 if( nConstraint ){
148642 if( regBignull ){
148643 /* Except, skip the end-of-range check while doing the NULL-scan */
@@ -148052,11 +149040,14 @@
149040 }
149041 sqlite3ExprDelete(db, pDelete);
149042 }
149043 }
149044 ExplainQueryPlanPop(pParse);
149045 assert( pLevel->pWLoop==pLoop );
149046 assert( (pLoop->wsFlags & WHERE_MULTI_OR)!=0 );
149047 assert( (pLoop->wsFlags & WHERE_IN_ABLE)==0 );
149048 pLevel->u.pCoveringIdx = pCov;
149049 if( pCov ) pLevel->iIdxCur = iCovCur;
149050 if( pAndExpr ){
149051 pAndExpr->pLeft = 0;
149052 sqlite3ExprDelete(db, pAndExpr);
149053 }
@@ -148179,11 +149170,11 @@
149170 ** Example: If the WHERE clause contains "t1.a=t2.b" and "t2.b=123"
149171 ** and we are coding the t1 loop and the t2 loop has not yet coded,
149172 ** then we cannot use the "t1.a=t2.b" constraint, but we can code
149173 ** the implied "t1.a=123" constraint.
149174 */
149175 for(pTerm=pWC->a, j=pWC->nBase; j>0; j--, pTerm++){
149176 Expr *pE, sEAlt;
149177 WhereTerm *pAlt;
149178 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
149179 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
149180 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
@@ -148196,16 +149187,17 @@
149187 sqlite3WhereTermPrint(pTerm, pWC->nTerm-j);
149188 }
149189 #endif
149190 assert( !ExprHasProperty(pE, EP_FromJoin) );
149191 assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
149192 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
149193 pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.x.leftColumn, notReady,
149194 WO_EQ|WO_IN|WO_IS, 0);
149195 if( pAlt==0 ) continue;
149196 if( pAlt->wtFlags & (TERM_CODED) ) continue;
149197 if( (pAlt->eOperator & WO_IN)
149198 && ExprUseXSelect(pAlt->pExpr)
149199 && (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
149200 ){
149201 continue;
149202 }
149203 testcase( pAlt->eOperator & WO_EQ );
@@ -148223,11 +149215,11 @@
149215 */
149216 if( pLevel->iLeftJoin ){
149217 pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
149218 sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
149219 VdbeComment((v, "record LEFT JOIN hit"));
149220 for(pTerm=pWC->a, j=0; j<pWC->nBase; j++, pTerm++){
149221 testcase( pTerm->wtFlags & TERM_VIRTUAL );
149222 testcase( pTerm->wtFlags & TERM_CODED );
149223 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
149224 if( (pTerm->prereqAll & pLevel->notReady)!=0 ){
149225 assert( pWInfo->untestedTerms );
@@ -148334,10 +149326,11 @@
149326 sqlite3DbFree(db, pOld);
149327 }
149328 pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]);
149329 }
149330 pTerm = &pWC->a[idx = pWC->nTerm++];
149331 if( (wtFlags & TERM_VIRTUAL)==0 ) pWC->nBase = pWC->nTerm;
149332 if( p && ExprHasProperty(p, EP_Unlikely) ){
149333 pTerm->truthProb = sqlite3LogEst(p->iTable) - 270;
149334 }else{
149335 pTerm->truthProb = 1;
149336 }
@@ -148450,10 +149443,11 @@
149443 return 0;
149444 }
149445 #ifdef SQLITE_EBCDIC
149446 if( *pnoCase ) return 0;
149447 #endif
149448 assert( ExprUseXList(pExpr) );
149449 pList = pExpr->x.pList;
149450 pLeft = pList->a[1].pExpr;
149451
149452 pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr);
149453 op = pRight->op;
@@ -148465,11 +149459,12 @@
149459 z = sqlite3_value_text(pVal);
149460 }
149461 sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
149462 assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
149463 }else if( op==TK_STRING ){
149464 assert( !ExprHasProperty(pRight, EP_IntValue) );
149465 z = (u8*)pRight->u.zToken;
149466 }
149467 if( z ){
149468
149469 /* Count the number of prefix characters prior to the first wildcard */
149470 cnt = 0;
@@ -148494,11 +149489,13 @@
149489
149490 /* Get the pattern prefix. Remove all escapes from the prefix. */
149491 pPrefix = sqlite3Expr(db, TK_STRING, (char*)z);
149492 if( pPrefix ){
149493 int iFrom, iTo;
149494 char *zNew;
149495 assert( !ExprHasProperty(pPrefix, EP_IntValue) );
149496 zNew = pPrefix->u.zToken;
149497 zNew[cnt] = 0;
149498 for(iFrom=iTo=0; iFrom<cnt; iFrom++){
149499 if( zNew[iFrom]==wc[3] ) iFrom++;
149500 zNew[iTo++] = zNew[iFrom];
149501 }
@@ -148518,11 +149515,13 @@
149515 ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
149516 ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
149517 */
149518 if( pLeft->op!=TK_COLUMN
149519 || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
149520 || (ALWAYS( ExprUseYTab(pLeft) )
149521 && pLeft->y.pTab
149522 && IsVirtual(pLeft->y.pTab)) /* Might be numeric */
149523 ){
149524 int isNum;
149525 double rDummy;
149526 isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
149527 if( isNum<=0 ){
@@ -148546,10 +149545,11 @@
149545 /* If the RHS pattern is a bound parameter, make arrangements to
149546 ** reprepare the statement when that parameter is rebound */
149547 if( op==TK_VARIABLE ){
149548 Vdbe *v = pParse->pVdbe;
149549 sqlite3VdbeSetVarmask(v, pRight->iColumn);
149550 assert( !ExprHasProperty(pRight, EP_IntValue) );
149551 if( *pisComplete && pRight->u.zToken[1] ){
149552 /* If the rhs of the LIKE expression is a variable, and the current
149553 ** value of the variable means there is no need to invoke the LIKE
149554 ** function, then no OP_Variable will be added to the program.
149555 ** This causes problems for the sqlite3_bind_parameter_name()
@@ -148619,10 +149619,11 @@
149619 };
149620 ExprList *pList;
149621 Expr *pCol; /* Column reference */
149622 int i;
149623
149624 assert( ExprUseXList(pExpr) );
149625 pList = pExpr->x.pList;
149626 if( pList==0 || pList->nExpr!=2 ){
149627 return 0;
149628 }
149629
@@ -148632,13 +149633,15 @@
149633 **
149634 ** vtab_column MATCH expression
149635 ** MATCH(expression,vtab_column)
149636 */
149637 pCol = pList->a[1].pExpr;
149638 assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
149639 testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
149640 if( ExprIsVtab(pCol) ){
149641 for(i=0; i<ArraySize(aOp); i++){
149642 assert( !ExprHasProperty(pExpr, EP_IntValue) );
149643 if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){
149644 *peOp2 = aOp[i].eOp2;
149645 *ppRight = pList->a[0].pExpr;
149646 *ppLeft = pCol;
149647 return 1;
@@ -148655,20 +149658,22 @@
149658 ** Historically, xFindFunction expected to see lower-case function
149659 ** names. But for this use case, xFindFunction is expected to deal
149660 ** with function names in an arbitrary case.
149661 */
149662 pCol = pList->a[0].pExpr;
149663 assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
149664 testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
149665 if( ExprIsVtab(pCol) ){
149666 sqlite3_vtab *pVtab;
149667 sqlite3_module *pMod;
149668 void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**);
149669 void *pNotUsed;
149670 pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab;
149671 assert( pVtab!=0 );
149672 assert( pVtab->pModule!=0 );
149673 assert( !ExprHasProperty(pExpr, EP_IntValue) );
149674 pMod = (sqlite3_module *)pVtab->pModule;
149675 if( pMod->xFindFunction!=0 ){
149676 i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed);
149677 if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){
149678 *peOp2 = i;
149679 *ppRight = pList->a[1].pExpr;
@@ -148679,14 +149684,16 @@
149684 }
149685 }else if( pExpr->op==TK_NE || pExpr->op==TK_ISNOT || pExpr->op==TK_NOTNULL ){
149686 int res = 0;
149687 Expr *pLeft = pExpr->pLeft;
149688 Expr *pRight = pExpr->pRight;
149689 assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
149690 testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
149691 if( ExprIsVtab(pLeft) ){
149692 res++;
149693 }
149694 assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
149695 testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
149696 if( pRight && ExprIsVtab(pRight) ){
149697 res++;
149698 SWAP(Expr*, pLeft, pRight);
149699 }
@@ -148935,10 +149942,11 @@
149942 int j;
149943 Bitmask b = 0;
149944 pOrTerm->u.pAndInfo = pAndInfo;
149945 pOrTerm->wtFlags |= TERM_ANDINFO;
149946 pOrTerm->eOperator = WO_AND;
149947 pOrTerm->leftCursor = -1;
149948 pAndWC = &pAndInfo->wc;
149949 memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic));
149950 sqlite3WhereClauseInit(pAndWC, pWC->pWInfo);
149951 sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
149952 sqlite3WhereExprAnalyze(pSrc, pAndWC);
@@ -148977,15 +149985,14 @@
149985 /*
149986 ** Record the set of tables that satisfy case 3. The set might be
149987 ** empty.
149988 */
149989 pOrInfo->indexable = indexable;
149990 pTerm->eOperator = WO_OR;
149991 pTerm->leftCursor = -1;
149992 if( indexable ){
 
149993 pWC->hasOr = 1;
 
 
149994 }
149995
149996 /* For a two-way OR, attempt to implementation case 2.
149997 */
149998 if( indexable && pOrWc->nTerm==2 ){
@@ -149054,10 +150061,11 @@
150061 testcase( pOrTerm->wtFlags & TERM_COPIED );
150062 testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
150063 assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
150064 continue;
150065 }
150066 assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
150067 iColumn = pOrTerm->u.x.leftColumn;
150068 iCursor = pOrTerm->leftCursor;
150069 pLeft = pOrTerm->pExpr->pLeft;
150070 break;
150071 }
@@ -149074,10 +150082,11 @@
150082 /* We have found a candidate table and column. Check to see if that
150083 ** table and column is common to every term in the OR clause */
150084 okToChngToIN = 1;
150085 for(; i>=0 && okToChngToIN; i--, pOrTerm++){
150086 assert( pOrTerm->eOperator & WO_EQ );
150087 assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
150088 if( pOrTerm->leftCursor!=iCursor ){
150089 pOrTerm->wtFlags &= ~TERM_OR_OK;
150090 }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR
150091 && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
150092 )){
@@ -149110,10 +150119,11 @@
150119 Expr *pNew; /* The complete IN operator */
150120
150121 for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0; i--, pOrTerm++){
150122 if( (pOrTerm->wtFlags & TERM_OR_OK)==0 ) continue;
150123 assert( pOrTerm->eOperator & WO_EQ );
150124 assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 );
150125 assert( pOrTerm->leftCursor==iCursor );
150126 assert( pOrTerm->u.x.leftColumn==iColumn );
150127 pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0);
150128 pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup);
150129 pLeft = pOrTerm->pExpr->pLeft;
@@ -149122,11 +150132,11 @@
150132 pDup = sqlite3ExprDup(db, pLeft, 0);
150133 pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0);
150134 if( pNew ){
150135 int idxNew;
150136 transferJoinMarkings(pNew, pExpr);
150137 assert( ExprUseXList(pNew) );
150138 pNew->x.pList = pList;
150139 idxNew = whereClauseInsert(pWC, pNew, TERM_VIRTUAL|TERM_DYNAMIC);
150140 testcase( idxNew==0 );
150141 exprAnalyze(pSrc, pWC, idxNew);
150142 /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where reused */
@@ -149250,10 +150260,11 @@
150260 ** on the first element of the vector. */
150261 assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE );
150262 assert( TK_IS<TK_GE && TK_ISNULL<TK_GE && TK_IN<TK_GE );
150263 assert( op<=TK_GE );
150264 if( pExpr->op==TK_VECTOR && (op>=TK_GT && ALWAYS(op<=TK_GE)) ){
150265 assert( ExprUseXList(pExpr) );
150266 pExpr = pExpr->x.pList->a[0].pExpr;
150267
150268 }
150269
150270 if( pExpr->op==TK_COLUMN ){
@@ -149307,32 +150318,49 @@
150318 int nLeft; /* Number of elements on left side vector */
150319
150320 if( db->mallocFailed ){
150321 return;
150322 }
150323 assert( pWC->nTerm > idxTerm );
150324 pTerm = &pWC->a[idxTerm];
150325 pMaskSet = &pWInfo->sMaskSet;
150326 pExpr = pTerm->pExpr;
150327 assert( pExpr!=0 ); /* Because malloc() has not failed */
150328 assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE );
150329 pMaskSet->bVarSelect = 0;
150330 prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft);
150331 op = pExpr->op;
150332 if( op==TK_IN ){
150333 assert( pExpr->pRight==0 );
150334 if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
150335 if( ExprUseXSelect(pExpr) ){
150336 pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect);
150337 }else{
150338 pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList);
150339 }
150340 prereqAll = prereqLeft | pTerm->prereqRight;
 
150341 }else{
150342 pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight);
150343 if( pExpr->pLeft==0
150344 || ExprHasProperty(pExpr, EP_xIsSelect|EP_IfNullRow)
150345 || pExpr->x.pList!=0
150346 ){
150347 prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr);
150348 }else{
150349 prereqAll = prereqLeft | pTerm->prereqRight;
150350 }
150351 }
 
 
150352 if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT;
150353
150354 #ifdef SQLITE_DEBUG
150355 if( prereqAll!=sqlite3WhereExprUsageNN(pMaskSet, pExpr) ){
150356 printf("\n*** Incorrect prereqAll computed for:\n");
150357 sqlite3TreeViewExpr(0,pExpr,0);
150358 abort();
150359 }
150360 #endif
150361
150362 if( ExprHasProperty(pExpr, EP_FromJoin) ){
150363 Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
150364 prereqAll |= x;
150365 extraRight = x-1; /* ON clause terms may not be used with an index
150366 ** on left table of a LEFT JOIN. Ticket #3015 */
@@ -149352,15 +150380,17 @@
150380 u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV;
150381
150382 if( pTerm->u.x.iField>0 ){
150383 assert( op==TK_IN );
150384 assert( pLeft->op==TK_VECTOR );
150385 assert( ExprUseXList(pLeft) );
150386 pLeft = pLeft->x.pList->a[pTerm->u.x.iField-1].pExpr;
150387 }
150388
150389 if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){
150390 pTerm->leftCursor = aiCurCol[0];
150391 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
150392 pTerm->u.x.leftColumn = aiCurCol[1];
150393 pTerm->eOperator = operatorMask(op) & opMask;
150394 }
150395 if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
150396 if( pRight
@@ -149394,10 +150424,11 @@
150424 pDup = pExpr;
150425 pNew = pTerm;
150426 }
150427 pNew->wtFlags |= exprCommute(pParse, pDup);
150428 pNew->leftCursor = aiCurCol[0];
150429 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
150430 pNew->u.x.leftColumn = aiCurCol[1];
150431 testcase( (prereqLeft | extraRight) != prereqLeft );
150432 pNew->prereqRight = prereqLeft | extraRight;
150433 pNew->prereqAll = prereqAll;
150434 pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
@@ -149404,10 +150435,11 @@
150435 }else
150436 if( op==TK_ISNULL
150437 && !ExprHasProperty(pExpr,EP_FromJoin)
150438 && 0==sqlite3ExprCanBeNull(pLeft)
150439 ){
150440 assert( !ExprHasProperty(pExpr, EP_IntValue) );
150441 pExpr->op = TK_TRUEFALSE;
150442 pExpr->u.zToken = "false";
150443 ExprSetProperty(pExpr, EP_IsFalse);
150444 pTerm->prereqAll = 0;
150445 pTerm->eOperator = 0;
@@ -149429,13 +150461,15 @@
150461 ** term. That means that if the BETWEEN term is coded, the children are
150462 ** skipped. Or, if the children are satisfied by an index, the original
150463 ** BETWEEN term is skipped.
150464 */
150465 else if( pExpr->op==TK_BETWEEN && pWC->op==TK_AND ){
150466 ExprList *pList;
150467 int i;
150468 static const u8 ops[] = {TK_GE, TK_LE};
150469 assert( ExprUseXList(pExpr) );
150470 pList = pExpr->x.pList;
150471 assert( pList!=0 );
150472 assert( pList->nExpr==2 );
150473 for(i=0; i<2; i++){
150474 Expr *pNewExpr;
150475 int idxNew;
@@ -149524,12 +150558,16 @@
150558 int idxNew1;
150559 int idxNew2;
150560 const char *zCollSeqName; /* Name of collating sequence */
150561 const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC;
150562
150563 assert( ExprUseXList(pExpr) );
150564 pLeft = pExpr->x.pList->a[1].pExpr;
150565 pStr2 = sqlite3ExprDup(db, pStr1, 0);
150566 assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) );
150567 assert( pStr2==0 || !ExprHasProperty(pStr2, EP_IntValue) );
150568
150569
150570 /* Convert the lower bound to upper-case and the upper bound to
150571 ** lower-case (upper-case is less than lower-case in ASCII) so that
150572 ** the range constraints also work for BLOBs
150573 */
@@ -149625,10 +150663,11 @@
150663 ** not use window functions.
150664 */
150665 else if( pExpr->op==TK_IN
150666 && pTerm->u.x.iField==0
150667 && pExpr->pLeft->op==TK_VECTOR
150668 && ALWAYS( ExprUseXSelect(pExpr) )
150669 && pExpr->x.pSelect->pPrior==0
150670 #ifndef SQLITE_OMIT_WINDOWFUNC
150671 && pExpr->x.pSelect->pWin==0
150672 #endif
150673 && pWC->op==TK_AND
@@ -149741,10 +150780,11 @@
150780 ){
150781 pWC->pWInfo = pWInfo;
150782 pWC->hasOr = 0;
150783 pWC->pOuter = 0;
150784 pWC->nTerm = 0;
150785 pWC->nBase = 0;
150786 pWC->nSlot = ArraySize(pWC->aStatic);
150787 pWC->a = pWC->aStatic;
150788 }
150789
150790 /*
@@ -149751,21 +150791,37 @@
150791 ** Deallocate a WhereClause structure. The WhereClause structure
150792 ** itself is not freed. This routine is the inverse of
150793 ** sqlite3WhereClauseInit().
150794 */
150795 SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){
 
 
150796 sqlite3 *db = pWC->pWInfo->pParse->db;
150797 assert( pWC->nTerm>=pWC->nBase );
150798 if( pWC->nTerm>0 ){
150799 WhereTerm *a = pWC->a;
150800 WhereTerm *aLast = &pWC->a[pWC->nTerm-1];
150801 #ifdef SQLITE_DEBUG
150802 int i;
150803 /* Verify that every term past pWC->nBase is virtual */
150804 for(i=pWC->nBase; i<pWC->nTerm; i++){
150805 assert( (pWC->a[i].wtFlags & TERM_VIRTUAL)!=0 );
150806 }
150807 #endif
150808 while(1){
150809 if( a->wtFlags & TERM_DYNAMIC ){
150810 sqlite3ExprDelete(db, a->pExpr);
150811 }
150812 if( a->wtFlags & (TERM_ORINFO|TERM_ANDINFO) ){
150813 if( a->wtFlags & TERM_ORINFO ){
150814 assert( (a->wtFlags & TERM_ANDINFO)==0 );
150815 whereOrInfoDelete(db, a->u.pOrInfo);
150816 }else{
150817 assert( (a->wtFlags & TERM_ANDINFO)!=0 );
150818 whereAndInfoDelete(db, a->u.pAndInfo);
150819 }
150820 }
150821 if( a==aLast ) break;
150822 a++;
150823 }
150824 }
150825 if( pWC->a!=pWC->aStatic ){
150826 sqlite3DbFree(db, pWC->a);
150827 }
@@ -149774,38 +150830,71 @@
150830
150831 /*
150832 ** These routines walk (recursively) an expression tree and generate
150833 ** a bitmask indicating which tables are used in that expression
150834 ** tree.
150835 **
150836 ** sqlite3WhereExprUsage(MaskSet, Expr) ->
150837 **
150838 ** Return a Bitmask of all tables referenced by Expr. Expr can be
150839 ** be NULL, in which case 0 is returned.
150840 **
150841 ** sqlite3WhereExprUsageNN(MaskSet, Expr) ->
150842 **
150843 ** Same as sqlite3WhereExprUsage() except that Expr must not be
150844 ** NULL. The "NN" suffix on the name stands for "Not Null".
150845 **
150846 ** sqlite3WhereExprListUsage(MaskSet, ExprList) ->
150847 **
150848 ** Return a Bitmask of all tables referenced by every expression
150849 ** in the expression list ExprList. ExprList can be NULL, in which
150850 ** case 0 is returned.
150851 **
150852 ** sqlite3WhereExprUsageFull(MaskSet, ExprList) ->
150853 **
150854 ** Internal use only. Called only by sqlite3WhereExprUsageNN() for
150855 ** complex expressions that require pushing register values onto
150856 ** the stack. Many calls to sqlite3WhereExprUsageNN() do not need
150857 ** the more complex analysis done by this routine. Hence, the
150858 ** computations done by this routine are broken out into a separate
150859 ** "no-inline" function to avoid the stack push overhead in the
150860 ** common case where it is not needed.
150861 */
150862 static SQLITE_NOINLINE Bitmask sqlite3WhereExprUsageFull(
150863 WhereMaskSet *pMaskSet,
150864 Expr *p
150865 ){
150866 Bitmask mask;
 
 
 
 
 
 
150867 mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0;
150868 if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft);
150869 if( p->pRight ){
150870 mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight);
150871 assert( p->x.pList==0 );
150872 }else if( ExprUseXSelect(p) ){
150873 if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1;
150874 mask |= exprSelectUsage(pMaskSet, p->x.pSelect);
150875 }else if( p->x.pList ){
150876 mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
150877 }
150878 #ifndef SQLITE_OMIT_WINDOWFUNC
150879 if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && ExprUseYWin(p) ){
150880 assert( p->y.pWin!=0 );
150881 mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
150882 mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
150883 mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter);
150884 }
150885 #endif
150886 return mask;
150887 }
150888 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
150889 if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){
150890 return sqlite3WhereGetMask(pMaskSet, p->iTable);
150891 }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){
150892 assert( p->op!=TK_IF_NULL_ROW );
150893 return 0;
150894 }
150895 return sqlite3WhereExprUsageFull(pMaskSet, p);
150896 }
150897 SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){
150898 return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0;
150899 }
150900 SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){
@@ -149870,10 +150959,11 @@
150959 }
150960 pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0);
150961 if( pColRef==0 ) return;
150962 pColRef->iTable = pItem->iCursor;
150963 pColRef->iColumn = k++;
150964 assert( ExprUseYTab(pColRef) );
150965 pColRef->y.pTab = pTab;
150966 pRhs = sqlite3PExpr(pParse, TK_UPLUS,
150967 sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);
150968 pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs);
150969 if( pItem->fg.jointype & JT_LEFT ){
@@ -150119,11 +151209,16 @@
151209 ** iCursor is not in the set.
151210 */
151211 SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){
151212 int i;
151213 assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 );
151214 assert( pMaskSet->n>0 || pMaskSet->ix[0]<0 );
151215 assert( iCursor>=-1 );
151216 if( pMaskSet->ix[0]==iCursor ){
151217 return 1;
151218 }
151219 for(i=1; i<pMaskSet->n; i++){
151220 if( pMaskSet->ix[i]==iCursor ){
151221 return MASKBIT(i);
151222 }
151223 }
151224 return 0;
@@ -150171,12 +151266,14 @@
151266 pWC = pScan->pWC;
151267 while(1){
151268 iColumn = pScan->aiColumn[pScan->iEquiv-1];
151269 iCur = pScan->aiCur[pScan->iEquiv-1];
151270 assert( pWC!=0 );
151271 assert( iCur>=0 );
151272 do{
151273 for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
151274 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 || pTerm->leftCursor<0 );
151275 if( pTerm->leftCursor==iCur
151276 && pTerm->u.x.leftColumn==iColumn
151277 && (iColumn!=XN_EXPR
151278 || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft,
151279 pScan->pIdxExpr,iCur)==0)
@@ -150214,11 +151311,12 @@
151311 if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
151312 continue;
151313 }
151314 }
151315 if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
151316 && (pX = pTerm->pExpr->pRight, ALWAYS(pX!=0))
151317 && pX->op==TK_COLUMN
151318 && pX->iTable==pScan->aiCur[0]
151319 && pX->iColumn==pScan->aiColumn[0]
151320 ){
151321 testcase( pTerm->eOperator & WO_IS );
151322 continue;
@@ -150301,20 +151399,20 @@
151399 pScan->nEquiv = 1;
151400 pScan->iEquiv = 1;
151401 if( pIdx ){
151402 int j = iColumn;
151403 iColumn = pIdx->aiColumn[j];
151404 if( iColumn==pIdx->pTable->iPKey ){
151405 iColumn = XN_ROWID;
151406 }else if( iColumn>=0 ){
151407 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
151408 pScan->zCollName = pIdx->azColl[j];
151409 }else if( iColumn==XN_EXPR ){
151410 pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
151411 pScan->zCollName = pIdx->azColl[j];
151412 pScan->aiColumn[0] = XN_EXPR;
151413 return whereScanInitIndexExpr(pScan);
 
 
 
 
 
151414 }
151415 }else if( iColumn==XN_EXPR ){
151416 return 0;
151417 }
151418 pScan->aiColumn[0] = iColumn;
@@ -150594,13 +151692,13 @@
151692 ** Return TRUE if the WHERE clause term pTerm is of a form where it
151693 ** could be used with an index to access pSrc, assuming an appropriate
151694 ** index existed.
151695 */
151696 static int termCanDriveIndex(
151697 const WhereTerm *pTerm, /* WHERE clause term to check */
151698 const SrcItem *pSrc, /* Table we are trying to access */
151699 const Bitmask notReady /* Tables in outer loops of the join */
151700 ){
151701 char aff;
151702 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
151703 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
151704 if( (pSrc->fg.jointype & JT_LEFT)
@@ -150611,10 +151709,11 @@
151709 ** the RHS of a LEFT JOIN. Such a term can only be used if it is from
151710 ** the ON clause. */
151711 return 0;
151712 }
151713 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
151714 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151715 if( pTerm->u.x.leftColumn<0 ) return 0;
151716 aff = pSrc->pTab->aCol[pTerm->u.x.leftColumn].affinity;
151717 if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
151718 testcase( pTerm->pExpr->op==TK_IS );
151719 return 1;
@@ -150626,15 +151725,15 @@
151725 /*
151726 ** Generate code to construct the Index object for an automatic index
151727 ** and to set up the WhereLevel object pLevel so that the code generator
151728 ** makes use of the automatic index.
151729 */
151730 static SQLITE_NOINLINE void constructAutomaticIndex(
151731 Parse *pParse, /* The parsing context */
151732 const WhereClause *pWC, /* The WHERE clause */
151733 const SrcItem *pSrc, /* The FROM clause term to get the next index */
151734 const Bitmask notReady, /* Mask of cursors that are not available */
151735 WhereLevel *pLevel /* Write new index here */
151736 ){
151737 int nKeyCol; /* Number of columns in the constructed index */
151738 WhereTerm *pTerm; /* A single term of the WHERE clause */
151739 WhereTerm *pWCEnd; /* End of pWC->a[] */
@@ -150672,23 +151771,26 @@
151771 pWCEnd = &pWC->a[pWC->nTerm];
151772 pLoop = pLevel->pWLoop;
151773 idxCols = 0;
151774 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
151775 Expr *pExpr = pTerm->pExpr;
151776 /* Make the automatic index a partial index if there are terms in the
151777 ** WHERE clause (or the ON clause of a LEFT join) that constrain which
151778 ** rows of the target table (pSrc) that can be used. */
151779 if( (pTerm->wtFlags & TERM_VIRTUAL)==0
151780 && ((pSrc->fg.jointype&JT_LEFT)==0 || ExprHasProperty(pExpr,EP_FromJoin))
151781 && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor)
151782 ){
151783 pPartial = sqlite3ExprAnd(pParse, pPartial,
151784 sqlite3ExprDup(pParse->db, pExpr, 0));
151785 }
151786 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
151787 int iCol;
151788 Bitmask cMask;
151789 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151790 iCol = pTerm->u.x.leftColumn;
151791 cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
151792 testcase( iCol==BMS );
151793 testcase( iCol==BMS-1 );
151794 if( !sentWarning ){
151795 sqlite3_log(SQLITE_WARNING_AUTOINDEX,
151796 "automatic index on %s(%s)", pTable->zName,
@@ -150736,12 +151838,15 @@
151838 pIdx->pTable = pTable;
151839 n = 0;
151840 idxCols = 0;
151841 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
151842 if( termCanDriveIndex(pTerm, pSrc, notReady) ){
151843 int iCol;
151844 Bitmask cMask;
151845 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
151846 iCol = pTerm->u.x.leftColumn;
151847 cMask = iCol>=BMS ? MASKBIT(BMS-1) : MASKBIT(iCol);
151848 testcase( iCol==BMS-1 );
151849 testcase( iCol==BMS );
151850 if( (idxCols & cMask)==0 ){
151851 Expr *pX = pTerm->pExpr;
151852 idxCols |= cMask;
@@ -150779,10 +151884,14 @@
151884 assert( pLevel->iIdxCur>=0 );
151885 pLevel->iIdxCur = pParse->nTab++;
151886 sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
151887 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
151888 VdbeComment((v, "for %s", pTable->zName));
151889 if( OptimizationEnabled(pParse->db, SQLITE_BloomFilter) ){
151890 pLevel->regFilter = ++pParse->nMem;
151891 sqlite3VdbeAddOp2(v, OP_Blob, 10000, pLevel->regFilter);
151892 }
151893
151894 /* Fill the automatic index with content */
151895 pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
151896 if( pTabItem->fg.viaCoroutine ){
151897 int regYield = pTabItem->regReturn;
@@ -150801,10 +151910,14 @@
151910 }
151911 regRecord = sqlite3GetTempReg(pParse);
151912 regBase = sqlite3GenerateIndexKey(
151913 pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
151914 );
151915 if( pLevel->regFilter ){
151916 sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0,
151917 regBase, pLoop->u.btree.nEq);
151918 }
151919 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
151920 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
151921 if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
151922 if( pTabItem->fg.viaCoroutine ){
151923 sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
@@ -150826,10 +151939,127 @@
151939
151940 end_auto_index_create:
151941 sqlite3ExprDelete(pParse->db, pPartial);
151942 }
151943 #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */
151944
151945 /*
151946 ** Generate bytecode that will initialize a Bloom filter that is appropriate
151947 ** for pLevel.
151948 **
151949 ** If there are inner loops within pLevel that have the WHERE_BLOOMFILTER
151950 ** flag set, initialize a Bloomfilter for them as well. Except don't do
151951 ** this recursive initialization if the SQLITE_BloomPulldown optimization has
151952 ** been turned off.
151953 **
151954 ** When the Bloom filter is initialized, the WHERE_BLOOMFILTER flag is cleared
151955 ** from the loop, but the regFilter value is set to a register that implements
151956 ** the Bloom filter. When regFilter is positive, the
151957 ** sqlite3WhereCodeOneLoopStart() will generate code to test the Bloom filter
151958 ** and skip the subsequence B-Tree seek if the Bloom filter indicates that
151959 ** no matching rows exist.
151960 **
151961 ** This routine may only be called if it has previously been determined that
151962 ** the loop would benefit from a Bloom filter, and the WHERE_BLOOMFILTER bit
151963 ** is set.
151964 */
151965 static SQLITE_NOINLINE void constructBloomFilter(
151966 WhereInfo *pWInfo, /* The WHERE clause */
151967 int iLevel, /* Index in pWInfo->a[] that is pLevel */
151968 WhereLevel *pLevel, /* Make a Bloom filter for this FROM term */
151969 Bitmask notReady /* Loops that are not ready */
151970 ){
151971 int addrOnce; /* Address of opening OP_Once */
151972 int addrTop; /* Address of OP_Rewind */
151973 int addrCont; /* Jump here to skip a row */
151974 const WhereTerm *pTerm; /* For looping over WHERE clause terms */
151975 const WhereTerm *pWCEnd; /* Last WHERE clause term */
151976 Parse *pParse = pWInfo->pParse; /* Parsing context */
151977 Vdbe *v = pParse->pVdbe; /* VDBE under construction */
151978 WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */
151979 int iCur; /* Cursor for table getting the filter */
151980
151981 assert( pLoop!=0 );
151982 assert( v!=0 );
151983 assert( pLoop->wsFlags & WHERE_BLOOMFILTER );
151984
151985 addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
151986 do{
151987 const SrcItem *pItem;
151988 const Table *pTab;
151989 u64 sz;
151990 sqlite3WhereExplainBloomFilter(pParse, pWInfo, pLevel);
151991 addrCont = sqlite3VdbeMakeLabel(pParse);
151992 iCur = pLevel->iTabCur;
151993 pLevel->regFilter = ++pParse->nMem;
151994
151995 /* The Bloom filter is a Blob held in a register. Initialize it
151996 ** to zero-filled blob of at least 80K bits, but maybe more if the
151997 ** estimated size of the table is larger. We could actually
151998 ** measure the size of the table at run-time using OP_Count with
151999 ** P3==1 and use that value to initialize the blob. But that makes
152000 ** testing complicated. By basing the blob size on the value in the
152001 ** sqlite_stat1 table, testing is much easier.
152002 */
152003 pItem = &pWInfo->pTabList->a[pLevel->iFrom];
152004 assert( pItem!=0 );
152005 pTab = pItem->pTab;
152006 assert( pTab!=0 );
152007 sz = sqlite3LogEstToInt(pTab->nRowLogEst);
152008 if( sz<10000 ){
152009 sz = 10000;
152010 }else if( sz>10000000 ){
152011 sz = 10000000;
152012 }
152013 sqlite3VdbeAddOp2(v, OP_Blob, (int)sz, pLevel->regFilter);
152014
152015 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
152016 pWCEnd = &pWInfo->sWC.a[pWInfo->sWC.nTerm];
152017 for(pTerm=pWInfo->sWC.a; pTerm<pWCEnd; pTerm++){
152018 Expr *pExpr = pTerm->pExpr;
152019 if( (pTerm->wtFlags & TERM_VIRTUAL)==0
152020 && sqlite3ExprIsTableConstant(pExpr, iCur)
152021 ){
152022 sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL);
152023 }
152024 }
152025 if( pLoop->wsFlags & WHERE_IPK ){
152026 int r1 = sqlite3GetTempReg(pParse);
152027 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, r1);
152028 sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, 1);
152029 sqlite3ReleaseTempReg(pParse, r1);
152030 }else{
152031 Index *pIdx = pLoop->u.btree.pIndex;
152032 int n = pLoop->u.btree.nEq;
152033 int r1 = sqlite3GetTempRange(pParse, n);
152034 int jj;
152035 for(jj=0; jj<n; jj++){
152036 int iCol = pIdx->aiColumn[jj];
152037 assert( pIdx->pTable==pItem->pTab );
152038 sqlite3ExprCodeGetColumnOfTable(v, pIdx->pTable, iCur, iCol,r1+jj);
152039 }
152040 sqlite3VdbeAddOp4Int(v, OP_FilterAdd, pLevel->regFilter, 0, r1, n);
152041 sqlite3ReleaseTempRange(pParse, r1, n);
152042 }
152043 sqlite3VdbeResolveLabel(v, addrCont);
152044 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
152045 VdbeCoverage(v);
152046 sqlite3VdbeJumpHere(v, addrTop);
152047 pLoop->wsFlags &= ~WHERE_BLOOMFILTER;
152048 if( OptimizationDisabled(pParse->db, SQLITE_BloomPulldown) ) break;
152049 while( iLevel < pWInfo->nLevel ){
152050 iLevel++;
152051 pLevel = &pWInfo->a[iLevel];
152052 pLoop = pLevel->pWLoop;
152053 if( pLoop==0 ) continue;
152054 if( pLoop->prereq & notReady ) continue;
152055 if( pLoop->wsFlags & WHERE_BLOOMFILTER ) break;
152056 }
152057 }while( iLevel < pWInfo->nLevel );
152058 sqlite3VdbeJumpHere(v, addrOnce);
152059 }
152060
152061
152062 #ifndef SQLITE_OMIT_VIRTUALTABLE
152063 /*
152064 ** Allocate and populate an sqlite3_index_info structure. It is the
152065 ** responsibility of the caller to eventually release the structure
@@ -150864,10 +152094,11 @@
152094 testcase( pTerm->eOperator & WO_ISNULL );
152095 testcase( pTerm->eOperator & WO_IS );
152096 testcase( pTerm->eOperator & WO_ALL );
152097 if( (pTerm->eOperator & ~(WO_EQUIV))==0 ) continue;
152098 if( pTerm->wtFlags & TERM_VNULL ) continue;
152099 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152100 assert( pTerm->u.x.leftColumn>=(-1) );
152101 nTerm++;
152102 }
152103
152104 /* If the ORDER BY clause contains only columns in the current
@@ -150924,10 +152155,11 @@
152155 if( (pSrc->fg.jointype & JT_LEFT)!=0
152156 && !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
152157 ){
152158 continue;
152159 }
152160 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152161 assert( pTerm->u.x.leftColumn>=(-1) );
152162 pIdxCons[j].iColumn = pTerm->u.x.leftColumn;
152163 pIdxCons[j].iTermOffset = i;
152164 op = pTerm->eOperator & WO_ALL;
152165 if( op==WO_IN ) op = WO_EQ;
@@ -151687,10 +152919,11 @@
152919 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
152920 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
152921 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
152922 if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C';
152923 if( pTerm->eOperator & WO_SINGLE ){
152924 assert( (pTerm->eOperator & (WO_OR|WO_AND))==0 );
152925 sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}",
152926 pTerm->leftCursor, pTerm->u.x.leftColumn);
152927 }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){
152928 sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx",
152929 pTerm->u.pOrInfo->indexable);
@@ -151704,11 +152937,11 @@
152937 ** shown about each Term */
152938 if( sqlite3WhereTrace & 0x10000 ){
152939 sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx",
152940 pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight);
152941 }
152942 if( (pTerm->eOperator & (WO_OR|WO_AND))==0 && pTerm->u.x.iField ){
152943 sqlite3DebugPrintf(" iField=%d", pTerm->u.x.iField);
152944 }
152945 if( pTerm->iParent>=0 ){
152946 sqlite3DebugPrintf(" iParent=%d", pTerm->iParent);
152947 }
@@ -151766,13 +152999,13 @@
152999 }
153000 sqlite3DebugPrintf(" %-19s", z);
153001 sqlite3_free(z);
153002 }
153003 if( p->wsFlags & WHERE_SKIPSCAN ){
153004 sqlite3DebugPrintf(" f %06x %d-%d", p->wsFlags, p->nLTerm,p->nSkip);
153005 }else{
153006 sqlite3DebugPrintf(" f %06x N %d", p->wsFlags, p->nLTerm);
153007 }
153008 sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
153009 if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){
153010 int i;
153011 for(i=0; i<p->nLTerm; i++){
@@ -151868,11 +153101,12 @@
153101 static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){
153102 int i;
153103 assert( pWInfo!=0 );
153104 for(i=0; i<pWInfo->nLevel; i++){
153105 WhereLevel *pLevel = &pWInfo->a[i];
153106 if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE)!=0 ){
153107 assert( (pLevel->pWLoop->wsFlags & WHERE_MULTI_OR)==0 );
153108 sqlite3DbFree(db, pLevel->u.in.aInLoop);
153109 }
153110 }
153111 sqlite3WhereClauseClear(&pWInfo->sWC);
153112 while( pWInfo->pLoops ){
@@ -152227,22 +153461,29 @@
153461 Bitmask notAllowed = ~(pLoop->prereq|pLoop->maskSelf);
153462 int i, j;
153463 LogEst iReduce = 0; /* pLoop->nOut should not exceed nRow-iReduce */
153464
153465 assert( (pLoop->wsFlags & WHERE_AUTO_INDEX)==0 );
153466 for(i=pWC->nBase, pTerm=pWC->a; i>0; i--, pTerm++){
153467 assert( pTerm!=0 );
153468 if( (pTerm->prereqAll & notAllowed)!=0 ) continue;
153469 if( (pTerm->prereqAll & pLoop->maskSelf)==0 ) continue;
153470 if( (pTerm->wtFlags & TERM_VIRTUAL)!=0 ) continue;
153471 for(j=pLoop->nLTerm-1; j>=0; j--){
153472 pX = pLoop->aLTerm[j];
153473 if( pX==0 ) continue;
153474 if( pX==pTerm ) break;
153475 if( pX->iParent>=0 && (&pWC->a[pX->iParent])==pTerm ) break;
153476 }
153477 if( j<0 ){
153478 if( pLoop->maskSelf==pTerm->prereqAll ){
153479 /* If there are extra terms in the WHERE clause not used by an index
153480 ** that depend only on the table being scanned, and that will tend to
153481 ** cause many rows to be omitted, then mark that table as
153482 ** "self-culling". */
153483 pLoop->wsFlags |= WHERE_SELFCULL;
153484 }
153485 if( pTerm->truthProb<=0 ){
153486 /* If a truth probability is specified using the likelihood() hints,
153487 ** then use the probability provided by the application. */
153488 pLoop->nOut += pTerm->truthProb;
153489 }else{
@@ -152266,11 +153507,13 @@
153507 }
153508 }
153509 }
153510 }
153511 }
153512 if( pLoop->nOut > nRow-iReduce ){
153513 pLoop->nOut = nRow - iReduce;
153514 }
153515 }
153516
153517 /*
153518 ** Term pTerm is a vector range comparison operation. The first comparison
153519 ** in the vector can be optimized using column nEq of the index. This
@@ -152303,13 +153546,16 @@
153546 /* Test if comparison i of pTerm is compatible with column (i+nEq)
153547 ** of the index. If not, exit the loop. */
153548 char aff; /* Comparison affinity */
153549 char idxaff = 0; /* Indexed columns affinity */
153550 CollSeq *pColl; /* Comparison collation sequence */
153551 Expr *pLhs, *pRhs;
153552
153553 assert( ExprUseXList(pTerm->pExpr->pLeft) );
153554 pLhs = pTerm->pExpr->pLeft->x.pList->a[i].pExpr;
153555 pRhs = pTerm->pExpr->pRight;
153556 if( ExprUseXSelect(pRhs) ){
153557 pRhs = pRhs->x.pSelect->pEList->a[i].pExpr;
153558 }else{
153559 pRhs = pRhs->x.pList->a[i].pExpr;
153560 }
153561
@@ -152466,11 +153712,11 @@
153712 || (pNew->wsFlags & WHERE_SKIPSCAN)!=0
153713 );
153714
153715 if( eOp & WO_IN ){
153716 Expr *pExpr = pTerm->pExpr;
153717 if( ExprUseXSelect(pExpr) ){
153718 /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */
153719 int i;
153720 nIn = 46; assert( 46==sqlite3LogEst(25) );
153721
153722 /* The expression may actually be of the form (x, y) IN (SELECT...).
@@ -152607,11 +153853,11 @@
153853 #ifdef SQLITE_ENABLE_STAT4
153854 tRowcnt nOut = 0;
153855 if( nInMul==0
153856 && pProbe->nSample
153857 && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol)
153858 && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr))
153859 && OptimizationEnabled(db, SQLITE_Stat4)
153860 ){
153861 Expr *pExpr = pTerm->pExpr;
153862 if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
153863 testcase( eOp & WO_EQ );
@@ -152883,10 +154129,11 @@
154129 pTab = pSrc->pTab;
154130 pWC = pBuilder->pWC;
154131 assert( !IsVirtual(pSrc->pTab) );
154132
154133 if( pSrc->fg.isIndexedBy ){
154134 assert( pSrc->fg.isCte==0 );
154135 /* An INDEXED BY clause specifies a particular index to use */
154136 pProbe = pSrc->u2.pIBIndex;
154137 }else if( !HasRowid(pTab) ){
154138 pProbe = pTab->pIndex;
154139 }else{
@@ -153498,10 +154745,11 @@
154745 }else if( pOrTerm->leftCursor==iCur ){
154746 tempWC.pWInfo = pWC->pWInfo;
154747 tempWC.pOuter = pWC;
154748 tempWC.op = TK_AND;
154749 tempWC.nTerm = 1;
154750 tempWC.nBase = 1;
154751 tempWC.a = pOrTerm;
154752 sSubBuild.pWC = &tempWC;
154753 }else{
154754 continue;
154755 }
@@ -153969,11 +155217,11 @@
155217 }
155218 } /* End the loop over all WhereLoops from outer-most down to inner-most */
155219 if( obSat==obDone ) return (i8)nOrderBy;
155220 if( !isOrderDistinct ){
155221 for(i=nOrderBy-1; i>0; i--){
155222 Bitmask m = ALWAYS(i<BMS) ? MASKBIT(i) - 1 : 0;
155223 if( (obSat&m)==m ) return i;
155224 }
155225 return 0;
155226 }
155227 return -1;
@@ -154494,13 +155742,13 @@
155742 pWC = &pWInfo->sWC;
155743 pLoop = pBuilder->pNew;
155744 pLoop->wsFlags = 0;
155745 pLoop->nSkip = 0;
155746 pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0);
155747 while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan);
155748 if( pTerm ){
155749 testcase( pTerm->eOperator & WO_IS );
 
155750 pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
155751 pLoop->aLTerm[0] = pTerm;
155752 pLoop->nLTerm = 1;
155753 pLoop->u.btree.nEq = 1;
155754 /* TUNING: Cost of a rowid lookup is 10 */
@@ -154604,10 +155852,154 @@
155852 }
155853 # define WHERETRACE_ALL_LOOPS(W,C) showAllWhereLoops(W,C)
155854 #else
155855 # define WHERETRACE_ALL_LOOPS(W,C)
155856 #endif
155857
155858 /* Attempt to omit tables from a join that do not affect the result.
155859 ** For a table to not affect the result, the following must be true:
155860 **
155861 ** 1) The query must not be an aggregate.
155862 ** 2) The table must be the RHS of a LEFT JOIN.
155863 ** 3) Either the query must be DISTINCT, or else the ON or USING clause
155864 ** must contain a constraint that limits the scan of the table to
155865 ** at most a single row.
155866 ** 4) The table must not be referenced by any part of the query apart
155867 ** from its own USING or ON clause.
155868 **
155869 ** For example, given:
155870 **
155871 ** CREATE TABLE t1(ipk INTEGER PRIMARY KEY, v1);
155872 ** CREATE TABLE t2(ipk INTEGER PRIMARY KEY, v2);
155873 ** CREATE TABLE t3(ipk INTEGER PRIMARY KEY, v3);
155874 **
155875 ** then table t2 can be omitted from the following:
155876 **
155877 ** SELECT v1, v3 FROM t1
155878 ** LEFT JOIN t2 ON (t1.ipk=t2.ipk)
155879 ** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
155880 **
155881 ** or from:
155882 **
155883 ** SELECT DISTINCT v1, v3 FROM t1
155884 ** LEFT JOIN t2
155885 ** LEFT JOIN t3 ON (t1.ipk=t3.ipk)
155886 */
155887 static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
155888 WhereInfo *pWInfo,
155889 Bitmask notReady
155890 ){
155891 int i;
155892 Bitmask tabUsed;
155893
155894 /* Preconditions checked by the caller */
155895 assert( pWInfo->nLevel>=2 );
155896 assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_OmitNoopJoin) );
155897
155898 /* These two preconditions checked by the caller combine to guarantee
155899 ** condition (1) of the header comment */
155900 assert( pWInfo->pResultSet!=0 );
155901 assert( 0==(pWInfo->wctrlFlags & WHERE_AGG_DISTINCT) );
155902
155903 tabUsed = sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pResultSet);
155904 if( pWInfo->pOrderBy ){
155905 tabUsed |= sqlite3WhereExprListUsage(&pWInfo->sMaskSet, pWInfo->pOrderBy);
155906 }
155907 for(i=pWInfo->nLevel-1; i>=1; i--){
155908 WhereTerm *pTerm, *pEnd;
155909 SrcItem *pItem;
155910 WhereLoop *pLoop;
155911 pLoop = pWInfo->a[i].pWLoop;
155912 pItem = &pWInfo->pTabList->a[pLoop->iTab];
155913 if( (pItem->fg.jointype & JT_LEFT)==0 ) continue;
155914 if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)==0
155915 && (pLoop->wsFlags & WHERE_ONEROW)==0
155916 ){
155917 continue;
155918 }
155919 if( (tabUsed & pLoop->maskSelf)!=0 ) continue;
155920 pEnd = pWInfo->sWC.a + pWInfo->sWC.nTerm;
155921 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
155922 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155923 if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
155924 || pTerm->pExpr->iRightJoinTable!=pItem->iCursor
155925 ){
155926 break;
155927 }
155928 }
155929 }
155930 if( pTerm<pEnd ) continue;
155931 WHERETRACE(0xffff, ("-> drop loop %c not used\n", pLoop->cId));
155932 notReady &= ~pLoop->maskSelf;
155933 for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
155934 if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
155935 pTerm->wtFlags |= TERM_CODED;
155936 }
155937 }
155938 if( i!=pWInfo->nLevel-1 ){
155939 int nByte = (pWInfo->nLevel-1-i) * sizeof(WhereLevel);
155940 memmove(&pWInfo->a[i], &pWInfo->a[i+1], nByte);
155941 }
155942 pWInfo->nLevel--;
155943 assert( pWInfo->nLevel>0 );
155944 }
155945 return notReady;
155946 }
155947
155948 /*
155949 ** Check to see if there are any SEARCH loops that might benefit from
155950 ** using a Bloom filter. Consider a Bloom filter if:
155951 **
155952 ** (1) The SEARCH happens more than N times where N is the number
155953 ** of rows in the table that is being considered for the Bloom
155954 ** filter.
155955 ** (2) Some searches are expected to find zero rows. (This is determined
155956 ** by the WHERE_SELFCULL flag on the term.)
155957 ** (3) Bloom-filter processing is not disabled. (Checked by the
155958 ** caller.)
155959 ** (4) The size of the table being searched is known by ANALYZE.
155960 **
155961 ** This block of code merely checks to see if a Bloom filter would be
155962 ** appropriate, and if so sets the WHERE_BLOOMFILTER flag on the
155963 ** WhereLoop. The implementation of the Bloom filter comes further
155964 ** down where the code for each WhereLoop is generated.
155965 */
155966 static SQLITE_NOINLINE void whereCheckIfBloomFilterIsUseful(
155967 const WhereInfo *pWInfo
155968 ){
155969 int i;
155970 LogEst nSearch;
155971
155972 assert( pWInfo->nLevel>=2 );
155973 assert( OptimizationEnabled(pWInfo->pParse->db, SQLITE_BloomFilter) );
155974 nSearch = pWInfo->a[0].pWLoop->nOut;
155975 for(i=1; i<pWInfo->nLevel; i++){
155976 WhereLoop *pLoop = pWInfo->a[i].pWLoop;
155977 const int reqFlags = (WHERE_SELFCULL|WHERE_COLUMN_EQ);
155978 if( (pLoop->wsFlags & reqFlags)==reqFlags
155979 /* vvvvvv--- Always the case if WHERE_COLUMN_EQ is defined */
155980 && ALWAYS((pLoop->wsFlags & (WHERE_IPK|WHERE_INDEXED))!=0)
155981 ){
155982 SrcItem *pItem = &pWInfo->pTabList->a[pLoop->iTab];
155983 Table *pTab = pItem->pTab;
155984 pTab->tabFlags |= TF_StatsUsed;
155985 if( nSearch > pTab->nRowLogEst
155986 && (pTab->tabFlags & TF_HasStat1)!=0
155987 ){
155988 testcase( pItem->fg.jointype & JT_LEFT );
155989 pLoop->wsFlags |= WHERE_BLOOMFILTER;
155990 pLoop->wsFlags &= ~WHERE_IDX_ONLY;
155991 WHERETRACE(0xffff, (
155992 "-> use Bloom-filter on loop %c because there are ~%.1e "
155993 "lookups into %s which has only ~%.1e rows\n",
155994 pLoop->cId, (double)sqlite3LogEstToInt(nSearch), pTab->zName,
155995 (double)sqlite3LogEstToInt(pTab->nRowLogEst)));
155996 }
155997 }
155998 nSearch += pLoop->nOut;
155999 }
156000 }
156001
156002 /*
156003 ** Generate the beginning of the loop used for WHERE clause processing.
156004 ** The return value is a pointer to an opaque structure that contains
156005 ** information needed to terminate the loop. Later, the calling routine
@@ -154735,16 +156127,10 @@
156127 /* An ORDER/GROUP BY clause of more than 63 terms cannot be optimized */
156128 testcase( pOrderBy && pOrderBy->nExpr==BMS-1 );
156129 if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0;
156130 sWLB.pOrderBy = pOrderBy;
156131
 
 
 
 
 
 
156132 /* The number of tables in the FROM clause is limited by the number of
156133 ** bits in a Bitmask
156134 */
156135 testcase( pTabList->nSrc==BMS );
156136 if( pTabList->nSrc>BMS ){
@@ -154787,10 +156173,14 @@
156173 memset(&pWInfo->nOBSat, 0,
156174 offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
156175 memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
156176 assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */
156177 pMaskSet = &pWInfo->sMaskSet;
156178 pMaskSet->n = 0;
156179 pMaskSet->ix[0] = -99; /* Initialize ix[0] to a value that can never be
156180 ** a valid cursor number, to avoid an initial
156181 ** test for pMaskSet->n==0 in sqlite3WhereGetMask() */
156182 sWLB.pWInfo = pWInfo;
156183 sWLB.pWC = &pWInfo->sWC;
156184 sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
156185 assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
156186 whereLoopInit(sWLB.pNew);
@@ -154799,19 +156189,20 @@
156189 #endif
156190
156191 /* Split the WHERE clause into separate subexpressions where each
156192 ** subexpression is separated by an AND operator.
156193 */
 
156194 sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo);
156195 sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND);
156196
156197 /* Special case: No FROM clause
156198 */
156199 if( nTabList==0 ){
156200 if( pOrderBy ) pWInfo->nOBSat = pOrderBy->nExpr;
156201 if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0
156202 && OptimizationEnabled(db, SQLITE_DistinctOpt)
156203 ){
156204 pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
156205 }
156206 ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
156207 }else{
156208 /* Assign a bit from the bitmask to every term in the FROM clause.
@@ -154858,21 +156249,26 @@
156249 ** preserves SQLite's legacy behaviour in the following two cases:
156250 **
156251 ** FROM ... WHERE random()>0; -- eval random() once per row
156252 ** FROM ... WHERE (SELECT random())>0; -- eval random() once overall
156253 */
156254 for(ii=0; ii<sWLB.pWC->nBase; ii++){
156255 WhereTerm *pT = &sWLB.pWC->a[ii];
156256 if( pT->wtFlags & TERM_VIRTUAL ) continue;
156257 if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){
156258 sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL);
156259 pT->wtFlags |= TERM_CODED;
156260 }
156261 }
156262
156263 if( wctrlFlags & WHERE_WANT_DISTINCT ){
156264 if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){
156265 /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via
156266 ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */
156267 wctrlFlags &= ~WHERE_WANT_DISTINCT;
156268 pWInfo->wctrlFlags &= ~WHERE_WANT_DISTINCT;
156269 }else if( isDistinctRedundant(pParse, pTabList, &pWInfo->sWC, pResultSet) ){
156270 /* The DISTINCT marking is pointless. Ignore it. */
156271 pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
156272 }else if( pOrderBy==0 ){
156273 /* Try to ORDER BY the result set to make distinct processing easier */
156274 pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
@@ -154969,88 +156365,40 @@
156365 sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC);
156366 }
156367 }
156368 #endif
156369
156370 /* Attempt to omit tables from a join that do not affect the result.
156371 ** See the comment on whereOmitNoopJoin() for further information.
156372 **
156373 ** This query optimization is factored out into a separate "no-inline"
156374 ** procedure to keep the sqlite3WhereBegin() procedure from becoming
156375 ** too large. If sqlite3WhereBegin() becomes too large, that prevents
156376 ** some C-compiler optimizers from in-lining the
156377 ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to
156378 ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156379 */
156380 notReady = ~(Bitmask)0;
156381 if( pWInfo->nLevel>=2
156382 && pResultSet!=0 /* these two combine to guarantee */
156383 && 0==(wctrlFlags & WHERE_AGG_DISTINCT) /* condition (1) above */
156384 && OptimizationEnabled(db, SQLITE_OmitNoopJoin)
156385 ){
156386 notReady = whereOmitNoopJoin(pWInfo, notReady);
156387 nTabList = pWInfo->nLevel;
156388 assert( nTabList>0 );
156389 }
156390
156391 /* Check to see if there are any SEARCH loops that might benefit from
156392 ** using a Bloom filter.
156393 */
156394 if( pWInfo->nLevel>=2
156395 && OptimizationEnabled(db, SQLITE_BloomFilter)
156396 ){
156397 whereCheckIfBloomFilterIsUseful(pWInfo);
156398 }
156399
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156400 #if defined(WHERETRACE_ENABLED)
156401 if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
156402 sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n");
156403 sqlite3WhereClausePrint(sWLB.pWC);
156404 }
@@ -155232,19 +156580,24 @@
156580 ** program.
156581 */
156582 for(ii=0; ii<nTabList; ii++){
156583 int addrExplain;
156584 int wsFlags;
156585 if( pParse->nErr ) goto whereBeginError;
156586 pLevel = &pWInfo->a[ii];
156587 wsFlags = pLevel->pWLoop->wsFlags;
156588 if( (wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))!=0 ){
156589 if( (wsFlags & WHERE_AUTO_INDEX)!=0 ){
156590 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
156591 constructAutomaticIndex(pParse, &pWInfo->sWC,
156592 &pTabList->a[pLevel->iFrom], notReady, pLevel);
156593 #endif
156594 }else{
156595 constructBloomFilter(pWInfo, ii, pLevel, notReady);
156596 }
156597 if( db->mallocFailed ) goto whereBeginError;
156598 }
 
156599 addrExplain = sqlite3WhereExplainOneScan(
156600 pParse, pTabList, pLevel, wctrlFlags
156601 );
156602 pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
156603 notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
@@ -155353,11 +156706,11 @@
156706 if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek);
156707 #endif
156708 }else{
156709 sqlite3VdbeResolveLabel(v, pLevel->addrCont);
156710 }
156711 if( (pLoop->wsFlags & WHERE_IN_ABLE)!=0 && pLevel->u.in.nIn>0 ){
156712 struct InLoop *pIn;
156713 int j;
156714 sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
156715 for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
156716 assert( sqlite3VdbeGetOp(v, pIn->addrInTop+1)->opcode==OP_IsNull
@@ -155422,14 +156775,14 @@
156775 if( (ws & WHERE_IDX_ONLY)==0 ){
156776 assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor );
156777 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur);
156778 }
156779 if( (ws & WHERE_INDEXED)
156780 || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx)
156781 ){
156782 if( ws & WHERE_MULTI_OR ){
156783 Index *pIx = pLevel->u.pCoveringIdx;
156784 int iDb = sqlite3SchemaToIndex(db, pIx->pSchema);
156785 sqlite3VdbeAddOp3(v, OP_ReopenIdx, pLevel->iIdxCur, pIx->tnum, iDb);
156786 sqlite3VdbeSetP4KeyInfo(pParse, pIx);
156787 }
156788 sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur);
@@ -155506,11 +156859,11 @@
156859 ** reference the index.
156860 */
156861 if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
156862 pIdx = pLoop->u.btree.pIndex;
156863 }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
156864 pIdx = pLevel->u.pCoveringIdx;
156865 }
156866 if( pIdx
156867 && !db->mallocFailed
156868 ){
156869 if( pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable) ){
@@ -156167,28 +157520,28 @@
157520 static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ }
157521
157522 /* Window functions that use all window interfaces: xStep, xFinal,
157523 ** xValue, and xInverse */
157524 #define WINDOWFUNCALL(name,nArg,extra) { \
157525 nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
157526 name ## StepFunc, name ## FinalizeFunc, name ## ValueFunc, \
157527 name ## InvFunc, name ## Name, {0} \
157528 }
157529
157530 /* Window functions that are implemented using bytecode and thus have
157531 ** no-op routines for their methods */
157532 #define WINDOWFUNCNOOP(name,nArg,extra) { \
157533 nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
157534 noopStepFunc, noopValueFunc, noopValueFunc, \
157535 noopStepFunc, name ## Name, {0} \
157536 }
157537
157538 /* Window functions that use all window interfaces: xStep, the
157539 ** same routine for xFinalize and xValue and which never call
157540 ** xInverse. */
157541 #define WINDOWFUNCX(name,nArg,extra) { \
157542 nArg, (SQLITE_FUNC_BUILTIN|SQLITE_UTF8|SQLITE_FUNC_WINDOW|extra), 0, 0, \
157543 name ## StepFunc, name ## ValueFunc, name ## ValueFunc, \
157544 noopStepFunc, name ## Name, {0} \
157545 }
157546
157547
@@ -156527,11 +157880,12 @@
157880 return WRC_Continue;
157881 }
157882
157883 static int disallowAggregatesInOrderByCb(Walker *pWalker, Expr *pExpr){
157884 if( pExpr->op==TK_AGG_FUNCTION && pExpr->pAggInfo==0 ){
157885 assert( !ExprHasProperty(pExpr, EP_IntValue) );
157886 sqlite3ErrorMsg(pWalker->pParse,
157887 "misuse of aggregate: %s()", pExpr->u.zToken);
157888 }
157889 return WRC_Continue;
157890 }
157891
@@ -156615,11 +157969,13 @@
157969 /* Append the arguments passed to each window function to the
157970 ** sub-select expression list. Also allocate two registers for each
157971 ** window function - one for the accumulator, another for interim
157972 ** results. */
157973 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
157974 ExprList *pArgs;
157975 assert( ExprUseXList(pWin->pOwner) );
157976 pArgs = pWin->pOwner->x.pList;
157977 if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){
157978 selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist);
157979 pWin->iArgCol = (pSublist ? pSublist->nExpr : 0);
157980 pWin->bExprArgs = 1;
157981 }else{
@@ -156682,11 +158038,15 @@
158038 }
158039 }else{
158040 sqlite3SelectDelete(db, pSub);
158041 }
158042 if( db->mallocFailed ) rc = SQLITE_NOMEM;
158043
158044 /* Defer deleting the temporary table pTab because if an error occurred,
158045 ** there could still be references to that table embedded in the
158046 ** result-set or ORDER BY clause of the SELECT statement p. */
158047 sqlite3ParserAddCleanup(pParse, sqlite3DbFree, pTab);
158048 }
158049
158050 if( rc ){
158051 if( pParse->nErr==0 ){
158052 assert( pParse->db->mallocFailed );
@@ -157008,12 +158368,15 @@
158368 **
158369 ** regApp+0: slot to copy min()/max() argument to for MakeRecord
158370 ** regApp+1: integer value used to ensure keys are unique
158371 ** regApp+2: output of MakeRecord
158372 */
158373 ExprList *pList;
158374 KeyInfo *pKeyInfo;
158375 assert( ExprUseXList(pWin->pOwner) );
158376 pList = pWin->pOwner->x.pList;
158377 pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0);
158378 pWin->csrApp = pParse->nTab++;
158379 pWin->regApp = pParse->nMem+1;
158380 pParse->nMem += 3;
158381 if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){
158382 assert( pKeyInfo->aSortFlags[0]==0 );
@@ -157097,11 +158460,13 @@
158460 /*
158461 ** Return the number of arguments passed to the window-function associated
158462 ** with the object passed as the only argument to this function.
158463 */
158464 static int windowArgCount(Window *pWin){
158465 const ExprList *pList;
158466 assert( ExprUseXList(pWin->pOwner) );
158467 pList = pWin->pOwner->x.pList;
158468 return (pList ? pList->nExpr : 0);
158469 }
158470
158471 typedef struct WindowCodeArg WindowCodeArg;
158472 typedef struct WindowCsrAndReg WindowCsrAndReg;
@@ -157282,10 +158647,11 @@
158647 sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
158648 }else if( pFunc->xSFunc!=noopStepFunc ){
158649 int addrIf = 0;
158650 if( pWin->pFilter ){
158651 int regTmp;
158652 assert( ExprUseXList(pWin->pOwner) );
158653 assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr );
158654 assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 );
158655 regTmp = sqlite3GetTempReg(pParse);
158656 sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
158657 addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
@@ -157295,10 +158661,11 @@
158661
158662 if( pWin->bExprArgs ){
158663 int iOp = sqlite3VdbeCurrentAddr(v);
158664 int iEnd;
158665
158666 assert( ExprUseXList(pWin->pOwner) );
158667 nArg = pWin->pOwner->x.pList->nExpr;
158668 regArg = sqlite3GetTempRange(pParse, nArg);
158669 sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0);
158670
158671 for(iEnd=sqlite3VdbeCurrentAddr(v); iOp<iEnd; iOp++){
@@ -157309,10 +158676,11 @@
158676 }
158677 }
158678 if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
158679 CollSeq *pColl;
158680 assert( nArg>0 );
158681 assert( ExprUseXList(pWin->pOwner) );
158682 pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
158683 sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
158684 }
158685 sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep,
158686 bInverse, regArg, pWin->regAccum);
@@ -157494,10 +158862,11 @@
158862 Parse *pParse = p->pParse;
158863 Window *pWin;
158864
158865 for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
158866 FuncDef *pFunc = pWin->pFunc;
158867 assert( ExprUseXList(pWin->pOwner) );
158868 if( pFunc->zName==nth_valueName
158869 || pFunc->zName==first_valueName
158870 ){
158871 int csr = pWin->csrApp;
158872 int lbl = sqlite3VdbeMakeLabel(pParse);
@@ -158843,13 +160212,13 @@
160212 p->affExpr = 0;
160213 p->flags = EP_Leaf;
160214 ExprClearVVAProperties(p);
160215 p->iAgg = -1;
160216 p->pLeft = p->pRight = 0;
 
160217 p->pAggInfo = 0;
160218 memset(&p->x, 0, sizeof(p->x));
160219 memset(&p->y, 0, sizeof(p->y));
160220 p->op2 = 0;
160221 p->iTable = 0;
160222 p->iColumn = 0;
160223 p->u.zToken = (char*)&p[1];
160224 memcpy(p->u.zToken, t.z, t.n);
@@ -158951,14 +160320,14 @@
160320 #define TK_DETACH 40
160321 #define TK_EACH 41
160322 #define TK_FAIL 42
160323 #define TK_OR 43
160324 #define TK_AND 44
160325 #define TK_MATCH 45
160326 #define TK_LIKE_KW 46
160327 #define TK_BETWEEN 47
160328 #define TK_IS 48
160329 #define TK_IN 49
160330 #define TK_ISNULL 50
160331 #define TK_NOTNULL 51
160332 #define TK_NE 52
160333 #define TK_EQ 53
@@ -159266,216 +160635,215 @@
160635 ** yy_reduce_ofst[] For each state, the offset into yy_action for
160636 ** shifting non-terminals after a reduce.
160637 ** yy_default[] Default action for each state.
160638 **
160639 *********** Begin parsing tables **********************************************/
160640 #define YY_ACTTAB_COUNT (2022)
160641 static const YYACTIONTYPE yy_action[] = {
160642 /* 0 */ 564, 115, 112, 220, 169, 199, 115, 112, 220, 564,
160643 /* 10 */ 375, 1266, 564, 376, 564, 270, 1309, 1309, 406, 407,
160644 /* 20 */ 1084, 199, 1513, 41, 41, 515, 489, 521, 558, 558,
160645 /* 30 */ 558, 965, 41, 41, 395, 41, 41, 51, 51, 966,
160646 /* 40 */ 296, 1269, 296, 122, 123, 1207, 1207, 1041, 113, 1044,
160647 /* 50 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 564, 407,
160648 /* 60 */ 275, 275, 275, 275, 1268, 115, 112, 220, 115, 112,
160649 /* 70 */ 220, 1512, 846, 561, 516, 561, 115, 112, 220, 250,
160650 /* 80 */ 217, 71, 71, 122, 123, 1207, 1207, 1041, 113, 1044,
160651 /* 90 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 440, 440,
160652 /* 100 */ 440, 1149, 119, 119, 119, 119, 118, 118, 117, 117,
160653 /* 110 */ 117, 116, 442, 1183, 1149, 116, 442, 1149, 546, 513,
160654 /* 120 */ 1548, 1554, 374, 213, 6, 169, 1154, 522, 1154, 407,
160655 /* 130 */ 1556, 461, 373, 1554, 535, 99, 463, 332, 121, 121,
160656 /* 140 */ 121, 121, 119, 119, 119, 119, 118, 118, 117, 117,
160657 /* 150 */ 117, 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044,
160658 /* 160 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 1257, 1183,
160659 /* 170 */ 1184, 1185, 243, 1064, 564, 502, 499, 498, 567, 124,
160660 /* 180 */ 567, 1128, 1627, 344, 1627, 497, 119, 119, 119, 119,
160661 /* 190 */ 118, 118, 117, 117, 117, 116, 442, 70, 70, 407,
160662 /* 200 */ 121, 121, 121, 121, 114, 117, 117, 117, 116, 442,
160663 /* 210 */ 474, 1469, 119, 119, 119, 119, 118, 118, 117, 117,
160664 /* 220 */ 117, 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044,
160665 /* 230 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 407, 208,
160666 /* 240 */ 539, 1548, 1424, 81, 339, 6, 342, 80, 119, 119,
160667 /* 250 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 381,
160668 /* 260 */ 1126, 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160669 /* 270 */ 1034, 120, 120, 121, 121, 121, 121, 262, 463, 332,
160670 /* 280 */ 359, 1567, 119, 119, 119, 119, 118, 118, 117, 117,
160671 /* 290 */ 117, 116, 442, 1231, 1, 1, 571, 2, 1235, 1573,
160672 /* 300 */ 571, 2, 1235, 307, 1149, 141, 417, 307, 407, 141,
160673 /* 310 */ 1183, 98, 1317, 489, 866, 531, 1317, 1149, 215, 512,
160674 /* 320 */ 1149, 119, 119, 119, 119, 118, 118, 117, 117, 117,
160675 /* 330 */ 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160676 /* 340 */ 1034, 120, 120, 121, 121, 121, 121, 275, 275, 1001,
160677 /* 350 */ 1257, 275, 275, 1128, 1628, 1021, 1628, 137, 415, 1600,
160678 /* 360 */ 561, 272, 1255, 950, 561, 1423, 1183, 1184, 1185, 1594,
160679 /* 370 */ 866, 1012, 530, 315, 231, 1011, 317, 1276, 231, 119,
160680 /* 380 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
160681 /* 390 */ 1570, 119, 119, 119, 119, 118, 118, 117, 117, 117,
160682 /* 400 */ 116, 442, 330, 359, 1567, 564, 446, 1011, 1011, 1013,
160683 /* 410 */ 446, 877, 564, 306, 555, 407, 447, 1021, 563, 346,
160684 /* 420 */ 184, 118, 118, 117, 117, 117, 116, 442, 71, 71,
160685 /* 430 */ 439, 438, 1126, 1012, 472, 71, 71, 1011, 205, 122,
160686 /* 440 */ 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120,
160687 /* 450 */ 121, 121, 121, 121, 1304, 219, 1283, 1183, 407, 570,
160688 /* 460 */ 1183, 1235, 503, 1477, 1304, 546, 307, 489, 141, 1011,
160689 /* 470 */ 1011, 1013, 546, 140, 545, 1317, 1214, 382, 1214, 378,
160690 /* 480 */ 950, 514, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160691 /* 490 */ 1034, 120, 120, 121, 121, 121, 121, 472, 119, 119,
160692 /* 500 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 283,
160693 /* 510 */ 275, 275, 1476, 1183, 1184, 1185, 1183, 1184, 1185, 417,
160694 /* 520 */ 1183, 243, 541, 561, 502, 499, 498, 1001, 407, 478,
160695 /* 530 */ 1183, 472, 870, 143, 497, 1549, 185, 231, 9, 6,
160696 /* 540 */ 253, 119, 119, 119, 119, 118, 118, 117, 117, 117,
160697 /* 550 */ 116, 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034,
160698 /* 560 */ 1034, 120, 120, 121, 121, 121, 121, 407, 372, 446,
160699 /* 570 */ 363, 863, 288, 1183, 397, 1204, 1183, 1184, 1185, 931,
160700 /* 580 */ 330, 458, 318, 526, 564, 541, 1183, 1184, 1185, 284,
160701 /* 590 */ 1183, 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034,
160702 /* 600 */ 120, 120, 121, 121, 121, 121, 291, 71, 71, 275,
160703 /* 610 */ 275, 119, 119, 119, 119, 118, 118, 117, 117, 117,
160704 /* 620 */ 116, 442, 561, 1031, 1031, 1042, 1183, 1045, 287, 1183,
160705 /* 630 */ 1184, 1185, 1204, 137, 218, 542, 1541, 407, 363, 470,
160706 /* 640 */ 431, 1167, 32, 363, 527, 350, 1183, 1184, 1185, 380,
160707 /* 650 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
160708 /* 660 */ 442, 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034,
160709 /* 670 */ 120, 120, 121, 121, 121, 121, 407, 392, 1227, 1183,
160710 /* 680 */ 1022, 1540, 1183, 1184, 1185, 1523, 149, 1307, 1307, 306,
160711 /* 690 */ 555, 151, 1546, 361, 5, 564, 6, 3, 1035, 1542,
160712 /* 700 */ 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120,
160713 /* 710 */ 120, 121, 121, 121, 121, 411, 505, 83, 71, 71,
160714 /* 720 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
160715 /* 730 */ 442, 1183, 426, 428, 1183, 1183, 1184, 1185, 191, 261,
160716 /* 740 */ 278, 358, 508, 353, 507, 248, 407, 455, 137, 1539,
160717 /* 750 */ 1006, 349, 363, 472, 1539, 302, 1228, 405, 281, 119,
160718 /* 760 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
160719 /* 770 */ 122, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120,
160720 /* 780 */ 120, 121, 121, 121, 121, 407, 452, 1183, 1184, 1185,
160721 /* 790 */ 1183, 1184, 1185, 275, 275, 269, 269, 489, 483, 1525,
160722 /* 800 */ 148, 363, 480, 564, 306, 555, 561, 489, 561, 122,
160723 /* 810 */ 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120,
160724 /* 820 */ 121, 121, 121, 121, 564, 886, 13, 13, 293, 119,
160725 /* 830 */ 119, 119, 119, 118, 118, 117, 117, 117, 116, 442,
160726 /* 840 */ 1183, 420, 1316, 564, 98, 417, 199, 13, 13, 150,
160727 /* 850 */ 306, 555, 1312, 322, 386, 407, 506, 478, 562, 400,
160728 /* 860 */ 920, 920, 425, 1539, 887, 292, 71, 71, 119, 119,
160729 /* 870 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 122,
160730 /* 880 */ 123, 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120,
160731 /* 890 */ 121, 121, 121, 121, 564, 1149, 1183, 1184, 1185, 407,
160732 /* 900 */ 275, 275, 451, 303, 1089, 1089, 486, 448, 1149, 276,
160733 /* 910 */ 276, 1149, 1539, 561, 319, 286, 321, 71, 71, 429,
160734 /* 920 */ 451, 450, 561, 952, 101, 1207, 1207, 1041, 113, 1044,
160735 /* 930 */ 1034, 1034, 120, 120, 121, 121, 121, 121, 119, 119,
160736 /* 940 */ 119, 119, 118, 118, 117, 117, 117, 116, 442, 1105,
160737 /* 950 */ 1183, 1547, 564, 12, 437, 6, 329, 564, 834, 835,
160738 /* 960 */ 836, 1629, 393, 547, 1106, 246, 245, 244, 1545, 1258,
160739 /* 970 */ 413, 1521, 6, 1086, 310, 71, 71, 1086, 564, 1107,
160740 /* 980 */ 13, 13, 119, 119, 119, 119, 118, 118, 117, 117,
160741 /* 990 */ 117, 116, 442, 451, 104, 427, 537, 320, 275, 275,
160742 /* 1000 */ 906, 13, 13, 520, 1482, 1105, 1183, 1184, 1185, 484,
160743 /* 1010 */ 907, 561, 546, 564, 407, 536, 295, 478, 253, 200,
160744 /* 1020 */ 1106, 548, 1482, 1484, 1160, 1409, 16, 16, 126, 557,
160745 /* 1030 */ 413, 479, 311, 951, 407, 1107, 71, 71, 122, 123,
160746 /* 1040 */ 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120, 121,
160747 /* 1050 */ 121, 121, 121, 1204, 407, 544, 552, 314, 122, 123,
160748 /* 1060 */ 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120, 121,
160749 /* 1070 */ 121, 121, 121, 441, 144, 1160, 468, 146, 122, 111,
160750 /* 1080 */ 1207, 1207, 1041, 113, 1044, 1034, 1034, 120, 120, 121,
160751 /* 1090 */ 121, 121, 121, 247, 12, 1482, 422, 119, 119, 119,
160752 /* 1100 */ 119, 118, 118, 117, 117, 117, 116, 442, 1183, 564,
160753 /* 1110 */ 1204, 207, 404, 403, 858, 950, 294, 119, 119, 119,
160754 /* 1120 */ 119, 118, 118, 117, 117, 117, 116, 442, 564, 30,
160755 /* 1130 */ 564, 1409, 55, 55, 1599, 564, 895, 119, 119, 119,
160756 /* 1140 */ 119, 118, 118, 117, 117, 117, 116, 442, 510, 1409,
160757 /* 1150 */ 1409, 56, 56, 15, 15, 439, 438, 407, 13, 13,
160758 /* 1160 */ 31, 1187, 412, 1211, 1183, 1184, 1185, 196, 1213, 306,
160759 /* 1170 */ 555, 858, 462, 193, 926, 564, 1212, 489, 361, 925,
160760 /* 1180 */ 1183, 564, 123, 1207, 1207, 1041, 113, 1044, 1034, 1034,
160761 /* 1190 */ 120, 120, 121, 121, 121, 121, 1544, 1149, 43, 43,
160762 /* 1200 */ 6, 1214, 423, 1214, 13, 13, 564, 219, 538, 494,
160763 /* 1210 */ 1149, 108, 556, 1149, 4, 392, 1127, 434, 1187, 194,
160764 /* 1220 */ 424, 485, 337, 1315, 414, 171, 1253, 1321, 559, 57,
160765 /* 1230 */ 57, 564, 950, 564, 224, 247, 1183, 1184, 1185, 561,
160766 /* 1240 */ 119, 119, 119, 119, 118, 118, 117, 117, 117, 116,
160767 /* 1250 */ 442, 443, 564, 517, 13, 13, 44, 44, 275, 275,
160768 /* 1260 */ 1409, 275, 275, 553, 1353, 529, 213, 549, 456, 543,
160769 /* 1270 */ 465, 561, 564, 137, 561, 58, 58, 469, 405, 1222,
160770 /* 1280 */ 405, 274, 217, 108, 556, 110, 4, 405, 275, 275,
160771 /* 1290 */ 564, 1352, 1021, 564, 1228, 59, 59, 523, 106, 106,
160772 /* 1300 */ 559, 561, 275, 275, 412, 107, 457, 443, 566, 565,
160773 /* 1310 */ 564, 8, 1011, 60, 60, 561, 61, 61, 564, 965,
160774 /* 1320 */ 349, 926, 305, 443, 84, 204, 925, 966, 564, 306,
160775 /* 1330 */ 555, 435, 405, 62, 62, 553, 476, 105, 564, 103,
160776 /* 1340 */ 464, 45, 45, 1203, 1011, 1011, 1013, 1014, 27, 533,
160777 /* 1350 */ 564, 46, 46, 453, 532, 1572, 1171, 445, 1528, 564,
160778 /* 1360 */ 279, 47, 47, 327, 1021, 390, 390, 389, 264, 387,
160779 /* 1370 */ 106, 106, 843, 49, 49, 108, 556, 107, 4, 443,
160780 /* 1380 */ 566, 565, 50, 50, 1011, 225, 564, 313, 564, 96,
160781 /* 1390 */ 564, 228, 559, 524, 147, 312, 38, 1123, 564, 394,
160782 /* 1400 */ 466, 328, 280, 98, 544, 564, 17, 564, 323, 63,
160783 /* 1410 */ 63, 64, 64, 65, 65, 443, 1011, 1011, 1013, 1014,
160784 /* 1420 */ 27, 14, 14, 289, 564, 227, 564, 553, 66, 66,
160785 /* 1430 */ 128, 128, 477, 162, 564, 309, 135, 564, 1003, 277,
160786 /* 1440 */ 252, 533, 564, 1501, 564, 418, 534, 67, 67, 52,
160787 /* 1450 */ 52, 564, 1287, 226, 564, 1500, 1021, 68, 68, 208,
160788 /* 1460 */ 69, 69, 106, 106, 1286, 53, 53, 157, 157, 107,
160789 /* 1470 */ 873, 443, 566, 565, 158, 158, 1011, 76, 76, 564,
160790 /* 1480 */ 357, 564, 108, 556, 471, 4, 252, 408, 885, 884,
160791 /* 1490 */ 356, 564, 306, 555, 564, 473, 564, 252, 481, 559,
160792 /* 1500 */ 564, 334, 54, 54, 72, 72, 564, 230, 1011, 1011,
160793 /* 1510 */ 1013, 1014, 27, 564, 129, 129, 449, 73, 73, 130,
160794 /* 1520 */ 130, 564, 443, 131, 131, 519, 564, 873, 564, 127,
160795 /* 1530 */ 127, 333, 1071, 98, 553, 1349, 156, 156, 564, 495,
160796 /* 1540 */ 347, 249, 98, 338, 155, 155, 892, 893, 533, 136,
160797 /* 1550 */ 136, 134, 134, 532, 341, 1171, 445, 1587, 564, 279,
160798 /* 1560 */ 343, 132, 132, 1021, 390, 390, 389, 264, 387, 106,
160799 /* 1570 */ 106, 843, 564, 1067, 564, 249, 107, 564, 443, 566,
160800 /* 1580 */ 565, 133, 133, 1011, 225, 1015, 313, 108, 556, 1071,
160801 /* 1590 */ 4, 345, 968, 969, 312, 75, 75, 77, 77, 1300,
160802 /* 1600 */ 74, 74, 564, 1132, 559, 564, 108, 556, 959, 4,
160803 /* 1610 */ 252, 923, 1083, 110, 1083, 1011, 1011, 1013, 1014, 27,
160804 /* 1620 */ 1082, 1285, 1082, 559, 227, 42, 42, 443, 48, 48,
160805 /* 1630 */ 1284, 856, 162, 145, 924, 135, 110, 352, 362, 553,
160806 /* 1640 */ 1340, 1361, 1015, 1408, 1336, 301, 443, 1561, 1347, 550,
160807 /* 1650 */ 1414, 551, 226, 202, 1265, 1333, 1256, 1244, 553, 1243,
160808 /* 1660 */ 490, 1245, 1580, 267, 11, 391, 210, 223, 1021, 1390,
160809 /* 1670 */ 1395, 282, 365, 367, 106, 106, 930, 369, 454, 285,
160810 /* 1680 */ 1383, 107, 325, 443, 566, 565, 408, 1021, 1011, 326,
160811 /* 1690 */ 475, 306, 555, 106, 106, 100, 556, 500, 4, 1400,
160812 /* 1700 */ 107, 1399, 443, 566, 565, 398, 1283, 1011, 214, 355,
160813 /* 1710 */ 1473, 290, 559, 1472, 1583, 449, 554, 371, 331, 197,
160814 /* 1720 */ 1011, 1011, 1013, 1014, 27, 198, 209, 385, 1222, 173,
160815 /* 1730 */ 221, 256, 1520, 1518, 1219, 443, 79, 416, 206, 1011,
160816 /* 1740 */ 1011, 1013, 1014, 27, 83, 279, 182, 553, 82, 167,
160817 /* 1750 */ 390, 390, 389, 264, 387, 35, 1396, 843, 1478, 459,
160818 /* 1760 */ 175, 177, 460, 493, 178, 179, 180, 233, 96, 396,
160819 /* 1770 */ 225, 1402, 313, 1401, 36, 1404, 1021, 467, 186, 482,
160820 /* 1780 */ 312, 399, 106, 106, 237, 1467, 89, 1489, 488, 107,
160821 /* 1790 */ 239, 443, 566, 565, 268, 336, 1011, 190, 491, 340,
160822 /* 1800 */ 240, 401, 1246, 241, 509, 1294, 430, 1303, 91, 877,
160823 /* 1810 */ 227, 215, 1566, 1302, 1301, 1273, 1598, 432, 162, 518,
160824 /* 1820 */ 1272, 135, 1597, 354, 402, 433, 1271, 1596, 1011, 1011,
160825 /* 1830 */ 1013, 1014, 27, 1293, 299, 360, 300, 525, 226, 95,
160826 /* 1840 */ 254, 255, 1344, 364, 436, 125, 544, 1552, 10, 1453,
160827 /* 1850 */ 379, 1551, 102, 304, 97, 528, 34, 568, 1177, 263,
160828 /* 1860 */ 265, 266, 569, 1241, 1236, 172, 409, 410, 159, 383,
160829 /* 1870 */ 377, 366, 408, 1345, 1343, 368, 370, 306, 555, 1342,
160830 /* 1880 */ 1326, 1325, 1368, 201, 384, 1367, 1505, 1506, 160, 1504,
160831 /* 1890 */ 1503, 142, 161, 211, 212, 78, 830, 444, 203, 308,
160832 /* 1900 */ 297, 449, 222, 1081, 139, 1079, 316, 174, 163, 1203,
160833 /* 1910 */ 229, 176, 232, 909, 324, 1095, 164, 181, 165, 419,
160834 /* 1920 */ 421, 183, 85, 86, 87, 88, 166, 1098, 235, 234,
160835 /* 1930 */ 1094, 152, 18, 236, 335, 1087, 252, 1216, 487, 238,
160836 /* 1940 */ 37, 187, 188, 845, 492, 356, 242, 348, 496, 189,
160837 /* 1950 */ 90, 93, 19, 20, 168, 875, 501, 351, 92, 504,
160838 /* 1960 */ 888, 153, 511, 1133, 1165, 154, 298, 1047, 94, 1134,
160839 /* 1970 */ 39, 958, 216, 271, 273, 192, 953, 110, 1151, 251,
160840 /* 1980 */ 1155, 21, 1159, 22, 1158, 1139, 1153, 33, 23, 24,
160841 /* 1990 */ 540, 25, 195, 98, 26, 1062, 1048, 1046, 1050, 1104,
160842 /* 2000 */ 7, 1103, 257, 258, 1051, 28, 40, 560, 1016, 857,
160843 /* 2010 */ 109, 29, 919, 138, 259, 260, 170, 1589, 388, 1588,
160844 /* 2020 */ 1173, 1172,
 
160845 };
160846 static const YYCODETYPE yy_lookahead[] = {
160847 /* 0 */ 192, 273, 274, 275, 192, 192, 273, 274, 275, 192,
160848 /* 10 */ 218, 215, 192, 218, 192, 212, 234, 235, 205, 19,
160849 /* 20 */ 11, 192, 294, 215, 216, 203, 192, 203, 209, 210,
@@ -159486,202 +160854,202 @@
160854 /* 70 */ 275, 237, 21, 251, 252, 251, 273, 274, 275, 255,
160855 /* 80 */ 256, 215, 216, 43, 44, 45, 46, 47, 48, 49,
160856 /* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 209, 210,
160857 /* 100 */ 211, 76, 102, 103, 104, 105, 106, 107, 108, 109,
160858 /* 110 */ 110, 111, 112, 59, 89, 111, 112, 92, 252, 307,
160859 /* 120 */ 308, 313, 314, 25, 312, 192, 86, 261, 88, 19,
160860 /* 130 */ 313, 80, 315, 313, 314, 25, 127, 128, 54, 55,
160861 /* 140 */ 56, 57, 102, 103, 104, 105, 106, 107, 108, 109,
160862 /* 150 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49,
160863 /* 160 */ 50, 51, 52, 53, 54, 55, 56, 57, 192, 115,
160864 /* 170 */ 116, 117, 118, 122, 192, 121, 122, 123, 202, 69,
160865 /* 180 */ 204, 22, 23, 16, 25, 131, 102, 103, 104, 105,
160866 /* 190 */ 106, 107, 108, 109, 110, 111, 112, 215, 216, 19,
160867 /* 200 */ 54, 55, 56, 57, 58, 108, 109, 110, 111, 112,
160868 /* 210 */ 192, 160, 102, 103, 104, 105, 106, 107, 108, 109,
160869 /* 220 */ 110, 111, 112, 43, 44, 45, 46, 47, 48, 49,
160870 /* 230 */ 50, 51, 52, 53, 54, 55, 56, 57, 19, 141,
160871 /* 240 */ 307, 308, 272, 24, 77, 312, 79, 67, 102, 103,
160872 /* 250 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 277,
160873 /* 260 */ 101, 112, 43, 44, 45, 46, 47, 48, 49, 50,
160874 /* 270 */ 51, 52, 53, 54, 55, 56, 57, 26, 127, 128,
160875 /* 280 */ 310, 311, 102, 103, 104, 105, 106, 107, 108, 109,
160876 /* 290 */ 110, 111, 112, 184, 185, 186, 187, 188, 189, 186,
160877 /* 300 */ 187, 188, 189, 194, 76, 196, 192, 194, 19, 196,
160878 /* 310 */ 59, 25, 203, 192, 59, 87, 203, 89, 164, 165,
160879 /* 320 */ 92, 102, 103, 104, 105, 106, 107, 108, 109, 110,
160880 /* 330 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50,
160881 /* 340 */ 51, 52, 53, 54, 55, 56, 57, 238, 239, 73,
160882 /* 350 */ 192, 238, 239, 22, 23, 100, 25, 81, 237, 229,
160883 /* 360 */ 251, 23, 204, 25, 251, 272, 115, 116, 117, 214,
160884 /* 370 */ 115, 116, 144, 192, 265, 120, 262, 222, 265, 102,
160885 /* 380 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
160886 /* 390 */ 192, 102, 103, 104, 105, 106, 107, 108, 109, 110,
160887 /* 400 */ 111, 112, 126, 310, 311, 192, 297, 152, 153, 154,
160888 /* 410 */ 297, 125, 192, 137, 138, 19, 295, 100, 192, 23,
160889 /* 420 */ 22, 106, 107, 108, 109, 110, 111, 112, 215, 216,
160890 /* 430 */ 106, 107, 101, 116, 192, 215, 216, 120, 149, 43,
160891 /* 440 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
160892 /* 450 */ 54, 55, 56, 57, 222, 117, 224, 59, 19, 187,
160893 /* 460 */ 59, 189, 23, 282, 232, 252, 194, 192, 196, 152,
160894 /* 470 */ 153, 154, 252, 72, 261, 203, 152, 248, 154, 250,
160895 /* 480 */ 142, 261, 43, 44, 45, 46, 47, 48, 49, 50,
160896 /* 490 */ 51, 52, 53, 54, 55, 56, 57, 192, 102, 103,
160897 /* 500 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 267,
160898 /* 510 */ 238, 239, 237, 115, 116, 117, 115, 116, 117, 192,
160899 /* 520 */ 59, 118, 192, 251, 121, 122, 123, 73, 19, 192,
160900 /* 530 */ 59, 192, 23, 72, 131, 308, 22, 265, 22, 312,
160901 /* 540 */ 24, 102, 103, 104, 105, 106, 107, 108, 109, 110,
160902 /* 550 */ 111, 112, 43, 44, 45, 46, 47, 48, 49, 50,
160903 /* 560 */ 51, 52, 53, 54, 55, 56, 57, 19, 192, 297,
160904 /* 570 */ 192, 23, 267, 59, 203, 59, 115, 116, 117, 108,
160905 /* 580 */ 126, 127, 128, 192, 192, 192, 115, 116, 117, 262,
160906 /* 590 */ 59, 43, 44, 45, 46, 47, 48, 49, 50, 51,
160907 /* 600 */ 52, 53, 54, 55, 56, 57, 267, 215, 216, 238,
160908 /* 610 */ 239, 102, 103, 104, 105, 106, 107, 108, 109, 110,
160909 /* 620 */ 111, 112, 251, 45, 46, 47, 59, 49, 291, 115,
160910 /* 630 */ 116, 117, 116, 81, 192, 305, 306, 19, 192, 268,
160911 /* 640 */ 19, 23, 22, 192, 252, 24, 115, 116, 117, 192,
160912 /* 650 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
160913 /* 660 */ 112, 43, 44, 45, 46, 47, 48, 49, 50, 51,
160914 /* 670 */ 52, 53, 54, 55, 56, 57, 19, 22, 23, 59,
160915 /* 680 */ 23, 303, 115, 116, 117, 192, 240, 234, 235, 137,
160916 /* 690 */ 138, 240, 308, 192, 22, 192, 312, 22, 120, 306,
160917 /* 700 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
160918 /* 710 */ 53, 54, 55, 56, 57, 197, 95, 150, 215, 216,
160919 /* 720 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
160920 /* 730 */ 112, 59, 231, 112, 59, 115, 116, 117, 25, 118,
160921 /* 740 */ 119, 120, 121, 122, 123, 124, 19, 243, 81, 303,
160922 /* 750 */ 23, 130, 192, 192, 303, 252, 101, 253, 203, 102,
160923 /* 760 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
160924 /* 770 */ 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
160925 /* 780 */ 53, 54, 55, 56, 57, 19, 119, 115, 116, 117,
160926 /* 790 */ 115, 116, 117, 238, 239, 238, 239, 192, 280, 192,
160927 /* 800 */ 240, 192, 284, 192, 137, 138, 251, 192, 251, 43,
160928 /* 810 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
160929 /* 820 */ 54, 55, 56, 57, 192, 35, 215, 216, 267, 102,
160930 /* 830 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
160931 /* 840 */ 59, 230, 237, 192, 25, 192, 192, 215, 216, 240,
160932 /* 850 */ 137, 138, 237, 16, 200, 19, 66, 192, 133, 205,
160933 /* 860 */ 135, 136, 230, 303, 74, 203, 215, 216, 102, 103,
160934 /* 870 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 43,
160935 /* 880 */ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
160936 /* 890 */ 54, 55, 56, 57, 192, 76, 115, 116, 117, 19,
160937 /* 900 */ 238, 239, 192, 252, 126, 127, 128, 192, 89, 238,
160938 /* 910 */ 239, 92, 303, 251, 77, 262, 79, 215, 216, 129,
160939 /* 920 */ 210, 211, 251, 142, 158, 45, 46, 47, 48, 49,
160940 /* 930 */ 50, 51, 52, 53, 54, 55, 56, 57, 102, 103,
160941 /* 940 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 12,
160942 /* 950 */ 59, 308, 192, 212, 252, 312, 291, 192, 7, 8,
160943 /* 960 */ 9, 300, 301, 203, 27, 126, 127, 128, 308, 207,
160944 /* 970 */ 208, 192, 312, 29, 192, 215, 216, 33, 192, 42,
160945 /* 980 */ 215, 216, 102, 103, 104, 105, 106, 107, 108, 109,
160946 /* 990 */ 110, 111, 112, 283, 158, 230, 66, 160, 238, 239,
160947 /* 1000 */ 63, 215, 216, 192, 192, 12, 115, 116, 117, 65,
160948 /* 1010 */ 73, 251, 252, 192, 19, 85, 230, 192, 24, 24,
160949 /* 1020 */ 27, 261, 210, 211, 94, 192, 215, 216, 22, 207,
160950 /* 1030 */ 208, 290, 192, 142, 19, 42, 215, 216, 43, 44,
160951 /* 1040 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
160952 /* 1050 */ 55, 56, 57, 59, 19, 144, 63, 192, 43, 44,
160953 /* 1060 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
160954 /* 1070 */ 55, 56, 57, 252, 163, 145, 114, 22, 43, 44,
160955 /* 1080 */ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
160956 /* 1090 */ 55, 56, 57, 45, 212, 283, 263, 102, 103, 104,
160957 /* 1100 */ 105, 106, 107, 108, 109, 110, 111, 112, 59, 192,
160958 /* 1110 */ 116, 149, 106, 107, 59, 25, 291, 102, 103, 104,
160959 /* 1120 */ 105, 106, 107, 108, 109, 110, 111, 112, 192, 22,
160960 /* 1130 */ 192, 192, 215, 216, 23, 192, 25, 102, 103, 104,
160961 /* 1140 */ 105, 106, 107, 108, 109, 110, 111, 112, 108, 192,
160962 /* 1150 */ 192, 215, 216, 215, 216, 106, 107, 19, 215, 216,
160963 /* 1160 */ 53, 59, 114, 114, 115, 116, 117, 285, 119, 137,
160964 /* 1170 */ 138, 116, 290, 230, 134, 192, 127, 192, 192, 139,
160965 /* 1180 */ 59, 192, 44, 45, 46, 47, 48, 49, 50, 51,
160966 /* 1190 */ 52, 53, 54, 55, 56, 57, 308, 76, 215, 216,
160967 /* 1200 */ 312, 152, 263, 154, 215, 216, 192, 117, 87, 19,
160968 /* 1210 */ 89, 19, 20, 92, 22, 22, 23, 231, 116, 230,
160969 /* 1220 */ 263, 263, 237, 203, 298, 299, 203, 239, 36, 215,
160970 /* 1230 */ 216, 192, 142, 192, 15, 45, 115, 116, 117, 251,
160971 /* 1240 */ 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
160972 /* 1250 */ 112, 59, 192, 203, 215, 216, 215, 216, 238, 239,
160973 /* 1260 */ 192, 238, 239, 71, 192, 144, 25, 203, 243, 230,
160974 /* 1270 */ 243, 251, 192, 81, 251, 215, 216, 243, 253, 60,
160975 /* 1280 */ 253, 255, 256, 19, 20, 25, 22, 253, 238, 239,
160976 /* 1290 */ 192, 192, 100, 192, 101, 215, 216, 19, 106, 107,
160977 /* 1300 */ 36, 251, 238, 239, 114, 113, 192, 115, 116, 117,
160978 /* 1310 */ 192, 47, 120, 215, 216, 251, 215, 216, 192, 31,
160979 /* 1320 */ 130, 134, 243, 59, 148, 149, 139, 39, 192, 137,
160980 /* 1330 */ 138, 263, 253, 215, 216, 71, 19, 157, 192, 159,
160981 /* 1340 */ 128, 215, 216, 25, 152, 153, 154, 155, 156, 85,
160982 /* 1350 */ 192, 215, 216, 268, 90, 0, 1, 2, 192, 192,
160983 /* 1360 */ 5, 215, 216, 151, 100, 10, 11, 12, 13, 14,
160984 /* 1370 */ 106, 107, 17, 215, 216, 19, 20, 113, 22, 115,
160985 /* 1380 */ 116, 117, 215, 216, 120, 30, 192, 32, 192, 148,
160986 /* 1390 */ 192, 24, 36, 115, 22, 40, 24, 23, 192, 25,
160987 /* 1400 */ 128, 23, 99, 25, 144, 192, 22, 192, 192, 215,
160988 /* 1410 */ 216, 215, 216, 215, 216, 59, 152, 153, 154, 155,
160989 /* 1420 */ 156, 215, 216, 151, 192, 70, 192, 71, 215, 216,
160990 /* 1430 */ 215, 216, 115, 78, 192, 132, 81, 192, 23, 22,
160991 /* 1440 */ 25, 85, 192, 192, 192, 61, 90, 215, 216, 215,
160992 /* 1450 */ 216, 192, 225, 98, 192, 192, 100, 215, 216, 141,
160993 /* 1460 */ 215, 216, 106, 107, 225, 215, 216, 215, 216, 113,
160994 /* 1470 */ 59, 115, 116, 117, 215, 216, 120, 215, 216, 192,
160995 /* 1480 */ 120, 192, 19, 20, 23, 22, 25, 132, 119, 120,
160996 /* 1490 */ 130, 192, 137, 138, 192, 23, 192, 25, 192, 36,
160997 /* 1500 */ 192, 192, 215, 216, 215, 216, 192, 140, 152, 153,
160998 /* 1510 */ 154, 155, 156, 192, 215, 216, 161, 215, 216, 215,
160999 /* 1520 */ 216, 192, 59, 215, 216, 19, 192, 116, 192, 215,
161000 /* 1530 */ 216, 23, 59, 25, 71, 192, 215, 216, 192, 23,
161001 /* 1540 */ 23, 25, 25, 192, 215, 216, 7, 8, 85, 215,
161002 /* 1550 */ 216, 215, 216, 90, 192, 1, 2, 140, 192, 5,
161003 /* 1560 */ 192, 215, 216, 100, 10, 11, 12, 13, 14, 106,
161004 /* 1570 */ 107, 17, 192, 23, 192, 25, 113, 192, 115, 116,
161005 /* 1580 */ 117, 215, 216, 120, 30, 59, 32, 19, 20, 116,
161006 /* 1590 */ 22, 192, 83, 84, 40, 215, 216, 215, 216, 192,
161007 /* 1600 */ 215, 216, 192, 97, 36, 192, 19, 20, 23, 22,
161008 /* 1610 */ 25, 23, 152, 25, 154, 152, 153, 154, 155, 156,
161009 /* 1620 */ 152, 225, 154, 36, 70, 215, 216, 59, 215, 216,
161010 /* 1630 */ 192, 23, 78, 25, 23, 81, 25, 192, 192, 71,
161011 /* 1640 */ 257, 192, 116, 192, 192, 254, 59, 317, 192, 192,
161012 /* 1650 */ 192, 235, 98, 241, 192, 254, 192, 192, 71, 192,
161013 /* 1660 */ 287, 192, 192, 286, 242, 190, 213, 296, 100, 266,
161014 /* 1670 */ 270, 244, 254, 254, 106, 107, 108, 254, 258, 258,
161015 /* 1680 */ 266, 113, 292, 115, 116, 117, 132, 100, 120, 245,
161016 /* 1690 */ 292, 137, 138, 106, 107, 19, 20, 219, 22, 270,
161017 /* 1700 */ 113, 270, 115, 116, 117, 270, 224, 120, 228, 218,
161018 /* 1710 */ 218, 245, 36, 218, 195, 161, 279, 258, 244, 248,
161019 /* 1720 */ 152, 153, 154, 155, 156, 248, 242, 244, 60, 296,
161020 /* 1730 */ 296, 140, 199, 199, 38, 59, 293, 199, 149, 152,
161021 /* 1740 */ 153, 154, 155, 156, 150, 5, 22, 71, 293, 43,
161022 /* 1750 */ 10, 11, 12, 13, 14, 269, 271, 17, 282, 18,
161023 /* 1760 */ 233, 236, 199, 18, 236, 236, 236, 198, 148, 245,
161024 /* 1770 */ 30, 271, 32, 271, 269, 233, 100, 245, 233, 199,
161025 /* 1780 */ 40, 245, 106, 107, 198, 245, 157, 289, 62, 113,
161026 /* 1790 */ 198, 115, 116, 117, 199, 288, 120, 22, 220, 199,
161027 /* 1800 */ 198, 220, 199, 198, 114, 226, 64, 217, 22, 125,
161028 /* 1810 */ 70, 164, 311, 217, 217, 217, 223, 24, 78, 304,
161029 /* 1820 */ 219, 81, 223, 217, 220, 112, 217, 217, 152, 153,
161030 /* 1830 */ 154, 155, 156, 226, 281, 220, 281, 143, 98, 114,
161031 /* 1840 */ 199, 91, 260, 259, 82, 147, 144, 316, 22, 276,
161032 /* 1850 */ 199, 316, 157, 278, 146, 145, 25, 201, 13, 193,
161033 /* 1860 */ 193, 6, 191, 191, 191, 299, 302, 302, 206, 246,
161034 /* 1870 */ 248, 259, 132, 260, 260, 259, 259, 137, 138, 260,
161035 /* 1880 */ 249, 249, 264, 247, 245, 264, 212, 212, 206, 212,
161036 /* 1890 */ 212, 221, 206, 213, 213, 212, 4, 3, 22, 162,
161037 /* 1900 */ 221, 161, 15, 23, 16, 23, 138, 150, 129, 25,
161038 /* 1910 */ 24, 141, 143, 20, 16, 1, 129, 141, 129, 61,
161039 /* 1920 */ 37, 150, 53, 53, 53, 53, 129, 115, 140, 34,
161040 /* 1930 */ 1, 5, 22, 114, 160, 68, 25, 75, 41, 140,
161041 /* 1940 */ 24, 68, 114, 20, 19, 130, 124, 23, 67, 22,
161042 /* 1950 */ 22, 148, 22, 22, 37, 59, 67, 24, 22, 96,
161043 /* 1960 */ 28, 23, 22, 97, 23, 23, 67, 23, 25, 23,
161044 /* 1970 */ 22, 115, 140, 23, 23, 22, 142, 25, 88, 34,
161045 /* 1980 */ 75, 34, 75, 34, 93, 23, 86, 22, 34, 34,
161046 /* 1990 */ 24, 34, 25, 25, 34, 23, 23, 23, 23, 23,
161047 /* 2000 */ 44, 23, 25, 22, 11, 22, 22, 25, 23, 23,
161048 /* 2010 */ 22, 22, 134, 23, 140, 140, 25, 140, 15, 140,
161049 /* 2020 */ 1, 1, 318, 318, 318, 318, 318, 318, 318, 318,
161050 /* 2030 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161051 /* 2040 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161052 /* 2050 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161053 /* 2060 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161054 /* 2070 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161055 /* 2080 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
@@ -159694,122 +161062,120 @@
161062 /* 2150 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161063 /* 2160 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161064 /* 2170 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161065 /* 2180 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161066 /* 2190 */ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
161067 /* 2200 */ 318, 318, 318, 318, 318, 318,
 
 
161068 };
161069 #define YY_SHIFT_COUNT (571)
161070 #define YY_SHIFT_MIN (0)
161071 #define YY_SHIFT_MAX (2020)
161072 static const unsigned short int yy_shift_ofst[] = {
161073 /* 0 */ 1554, 1355, 1740, 1192, 1192, 552, 1264, 1356, 1463, 1587,
161074 /* 10 */ 1587, 1587, 276, 0, 0, 180, 1015, 1587, 1587, 1587,
161075 /* 20 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161076 /* 30 */ 1049, 1049, 1121, 1121, 54, 667, 552, 552, 552, 552,
161077 /* 40 */ 552, 40, 110, 219, 289, 396, 439, 509, 548, 618,
161078 /* 50 */ 657, 727, 766, 836, 995, 1015, 1015, 1015, 1015, 1015,
161079 /* 60 */ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015,
161080 /* 70 */ 1015, 1015, 1015, 1035, 1015, 1138, 880, 880, 1568, 1587,
161081 /* 80 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161082 /* 90 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161083 /* 100 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587, 1587,
161084 /* 110 */ 1587, 1587, 1587, 1676, 1587, 1587, 1587, 1587, 1587, 1587,
161085 /* 120 */ 1587, 1587, 1587, 1587, 1587, 1587, 1587, 146, 84, 84,
161086 /* 130 */ 84, 84, 84, 277, 315, 401, 97, 461, 251, 531,
161087 /* 140 */ 531, 51, 1190, 531, 531, 324, 324, 531, 713, 713,
161088 /* 150 */ 713, 713, 151, 154, 154, 4, 149, 2022, 2022, 621,
161089 /* 160 */ 621, 621, 567, 398, 398, 398, 398, 937, 937, 228,
161090 /* 170 */ 251, 159, 331, 531, 531, 531, 531, 531, 531, 531,
161091 /* 180 */ 531, 531, 531, 531, 531, 531, 531, 531, 531, 531,
161092 /* 190 */ 531, 531, 531, 819, 819, 531, 9, 25, 25, 1102,
161093 /* 200 */ 1102, 911, 1032, 2022, 2022, 2022, 2022, 2022, 2022, 2022,
161094 /* 210 */ 255, 317, 317, 514, 403, 620, 471, 672, 781, 891,
161095 /* 220 */ 675, 531, 531, 531, 531, 531, 531, 531, 531, 531,
161096 /* 230 */ 531, 454, 531, 531, 531, 531, 531, 531, 531, 531,
161097 /* 240 */ 531, 531, 531, 531, 790, 790, 790, 531, 531, 531,
161098 /* 250 */ 338, 531, 531, 531, 516, 930, 531, 531, 993, 531,
161099 /* 260 */ 531, 531, 531, 531, 531, 531, 531, 778, 944, 725,
161100 /* 270 */ 994, 994, 994, 994, 1090, 725, 725, 1040, 1006, 951,
161101 /* 280 */ 1219, 962, 1176, 98, 1278, 1176, 1278, 1317, 1241, 962,
161102 /* 290 */ 962, 1241, 962, 98, 1317, 286, 1111, 1048, 1288, 1288,
161103 /* 300 */ 1288, 1278, 1260, 1260, 1180, 1318, 1187, 1372, 1668, 1668,
161104 /* 310 */ 1591, 1591, 1696, 1696, 1591, 1594, 1589, 1724, 1706, 1741,
161105 /* 320 */ 1741, 1741, 1741, 1591, 1745, 1620, 1589, 1589, 1620, 1724,
161106 /* 330 */ 1706, 1620, 1706, 1620, 1591, 1745, 1629, 1726, 1591, 1745,
161107 /* 340 */ 1775, 1591, 1745, 1591, 1745, 1775, 1690, 1690, 1690, 1742,
161108 /* 350 */ 1786, 1786, 1775, 1690, 1684, 1690, 1742, 1690, 1690, 1647,
161109 /* 360 */ 1793, 1713, 1713, 1775, 1694, 1725, 1694, 1725, 1694, 1725,
161110 /* 370 */ 1694, 1725, 1591, 1750, 1750, 1762, 1762, 1698, 1702, 1826,
161111 /* 380 */ 1591, 1695, 1698, 1708, 1710, 1620, 1831, 1845, 1845, 1855,
161112 /* 390 */ 1855, 1855, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022,
161113 /* 400 */ 2022, 2022, 2022, 2022, 2022, 2022, 2022, 578, 837, 655,
161114 /* 410 */ 1193, 167, 839, 1055, 1374, 1303, 1107, 1367, 1212, 1272,
161115 /* 420 */ 1378, 1384, 1415, 1461, 1472, 1508, 1516, 1517, 1411, 1369,
161116 /* 430 */ 1539, 1360, 1506, 1473, 1550, 1585, 1509, 1588, 1460, 1468,
161117 /* 440 */ 1608, 1611, 1526, 1417, 1892, 1894, 1876, 1737, 1887, 1888,
161118 /* 450 */ 1880, 1882, 1768, 1757, 1779, 1884, 1884, 1886, 1770, 1893,
161119 /* 460 */ 1769, 1898, 1914, 1776, 1787, 1884, 1789, 1858, 1883, 1884,
161120 /* 470 */ 1771, 1869, 1870, 1871, 1872, 1797, 1812, 1895, 1788, 1929,
161121 /* 480 */ 1926, 1910, 1819, 1774, 1867, 1911, 1873, 1862, 1897, 1799,
161122 /* 490 */ 1828, 1916, 1923, 1925, 1815, 1822, 1927, 1881, 1928, 1930,
161123 /* 500 */ 1924, 1931, 1889, 1896, 1933, 1863, 1932, 1936, 1899, 1917,
161124 /* 510 */ 1938, 1803, 1940, 1941, 1942, 1944, 1943, 1946, 1948, 1866,
161125 /* 520 */ 1832, 1950, 1951, 1856, 1945, 1953, 1834, 1952, 1947, 1949,
161126 /* 530 */ 1954, 1955, 1890, 1905, 1900, 1956, 1907, 1891, 1957, 1962,
161127 /* 540 */ 1965, 1966, 1967, 1968, 1960, 1972, 1952, 1973, 1974, 1975,
161128 /* 550 */ 1976, 1977, 1978, 1981, 1993, 1983, 1984, 1985, 1986, 1988,
161129 /* 560 */ 1989, 1982, 1878, 1874, 1875, 1877, 1879, 1991, 1990, 2003,
161130 /* 570 */ 2019, 2020,
161131 };
161132 #define YY_REDUCE_COUNT (406)
161133 #define YY_REDUCE_MIN (-272)
161134 #define YY_REDUCE_MAX (1686)
161135 static const short yy_reduce_ofst[] = {
161136 /* 0 */ 109, 113, 272, 760, -178, -176, -192, -183, -180, -134,
161137 /* 10 */ 213, 220, 371, -208, -205, -272, -197, 611, 632, 765,
161138 /* 20 */ 786, 392, 943, 989, 503, 651, 1039, -18, 702, 821,
161139 /* 30 */ 710, 812, -188, -67, -187, 555, 662, 1020, 1023, 1050,
161140 /* 40 */ 1064, -267, -267, -267, -267, -267, -267, -267, -267, -267,
161141 /* 50 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267,
161142 /* 60 */ -267, -267, -267, -267, -267, -267, -267, -267, -267, -267,
161143 /* 70 */ -267, -267, -267, -267, -267, -267, -267, -267, 811, 917,
161144 /* 80 */ 936, 938, 983, 1014, 1041, 1060, 1080, 1098, 1101, 1118,
161145 /* 90 */ 1126, 1136, 1146, 1158, 1167, 1194, 1196, 1198, 1206, 1213,
161146 /* 100 */ 1215, 1232, 1234, 1242, 1245, 1250, 1252, 1259, 1262, 1287,
161147 /* 110 */ 1289, 1299, 1302, 1304, 1308, 1314, 1321, 1329, 1334, 1336,
161148 /* 120 */ 1346, 1366, 1380, 1382, 1385, 1410, 1413, -267, -267, -267,
161149 /* 130 */ -267, -267, -267, -267, -267, 446, -267, 451, -24, 121,
161150 /* 140 */ 560, 518, 232, 609, 330, -181, -111, 654, 557, 671,
161151 /* 150 */ 557, 671, 882, -30, 93, -267, -267, -267, -267, 155,
161152 /* 160 */ 155, 155, 181, 242, 305, 339, 561, -218, 453, 227,
161153 /* 170 */ 158, 661, 661, -171, 114, 327, 653, -166, 275, 605,
161154 /* 180 */ 615, 337, 833, 665, 939, 957, 825, 958, 985, 501,
161155 /* 190 */ 986, 378, 1068, 384, 643, 393, 741, 660, 888, 762,
161156 /* 200 */ 822, 229, 988, 926, 504, 1025, 1027, 1034, 1026, 1079,
161157 /* 210 */ -204, -174, -151, 18, 130, 198, 226, 376, 391, 442,
161158 /* 220 */ 457, 493, 607, 715, 779, 782, 840, 865, 1072, 1099,
161159 /* 230 */ 1114, 1085, 1166, 1216, 1251, 1263, 1306, 1309, 1343, 1351,
161160 /* 240 */ 1362, 1368, 1399, 1407, 1227, 1239, 1396, 1438, 1445, 1446,
161161 /* 250 */ 1383, 1449, 1451, 1452, 1391, 1330, 1456, 1457, 1416, 1458,
161162 /* 260 */ 226, 1462, 1464, 1465, 1467, 1469, 1470, 1373, 1377, 1412,
161163 /* 270 */ 1401, 1418, 1419, 1423, 1383, 1412, 1412, 1422, 1453, 1475,
161164 /* 280 */ 1371, 1400, 1403, 1427, 1420, 1414, 1421, 1390, 1444, 1429,
161165 /* 290 */ 1431, 1466, 1435, 1474, 1398, 1478, 1480, 1482, 1491, 1492,
161166 /* 300 */ 1495, 1459, 1471, 1477, 1437, 1483, 1484, 1519, 1433, 1434,
161167 /* 310 */ 1533, 1534, 1443, 1455, 1538, 1476, 1485, 1486, 1527, 1525,
161168 /* 320 */ 1528, 1529, 1530, 1563, 1569, 1524, 1500, 1502, 1532, 1505,
161169 /* 330 */ 1542, 1536, 1545, 1540, 1580, 1586, 1498, 1507, 1595, 1592,
161170 /* 340 */ 1578, 1600, 1602, 1603, 1605, 1581, 1590, 1596, 1597, 1579,
161171 /* 350 */ 1593, 1599, 1604, 1598, 1601, 1606, 1607, 1609, 1610, 1501,
161172 /* 360 */ 1515, 1553, 1555, 1615, 1582, 1584, 1613, 1612, 1614, 1616,
161173 /* 370 */ 1619, 1617, 1641, 1531, 1535, 1618, 1621, 1631, 1622, 1573,
161174 /* 380 */ 1651, 1575, 1632, 1636, 1623, 1639, 1656, 1666, 1667, 1671,
161175 /* 390 */ 1672, 1673, 1564, 1565, 1566, 1662, 1674, 1675, 1677, 1678,
161176 /* 400 */ 1682, 1670, 1679, 1680, 1681, 1683, 1686,
161177 };
161178 static const YYACTIONTYPE yy_default[] = {
161179 /* 0 */ 1633, 1633, 1633, 1462, 1230, 1341, 1230, 1230, 1230, 1462,
161180 /* 10 */ 1462, 1462, 1230, 1371, 1371, 1515, 1263, 1230, 1230, 1230,
161181 /* 20 */ 1230, 1230, 1230, 1230, 1230, 1230, 1230, 1461, 1230, 1230,
@@ -159930,14 +161296,14 @@
161296 59, /* DETACH => ID */
161297 59, /* EACH => ID */
161298 59, /* FAIL => ID */
161299 0, /* OR => nothing */
161300 0, /* AND => nothing */
 
161301 59, /* MATCH => ID */
161302 59, /* LIKE_KW => ID */
161303 0, /* BETWEEN => nothing */
161304 0, /* IS => nothing */
161305 0, /* IN => nothing */
161306 0, /* ISNULL => nothing */
161307 0, /* NOTNULL => nothing */
161308 0, /* NE => nothing */
161309 0, /* EQ => nothing */
@@ -160120,13 +161486,13 @@
161486 yyStackEntry *yystackEnd; /* Last entry in the stack */
161487 #endif
161488 };
161489 typedef struct yyParser yyParser;
161490
161491 /* #include <assert.h> */
161492 #ifndef NDEBUG
161493 /* #include <stdio.h> */
 
161494 static FILE *yyTraceFILE = 0;
161495 static char *yyTracePrompt = 0;
161496 #endif /* NDEBUG */
161497
161498 #ifndef NDEBUG
@@ -160202,14 +161568,14 @@
161568 /* 40 */ "DETACH",
161569 /* 41 */ "EACH",
161570 /* 42 */ "FAIL",
161571 /* 43 */ "OR",
161572 /* 44 */ "AND",
161573 /* 45 */ "MATCH",
161574 /* 46 */ "LIKE_KW",
161575 /* 47 */ "BETWEEN",
161576 /* 48 */ "IS",
161577 /* 49 */ "IN",
161578 /* 50 */ "ISNULL",
161579 /* 51 */ "NOTNULL",
161580 /* 52 */ "NE",
161581 /* 53 */ "EQ",
@@ -163871,12 +165237,12 @@
165237 assert( yypParser->yytos>=yypParser->yystack );
165238 assert( yyact==yypParser->yytos->stateno );
165239 yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
165240 if( yyact >= YY_MIN_REDUCE ){
165241 unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
 
165242 #ifndef NDEBUG
165243 assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
165244 if( yyTraceFILE ){
165245 int yysize = yyRuleInfoNRhs[yyruleno];
165246 if( yysize ){
165247 fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
165248 yyTracePrompt,
@@ -165119,10 +166485,11 @@
166485 int n = 0; /* Length of the next token token */
166486 int tokenType; /* type of the next token */
166487 int lastTokenParsed = -1; /* type of the previous token */
166488 sqlite3 *db = pParse->db; /* The database connection */
166489 int mxSqlLen; /* Max length of an SQL string */
166490 Parse *pParentParse = 0; /* Outer parse context, if any */
166491 #ifdef sqlite3Parser_ENGINEALWAYSONSTACK
166492 yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
166493 #endif
166494 VVA_ONLY( u8 startedWithOom = db->mallocFailed );
166495
@@ -165154,11 +166521,11 @@
166521 #endif
166522 assert( pParse->pNewTable==0 );
166523 assert( pParse->pNewTrigger==0 );
166524 assert( pParse->nVar==0 );
166525 assert( pParse->pVList==0 );
166526 pParentParse = db->pParse;
166527 db->pParse = pParse;
166528 while( 1 ){
166529 n = sqlite3GetToken((u8*)zSql, &tokenType);
166530 mxSqlLen -= n;
166531 if( mxSqlLen<0 ){
@@ -165269,12 +166636,11 @@
166636 }
166637 if( !IN_RENAME_OBJECT ){
166638 sqlite3DeleteTrigger(db, pParse->pNewTrigger);
166639 }
166640 sqlite3DbFree(db, pParse->pVList);
166641 db->pParse = pParentParse;
 
166642 assert( nErr==0 || pParse->rc!=SQLITE_OK );
166643 return nErr;
166644 }
166645
166646
@@ -166939,11 +168305,13 @@
168305 ** if this is not the last copy of the function, do not invoke it. Multiple
168306 ** copies of a single function are created when create_function() is called
168307 ** with SQLITE_ANY as the encoding.
168308 */
168309 static void functionDestroy(sqlite3 *db, FuncDef *p){
168310 FuncDestructor *pDestructor;
168311 assert( (p->funcFlags & SQLITE_FUNC_BUILTIN)==0 );
168312 pDestructor = p->u.pDestructor;
168313 if( pDestructor ){
168314 pDestructor->nRef--;
168315 if( pDestructor->nRef==0 ){
168316 pDestructor->xDestroy(pDestructor->pUserData);
168317 sqlite3DbFree(db, pDestructor);
@@ -167202,10 +168570,13 @@
168570 ** So it needs to be freed here. Todo: Why not roll the temp schema into
168571 ** the same sqliteMalloc() as the one that allocates the database
168572 ** structure?
168573 */
168574 sqlite3DbFree(db, db->aDb[1].pSchema);
168575 if( db->xAutovacDestr ){
168576 db->xAutovacDestr(db->pAutovacPagesArg);
168577 }
168578 sqlite3_mutex_leave(db->mutex);
168579 db->eOpenState = SQLITE_STATE_CLOSED;
168580 sqlite3_mutex_free(db->mutex);
168581 assert( sqlite3LookasideUsed(db,0)==0 );
168582 if( db->lookaside.bMalloced ){
@@ -167256,11 +168627,11 @@
168627 sqlite3BtreeLeaveAll(db);
168628
168629 /* Any deferred constraint violations have now been resolved. */
168630 db->nDeferredCons = 0;
168631 db->nDeferredImmCons = 0;
168632 db->flags &= ~(u64)(SQLITE_DeferFKs|SQLITE_CorruptRdOnly);
168633
168634 /* If one has been configured, invoke the rollback-hook callback */
168635 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
168636 db->xRollbackCallback(db->pRollbackArg);
168637 }
@@ -167620,21 +168991,20 @@
168991 void (*xValue)(sqlite3_context*),
168992 void (*xInverse)(sqlite3_context*,int,sqlite3_value **),
168993 FuncDestructor *pDestructor
168994 ){
168995 FuncDef *p;
 
168996 int extraFlags;
168997
168998 assert( sqlite3_mutex_held(db->mutex) );
168999 assert( xValue==0 || xSFunc==0 );
169000 if( zFunctionName==0 /* Must have a valid name */
169001 || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */
169002 || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */
169003 || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */
169004 || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG)
169005 || (255<sqlite3Strlen30(zFunctionName))
169006 ){
169007 return SQLITE_MISUSE_BKPT;
169008 }
169009
169010 assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC );
@@ -168103,10 +169473,38 @@
169473 db->pPreUpdateArg = pArg;
169474 sqlite3_mutex_leave(db->mutex);
169475 return pRet;
169476 }
169477 #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
169478
169479 /*
169480 ** Register a function to be invoked prior to each autovacuum that
169481 ** determines the number of pages to vacuum.
169482 */
169483 SQLITE_API int sqlite3_autovacuum_pages(
169484 sqlite3 *db, /* Attach the hook to this database */
169485 unsigned int (*xCallback)(void*,const char*,u32,u32,u32),
169486 void *pArg, /* Argument to the function */
169487 void (*xDestructor)(void*) /* Destructor for pArg */
169488 ){
169489 #ifdef SQLITE_ENABLE_API_ARMOR
169490 if( !sqlite3SafetyCheckOk(db) ){
169491 if( xDestructor ) xDestructor(pArg);
169492 return SQLITE_MISUSE_BKPT;
169493 }
169494 #endif
169495 sqlite3_mutex_enter(db->mutex);
169496 if( db->xAutovacDestr ){
169497 db->xAutovacDestr(db->pAutovacPagesArg);
169498 }
169499 db->xAutovacPages = xCallback;
169500 db->pAutovacPagesArg = pArg;
169501 db->xAutovacDestr = xDestructor;
169502 sqlite3_mutex_leave(db->mutex);
169503 return SQLITE_OK;
169504 }
169505
169506
169507 #ifndef SQLITE_OMIT_WAL
169508 /*
169509 ** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint().
169510 ** Invoke sqlite3_wal_checkpoint if the number of frames in the log file
@@ -168626,10 +170024,12 @@
170024 }
170025 oldLimit = db->aLimit[limitId];
170026 if( newLimit>=0 ){ /* IMP: R-52476-28732 */
170027 if( newLimit>aHardLimit[limitId] ){
170028 newLimit = aHardLimit[limitId]; /* IMP: R-51463-25634 */
170029 }else if( newLimit<1 && limitId==SQLITE_LIMIT_LENGTH ){
170030 newLimit = 1;
170031 }
170032 db->aLimit[limitId] = newLimit;
170033 }
170034 return oldLimit; /* IMP: R-53341-35419 */
170035 }
@@ -168897,11 +170297,11 @@
170297 ** This routine does the core work of extracting URI parameters from a
170298 ** database filename for the sqlite3_uri_parameter() interface.
170299 */
170300 static const char *uriParameter(const char *zFilename, const char *zParam){
170301 zFilename += sqlite3Strlen30(zFilename) + 1;
170302 while( ALWAYS(zFilename!=0) && zFilename[0] ){
170303 int x = strcmp(zFilename, zParam);
170304 zFilename += sqlite3Strlen30(zFilename) + 1;
170305 if( x==0 ) return zFilename;
170306 zFilename += sqlite3Strlen30(zFilename) + 1;
170307 }
@@ -168957,14 +170357,15 @@
170357 **
170358 ** The SQLITE_OPEN_NOMUTEX and SQLITE_OPEN_FULLMUTEX flags were
170359 ** dealt with in the previous code block. Besides these, the only
170360 ** valid input flags for sqlite3_open_v2() are SQLITE_OPEN_READONLY,
170361 ** SQLITE_OPEN_READWRITE, SQLITE_OPEN_CREATE, SQLITE_OPEN_SHAREDCACHE,
170362 ** SQLITE_OPEN_PRIVATECACHE, SQLITE_OPEN_EXRESCODE, and some reserved
170363 ** bits. Silently mask off all other flags.
170364 */
170365 flags &= ~( SQLITE_OPEN_DELETEONCLOSE |
170366 SQLITE_OPEN_EXCLUSIVE |
170367 SQLITE_OPEN_MAIN_DB |
170368 SQLITE_OPEN_TEMP_DB |
170369 SQLITE_OPEN_TRANSIENT_DB |
170370 SQLITE_OPEN_MAIN_JOURNAL |
170371 SQLITE_OPEN_TEMP_JOURNAL |
@@ -168992,11 +170393,11 @@
170393 if( isThreadsafe==0 ){
170394 sqlite3MutexWarnOnContention(db->mutex);
170395 }
170396 }
170397 sqlite3_mutex_enter(db->mutex);
170398 db->errMask = (flags & SQLITE_OPEN_EXRESCODE)!=0 ? 0xffffffff : 0xff;
170399 db->nDb = 2;
170400 db->eOpenState = SQLITE_STATE_BUSY;
170401 db->aDb = db->aDbStatic;
170402 db->lookaside.bDisable = 1;
170403 db->lookaside.sz = 0;
@@ -169224,12 +170625,12 @@
170625 assert( db->mutex!=0 || isThreadsafe==0
170626 || sqlite3GlobalConfig.bFullMutex==0 );
170627 sqlite3_mutex_leave(db->mutex);
170628 }
170629 rc = sqlite3_errcode(db);
170630 assert( db!=0 || (rc&0xff)==SQLITE_NOMEM );
170631 if( (rc&0xff)==SQLITE_NOMEM ){
170632 sqlite3_close(db);
170633 db = 0;
170634 }else if( rc!=SQLITE_OK ){
170635 db->eOpenState = SQLITE_STATE_SICK;
170636 }
@@ -169240,11 +170641,11 @@
170641 void *pArg = sqlite3GlobalConfig.pSqllogArg;
170642 sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0);
170643 }
170644 #endif
170645 sqlite3_free_filename(zOpen);
170646 return rc;
170647 }
170648
170649
170650 /*
170651 ** Open a new database handle.
@@ -170028,16 +171429,20 @@
171429 ** the schema to be reparsed the next time it is needed. This has the
171430 ** effect of erasing all imposter tables.
171431 */
171432 case SQLITE_TESTCTRL_IMPOSTER: {
171433 sqlite3 *db = va_arg(ap, sqlite3*);
171434 int iDb;
171435 sqlite3_mutex_enter(db->mutex);
171436 iDb = sqlite3FindDbName(db, va_arg(ap,const char*));
171437 if( iDb>=0 ){
171438 db->init.iDb = iDb;
171439 db->init.busy = db->init.imposterTable = va_arg(ap,int);
171440 db->init.newTnum = va_arg(ap,int);
171441 if( db->init.busy==0 && db->init.newTnum>0 ){
171442 sqlite3ResetAllSchemasOfConnection(db);
171443 }
171444 }
171445 sqlite3_mutex_leave(db->mutex);
171446 break;
171447 }
171448
@@ -170108,10 +171513,30 @@
171513 case 2: *ptr = sqlite3WhereTrace; break;
171514 case 3: sqlite3WhereTrace = *ptr; break;
171515 }
171516 break;
171517 }
171518
171519 /* sqlite3_test_control(SQLITE_TESTCTRL_LOGEST,
171520 ** double fIn, // Input value
171521 ** int *pLogEst, // sqlite3LogEstFromDouble(fIn)
171522 ** u64 *pInt, // sqlite3LogEstToInt(*pLogEst)
171523 ** int *pLogEst2 // sqlite3LogEst(*pInt)
171524 ** );
171525 **
171526 ** Test access for the LogEst conversion routines.
171527 */
171528 case SQLITE_TESTCTRL_LOGEST: {
171529 double rIn = va_arg(ap, double);
171530 LogEst rLogEst = sqlite3LogEstFromDouble(rIn);
171531 u64 iInt = sqlite3LogEstToInt(rLogEst);
171532 va_arg(ap, int*)[0] = rLogEst;
171533 va_arg(ap, u64*)[0] = iInt;
171534 va_arg(ap, int*)[0] = sqlite3LogEst(iInt);
171535 break;
171536 }
171537
171538
171539 #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD)
171540 /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue)
171541 **
171542 ** If "id" is an integer between 1 and SQLITE_NTUNE then set the value
@@ -170245,11 +171670,11 @@
171670 */
171671 SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){
171672 if( zFilename==0 || N<0 ) return 0;
171673 zFilename = databaseName(zFilename);
171674 zFilename += sqlite3Strlen30(zFilename) + 1;
171675 while( ALWAYS(zFilename) && zFilename[0] && (N--)>0 ){
171676 zFilename += sqlite3Strlen30(zFilename) + 1;
171677 zFilename += sqlite3Strlen30(zFilename) + 1;
171678 }
171679 return zFilename[0] ? zFilename : 0;
171680 }
@@ -170295,11 +171720,11 @@
171720 }
171721 SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){
171722 if( zFilename==0 ) return 0;
171723 zFilename = databaseName(zFilename);
171724 zFilename += sqlite3Strlen30(zFilename) + 1;
171725 while( ALWAYS(zFilename) && zFilename[0] ){
171726 zFilename += sqlite3Strlen30(zFilename) + 1;
171727 zFilename += sqlite3Strlen30(zFilename) + 1;
171728 }
171729 return zFilename + 1;
171730 }
@@ -171599,21 +173024,22 @@
173024 #ifndef SQLITE_AMALGAMATION
173025 /*
173026 ** Macros indicating that conditional expressions are always true or
173027 ** false.
173028 */
173029 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
173030 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
173031 #endif
173032 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
173033 # define ALWAYS(X) (1)
173034 # define NEVER(X) (0)
173035 #elif !defined(NDEBUG)
173036 # define ALWAYS(X) ((X)?1:(assert(0),0))
173037 # define NEVER(X) ((X)?(assert(0),1):0)
173038 #else
173039 # define ALWAYS(X) (X)
173040 # define NEVER(X) (X)
173041 #endif
173042
173043 /*
173044 ** Internal types used by SQLite.
173045 */
@@ -172068,10 +173494,11 @@
173494 SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
173495 #ifdef SQLITE_TEST
173496 SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
173497 SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
173498 #endif
173499 SQLITE_PRIVATE void *sqlite3Fts3MallocZero(i64 nByte);
173500
173501 SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
173502 sqlite3_tokenizer_cursor **
173503 );
173504
@@ -172125,17 +173552,10 @@
173552 static int fts3EvalNext(Fts3Cursor *pCsr);
173553 static int fts3EvalStart(Fts3Cursor *pCsr);
173554 static int fts3TermSegReaderCursor(
173555 Fts3Cursor *, const char *, int, int, Fts3MultiSegReader **);
173556
 
 
 
 
 
 
 
173557 /*
173558 ** This variable is set to false when running tests for which the on disk
173559 ** structures should not be corrupt. Otherwise, true. If it is false, extra
173560 ** assert() conditions in the fts3 code are activated - conditions that are
173561 ** only true if it is guaranteed that the fts3 database is not corrupt.
@@ -177156,12 +178576,12 @@
178576 case FTSQUERY_OR: {
178577 Fts3Expr *pLeft = pExpr->pLeft;
178578 Fts3Expr *pRight = pExpr->pRight;
178579 sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid);
178580
178581 assert_fts3_nc( pLeft->bStart || pLeft->iDocid==pRight->iDocid );
178582 assert_fts3_nc( pRight->bStart || pLeft->iDocid==pRight->iDocid );
178583
178584 if( pRight->bEof || (pLeft->bEof==0 && iCmp<0) ){
178585 fts3EvalNextRow(pCsr, pLeft, pRc);
178586 }else if( pLeft->bEof || iCmp>0 ){
178587 fts3EvalNextRow(pCsr, pRight, pRc);
@@ -177795,10 +179215,13 @@
179215 while( rc==SQLITE_OK && !pNear->bEof ){
179216 fts3EvalNextRow(pCsr, pNear, &rc);
179217 if( bEofSave==0 && pNear->iDocid==iDocid ) break;
179218 }
179219 assert( rc!=SQLITE_OK || pPhrase->bIncr==0 );
179220 if( rc==SQLITE_OK && pNear->bEof!=bEofSave ){
179221 rc = FTS_CORRUPT_VTAB;
179222 }
179223 }
179224 if( bTreeEof ){
179225 while( rc==SQLITE_OK && !pNear->bEof ){
179226 fts3EvalNextRow(pCsr, pNear, &rc);
179227 }
@@ -178217,10 +179640,11 @@
179640 }
179641
179642 if( fts3auxGrowStatArray(pCsr, 2) ) return SQLITE_NOMEM;
179643 memset(pCsr->aStat, 0, sizeof(struct Fts3auxColstats) * pCsr->nStat);
179644 iCol = 0;
179645 rc = SQLITE_OK;
179646
179647 while( i<nDoclist ){
179648 sqlite3_int64 v = 0;
179649
179650 i += sqlite3Fts3GetVarint(&aDoclist[i], &v);
@@ -178260,19 +179684,22 @@
179684 break;
179685
179686 /* State 3. The integer just read is a column number. */
179687 default: assert( eState==3 );
179688 iCol = (int)v;
179689 if( iCol<1 ){
179690 rc = SQLITE_CORRUPT_VTAB;
179691 break;
179692 }
179693 if( fts3auxGrowStatArray(pCsr, iCol+2) ) return SQLITE_NOMEM;
179694 pCsr->aStat[iCol+1].nDoc++;
179695 eState = 2;
179696 break;
179697 }
179698 }
179699
179700 pCsr->iCol = 0;
 
179701 }else{
179702 pCsr->isEof = 1;
179703 }
179704 return rc;
179705 }
@@ -178597,11 +180024,11 @@
180024 /*
180025 ** Allocate nByte bytes of memory using sqlite3_malloc(). If successful,
180026 ** zero the memory before returning a pointer to it. If unsuccessful,
180027 ** return NULL.
180028 */
180029 SQLITE_PRIVATE void *sqlite3Fts3MallocZero(sqlite3_int64 nByte){
180030 void *pRet = sqlite3_malloc64(nByte);
180031 if( pRet ) memset(pRet, 0, nByte);
180032 return pRet;
180033 }
180034
@@ -178678,11 +180105,11 @@
180105 sqlite3_int64 nByte; /* total space to allocate */
180106
180107 rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition);
180108 if( rc==SQLITE_OK ){
180109 nByte = sizeof(Fts3Expr) + sizeof(Fts3Phrase) + nToken;
180110 pRet = (Fts3Expr *)sqlite3Fts3MallocZero(nByte);
180111 if( !pRet ){
180112 rc = SQLITE_NOMEM;
180113 }else{
180114 pRet->eType = FTSQUERY_PHRASE;
180115 pRet->pPhrase = (Fts3Phrase *)&pRet[1];
@@ -178933,11 +180360,11 @@
180360 */
180361 cNext = zInput[nKey];
180362 if( fts3isspace(cNext)
180363 || cNext=='"' || cNext=='(' || cNext==')' || cNext==0
180364 ){
180365 pRet = (Fts3Expr *)sqlite3Fts3MallocZero(sizeof(Fts3Expr));
180366 if( !pRet ){
180367 return SQLITE_NOMEM;
180368 }
180369 pRet->eType = pKey->eType;
180370 pRet->nNear = nNear;
@@ -179112,11 +180539,11 @@
180539
180540 if( !sqlite3_fts3_enable_parentheses
180541 && p->eType==FTSQUERY_PHRASE && pParse->isNot
180542 ){
180543 /* Create an implicit NOT operator. */
180544 Fts3Expr *pNot = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
180545 if( !pNot ){
180546 sqlite3Fts3ExprFree(p);
180547 rc = SQLITE_NOMEM;
180548 goto exprparse_out;
180549 }
@@ -179146,11 +180573,11 @@
180573
180574 if( isPhrase && !isRequirePhrase ){
180575 /* Insert an implicit AND operator. */
180576 Fts3Expr *pAnd;
180577 assert( pRet && pPrev );
180578 pAnd = sqlite3Fts3MallocZero(sizeof(Fts3Expr));
180579 if( !pAnd ){
180580 sqlite3Fts3ExprFree(p);
180581 rc = SQLITE_NOMEM;
180582 goto exprparse_out;
180583 }
@@ -183376,12 +184803,22 @@
184803 pReader->aNode = 0;
184804 if( pElem ){
184805 char *aCopy;
184806 PendingList *pList = (PendingList *)fts3HashData(pElem);
184807 int nCopy = pList->nData+1;
184808
184809 int nTerm = fts3HashKeysize(pElem);
184810 if( (nTerm+1)>pReader->nTermAlloc ){
184811 sqlite3_free(pReader->zTerm);
184812 pReader->zTerm = (char*)sqlite3_malloc((nTerm+1)*2);
184813 if( !pReader->zTerm ) return SQLITE_NOMEM;
184814 pReader->nTermAlloc = (nTerm+1)*2;
184815 }
184816 memcpy(pReader->zTerm, fts3HashKey(pElem), nTerm);
184817 pReader->zTerm[nTerm] = '\0';
184818 pReader->nTerm = nTerm;
184819
184820 aCopy = (char*)sqlite3_malloc(nCopy);
184821 if( !aCopy ) return SQLITE_NOMEM;
184822 memcpy(aCopy, pList->aData, nCopy);
184823 pReader->nNode = pReader->nDoclist = nCopy;
184824 pReader->aNode = pReader->aDoclist = aCopy;
@@ -183630,13 +185067,11 @@
185067 ** Free all allocations associated with the iterator passed as the
185068 ** second argument.
185069 */
185070 SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
185071 if( pReader ){
185072 sqlite3_free(pReader->zTerm);
 
 
185073 if( !fts3SegReaderIsRootOnly(pReader) ){
185074 sqlite3_free(pReader->aNode);
185075 }
185076 sqlite3_blob_close(pReader->pBlob);
185077 }
@@ -185824,11 +187259,11 @@
187259
187260 if( nPrefix>p->term.n || nSuffix>p->nNode-p->iOff || nSuffix==0 ){
187261 return FTS_CORRUPT_VTAB;
187262 }
187263 blobGrowBuffer(&p->term, nPrefix+nSuffix, &rc);
187264 if( rc==SQLITE_OK && ALWAYS(p->term.a!=0) ){
187265 memcpy(&p->term.a[nPrefix], &p->aNode[p->iOff], nSuffix);
187266 p->term.n = nPrefix+nSuffix;
187267 p->iOff += nSuffix;
187268 if( p->iChild==0 ){
187269 p->iOff += fts3GetVarint32(&p->aNode[p->iOff], &p->nDoclist);
@@ -186218,11 +187653,15 @@
187653 const char *zRhs, int nRhs /* RHS of comparison */
187654 ){
187655 int nCmp = MIN(nLhs, nRhs);
187656 int res;
187657
187658 if( nCmp && ALWAYS(zLhs) && ALWAYS(zRhs) ){
187659 res = memcmp(zLhs, zRhs, nCmp);
187660 }else{
187661 res = 0;
187662 }
187663 if( res==0 ) res = nLhs - nRhs;
187664
187665 return res;
187666 }
187667
@@ -186862,11 +188301,11 @@
188301 const char *aHint = sqlite3_column_blob(pSelect, 0);
188302 int nHint = sqlite3_column_bytes(pSelect, 0);
188303 if( aHint ){
188304 blobGrowBuffer(pHint, nHint, &rc);
188305 if( rc==SQLITE_OK ){
188306 if( ALWAYS(pHint->a!=0) ) memcpy(pHint->a, aHint, nHint);
188307 pHint->n = nHint;
188308 }
188309 }
188310 }
188311 rc2 = sqlite3_reset(pSelect);
@@ -187979,13 +189418,12 @@
189418 MatchinfoBuffer *pRet;
189419 sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
189420 + sizeof(MatchinfoBuffer);
189421 sqlite3_int64 nStr = strlen(zMatchinfo);
189422
189423 pRet = sqlite3Fts3MallocZero(nByte + nStr+1);
189424 if( pRet ){
 
189425 pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
189426 pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
189427 + sizeof(u32)*((int)nElem+1);
189428 pRet->nElem = (int)nElem;
189429 pRet->zMatchinfo = ((char*)pRet) + nByte;
@@ -188385,15 +189823,14 @@
189823
189824 /* Now that it is known how many phrases there are, allocate and zero
189825 ** the required space using malloc().
189826 */
189827 nByte = sizeof(SnippetPhrase) * nList;
189828 sIter.aPhrase = (SnippetPhrase *)sqlite3Fts3MallocZero(nByte);
189829 if( !sIter.aPhrase ){
189830 return SQLITE_NOMEM;
189831 }
 
189832
189833 /* Initialize the contents of the SnippetIter object. Then iterate through
189834 ** the set of phrases in the expression to populate the aPhrase[] array.
189835 */
189836 sIter.pCsr = pCsr;
@@ -188953,14 +190390,16 @@
190390 ** Advance the iterator passed as an argument to the next position. Return
190391 ** 1 if the iterator is at EOF or if it now points to the start of the
190392 ** position list for the next column.
190393 */
190394 static int fts3LcsIteratorAdvance(LcsIterator *pIter){
190395 char *pRead;
190396 sqlite3_int64 iRead;
190397 int rc = 0;
190398
190399 if( NEVER(pIter==0) ) return 1;
190400 pRead = pIter->pRead;
190401 pRead += sqlite3Fts3GetVarint(pRead, &iRead);
190402 if( iRead==0 || iRead==1 ){
190403 pRead = 0;
190404 rc = 1;
190405 }else{
@@ -188990,13 +190429,12 @@
190429 int rc = SQLITE_OK;
190430
190431 /* Allocate and populate the array of LcsIterator objects. The array
190432 ** contains one element for each matchable phrase in the query.
190433 **/
190434 aIter = sqlite3Fts3MallocZero(sizeof(LcsIterator) * pCsr->nPhrase);
190435 if( !aIter ) return SQLITE_NOMEM;
 
190436 (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter);
190437
190438 for(i=0; i<pInfo->nPhrase; i++){
190439 LcsIterator *pIter = &aIter[i];
190440 nToken -= pIter->pExpr->pPhrase->nToken;
@@ -189453,11 +190891,11 @@
190891 /* Count the number of terms in the query */
190892 rc = fts3ExprLoadDoclists(pCsr, 0, &nToken);
190893 if( rc!=SQLITE_OK ) goto offsets_out;
190894
190895 /* Allocate the array of TermOffset iterators. */
190896 sCtx.aTerm = (TermOffset *)sqlite3Fts3MallocZero(sizeof(TermOffset)*nToken);
190897 if( 0==sCtx.aTerm ){
190898 rc = SQLITE_NOMEM;
190899 goto offsets_out;
190900 }
190901 sCtx.iDocid = pCsr->iPrevId;
@@ -189474,17 +190912,17 @@
190912 int iEnd = 0;
190913 int iCurrent = 0;
190914 const char *zDoc;
190915 int nDoc;
190916
190917 /* Initialize the contents of sCtx.aTerm[] for column iCol. This
190918 ** operation may fail if the database contains corrupt records.
 
190919 */
190920 sCtx.iCol = iCol;
190921 sCtx.iTerm = 0;
190922 rc = fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
190923 if( rc!=SQLITE_OK ) goto offsets_out;
190924
190925 /* Retreive the text stored in column iCol. If an SQL NULL is stored
190926 ** in column iCol, jump immediately to the next iteration of the loop.
190927 ** If an OOM occurs while retrieving the data (this can happen if SQLite
190928 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -190478,11 +191916,38 @@
191916 ** but the definitions need to be repeated for separate compilation. */
191917 typedef sqlite3_uint64 u64;
191918 typedef unsigned int u32;
191919 typedef unsigned short int u16;
191920 typedef unsigned char u8;
191921 # if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
191922 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
191923 # endif
191924 # if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
191925 # define ALWAYS(X) (1)
191926 # define NEVER(X) (0)
191927 # elif !defined(NDEBUG)
191928 # define ALWAYS(X) ((X)?1:(assert(0),0))
191929 # define NEVER(X) ((X)?(assert(0),1):0)
191930 # else
191931 # define ALWAYS(X) (X)
191932 # define NEVER(X) (X)
191933 # endif
191934 # define testcase(X)
191935 #endif
191936 #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST)
191937 # define VVA(X)
191938 #else
191939 # define VVA(X) X
191940 #endif
191941
191942 /*
191943 ** Some of the testcase() macros in this file are problematic for gcov
191944 ** in that they generate false-miss errors randomly. This is a gcov problem,
191945 ** not a problem in this case. But to work around it, we disable the
191946 ** problematic test cases for production builds.
191947 */
191948 #define json_testcase(X)
191949
191950 /* Objects */
191951 typedef struct JsonString JsonString;
191952 typedef struct JsonNode JsonNode;
191953 typedef struct JsonParse JsonParse;
@@ -190536,17 +192001,18 @@
192001 /* A single node of parsed JSON
192002 */
192003 struct JsonNode {
192004 u8 eType; /* One of the JSON_ type values */
192005 u8 jnFlags; /* JNODE flags */
192006 u8 eU; /* Which union element to use */
192007 u32 n; /* Bytes of content, or number of sub-nodes */
192008 union {
192009 const char *zJContent; /* 1: Content for INT, REAL, and STRING */
192010 u32 iAppend; /* 2: More terms for ARRAY and OBJECT */
192011 u32 iKey; /* 3: Key for ARRAY objects in json_tree() */
192012 u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */
192013 JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */
192014 } u;
192015 };
192016
192017 /* A completely parsed JSON string
192018 */
@@ -190820,15 +192286,18 @@
192286 static void jsonRenderNode(
192287 JsonNode *pNode, /* The node to render */
192288 JsonString *pOut, /* Write JSON here */
192289 sqlite3_value **aReplace /* Replacement values */
192290 ){
192291 assert( pNode!=0 );
192292 if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){
192293 if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){
192294 assert( pNode->eU==4 );
192295 jsonAppendValue(pOut, aReplace[pNode->u.iReplace]);
192296 return;
192297 }
192298 assert( pNode->eU==5 );
192299 pNode = pNode->u.pPatch;
192300 }
192301 switch( pNode->eType ){
192302 default: {
192303 assert( pNode->eType==JSON_NULL );
@@ -190843,17 +192312,19 @@
192312 jsonAppendRaw(pOut, "false", 5);
192313 break;
192314 }
192315 case JSON_STRING: {
192316 if( pNode->jnFlags & JNODE_RAW ){
192317 assert( pNode->eU==1 );
192318 jsonAppendString(pOut, pNode->u.zJContent, pNode->n);
192319 break;
192320 }
192321 /* no break */ deliberate_fall_through
192322 }
192323 case JSON_REAL:
192324 case JSON_INT: {
192325 assert( pNode->eU==1 );
192326 jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n);
192327 break;
192328 }
192329 case JSON_ARRAY: {
192330 u32 j = 1;
@@ -190865,10 +192336,11 @@
192336 jsonRenderNode(&pNode[j], pOut, aReplace);
192337 }
192338 j += jsonNodeSize(&pNode[j]);
192339 }
192340 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
192341 assert( pNode->eU==2 );
192342 pNode = &pNode[pNode->u.iAppend];
192343 j = 1;
192344 }
192345 jsonAppendChar(pOut, ']');
192346 break;
@@ -190885,10 +192357,11 @@
192357 jsonRenderNode(&pNode[j+1], pOut, aReplace);
192358 }
192359 j += 1 + jsonNodeSize(&pNode[j+1]);
192360 }
192361 if( (pNode->jnFlags & JNODE_APPEND)==0 ) break;
192362 assert( pNode->eU==2 );
192363 pNode = &pNode[pNode->u.iAppend];
192364 j = 1;
192365 }
192366 jsonAppendChar(pOut, '}');
192367 break;
@@ -190964,11 +192437,13 @@
192437 sqlite3_result_int(pCtx, 0);
192438 break;
192439 }
192440 case JSON_INT: {
192441 sqlite3_int64 i = 0;
192442 const char *z;
192443 assert( pNode->eU==1 );
192444 z = pNode->u.zJContent;
192445 if( z[0]=='-' ){ z++; }
192446 while( z[0]>='0' && z[0]<='9' ){
192447 unsigned v = *(z++) - '0';
192448 if( i>=LARGEST_INT64/10 ){
192449 if( i>LARGEST_INT64/10 ) goto int_as_real;
@@ -190992,13 +192467,16 @@
192467 int_as_real: ; /* no break */ deliberate_fall_through
192468 }
192469 case JSON_REAL: {
192470 double r;
192471 #ifdef SQLITE_AMALGAMATION
192472 const char *z;
192473 assert( pNode->eU==1 );
192474 z = pNode->u.zJContent;
192475 sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
192476 #else
192477 assert( pNode->eU==1 );
192478 r = strtod(pNode->u.zJContent, 0);
192479 #endif
192480 sqlite3_result_double(pCtx, r);
192481 break;
192482 }
@@ -191005,26 +192483,30 @@
192483 case JSON_STRING: {
192484 #if 0 /* Never happens because JNODE_RAW is only set by json_set(),
192485 ** json_insert() and json_replace() and those routines do not
192486 ** call jsonReturn() */
192487 if( pNode->jnFlags & JNODE_RAW ){
192488 assert( pNode->eU==1 );
192489 sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n,
192490 SQLITE_TRANSIENT);
192491 }else
192492 #endif
192493 assert( (pNode->jnFlags & JNODE_RAW)==0 );
192494 if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){
192495 /* JSON formatted without any backslash-escapes */
192496 assert( pNode->eU==1 );
192497 sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2,
192498 SQLITE_TRANSIENT);
192499 }else{
192500 /* Translate JSON formatted string into raw text */
192501 u32 i;
192502 u32 n = pNode->n;
192503 const char *z;
192504 char *zOut;
192505 u32 j;
192506 assert( pNode->eU==1 );
192507 z = pNode->u.zJContent;
192508 zOut = sqlite3_malloc( n+1 );
192509 if( zOut==0 ){
192510 sqlite3_result_error_nomem(pCtx);
192511 break;
192512 }
@@ -191141,16 +192623,17 @@
192623 u32 eType, /* Node type */
192624 u32 n, /* Content size or sub-node count */
192625 const char *zContent /* Content */
192626 ){
192627 JsonNode *p;
192628 if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){
192629 return jsonParseAddNodeExpand(pParse, eType, n, zContent);
192630 }
192631 p = &pParse->aNode[pParse->nNode];
192632 p->eType = (u8)eType;
192633 p->jnFlags = 0;
192634 VVA( p->eU = zContent ? 1 : 0 );
192635 p->n = n;
192636 p->u.zJContent = zContent;
192637 return pParse->nNode++;
192638 }
192639
@@ -191214,10 +192697,11 @@
192697 return j+1;
192698 }else if( c=='[' ){
192699 /* Parse array */
192700 iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0);
192701 if( iThis<0 ) return -1;
192702 memset(&pParse->aNode[iThis].u, 0, sizeof(pParse->aNode[iThis].u));
192703 for(j=i+1;;j++){
192704 while( safe_isspace(z[j]) ){ j++; }
192705 if( ++pParse->iDepth > JSON_MAX_DEPTH ) return -1;
192706 x = jsonParseValue(pParse, j);
192707 pParse->iDepth--;
@@ -191478,10 +192962,11 @@
192962 /*
192963 ** Compare the OBJECT label at pNode against zKey,nKey. Return true on
192964 ** a match.
192965 */
192966 static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
192967 assert( pNode->eU==1 );
192968 if( pNode->jnFlags & JNODE_RAW ){
192969 if( pNode->n!=nKey ) return 0;
192970 return strncmp(pNode->u.zJContent, zKey, nKey)==0;
192971 }else{
192972 if( pNode->n!=nKey+2 ) return 0;
@@ -191543,10 +193028,11 @@
193028 }
193029 j++;
193030 j += jsonNodeSize(&pRoot[j]);
193031 }
193032 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
193033 assert( pRoot->eU==2 );
193034 iRoot += pRoot->u.iAppend;
193035 pRoot = &pParse->aNode[iRoot];
193036 j = 1;
193037 }
193038 if( pApnd ){
@@ -191557,12 +193043,14 @@
193043 zPath += i;
193044 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
193045 if( pParse->oom ) return 0;
193046 if( pNode ){
193047 pRoot = &pParse->aNode[iRoot];
193048 assert( pRoot->eU==0 );
193049 pRoot->u.iAppend = iStart - iRoot;
193050 pRoot->jnFlags |= JNODE_APPEND;
193051 VVA( pRoot->eU = 2 );
193052 pParse->aNode[iLabel].jnFlags |= JNODE_RAW;
193053 }
193054 return pNode;
193055 }
193056 }else if( zPath[0]=='[' ){
@@ -191581,10 +193069,11 @@
193069 while( j<=pBase->n ){
193070 if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++;
193071 j += jsonNodeSize(&pBase[j]);
193072 }
193073 if( (pBase->jnFlags & JNODE_APPEND)==0 ) break;
193074 assert( pBase->eU==2 );
193075 iBase += pBase->u.iAppend;
193076 pBase = &pParse->aNode[iBase];
193077 j = 1;
193078 }
193079 j = 2;
@@ -191614,10 +193103,11 @@
193103 while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){
193104 if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--;
193105 j += jsonNodeSize(&pRoot[j]);
193106 }
193107 if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break;
193108 assert( pRoot->eU==2 );
193109 iRoot += pRoot->u.iAppend;
193110 pRoot = &pParse->aNode[iRoot];
193111 j = 1;
193112 }
193113 if( j<=pRoot->n ){
@@ -191629,12 +193119,14 @@
193119 iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0);
193120 pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr);
193121 if( pParse->oom ) return 0;
193122 if( pNode ){
193123 pRoot = &pParse->aNode[iRoot];
193124 assert( pRoot->eU==0 );
193125 pRoot->u.iAppend = iStart - iRoot;
193126 pRoot->jnFlags |= JNODE_APPEND;
193127 VVA( pRoot->eU = 2 );
193128 }
193129 return pNode;
193130 }
193131 }else{
193132 *pzErr = zPath;
@@ -191784,13 +193276,17 @@
193276 }else{
193277 zType = jsonType[x.aNode[i].eType];
193278 }
193279 jsonPrintf(100, &s,"node %3u: %7s n=%-4d up=%-4d",
193280 i, zType, x.aNode[i].n, x.aUp[i]);
193281 assert( x.aNode[i].eU==0 || x.aNode[i].eU==1 );
193282 if( x.aNode[i].u.zJContent!=0 ){
193283 assert( x.aNode[i].eU==1 );
193284 jsonAppendRaw(&s, " ", 1);
193285 jsonAppendRaw(&s, x.aNode[i].u.zJContent, x.aNode[i].n);
193286 }else{
193287 assert( x.aNode[i].eU==0 );
193288 }
193289 jsonAppendRaw(&s, "\n", 1);
193290 }
193291 jsonParseReset(&x);
193292 jsonResult(&s);
@@ -191969,10 +193465,11 @@
193465 for(i=1; i<pPatch->n; i += jsonNodeSize(&pPatch[i+1])+1){
193466 u32 nKey;
193467 const char *zKey;
193468 assert( pPatch[i].eType==JSON_STRING );
193469 assert( pPatch[i].jnFlags & JNODE_LABEL );
193470 assert( pPatch[i].eU==1 );
193471 nKey = pPatch[i].n;
193472 zKey = pPatch[i].u.zJContent;
193473 assert( (pPatch[i].jnFlags & JNODE_RAW)==0 );
193474 for(j=1; j<pTarget->n; j += jsonNodeSize(&pTarget[j+1])+1 ){
193475 assert( pTarget[j].eType==JSON_STRING );
@@ -191985,10 +193482,16 @@
193482 }else{
193483 JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]);
193484 if( pNew==0 ) return 0;
193485 pTarget = &pParse->aNode[iTarget];
193486 if( pNew!=&pTarget[j+1] ){
193487 assert( pTarget[j+1].eU==0
193488 || pTarget[j+1].eU==1
193489 || pTarget[j+1].eU==2 );
193490 testcase( pTarget[j+1].eU==1 );
193491 testcase( pTarget[j+1].eU==2 );
193492 VVA( pTarget[j+1].eU = 5 );
193493 pTarget[j+1].u.pPatch = pNew;
193494 pTarget[j+1].jnFlags |= JNODE_PATCH;
193495 }
193496 }
193497 break;
@@ -192000,13 +193503,18 @@
193503 jsonParseAddNode(pParse, JSON_STRING, nKey, zKey);
193504 iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0);
193505 if( pParse->oom ) return 0;
193506 jsonRemoveAllNulls(pPatch);
193507 pTarget = &pParse->aNode[iTarget];
193508 assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 );
193509 testcase( pParse->aNode[iRoot].eU==2 );
193510 pParse->aNode[iRoot].jnFlags |= JNODE_APPEND;
193511 VVA( pParse->aNode[iRoot].eU = 2 );
193512 pParse->aNode[iRoot].u.iAppend = iStart - iRoot;
193513 iRoot = iStart;
193514 assert( pParse->aNode[iPatch].eU==0 );
193515 VVA( pParse->aNode[iPatch].eU = 5 );
193516 pParse->aNode[iPatch].jnFlags |= JNODE_PATCH;
193517 pParse->aNode[iPatch].u.pPatch = &pPatch[i+1];
193518 }
193519 }
193520 return pTarget;
@@ -192144,15 +193652,19 @@
193652 for(i=1; i<(u32)argc; i+=2){
193653 zPath = (const char*)sqlite3_value_text(argv[i]);
193654 pNode = jsonLookup(&x, zPath, 0, ctx);
193655 if( x.nErr ) goto replace_err;
193656 if( pNode ){
193657 assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 );
193658 json_testcase( pNode->eU!=0 && pNode->eU!=1 );
193659 pNode->jnFlags |= (u8)JNODE_REPLACE;
193660 VVA( pNode->eU = 4 );
193661 pNode->u.iReplace = i + 1;
193662 }
193663 }
193664 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
193665 assert( x.aNode[0].eU==4 );
193666 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
193667 }else{
193668 jsonReturnJson(x.aNode, ctx, argv);
193669 }
193670 replace_err:
@@ -192198,15 +193710,19 @@
193710 sqlite3_result_error_nomem(ctx);
193711 goto jsonSetDone;
193712 }else if( x.nErr ){
193713 goto jsonSetDone;
193714 }else if( pNode && (bApnd || bIsSet) ){
193715 json_testcase( pNode->eU!=0 && pNode->eU!=1 && pNode->eU!=4 );
193716 assert( pNode->eU!=3 || pNode->eU!=5 );
193717 VVA( pNode->eU = 4 );
193718 pNode->jnFlags |= (u8)JNODE_REPLACE;
193719 pNode->u.iReplace = i + 1;
193720 }
193721 }
193722 if( x.aNode[0].jnFlags & JNODE_REPLACE ){
193723 assert( x.aNode[0].eU==4 );
193724 sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]);
193725 }else{
193726 jsonReturnJson(x.aNode, ctx, argv);
193727 }
193728 jsonSetDone:
@@ -192553,10 +194069,13 @@
194069 if( p->i<p->iEnd ){
194070 u32 iUp = p->sParse.aUp[p->i];
194071 JsonNode *pUp = &p->sParse.aNode[iUp];
194072 p->eType = pUp->eType;
194073 if( pUp->eType==JSON_ARRAY ){
194074 assert( pUp->eU==0 || pUp->eU==3 );
194075 json_testcase( pUp->eU==3 );
194076 VVA( pUp->eU = 3 );
194077 if( iUp==p->i-1 ){
194078 pUp->u.iKey = 0;
194079 }else{
194080 pUp->u.iKey++;
194081 }
@@ -192599,16 +194118,19 @@
194118 iUp = p->sParse.aUp[i];
194119 jsonEachComputePath(p, pStr, iUp);
194120 pNode = &p->sParse.aNode[i];
194121 pUp = &p->sParse.aNode[iUp];
194122 if( pUp->eType==JSON_ARRAY ){
194123 assert( pUp->eU==3 || (pUp->eU==0 && pUp->u.iKey==0) );
194124 testcase( pUp->eU==0 );
194125 jsonPrintf(30, pStr, "[%d]", pUp->u.iKey);
194126 }else{
194127 assert( pUp->eType==JSON_OBJECT );
194128 if( (pNode->jnFlags & JNODE_LABEL)==0 ) pNode--;
194129 assert( pNode->eType==JSON_STRING );
194130 assert( pNode->jnFlags & JNODE_LABEL );
194131 assert( pNode->eU==1 );
194132 jsonPrintf(pNode->n+1, pStr, ".%.*s", pNode->n-2, pNode->u.zJContent+1);
194133 }
194134 }
194135
194136 /* Return the value of a column */
@@ -192626,10 +194148,11 @@
194148 jsonReturn(pThis, ctx, 0);
194149 }else if( p->eType==JSON_ARRAY ){
194150 u32 iKey;
194151 if( p->bRecursive ){
194152 if( p->iRowid==0 ) break;
194153 assert( p->sParse.aNode[p->sParse.aUp[p->i]].eU==3 );
194154 iKey = p->sParse.aNode[p->sParse.aUp[p->i]].u.iKey;
194155 }else{
194156 iKey = p->iRowid;
194157 }
194158 sqlite3_result_int64(ctx, (sqlite3_int64)iKey);
@@ -192675,10 +194198,11 @@
194198 jsonAppendChar(&x, '$');
194199 }
194200 if( p->eType==JSON_ARRAY ){
194201 jsonPrintf(30, &x, "[%d]", p->iRowid);
194202 }else if( p->eType==JSON_OBJECT ){
194203 assert( pThis->eU==1 );
194204 jsonPrintf(pThis->n, &x, ".%.*s", pThis->n-2, pThis->u.zJContent+1);
194205 }
194206 }
194207 jsonResult(&x);
194208 break;
@@ -192742,10 +194266,11 @@
194266 int iCol;
194267 int iMask;
194268 if( pConstraint->iColumn < JEACH_JSON ) continue;
194269 iCol = pConstraint->iColumn - JEACH_JSON;
194270 assert( iCol==0 || iCol==1 );
194271 testcase( iCol==0 );
194272 iMask = 1 << iCol;
194273 if( pConstraint->usable==0 ){
194274 unusableMask |= iMask;
194275 }else if( pConstraint->op==SQLITE_INDEX_CONSTRAINT_EQ ){
194276 aIdx[iCol] = i;
@@ -192839,10 +194364,12 @@
194364 pNode = p->sParse.aNode;
194365 }
194366 p->iBegin = p->i = (int)(pNode - p->sParse.aNode);
194367 p->eType = pNode->eType;
194368 if( p->eType>=JSON_ARRAY ){
194369 assert( pNode->eU==0 );
194370 VVA( pNode->eU = 3 );
194371 pNode->u.iKey = 0;
194372 p->iEnd = p->i + pNode->n + 1;
194373 if( p->bRecursive ){
194374 p->eType = p->sParse.aNode[p->sParse.aUp[p->i]].eType;
194375 if( p->i>0 && (p->sParse.aNode[p->i-1].jnFlags & JNODE_LABEL)!=0 ){
@@ -193099,10 +194626,13 @@
194626 #endif
194627 #if defined(NDEBUG) && defined(SQLITE_DEBUG)
194628 # undef NDEBUG
194629 #endif
194630 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
194631 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
194632 #endif
194633 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
194634 # define ALWAYS(X) (1)
194635 # define NEVER(X) (0)
194636 #elif !defined(NDEBUG)
194637 # define ALWAYS(X) ((X)?1:(assert(0),0))
194638 # define NEVER(X) ((X)?(assert(0),1):0)
@@ -193450,11 +194980,16 @@
194980
194981 /* The testcase() macro should already be defined in the amalgamation. If
194982 ** it is not, make it a no-op.
194983 */
194984 #ifndef SQLITE_AMALGAMATION
194985 # if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG)
194986 unsigned int sqlite3RtreeTestcase = 0;
194987 # define testcase(X) if( X ){ sqlite3RtreeTestcase += __LINE__; }
194988 # else
194989 # define testcase(X)
194990 # endif
194991 #endif
194992
194993 /*
194994 ** Make sure that the compiler intrinsics we desire are enabled when
194995 ** compiling with an appropriate version of MSVC unless prevented by
@@ -194296,24 +195831,33 @@
195831 || p->op==RTREE_FALSE );
195832 assert( ((((char*)pCellData) - (char*)0)&3)==0 ); /* 4-byte aligned */
195833 switch( p->op ){
195834 case RTREE_TRUE: return; /* Always satisfied */
195835 case RTREE_FALSE: break; /* Never satisfied */
 
 
195836 case RTREE_EQ:
195837 RTREE_DECODE_COORD(eInt, pCellData, val);
195838 /* val now holds the lower bound of the coordinate pair */
195839 if( p->u.rValue>=val ){
195840 pCellData += 4;
195841 RTREE_DECODE_COORD(eInt, pCellData, val);
195842 /* val now holds the upper bound of the coordinate pair */
195843 if( p->u.rValue<=val ) return;
195844 }
195845 break;
195846 case RTREE_LE:
195847 case RTREE_LT:
195848 RTREE_DECODE_COORD(eInt, pCellData, val);
195849 /* val now holds the lower bound of the coordinate pair */
195850 if( p->u.rValue>=val ) return;
195851 break;
 
195852
195853 default:
195854 pCellData += 4;
195855 RTREE_DECODE_COORD(eInt, pCellData, val);
195856 /* val now holds the upper bound of the coordinate pair */
195857 if( p->u.rValue<=val ) return;
195858 break;
195859 }
195860 *peWithin = NOT_WITHIN;
195861 }
195862
195863 /*
@@ -195214,11 +196758,11 @@
196758 RtreeDValue fMinGrowth = RTREE_ZERO;
196759 RtreeDValue fMinArea = RTREE_ZERO;
196760
196761 int nCell = NCELL(pNode);
196762 RtreeCell cell;
196763 RtreeNode *pChild = 0;
196764
196765 RtreeCell *aCell = 0;
196766
196767 /* Select the child node which will be enlarged the least if pCell
196768 ** is inserted into it. Resolve ties by choosing the entry with
@@ -195572,10 +197116,11 @@
197116 nodeRelease(pRtree, pChild->pParent);
197117 nodeReference(pNode);
197118 pChild->pParent = pNode;
197119 }
197120 }
197121 if( NEVER(pNode==0) ) return SQLITE_ERROR;
197122 return xSetMapping(pRtree, iRowid, pNode->iNode);
197123 }
197124
197125 static int SplitNode(
197126 Rtree *pRtree,
@@ -196876,10 +198421,11 @@
198421 tree.nDim = (u8)sqlite3_value_int(apArg[0]);
198422 if( tree.nDim<1 || tree.nDim>5 ) return;
198423 tree.nDim2 = tree.nDim*2;
198424 tree.nBytesPerCell = 8 + 8 * tree.nDim;
198425 node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
198426 if( node.zData==0 ) return;
198427 nData = sqlite3_value_bytes(apArg[1]);
198428 if( nData<4 ) return;
198429 if( nData<NCELL(&node)*tree.nBytesPerCell ) return;
198430
198431 pOut = sqlite3_str_new(0);
@@ -197707,17 +199253,18 @@
199253 sqlite3_value *pVal, /* The value to decode */
199254 int *pRc /* Write error here */
199255 ){
199256 GeoPoly *p = 0;
199257 int nByte;
199258 testcase( pCtx==0 );
199259 if( sqlite3_value_type(pVal)==SQLITE_BLOB
199260 && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord))
199261 ){
199262 const unsigned char *a = sqlite3_value_blob(pVal);
199263 int nVertex;
199264 if( a==0 ){
199265 if( pCtx ) sqlite3_result_error_nomem(pCtx);
199266 return 0;
199267 }
199268 nVertex = (a[1]<<16) + (a[2]<<8) + a[3];
199269 if( (a[0]==0 || a[0]==1)
199270 && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte
@@ -198540,15 +200087,15 @@
200087 pActive = pSeg;
200088 needSort = 1;
200089 }else{
200090 /* Remove a segment */
200091 if( pActive==pThisEvent->pSeg ){
200092 pActive = ALWAYS(pActive) ? pActive->pNext : 0;
200093 }else{
200094 for(pSeg=pActive; pSeg; pSeg=pSeg->pNext){
200095 if( pSeg->pNext==pThisEvent->pSeg ){
200096 pSeg->pNext = ALWAYS(pSeg->pNext) ? pSeg->pNext->pNext : 0;
200097 break;
200098 }
200099 }
200100 }
200101 }
@@ -198788,10 +200335,11 @@
200335 rc = nodeAcquire(pRtree, 1, 0, &pRoot);
200336 if( rc==SQLITE_OK && idxNum<=3 ){
200337 RtreeCoord bbox[4];
200338 RtreeConstraint *p;
200339 assert( argc==1 );
200340 assert( argv[0]!=0 );
200341 geopolyBBox(0, argv[0], bbox, &rc);
200342 if( rc ){
200343 goto geopoly_filter_end;
200344 }
200345 pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4);
@@ -199015,10 +200563,11 @@
200563 if( nData>1 /* not a DELETE */
200564 && (!oldRowidValid /* INSERT */
200565 || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */
200566 || oldRowid!=newRowid) /* Rowid change */
200567 ){
200568 assert( aData[2]!=0 );
200569 geopolyBBox(0, aData[2], cell.aCoord, &rc);
200570 if( rc ){
200571 if( rc==SQLITE_ERROR ){
200572 pVtab->zErrMsg =
200573 sqlite3_mprintf("_shape does not contain a valid polygon");
@@ -200941,10 +202490,17 @@
202490 ** Swap two objects of type TYPE.
202491 */
202492 #if !defined(SQLITE_AMALGAMATION)
202493 # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
202494 #endif
202495
202496 /*
202497 ** Name of the URI option that causes RBU to take an exclusive lock as
202498 ** part of the incremental checkpoint operation.
202499 */
202500 #define RBU_EXCLUSIVE_CHECKPOINT "rbu_exclusive_checkpoint"
202501
202502
202503 /*
202504 ** The rbu_state table is used to save the state of a partially applied
202505 ** update so that it can be resumed later. The table consists of integer
202506 ** keys mapped to values as follows:
@@ -202388,11 +203944,11 @@
203944 **
203945 ** If the expression cannot be created, NULL is returned. In this case,
203946 ** the caller has to use an OFFSET clause to extract only the required
203947 ** rows from the sourct table, just as it does for an RBU update operation.
203948 */
203949 static char *rbuVacuumIndexStart(
203950 sqlite3rbu *p, /* RBU handle */
203951 RbuObjIter *pIter /* RBU iterator object */
203952 ){
203953 char *zOrder = 0;
203954 char *zLhs = 0;
@@ -203588,17 +205144,23 @@
205144
205145
205146 /*
205147 ** Open the database handle and attach the RBU database as "rbu". If an
205148 ** error occurs, leave an error code and message in the RBU handle.
205149 **
205150 ** If argument dbMain is not NULL, then it is a database handle already
205151 ** open on the target database. Use this handle instead of opening a new
205152 ** one.
205153 */
205154 static void rbuOpenDatabase(sqlite3rbu *p, sqlite3 *dbMain, int *pbRetry){
205155 assert( p->rc || (p->dbMain==0 && p->dbRbu==0) );
205156 assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 );
205157 assert( dbMain==0 || rbuIsVacuum(p)==0 );
205158
205159 /* Open the RBU database */
205160 p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1);
205161 p->dbMain = dbMain;
205162
205163 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){
205164 sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p);
205165 if( p->zState==0 ){
205166 const char *zFile = sqlite3_db_filename(p->dbRbu, "main");
@@ -203960,19 +205522,35 @@
205522 p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
205523 }
205524
205525
205526 /*
205527 ** Take an EXCLUSIVE lock on the database file. Return SQLITE_OK if
205528 ** successful, or an SQLite error code otherwise.
205529 */
205530 static int rbuLockDatabase(sqlite3 *db){
205531 int rc = SQLITE_OK;
205532 sqlite3_file *fd = 0;
205533 sqlite3_file_control(db, "main", SQLITE_FCNTL_FILE_POINTER, &fd);
205534
205535 if( fd->pMethods ){
205536 rc = fd->pMethods->xLock(fd, SQLITE_LOCK_SHARED);
205537 if( rc==SQLITE_OK ){
205538 rc = fd->pMethods->xLock(fd, SQLITE_LOCK_EXCLUSIVE);
205539 }
205540 }
205541 return rc;
205542 }
205543
205544 /*
205545 ** Return true if the database handle passed as the only argument
205546 ** was opened with the rbu_exclusive_checkpoint=1 URI parameter
205547 ** specified. Or false otherwise.
205548 */
205549 static int rbuExclusiveCheckpoint(sqlite3 *db){
205550 const char *zUri = sqlite3_db_filename(db, 0);
205551 return sqlite3_uri_boolean(zUri, RBU_EXCLUSIVE_CHECKPOINT, 0);
205552 }
205553
205554 #if defined(_WIN32_WCE)
205555 static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
205556 int nChar;
@@ -204026,22 +205604,28 @@
205604 ** in WAL mode). So no other connection may be writing the db.
205605 **
205606 ** In order to ensure that there are no database readers, an EXCLUSIVE
205607 ** lock is obtained here before the *-oal is moved to *-wal.
205608 */
205609 sqlite3 *dbMain = 0;
205610 rbuFileSuffix3(zBase, zWal);
205611 rbuFileSuffix3(zBase, zOal);
205612
205613 /* Re-open the databases. */
205614 rbuObjIterFinalize(&p->objiter);
205615 sqlite3_close(p->dbRbu);
205616 sqlite3_close(p->dbMain);
205617 p->dbMain = 0;
205618 p->dbRbu = 0;
205619
205620 dbMain = rbuOpenDbhandle(p, p->zTarget, 1);
205621 if( dbMain ){
205622 assert( p->rc==SQLITE_OK );
205623 p->rc = rbuLockDatabase(dbMain);
205624 }
205625
205626 if( p->rc==SQLITE_OK ){
 
 
 
 
 
 
 
 
 
 
205627 #if defined(_WIN32_WCE)
205628 {
205629 LPWSTR zWideOal;
205630 LPWSTR zWideWal;
205631
@@ -204064,15 +205648,23 @@
205648 }
205649 }
205650 #else
205651 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
205652 #endif
205653 }
205654
205655 if( p->rc!=SQLITE_OK
205656 || rbuIsVacuum(p)
205657 || rbuExclusiveCheckpoint(dbMain)==0
205658 ){
205659 sqlite3_close(dbMain);
205660 dbMain = 0;
205661 }
205662
205663 if( p->rc==SQLITE_OK ){
205664 rbuOpenDatabase(p, dbMain, 0);
205665 rbuSetupCheckpoint(p, 0);
205666 }
205667 }
205668
205669 sqlite3_free(zWal);
205670 sqlite3_free(zOal);
@@ -204819,13 +206411,13 @@
206411 ** to be a wal-mode db. But, this may have happened due to an earlier
206412 ** RBU vacuum operation leaving an old wal file in the directory.
206413 ** If this is the case, it will have been checkpointed and deleted
206414 ** when the handle was closed and a second attempt to open the
206415 ** database may succeed. */
206416 rbuOpenDatabase(p, 0, &bRetry);
206417 if( bRetry ){
206418 rbuOpenDatabase(p, 0, 0);
206419 }
206420 }
206421
206422 if( p->rc==SQLITE_OK ){
206423 pState = rbuLoadState(p);
@@ -204916,10 +206508,18 @@
206508 }
206509 }
206510 }else if( p->eStage==RBU_STAGE_MOVE ){
206511 /* no-op */
206512 }else if( p->eStage==RBU_STAGE_CKPT ){
206513 if( !rbuIsVacuum(p) && rbuExclusiveCheckpoint(p->dbMain) ){
206514 /* If the rbu_exclusive_checkpoint=1 URI parameter was specified
206515 ** and an incremental checkpoint is being resumed, attempt an
206516 ** exclusive lock on the db file. If this fails, so be it. */
206517 p->eStage = RBU_STAGE_DONE;
206518 rbuLockDatabase(p->dbMain);
206519 p->eStage = RBU_STAGE_CKPT;
206520 }
206521 rbuSetupCheckpoint(p, pState);
206522 }else if( p->eStage==RBU_STAGE_DONE ){
206523 p->rc = SQLITE_DONE;
206524 }else{
206525 p->rc = SQLITE_CORRUPT;
@@ -204953,11 +206553,10 @@
206553 const char *zTarget,
206554 const char *zRbu,
206555 const char *zState
206556 ){
206557 if( zTarget==0 || zRbu==0 ){ return rbuMisuseError(); }
 
206558 return openRbuHandle(zTarget, zRbu, zState);
206559 }
206560
206561 /*
206562 ** Open a handle to begin or resume an RBU VACUUM operation.
@@ -207873,11 +209472,11 @@
209472 if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
209473 nVarint = sessionVarintLen(n);
209474
209475 if( aBuf ){
209476 sessionVarintPut(&aBuf[1], n);
209477 if( n>0 ) memcpy(&aBuf[nVarint + 1], z, n);
209478 }
209479
209480 nByte = 1 + nVarint + n;
209481 break;
209482 }
@@ -208478,20 +210077,36 @@
210077 "SELECT 2, 'stat', '', 0, '', 0"
210078 );
210079 }else if( rc==SQLITE_ERROR ){
210080 zPragma = sqlite3_mprintf("");
210081 }else{
210082 *pazCol = 0;
210083 *pabPK = 0;
210084 *pnCol = 0;
210085 if( pzTab ) *pzTab = 0;
210086 return rc;
210087 }
210088 }else{
210089 zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
210090 }
210091 if( !zPragma ){
210092 *pazCol = 0;
210093 *pabPK = 0;
210094 *pnCol = 0;
210095 if( pzTab ) *pzTab = 0;
210096 return SQLITE_NOMEM;
210097 }
210098
210099 rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
210100 sqlite3_free(zPragma);
210101 if( rc!=SQLITE_OK ){
210102 *pazCol = 0;
210103 *pabPK = 0;
210104 *pnCol = 0;
210105 if( pzTab ) *pzTab = 0;
210106 return rc;
210107 }
210108
210109 nByte = nThis + 1;
210110 while( SQLITE_ROW==sqlite3_step(pStmt) ){
210111 nByte += sqlite3_column_bytes(pStmt, 1);
210112 nDbCol++;
@@ -208905,11 +210520,15 @@
210520 if( pSession->xTableFilter==0
210521 || pSession->xTableFilter(pSession->pFilterCtx, zName)
210522 ){
210523 rc = sqlite3session_attach(pSession, zName);
210524 if( rc==SQLITE_OK ){
210525 pRet = pSession->pTable;
210526 while( ALWAYS(pRet) && pRet->pNext ){
210527 pRet = pRet->pNext;
210528 }
210529 assert( pRet!=0 );
210530 assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) );
210531 }
210532 }
210533 }
210534
@@ -209678,10 +211297,11 @@
211297 int bNoop = 1; /* Set to zero if any values are modified */
211298 int nRewind = pBuf->nBuf; /* Set to zero if any values are modified */
211299 int i; /* Used to iterate through columns */
211300 u8 *pCsr = p->aRecord; /* Used to iterate through old.* values */
211301
211302 assert( abPK!=0 );
211303 sessionAppendByte(pBuf, SQLITE_UPDATE, &rc);
211304 sessionAppendByte(pBuf, p->bIndirect, &rc);
211305 for(i=0; i<sqlite3_column_count(pStmt); i++){
211306 int bChanged = 0;
211307 int nAdvance;
@@ -209982,16 +211602,18 @@
211602 sqlite3 *db = pSession->db; /* Source database handle */
211603 SessionTable *pTab; /* Used to iterate through attached tables */
211604 SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */
211605 int rc; /* Return code */
211606
211607 assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0) );
211608 assert( xOutput!=0 || (pnChangeset!=0 && ppChangeset!=0) );
211609
211610 /* Zero the output variables in case an error occurs. If this session
211611 ** object is already in the error state (sqlite3_session.rc != SQLITE_OK),
211612 ** this call will be a no-op. */
211613 if( xOutput==0 ){
211614 assert( pnChangeset!=0 && ppChangeset!=0 );
211615 *pnChangeset = 0;
211616 *ppChangeset = 0;
211617 }
211618
211619 if( pSession->rc ) return pSession->rc;
@@ -210001,12 +211623,12 @@
211623 sqlite3_mutex_enter(sqlite3_db_mutex(db));
211624
211625 for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){
211626 if( pTab->nEntry ){
211627 const char *zName = pTab->zName;
211628 int nCol = 0; /* Number of columns in table */
211629 u8 *abPK = 0; /* Primary key array */
211630 const char **azCol = 0; /* Table columns */
211631 int i; /* Used to iterate through hash buckets */
211632 sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */
211633 int nRewind = buf.nBuf; /* Initial size of write buffer */
211634 int nNoop; /* Size of buffer after writing tbl header */
@@ -210040,10 +211662,11 @@
211662 sessionAppendByte(&buf, p->bIndirect, &rc);
211663 for(iCol=0; iCol<nCol; iCol++){
211664 sessionAppendCol(&buf, pSel, iCol, &rc);
211665 }
211666 }else{
211667 assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */
211668 rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK);
211669 }
211670 }else if( p->op!=SQLITE_INSERT ){
211671 rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK);
211672 }
@@ -210100,11 +211723,14 @@
211723 SQLITE_API int sqlite3session_changeset(
211724 sqlite3_session *pSession, /* Session object */
211725 int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */
211726 void **ppChangeset /* OUT: Buffer containing changeset */
211727 ){
211728 int rc;
211729
211730 if( pnChangeset==0 || ppChangeset==0 ) return SQLITE_MISUSE;
211731 rc = sessionGenerateChangeset(pSession, 0, 0, 0, pnChangeset,ppChangeset);
211732 assert( rc || pnChangeset==0
211733 || pSession->bEnableSize==0 || *pnChangeset<=pSession->nMaxChangesetSize
211734 );
211735 return rc;
211736 }
@@ -210115,10 +211741,11 @@
211741 SQLITE_API int sqlite3session_changeset_strm(
211742 sqlite3_session *pSession,
211743 int (*xOutput)(void *pOut, const void *pData, int nData),
211744 void *pOut
211745 ){
211746 if( xOutput==0 ) return SQLITE_MISUSE;
211747 return sessionGenerateChangeset(pSession, 0, xOutput, pOut, 0, 0);
211748 }
211749
211750 /*
211751 ** Streaming version of sqlite3session_patchset().
@@ -210126,10 +211753,11 @@
211753 SQLITE_API int sqlite3session_patchset_strm(
211754 sqlite3_session *pSession,
211755 int (*xOutput)(void *pOut, const void *pData, int nData),
211756 void *pOut
211757 ){
211758 if( xOutput==0 ) return SQLITE_MISUSE;
211759 return sessionGenerateChangeset(pSession, 1, xOutput, pOut, 0, 0);
211760 }
211761
211762 /*
211763 ** Obtain a patchset object containing all changes recorded by the
@@ -210141,10 +211769,11 @@
211769 SQLITE_API int sqlite3session_patchset(
211770 sqlite3_session *pSession, /* Session object */
211771 int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */
211772 void **ppPatchset /* OUT: Buffer containing changeset */
211773 ){
211774 if( pnPatchset==0 || ppPatchset==0 ) return SQLITE_MISUSE;
211775 return sessionGenerateChangeset(pSession, 1, 0, 0, pnPatchset, ppPatchset);
211776 }
211777
211778 /*
211779 ** Enable or disable the session object passed as the first argument.
@@ -211104,15 +212733,15 @@
212733 if( rc!=SQLITE_OK ) goto finished_invert;
212734 }
212735 }
212736
212737 assert( rc==SQLITE_OK );
212738 if( pnInverted && ALWAYS(ppInverted) ){
212739 *pnInverted = sOut.nBuf;
212740 *ppInverted = sOut.aBuf;
212741 sOut.aBuf = 0;
212742 }else if( sOut.nBuf>0 && ALWAYS(xOutput!=0) ){
212743 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
212744 }
212745
212746 finished_invert:
212747 sqlite3_free(sOut.aBuf);
@@ -211564,11 +213193,11 @@
213193 ** in the code below. */
213194 assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new );
213195
213196 for(i=0; rc==SQLITE_OK && i<nCol; i++){
213197 if( !abPK || abPK[i] ){
213198 sqlite3_value *pVal = 0;
213199 (void)xValue(pIter, i, &pVal);
213200 if( pVal==0 ){
213201 /* The value in the changeset was "undefined". This indicates a
213202 ** corrupt changeset blob. */
213203 rc = SQLITE_CORRUPT_BKPT;
@@ -212707,13 +214336,13 @@
214336 }
214337
214338 if( rc==SQLITE_OK ){
214339 if( xOutput ){
214340 if( buf.nBuf>0 ) rc = xOutput(pOut, buf.aBuf, buf.nBuf);
214341 }else if( ppOut ){
214342 *ppOut = buf.aBuf;
214343 if( pnOut ) *pnOut = buf.nBuf;
214344 buf.aBuf = 0;
214345 }
214346 }
214347 sqlite3_free(buf.aBuf);
214348
@@ -213109,11 +214738,11 @@
214738 if( rc==SQLITE_OK ){
214739 if( xOutput ){
214740 if( sOut.nBuf>0 ){
214741 rc = xOutput(pOut, sOut.aBuf, sOut.nBuf);
214742 }
214743 }else if( ppOut ){
214744 *ppOut = (void*)sOut.aBuf;
214745 *pnOut = sOut.nBuf;
214746 sOut.aBuf = 0;
214747 }
214748 }
@@ -213852,12 +215481,24 @@
215481 #ifndef ArraySize
215482 # define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
215483 #endif
215484
215485 #define testcase(x)
215486
215487 #if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
215488 # define SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS 1
215489 #endif
215490 #if defined(SQLITE_OMIT_AUXILIARY_SAFETY_CHECKS)
215491 # define ALWAYS(X) (1)
215492 # define NEVER(X) (0)
215493 #elif !defined(NDEBUG)
215494 # define ALWAYS(X) ((X)?1:(assert(0),0))
215495 # define NEVER(X) ((X)?(assert(0),1):0)
215496 #else
215497 # define ALWAYS(X) (X)
215498 # define NEVER(X) (X)
215499 #endif
215500
215501 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
215502 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
215503
215504 /*
@@ -213913,11 +215554,11 @@
215554
215555 /*
215556 ** A version of memcmp() that does not cause asan errors if one of the pointer
215557 ** parameters is NULL and the number of bytes to compare is zero.
215558 */
215559 #define fts5Memcmp(s1, s2, n) ((n)<=0 ? 0 : memcmp((s1), (s2), (n)))
215560
215561 /* Mark a function parameter as unused, to suppress nuisance compiler
215562 ** warnings. */
215563 #ifndef UNUSED_PARAM
215564 # define UNUSED_PARAM(X) (void)(X)
@@ -215032,13 +216673,13 @@
216673 fts5yyStackEntry *fts5yystackEnd; /* Last entry in the stack */
216674 #endif
216675 };
216676 typedef struct fts5yyParser fts5yyParser;
216677
 
 
216678 /* #include <assert.h> */
216679 #ifndef NDEBUG
216680 /* #include <stdio.h> */
216681 static FILE *fts5yyTraceFILE = 0;
216682 static char *fts5yyTracePrompt = 0;
216683 #endif /* NDEBUG */
216684
216685 #ifndef NDEBUG
@@ -215971,12 +217612,12 @@
217612 assert( fts5yypParser->fts5yytos>=fts5yypParser->fts5yystack );
217613 assert( fts5yyact==fts5yypParser->fts5yytos->stateno );
217614 fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact);
217615 if( fts5yyact >= fts5YY_MIN_REDUCE ){
217616 unsigned int fts5yyruleno = fts5yyact - fts5YY_MIN_REDUCE; /* Reduce by this rule */
 
217617 #ifndef NDEBUG
217618 assert( fts5yyruleno<(int)(sizeof(fts5yyRuleName)/sizeof(fts5yyRuleName[0])) );
217619 if( fts5yyTraceFILE ){
217620 int fts5yysize = fts5yyRuleInfoNRhs[fts5yyruleno];
217621 if( fts5yysize ){
217622 fprintf(fts5yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
217623 fts5yyTracePrompt,
@@ -216939,11 +218580,10 @@
218580 int *pRc,
218581 Fts5Buffer *pBuf,
218582 u32 nData,
218583 const u8 *pData
218584 ){
 
218585 if( nData ){
218586 if( fts5BufferGrow(pRc, pBuf, nData) ) return;
218587 memcpy(&pBuf->p[pBuf->n], pData, nData);
218588 pBuf->n += nData;
218589 }
@@ -217051,11 +218691,10 @@
218691 return 1;
218692 }else{
218693 i64 iOff = *piOff;
218694 u32 iVal;
218695 fts5FastGetVarint32(a, i, iVal);
 
218696 if( iVal<=1 ){
218697 if( iVal==0 ){
218698 *pi = i;
218699 return 0;
218700 }
@@ -217846,10 +219485,11 @@
219485
219486 z = fts5ConfigGobbleWord(&rc, zOrig, &zOne, &bMustBeCol);
219487 z = fts5ConfigSkipWhitespace(z);
219488 if( z && *z=='=' ){
219489 bOption = 1;
219490 assert( zOne!=0 );
219491 z++;
219492 if( bMustBeCol ) z = 0;
219493 }
219494 z = fts5ConfigSkipWhitespace(z);
219495 if( z && z[0] ){
@@ -217862,11 +219502,15 @@
219502 if( z==0 ){
219503 *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig);
219504 rc = SQLITE_ERROR;
219505 }else{
219506 if( bOption ){
219507 rc = fts5ConfigParseSpecial(pGlobal, pRet,
219508 ALWAYS(zOne)?zOne:"",
219509 zTwo?zTwo:"",
219510 pzErr
219511 );
219512 }else{
219513 rc = fts5ConfigParseColumn(pRet, zOne, zTwo, pzErr);
219514 zOne = 0;
219515 }
219516 }
@@ -218679,10 +220323,11 @@
220323 static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
220324 i64 iRet = 0;
220325 int bRetValid = 0;
220326 Fts5ExprTerm *p;
220327
220328 assert( pTerm );
220329 assert( pTerm->pSynonym );
220330 assert( bDesc==0 || bDesc==1 );
220331 for(p=pTerm; p; p=p->pSynonym){
220332 if( 0==sqlite3Fts5IterEof(p->pIter) ){
220333 i64 iRowid = p->pIter->iRowid;
@@ -220119,11 +221764,11 @@
221764 /* This happens when parsing a token or quoted phrase that contains
221765 ** no token characters at all. (e.g ... MATCH '""'). */
221766 sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
221767 }
221768
221769 if( rc==SQLITE_OK && ALWAYS(sCtx.pPhrase) ){
221770 /* All the allocations succeeded. Put the expression object together. */
221771 pNew->pIndex = pExpr->pIndex;
221772 pNew->pConfig = pExpr->pConfig;
221773 pNew->nPhrase = 1;
221774 pNew->apExprPhrase[0] = sCtx.pPhrase;
@@ -221100,20 +222745,29 @@
222745 Fts5PoslistWriter writer;
222746 int bOk; /* True if ok to populate */
222747 int bMiss;
222748 };
222749
222750 /*
222751 ** Clear the position lists associated with all phrases in the expression
222752 ** passed as the first argument. Argument bLive is true if the expression
222753 ** might be pointing to a real entry, otherwise it has just been reset.
222754 **
222755 ** At present this function is only used for detail=col and detail=none
222756 ** fts5 tables. This implies that all phrases must be at most 1 token
222757 ** in size, as phrase matches are not supported without detail=full.
222758 */
222759 static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){
222760 Fts5PoslistPopulator *pRet;
222761 pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
222762 if( pRet ){
222763 int i;
222764 memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase);
222765 for(i=0; i<pExpr->nPhrase; i++){
222766 Fts5Buffer *pBuf = &pExpr->apExprPhrase[i]->poslist;
222767 Fts5ExprNode *pNode = pExpr->apExprPhrase[i]->pNode;
222768 assert( pExpr->apExprPhrase[i]->nTerm<=1 );
222769 if( bLive &&
222770 (pBuf->n==0 || pNode->iRowid!=pExpr->pRoot->iRowid || pNode->bEof)
222771 ){
222772 pRet[i].bMiss = 1;
222773 }else{
@@ -221660,11 +223314,11 @@
223314 if( iCol>=0 ){
223315 if( pHash->eDetail==FTS5_DETAIL_NONE ){
223316 p->bContent = 1;
223317 }else{
223318 /* Append a new column value, if necessary */
223319 assert_nc( iCol>=p->iCol );
223320 if( iCol!=p->iCol ){
223321 if( pHash->eDetail==FTS5_DETAIL_FULL ){
223322 pPtr[p->nData++] = 0x01;
223323 p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol);
223324 p->iCol = (i16)iCol;
@@ -222465,12 +224119,15 @@
224119 ** +ve if pRight is smaller than pLeft. In other words:
224120 **
224121 ** res = *pLeft - *pRight
224122 */
224123 static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
224124 int nCmp, res;
224125 nCmp = MIN(pLeft->n, pRight->n);
224126 assert( nCmp<=0 || pLeft->p!=0 );
224127 assert( nCmp<=0 || pRight->p!=0 );
224128 res = fts5Memcmp(pLeft->p, pRight->p, nCmp);
224129 return (res==0 ? (pLeft->n - pRight->n) : res);
224130 }
224131
224132 static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
224133 int ret;
@@ -222712,11 +224369,11 @@
224369 ** an error occurs, (*pRc) is set to an SQLite error code before returning.
224370 */
224371 static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
224372 Fts5Structure *p = *pp;
224373 if( *pRc==SQLITE_OK && p->nRef>1 ){
224374 i64 nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
224375 Fts5Structure *pNew;
224376 pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
224377 if( pNew ){
224378 int i;
224379 memcpy(pNew, p, nByte);
@@ -223638,10 +225295,11 @@
225295 fts5SegIterNextPage(p, pIter);
225296 }
225297
225298 if( p->rc==SQLITE_OK ){
225299 pIter->iLeafOffset = 4;
225300 assert( pIter->pLeaf!=0 );
225301 assert_nc( pIter->pLeaf->nn>4 );
225302 assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
225303 pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
225304 fts5SegIterLoadTerm(p, pIter, 0);
225305 fts5SegIterLoadNPos(p, pIter);
@@ -223740,12 +225398,16 @@
225398 }
225399 }else{
225400 int iRowidOff;
225401 iRowidOff = fts5LeafFirstRowidOff(pNew);
225402 if( iRowidOff ){
225403 if( iRowidOff>=pNew->szLeaf ){
225404 p->rc = FTS5_CORRUPT;
225405 }else{
225406 pIter->pLeaf = pNew;
225407 pIter->iLeafOffset = iRowidOff;
225408 }
225409 }
225410 }
225411
225412 if( pIter->pLeaf ){
225413 u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset];
@@ -224142,25 +225804,24 @@
225804 Fts5Index *p, /* Leave any error code here */
225805 int bGe, /* True for a >= search */
225806 Fts5SegIter *pIter, /* Iterator to seek */
225807 const u8 *pTerm, int nTerm /* Term to search for */
225808 ){
225809 u32 iOff;
225810 const u8 *a = pIter->pLeaf->p;
225811 u32 n = (u32)pIter->pLeaf->nn;
 
225812
225813 u32 nMatch = 0;
225814 u32 nKeep = 0;
225815 u32 nNew = 0;
225816 u32 iTermOff;
225817 u32 iPgidx; /* Current offset in pgidx */
225818 int bEndOfPage = 0;
225819
225820 assert( p->rc==SQLITE_OK );
225821
225822 iPgidx = (u32)pIter->pLeaf->szLeaf;
225823 iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
225824 iOff = iTermOff;
225825 if( iOff>n ){
225826 p->rc = FTS5_CORRUPT;
225827 return;
@@ -224222,19 +225883,19 @@
225883 do {
225884 fts5SegIterNextPage(p, pIter);
225885 if( pIter->pLeaf==0 ) return;
225886 a = pIter->pLeaf->p;
225887 if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
225888 iPgidx = (u32)pIter->pLeaf->szLeaf;
225889 iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
225890 if( iOff<4 || (i64)iOff>=pIter->pLeaf->szLeaf ){
225891 p->rc = FTS5_CORRUPT;
225892 return;
225893 }else{
225894 nKeep = 0;
225895 iTermOff = iOff;
225896 n = (u32)pIter->pLeaf->nn;
225897 iOff += fts5GetVarint32(&a[iOff], nNew);
225898 break;
225899 }
225900 }
225901 }while( 1 );
@@ -224598,11 +226259,11 @@
226259 pIter->pNextLeaf = 0;
226260 pIter->iLeafPgno = iLeafPgno-1;
226261 fts5SegIterNextPage(p, pIter);
226262 assert( p->rc!=SQLITE_OK || pIter->iLeafPgno==iLeafPgno );
226263
226264 if( p->rc==SQLITE_OK && ALWAYS(pIter->pLeaf!=0) ){
226265 int iOff;
226266 u8 *a = pIter->pLeaf->p;
226267 int n = pIter->pLeaf->szLeaf;
226268
226269 iOff = fts5LeafFirstRowidOff(pIter->pLeaf);
@@ -225030,11 +226691,15 @@
226691 Fts5Index *p,
226692 Fts5SegIter *pSeg,
226693 Fts5Colset *pColset,
226694 Fts5Buffer *pBuf
226695 ){
226696 assert( pBuf!=0 );
226697 assert( pSeg!=0 );
226698 if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+FTS5_DATA_ZERO_PADDING) ){
226699 assert( pBuf->p!=0 );
226700 assert( pBuf->nSpace >= pBuf->n+pSeg->nPos+FTS5_DATA_ZERO_PADDING );
226701 memset(&pBuf->p[pBuf->n+pSeg->nPos], 0, FTS5_DATA_ZERO_PADDING);
226702 if( pColset==0 ){
226703 fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
226704 }else{
226705 if( p->pConfig->eDetail==FTS5_DETAIL_FULL ){
@@ -225254,10 +226919,11 @@
226919 pIter->base.nData = pIter->poslist.n;
226920 }
226921 }
226922
226923 static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
226924 assert( pIter!=0 || (*pRc)!=SQLITE_OK );
226925 if( *pRc==SQLITE_OK ){
226926 Fts5Config *pConfig = pIter->pIndex->pConfig;
226927 if( pConfig->eDetail==FTS5_DETAIL_NONE ){
226928 pIter->xSetOutputs = fts5IterSetOutputs_None;
226929 }
@@ -225325,11 +226991,14 @@
226991 }else{
226992 nSeg = MIN(pStruct->aLevel[iLevel].nSeg, nSegment);
226993 }
226994 }
226995 *ppOut = pNew = fts5MultiIterAlloc(p, nSeg);
226996 if( pNew==0 ){
226997 assert( p->rc!=SQLITE_OK );
226998 goto fts5MultiIterNew_post_check;
226999 }
227000 pNew->bRev = (0!=(flags & FTS5INDEX_QUERY_DESC));
227001 pNew->bSkipEmpty = (0!=(flags & FTS5INDEX_QUERY_SKIPEMPTY));
227002 pNew->pColset = pColset;
227003 if( (flags & FTS5INDEX_QUERY_NOOUTPUT)==0 ){
227004 fts5IterSetOutputCb(&p->rc, pNew);
@@ -225389,10 +227058,14 @@
227058
227059 }else{
227060 fts5MultiIterFree(pNew);
227061 *ppOut = 0;
227062 }
227063
227064 fts5MultiIterNew_post_check:
227065 assert( (*ppOut)!=0 || p->rc!=SQLITE_OK );
227066 return;
227067 }
227068
227069 /*
227070 ** Create an Fts5Iter that iterates through the doclist provided
227071 ** as the second argument.
@@ -225436,11 +227109,12 @@
227109 /*
227110 ** Return true if the iterator is at EOF or if an error has occurred.
227111 ** False otherwise.
227112 */
227113 static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
227114 assert( pIter!=0 || p->rc!=SQLITE_OK );
227115 assert( p->rc!=SQLITE_OK
227116 || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->base.bEof
227117 );
227118 return (p->rc || pIter->base.bEof);
227119 }
227120
@@ -226240,10 +227914,11 @@
227914
227915 /* Flush the last leaf page to disk. Set the output segment b-tree height
227916 ** and last leaf page number at the same time. */
227917 fts5WriteFinish(p, &writer, &pSeg->pgnoLast);
227918
227919 assert( pIter!=0 || p->rc!=SQLITE_OK );
227920 if( fts5MultiIterEof(p, pIter) ){
227921 int i;
227922
227923 /* Remove the redundant segments from the %_data table */
227924 for(i=0; i<nInput; i++){
@@ -226340,11 +228015,11 @@
228015 static void fts5IndexAutomerge(
228016 Fts5Index *p, /* FTS5 backend object */
228017 Fts5Structure **ppStruct, /* IN/OUT: Current structure of index */
228018 int nLeaf /* Number of output leaves just written */
228019 ){
228020 if( p->rc==SQLITE_OK && p->pConfig->nAutomerge>0 && ALWAYS((*ppStruct)!=0) ){
228021 Fts5Structure *pStruct = *ppStruct;
228022 u64 nWrite; /* Initial value of write-counter */
228023 int nWork; /* Number of work-quanta to perform */
228024 int nRem; /* Number of leaf pages left to write */
228025
@@ -227450,15 +229125,19 @@
229125 }
229126 }else{
229127 /* Scan multiple terms in the main index */
229128 int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
229129 fts5SetupPrefixIter(p, bDesc, iPrefixIdx, buf.p, nToken+1, pColset,&pRet);
229130 if( pRet==0 ){
229131 assert( p->rc!=SQLITE_OK );
229132 }else{
229133 assert( pRet->pColset==0 );
229134 fts5IterSetOutputCb(&p->rc, pRet);
229135 if( p->rc==SQLITE_OK ){
229136 Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
229137 if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
229138 }
229139 }
229140 }
229141
229142 if( p->rc ){
229143 sqlite3Fts5IterClose((Fts5IndexIter*)pRet);
@@ -227702,11 +229381,11 @@
229381 int eDetail = p->pConfig->eDetail;
229382 u64 cksum = *pCksum;
229383 Fts5IndexIter *pIter = 0;
229384 int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
229385
229386 while( rc==SQLITE_OK && ALWAYS(pIter!=0) && 0==sqlite3Fts5IterEof(pIter) ){
229387 i64 rowid = pIter->iRowid;
229388
229389 if( eDetail==FTS5_DETAIL_NONE ){
229390 cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
229391 }else{
@@ -228067,10 +229746,11 @@
229746 int eDetail = p->pConfig->eDetail;
229747 u64 cksum2 = 0; /* Checksum based on contents of indexes */
229748 Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */
229749 Fts5Iter *pIter; /* Used to iterate through entire index */
229750 Fts5Structure *pStruct; /* Index structure */
229751 int iLvl, iSeg;
229752
229753 #ifdef SQLITE_DEBUG
229754 /* Used by extra internal tests only run if NDEBUG is not defined */
229755 u64 cksum3 = 0; /* Checksum based on contents of indexes */
229756 Fts5Buffer term = {0,0,0}; /* Buffer used to hold most recent term */
@@ -228077,19 +229757,20 @@
229757 #endif
229758 const int flags = FTS5INDEX_QUERY_NOOUTPUT;
229759
229760 /* Load the FTS index structure */
229761 pStruct = fts5StructureRead(p);
229762 if( pStruct==0 ){
229763 assert( p->rc!=SQLITE_OK );
229764 return fts5IndexReturn(p);
229765 }
229766
229767 /* Check that the internal nodes of each segment match the leaves */
229768 for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
229769 for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
229770 Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg];
229771 fts5IndexIntegrityCheckSegment(p, pSeg);
 
 
 
229772 }
229773 }
229774
229775 /* The cksum argument passed to this function is a checksum calculated
229776 ** based on all expected entries in the FTS index (including prefix index
@@ -230032,11 +231713,12 @@
231713 pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN);
231714 rc = sqlite3Fts5StorageStmt(
231715 pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg
231716 );
231717 if( rc==SQLITE_OK ){
231718 if( pRowidEq!=0 ){
231719 assert( pCsr->ePlan==FTS5_PLAN_ROWID );
231720 sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq);
231721 }else{
231722 sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid);
231723 sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid);
231724 }
@@ -231450,11 +233132,11 @@
233132 int nArg, /* Number of args */
233133 sqlite3_value **apUnused /* Function arguments */
233134 ){
233135 assert( nArg==0 );
233136 UNUSED_PARAM2(nArg, apUnused);
233137 sqlite3_result_text(pCtx, "fts5: 2021-12-09 20:06:18 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882", -1, SQLITE_TRANSIENT);
233138 }
233139
233140 /*
233141 ** Return true if zName is the extension on one of the shadow tables used
233142 ** by this module.
@@ -232001,16 +233683,20 @@
233683 rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
233684 for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
233685 if( pConfig->abUnindexed[iCol-1]==0 ){
233686 const char *zText;
233687 int nText;
233688 assert( pSeek==0 || apVal==0 );
233689 assert( pSeek!=0 || apVal!=0 );
233690 if( pSeek ){
233691 zText = (const char*)sqlite3_column_text(pSeek, iCol);
233692 nText = sqlite3_column_bytes(pSeek, iCol);
233693 }else if( ALWAYS(apVal) ){
233694 zText = (const char*)sqlite3_value_text(apVal[iCol-1]);
233695 nText = sqlite3_value_bytes(apVal[iCol-1]);
233696 }else{
233697 continue;
233698 }
233699 ctx.szCol = 0;
233700 rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT,
233701 zText, nText, (void*)&ctx, fts5StorageInsertCallback
233702 );
@@ -232642,12 +234328,13 @@
234328 sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */
234329 int rc; /* Return Code */
234330
234331 assert( p->pConfig->bColumnsize );
234332 rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0);
234333 if( pLookup ){
234334 int bCorrupt = 1;
234335 assert( rc==SQLITE_OK );
234336 sqlite3_bind_int64(pLookup, 1, iRowid);
234337 if( SQLITE_ROW==sqlite3_step(pLookup) ){
234338 const u8 *aBlob = sqlite3_column_blob(pLookup, 0);
234339 int nBlob = sqlite3_column_bytes(pLookup, 0);
234340 if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){
@@ -232656,10 +234343,12 @@
234343 }
234344 rc = sqlite3_reset(pLookup);
234345 if( bCorrupt && rc==SQLITE_OK ){
234346 rc = FTS5_CORRUPT;
234347 }
234348 }else{
234349 assert( rc!=SQLITE_OK );
234350 }
234351
234352 return rc;
234353 }
234354
@@ -235660,11 +237349,11 @@
237349 rc = sqlite3Fts5FlushToDisk(pFts5);
237350 }
237351 }
237352
237353 if( rc==SQLITE_OK ){
237354 i64 nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor);
237355 pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte);
237356 }
237357
237358 if( pCsr ){
237359 pCsr->pFts5 = pFts5;
237360
+114 -12
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -144,13 +144,13 @@
144144
**
145145
** See also: [sqlite3_libversion()],
146146
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147147
** [sqlite_version()] and [sqlite_source_id()].
148148
*/
149
-#define SQLITE_VERSION "3.37.0"
150
-#define SQLITE_VERSION_NUMBER 3037000
151
-#define SQLITE_SOURCE_ID "2021-10-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813"
149
+#define SQLITE_VERSION "3.38.0"
150
+#define SQLITE_VERSION_NUMBER 3038000
151
+#define SQLITE_SOURCE_ID "2021-12-09 20:06:18 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882"
152152
153153
/*
154154
** CAPI3REF: Run-Time Library Version Numbers
155155
** KEYWORDS: sqlite3_version sqlite3_sourceid
156156
**
@@ -537,11 +537,10 @@
537537
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
538538
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
539539
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
540540
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
541541
#define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
542
-#define SQLITE_CANTOPEN_EXISTS (SQLITE_CANTOPEN | (7<<8))
543542
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
544543
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
545544
#define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
546545
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
547546
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -573,10 +572,23 @@
573572
** CAPI3REF: Flags For File Open Operations
574573
**
575574
** These bit values are intended for use in the
576575
** 3rd parameter to the [sqlite3_open_v2()] interface and
577576
** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
577
+**
578
+** Only those flags marked as "Ok for sqlite3_open_v2()" may be
579
+** used as the third argument to the [sqlite3_open_v2()] interface.
580
+** The other flags have historically been ignored by sqlite3_open_v2(),
581
+** though future versions of SQLite might change so that an error is
582
+** raised if any of the disallowed bits are passed into sqlite3_open_v2().
583
+** Applications should not depend on the historical behavior.
584
+**
585
+** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into
586
+** [sqlite3_open_v2()] does *not* cause the underlying database file
587
+** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into
588
+** [sqlite3_open_v2()] has historically be a no-op and might become an
589
+** error in future versions of SQLite.
578590
*/
579591
#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
580592
#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
581593
#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
582594
#define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
@@ -595,10 +607,11 @@
595607
#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
596608
#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
597609
#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
598610
#define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
599611
#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
612
+#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
600613
601614
/* Reserved: 0x00F00000 */
602615
/* Legacy compatibility: */
603616
#define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
604617
@@ -3414,25 +3427,35 @@
34143427
**
34153428
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
34163429
** <dd>The database is opened [shared cache] disabled, overriding
34173430
** the default shared cache setting provided by
34183431
** [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>
34193440
**
34203441
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
34213442
** <dd>The database filename is not allowed to be a symbolic link</dd>
3422
-**
3423
-** [[OPEN_EXCLUSIVE]] ^(<dt>[SQLITE_OPEN_EXCLUSIVE]</dt>
3424
-** <dd>This flag causes the open to fail if the database file already
3425
-** exists. The open will only be success if this flag is used in combination
3426
-** with the SQLITE_OPEN_CREATE and SQLITE_OPEN_READWRITE flags and if
3427
-** the file does not previously exist.</dd>
34283443
** </dl>)^
34293444
**
34303445
** If the 3rd parameter to sqlite3_open_v2() is not one of the
34313446
** required combinations shown above optionally combined with other
34323447
** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
3433
-** then the behavior is undefined.
3448
+** then the behavior is undefined. Historic versions of SQLite
3449
+** have silently ignored surplus bits in the flags parameter to
3450
+** sqlite3_open_v2(), however that behavior might not be carried through
3451
+** into future versions of SQLite and so applications should not rely
3452
+** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op
3453
+** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause
3454
+** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE
3455
+** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not
3456
+** by sqlite3_open_v2().
34343457
**
34353458
** ^The fourth parameter to sqlite3_open_v2() is the name of the
34363459
** [sqlite3_vfs] object that defines the operating system interface that
34373460
** the new database connection should use. ^If the fourth parameter is
34383461
** a NULL pointer then the default [sqlite3_vfs] object is used.
@@ -6389,10 +6412,76 @@
63896412
**
63906413
** See also the [sqlite3_update_hook()] interface.
63916414
*/
63926415
SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
63936416
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
+
63946483
63956484
/*
63966485
** CAPI3REF: Data Change Notification Callbacks
63976486
** METHOD: sqlite3
63986487
**
@@ -7853,11 +7942,12 @@
78537942
#define SQLITE_TESTCTRL_PRNG_SEED 28
78547943
#define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
78557944
#define SQLITE_TESTCTRL_SEEK_COUNT 30
78567945
#define SQLITE_TESTCTRL_TRACEFLAGS 31
78577946
#define SQLITE_TESTCTRL_TUNE 32
7858
-#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */
7947
+#define SQLITE_TESTCTRL_LOGEST 33
7948
+#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */
78597949
78607950
/*
78617951
** CAPI3REF: SQL Keyword Checking
78627952
**
78637953
** These routines provide access to the set of SQL language keywords
@@ -8375,10 +8465,20 @@
83758465
** <dd>^This is the number of times that the prepared statement has
83768466
** been run. A single "run" for the purposes of this counter is one
83778467
** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
83788468
** The counter is incremented on the first [sqlite3_step()] call of each
83798469
** cycle.
8470
+**
8471
+** [[SQLITE_STMTSTATUS_FILTER_MISS]]
8472
+** [[SQLITE_STMTSTATUS_FILTER HIT]]
8473
+** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br>
8474
+** SQLITE_STMTSTATUS_FILTER_MISS</dt>
8475
+** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join
8476
+** step was bypassed because a Bloom filter returned not-found. The
8477
+** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of
8478
+** times that the Bloom filter returned a find, and thus the join step
8479
+** had to be processed as normal.
83808480
**
83818481
** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
83828482
** <dd>^This is the approximate number of bytes of heap memory
83838483
** used to store the prepared statement. ^This value is not actually
83848484
** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -8390,10 +8490,12 @@
83908490
#define SQLITE_STMTSTATUS_SORT 2
83918491
#define SQLITE_STMTSTATUS_AUTOINDEX 3
83928492
#define SQLITE_STMTSTATUS_VM_STEP 4
83938493
#define SQLITE_STMTSTATUS_REPREPARE 5
83948494
#define SQLITE_STMTSTATUS_RUN 6
8495
+#define SQLITE_STMTSTATUS_FILTER_MISS 7
8496
+#define SQLITE_STMTSTATUS_FILTER_HIT 8
83958497
#define SQLITE_STMTSTATUS_MEMUSED 99
83968498
83978499
/*
83988500
** CAPI3REF: Custom Page Cache Object
83998501
**
84008502
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
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-04 11:10:15 8b24c177061c38361588f419eda9b7943b72a0c6b2855b6f39272451b8a1b813"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -537,11 +537,10 @@
537 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
538 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
539 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
540 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
541 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
542 #define SQLITE_CANTOPEN_EXISTS (SQLITE_CANTOPEN | (7<<8))
543 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
544 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
545 #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
546 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
547 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -573,10 +572,23 @@
573 ** CAPI3REF: Flags For File Open Operations
574 **
575 ** These bit values are intended for use in the
576 ** 3rd parameter to the [sqlite3_open_v2()] interface and
577 ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
 
 
 
 
 
 
 
 
 
 
 
 
 
578 */
579 #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
580 #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
581 #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
582 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
@@ -595,10 +607,11 @@
595 #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */
596 #define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */
597 #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */
598 #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */
599 #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */
 
600
601 /* Reserved: 0x00F00000 */
602 /* Legacy compatibility: */
603 #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */
604
@@ -3414,25 +3427,35 @@
3414 **
3415 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3416 ** <dd>The database is opened [shared cache] disabled, overriding
3417 ** the default shared cache setting provided by
3418 ** [sqlite3_enable_shared_cache()].)^
 
 
 
 
 
 
 
 
3419 **
3420 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3421 ** <dd>The database filename is not allowed to be a symbolic link</dd>
3422 **
3423 ** [[OPEN_EXCLUSIVE]] ^(<dt>[SQLITE_OPEN_EXCLUSIVE]</dt>
3424 ** <dd>This flag causes the open to fail if the database file already
3425 ** exists. The open will only be success if this flag is used in combination
3426 ** with the SQLITE_OPEN_CREATE and SQLITE_OPEN_READWRITE flags and if
3427 ** the file does not previously exist.</dd>
3428 ** </dl>)^
3429 **
3430 ** If the 3rd parameter to sqlite3_open_v2() is not one of the
3431 ** required combinations shown above optionally combined with other
3432 ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
3433 ** then the behavior is undefined.
 
 
 
 
 
 
 
 
3434 **
3435 ** ^The fourth parameter to sqlite3_open_v2() is the name of the
3436 ** [sqlite3_vfs] object that defines the operating system interface that
3437 ** the new database connection should use. ^If the fourth parameter is
3438 ** a NULL pointer then the default [sqlite3_vfs] object is used.
@@ -6389,10 +6412,76 @@
6389 **
6390 ** See also the [sqlite3_update_hook()] interface.
6391 */
6392 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
6393 SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6394
6395 /*
6396 ** CAPI3REF: Data Change Notification Callbacks
6397 ** METHOD: sqlite3
6398 **
@@ -7853,11 +7942,12 @@
7853 #define SQLITE_TESTCTRL_PRNG_SEED 28
7854 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
7855 #define SQLITE_TESTCTRL_SEEK_COUNT 30
7856 #define SQLITE_TESTCTRL_TRACEFLAGS 31
7857 #define SQLITE_TESTCTRL_TUNE 32
7858 #define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */
 
7859
7860 /*
7861 ** CAPI3REF: SQL Keyword Checking
7862 **
7863 ** These routines provide access to the set of SQL language keywords
@@ -8375,10 +8465,20 @@
8375 ** <dd>^This is the number of times that the prepared statement has
8376 ** been run. A single "run" for the purposes of this counter is one
8377 ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
8378 ** The counter is incremented on the first [sqlite3_step()] call of each
8379 ** cycle.
 
 
 
 
 
 
 
 
 
 
8380 **
8381 ** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
8382 ** <dd>^This is the approximate number of bytes of heap memory
8383 ** used to store the prepared statement. ^This value is not actually
8384 ** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -8390,10 +8490,12 @@
8390 #define SQLITE_STMTSTATUS_SORT 2
8391 #define SQLITE_STMTSTATUS_AUTOINDEX 3
8392 #define SQLITE_STMTSTATUS_VM_STEP 4
8393 #define SQLITE_STMTSTATUS_REPREPARE 5
8394 #define SQLITE_STMTSTATUS_RUN 6
 
 
8395 #define SQLITE_STMTSTATUS_MEMUSED 99
8396
8397 /*
8398 ** CAPI3REF: Custom Page Cache Object
8399 **
8400
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -144,13 +144,13 @@
144 **
145 ** See also: [sqlite3_libversion()],
146 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
147 ** [sqlite_version()] and [sqlite_source_id()].
148 */
149 #define SQLITE_VERSION "3.38.0"
150 #define SQLITE_VERSION_NUMBER 3038000
151 #define SQLITE_SOURCE_ID "2021-12-09 20:06:18 633bfeeea2bccdd44126acf3f61ecca163c9d933bdc787a2c18a697dc9406882"
152
153 /*
154 ** CAPI3REF: Run-Time Library Version Numbers
155 ** KEYWORDS: sqlite3_version sqlite3_sourceid
156 **
@@ -537,11 +537,10 @@
537 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
538 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
539 #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
540 #define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
541 #define SQLITE_CANTOPEN_SYMLINK (SQLITE_CANTOPEN | (6<<8))
 
542 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
543 #define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
544 #define SQLITE_CORRUPT_INDEX (SQLITE_CORRUPT | (3<<8))
545 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
546 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
@@ -573,10 +572,23 @@
572 ** CAPI3REF: Flags For File Open Operations
573 **
574 ** These bit values are intended for use in the
575 ** 3rd parameter to the [sqlite3_open_v2()] interface and
576 ** in the 4th parameter to the [sqlite3_vfs.xOpen] method.
577 **
578 ** Only those flags marked as "Ok for sqlite3_open_v2()" may be
579 ** used as the third argument to the [sqlite3_open_v2()] interface.
580 ** The other flags have historically been ignored by sqlite3_open_v2(),
581 ** though future versions of SQLite might change so that an error is
582 ** raised if any of the disallowed bits are passed into sqlite3_open_v2().
583 ** Applications should not depend on the historical behavior.
584 **
585 ** Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into
586 ** [sqlite3_open_v2()] does *not* cause the underlying database file
587 ** to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into
588 ** [sqlite3_open_v2()] has historically be a no-op and might become an
589 ** error in future versions of SQLite.
590 */
591 #define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */
592 #define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */
593 #define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */
594 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */
@@ -595,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
@@ -3414,25 +3427,35 @@
3427 **
3428 ** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
3429 ** <dd>The database is opened [shared cache] disabled, overriding
3430 ** the default shared cache setting provided by
3431 ** [sqlite3_enable_shared_cache()].)^
3432 **
3433 ** [[OPEN_EXRESCODE]] ^(<dt>[SQLITE_OPEN_EXRESCODE]</dt>
3434 ** <dd>The database connection comes up in "extended result code mode".
3435 ** In other words, the database behaves has if
3436 ** [sqlite3_extended_result_codes(db,1)] where called on the database
3437 ** connection as soon as the connection is created. In addition to setting
3438 ** the extended result code mode, this flag also causes [sqlite3_open_v2()]
3439 ** to return an extended result code.</dd>
3440 **
3441 ** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
3442 ** <dd>The database filename is not allowed to be a symbolic link</dd>
 
 
 
 
 
 
3443 ** </dl>)^
3444 **
3445 ** If the 3rd parameter to sqlite3_open_v2() is not one of the
3446 ** required combinations shown above optionally combined with other
3447 ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits]
3448 ** then the behavior is undefined. Historic versions of SQLite
3449 ** have silently ignored surplus bits in the flags parameter to
3450 ** sqlite3_open_v2(), however that behavior might not be carried through
3451 ** into future versions of SQLite and so applications should not rely
3452 ** upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op
3453 ** for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause
3454 ** the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE
3455 ** flag is intended for use by the [sqlite3_vfs|VFS interface] only, and not
3456 ** by sqlite3_open_v2().
3457 **
3458 ** ^The fourth parameter to sqlite3_open_v2() is the name of the
3459 ** [sqlite3_vfs] object that defines the operating system interface that
3460 ** the new database connection should use. ^If the fourth parameter is
3461 ** a NULL pointer then the default [sqlite3_vfs] object is used.
@@ -6389,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 **
@@ -7853,11 +7942,12 @@
7942 #define SQLITE_TESTCTRL_PRNG_SEED 28
7943 #define SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS 29
7944 #define SQLITE_TESTCTRL_SEEK_COUNT 30
7945 #define SQLITE_TESTCTRL_TRACEFLAGS 31
7946 #define SQLITE_TESTCTRL_TUNE 32
7947 #define SQLITE_TESTCTRL_LOGEST 33
7948 #define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */
7949
7950 /*
7951 ** CAPI3REF: SQL Keyword Checking
7952 **
7953 ** These routines provide access to the set of SQL language keywords
@@ -8375,10 +8465,20 @@
8465 ** <dd>^This is the number of times that the prepared statement has
8466 ** been run. A single "run" for the purposes of this counter is one
8467 ** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()].
8468 ** The counter is incremented on the first [sqlite3_step()] call of each
8469 ** cycle.
8470 **
8471 ** [[SQLITE_STMTSTATUS_FILTER_MISS]]
8472 ** [[SQLITE_STMTSTATUS_FILTER HIT]]
8473 ** <dt>SQLITE_STMTSTATUS_FILTER_HIT<br>
8474 ** SQLITE_STMTSTATUS_FILTER_MISS</dt>
8475 ** <dd>^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join
8476 ** step was bypassed because a Bloom filter returned not-found. The
8477 ** corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of
8478 ** times that the Bloom filter returned a find, and thus the join step
8479 ** had to be processed as normal.
8480 **
8481 ** [[SQLITE_STMTSTATUS_MEMUSED]] <dt>SQLITE_STMTSTATUS_MEMUSED</dt>
8482 ** <dd>^This is the approximate number of bytes of heap memory
8483 ** used to store the prepared statement. ^This value is not actually
8484 ** a counter, and so the resetFlg parameter to sqlite3_stmt_status()
@@ -8390,10 +8490,12 @@
8490 #define SQLITE_STMTSTATUS_SORT 2
8491 #define SQLITE_STMTSTATUS_AUTOINDEX 3
8492 #define SQLITE_STMTSTATUS_VM_STEP 4
8493 #define SQLITE_STMTSTATUS_REPREPARE 5
8494 #define SQLITE_STMTSTATUS_RUN 6
8495 #define SQLITE_STMTSTATUS_FILTER_MISS 7
8496 #define SQLITE_STMTSTATUS_FILTER_HIT 8
8497 #define SQLITE_STMTSTATUS_MEMUSED 99
8498
8499 /*
8500 ** CAPI3REF: Custom Page Cache Object
8501 **
8502
+8 -4
--- src/stash.c
+++ src/stash.c
@@ -308,12 +308,14 @@
308308
static void stash_apply(int stashid, int nConflict){
309309
int vid;
310310
Stmt q;
311311
db_prepare(&q,
312312
"SELECT blob.rid, isRemoved, isExec, isLink, origname, newname, delta"
313
- " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash",
314
- stashid
313
+ " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash"
314
+ " UNION ALL SELECT 0, isRemoved, isExec, isLink, origname, newname, delta"
315
+ " FROM stashfile WHERE stashid=%d AND stashfile.hash IS NULL",
316
+ stashid, stashid
315317
);
316318
vid = db_lget_int("checkout",0);
317319
db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
318320
filename_collation());
319321
while( db_step(&q)==SQLITE_ROW ){
@@ -412,12 +414,14 @@
412414
int bWebpage = (pCfg->diffFlags & (DIFF_WEBPAGE|DIFF_JSON|DIFF_TCL))!=0;
413415
blob_zero(&empty);
414416
diff_begin(pCfg);
415417
db_prepare(&q,
416418
"SELECT blob.rid, isRemoved, isExec, isLink, origname, newname, delta"
417
- " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash",
418
- stashid
419
+ " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash"
420
+ " UNION ALL SELECT 0, isRemoved, isExec, isLink, origname, newname, delta"
421
+ " FROM stashfile WHERE stashid=%d AND stashfile.hash IS NULL",
422
+ stashid, stashid
419423
);
420424
while( db_step(&q)==SQLITE_ROW ){
421425
int rid = db_column_int(&q, 0);
422426
int isRemoved = db_column_int(&q, 1);
423427
int isLink = db_column_int(&q, 3);
424428
--- src/stash.c
+++ src/stash.c
@@ -308,12 +308,14 @@
308 static void stash_apply(int stashid, int nConflict){
309 int vid;
310 Stmt q;
311 db_prepare(&q,
312 "SELECT blob.rid, isRemoved, isExec, isLink, origname, newname, delta"
313 " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash",
314 stashid
 
 
315 );
316 vid = db_lget_int("checkout",0);
317 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
318 filename_collation());
319 while( db_step(&q)==SQLITE_ROW ){
@@ -412,12 +414,14 @@
412 int bWebpage = (pCfg->diffFlags & (DIFF_WEBPAGE|DIFF_JSON|DIFF_TCL))!=0;
413 blob_zero(&empty);
414 diff_begin(pCfg);
415 db_prepare(&q,
416 "SELECT blob.rid, isRemoved, isExec, isLink, origname, newname, delta"
417 " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash",
418 stashid
 
 
419 );
420 while( db_step(&q)==SQLITE_ROW ){
421 int rid = db_column_int(&q, 0);
422 int isRemoved = db_column_int(&q, 1);
423 int isLink = db_column_int(&q, 3);
424
--- src/stash.c
+++ src/stash.c
@@ -308,12 +308,14 @@
308 static void stash_apply(int stashid, int nConflict){
309 int vid;
310 Stmt q;
311 db_prepare(&q,
312 "SELECT blob.rid, isRemoved, isExec, isLink, origname, newname, delta"
313 " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash"
314 " UNION ALL SELECT 0, isRemoved, isExec, isLink, origname, newname, delta"
315 " FROM stashfile WHERE stashid=%d AND stashfile.hash IS NULL",
316 stashid, stashid
317 );
318 vid = db_lget_int("checkout",0);
319 db_multi_exec("CREATE TEMP TABLE sfile(pathname TEXT PRIMARY KEY %s)",
320 filename_collation());
321 while( db_step(&q)==SQLITE_ROW ){
@@ -412,12 +414,14 @@
414 int bWebpage = (pCfg->diffFlags & (DIFF_WEBPAGE|DIFF_JSON|DIFF_TCL))!=0;
415 blob_zero(&empty);
416 diff_begin(pCfg);
417 db_prepare(&q,
418 "SELECT blob.rid, isRemoved, isExec, isLink, origname, newname, delta"
419 " FROM stashfile, blob WHERE stashid=%d AND blob.uuid=stashfile.hash"
420 " UNION ALL SELECT 0, isRemoved, isExec, isLink, origname, newname, delta"
421 " FROM stashfile WHERE stashid=%d AND stashfile.hash IS NULL",
422 stashid, stashid
423 );
424 while( db_step(&q)==SQLITE_ROW ){
425 int rid = db_column_int(&q, 0);
426 int isRemoved = db_column_int(&q, 1);
427 int isLink = db_column_int(&q, 3);
428
+7 -3
--- src/stat.c
+++ src/stat.c
@@ -392,29 +392,33 @@
392392
}
393393
n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'");
394394
fossil_print("%*s%,d\n", colWidth, "check-ins:", n);
395395
n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
396396
fossil_print("%*s%,d across all branches\n", colWidth, "files:", n);
397
- n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
398
- " WHERE tagname GLOB 'wiki-*'");
397
+ n = db_int(0, "SELECT count(*) FROM ("
398
+ "SELECT DISTINCT substr(tagname,6) "
399
+ "FROM tag JOIN tagxref USING('tagid')"
400
+ " WHERE tagname GLOB 'wiki-*'"
401
+ " AND TYPEOF(tagxref.value+0)='integer'"
402
+ ")");
399403
m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'");
400404
fossil_print("%*s%,d (%,d changes)\n", colWidth, "wiki-pages:", n, m);
401405
n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
402406
" WHERE tagname GLOB 'tkt-*'");
403407
m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'");
404408
fossil_print("%*s%,d (%,d changes)\n", colWidth, "tickets:", n, m);
405409
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
410
+ fossil_print("%*s%,d\n", colWidth, "events:", n);
406411
if( db_table_exists("repository","forumpost") ){
407412
n = db_int(0, "SELECT count(*) FROM forumpost/*scan*/");
408413
if( n>0 ){
409414
int nThread = db_int(0, "SELECT count(*) FROM forumpost"
410415
" WHERE froot=fpid");
411416
fossil_print("%*s%,d (on %,d threads)\n", colWidth, "forum-posts:",
412417
n, nThread);
413418
}
414419
}
415
- fossil_print("%*s%,d\n", colWidth, "events:", n);
416420
n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
417421
fossil_print("%*s%,d\n", colWidth, "tag-changes:", n);
418422
z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
419423
" CAST(julianday('now') - mtime AS INTEGER)"
420424
" || ' days ago' FROM event "
421425
--- src/stat.c
+++ src/stat.c
@@ -392,29 +392,33 @@
392 }
393 n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'");
394 fossil_print("%*s%,d\n", colWidth, "check-ins:", n);
395 n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
396 fossil_print("%*s%,d across all branches\n", colWidth, "files:", n);
397 n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
398 " WHERE tagname GLOB 'wiki-*'");
 
 
 
 
399 m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'");
400 fossil_print("%*s%,d (%,d changes)\n", colWidth, "wiki-pages:", n, m);
401 n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
402 " WHERE tagname GLOB 'tkt-*'");
403 m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'");
404 fossil_print("%*s%,d (%,d changes)\n", colWidth, "tickets:", n, m);
405 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
 
406 if( db_table_exists("repository","forumpost") ){
407 n = db_int(0, "SELECT count(*) FROM forumpost/*scan*/");
408 if( n>0 ){
409 int nThread = db_int(0, "SELECT count(*) FROM forumpost"
410 " WHERE froot=fpid");
411 fossil_print("%*s%,d (on %,d threads)\n", colWidth, "forum-posts:",
412 n, nThread);
413 }
414 }
415 fossil_print("%*s%,d\n", colWidth, "events:", n);
416 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
417 fossil_print("%*s%,d\n", colWidth, "tag-changes:", n);
418 z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
419 " CAST(julianday('now') - mtime AS INTEGER)"
420 " || ' days ago' FROM event "
421
--- src/stat.c
+++ src/stat.c
@@ -392,29 +392,33 @@
392 }
393 n = db_int(0, "SELECT COUNT(*) FROM event e WHERE e.type='ci'");
394 fossil_print("%*s%,d\n", colWidth, "check-ins:", n);
395 n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
396 fossil_print("%*s%,d across all branches\n", colWidth, "files:", n);
397 n = db_int(0, "SELECT count(*) FROM ("
398 "SELECT DISTINCT substr(tagname,6) "
399 "FROM tag JOIN tagxref USING('tagid')"
400 " WHERE tagname GLOB 'wiki-*'"
401 " AND TYPEOF(tagxref.value+0)='integer'"
402 ")");
403 m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='w'");
404 fossil_print("%*s%,d (%,d changes)\n", colWidth, "wiki-pages:", n, m);
405 n = db_int(0, "SELECT count(*) FROM tag /*scan*/"
406 " WHERE tagname GLOB 'tkt-*'");
407 m = db_int(0, "SELECT COUNT(*) FROM event WHERE type='t'");
408 fossil_print("%*s%,d (%,d changes)\n", colWidth, "tickets:", n, m);
409 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='e'");
410 fossil_print("%*s%,d\n", colWidth, "events:", n);
411 if( db_table_exists("repository","forumpost") ){
412 n = db_int(0, "SELECT count(*) FROM forumpost/*scan*/");
413 if( n>0 ){
414 int nThread = db_int(0, "SELECT count(*) FROM forumpost"
415 " WHERE froot=fpid");
416 fossil_print("%*s%,d (on %,d threads)\n", colWidth, "forum-posts:",
417 n, nThread);
418 }
419 }
 
420 n = db_int(0, "SELECT COUNT(*) FROM event WHERE type='g'");
421 fossil_print("%*s%,d\n", colWidth, "tag-changes:", n);
422 z = db_text(0, "SELECT datetime(mtime) || ' - about ' ||"
423 " CAST(julianday('now') - mtime AS INTEGER)"
424 " || ' days ago' FROM event "
425
+111 -46
--- src/style.chat.css
+++ src/style.chat.css
@@ -40,13 +40,11 @@
4040
min-width: 9em /*avoid unsightly "underlap" with the neighboring
4141
.message-widget-tab element*/;
4242
white-space: normal;
4343
}
4444
body.chat.monospace-messages .message-widget-content,
45
-/*body.chat.monospace-messages textarea,*/
46
-/*body.chat.monospace-messages input[type=text],*/
47
-body.chat.monospace-messages #chat-input-field{
45
+body.chat.monospace-messages .chat-input-field{
4846
font-family: monospace;
4947
}
5048
body.chat .message-widget-content > * {
5149
margin: 0;
5250
padding: 0;
@@ -58,10 +56,31 @@
5856
margin-top: 0;
5957
}
6058
body.chat .message-widget-content > .markdown > *:last-child {
6159
margin-bottom: 0;
6260
}
61
+body.chat .message-widget-content.error .buttons {
62
+ display: flex;
63
+ flex-direction: row;
64
+ justify-content: space-around;
65
+ flex-wrap: wrap;
66
+}
67
+body.chat .message-widget-content.error .buttons > button {
68
+ margin: 0.25em;
69
+}
70
+
71
+body.chat .message-widget-content.error a {
72
+ color: inherit;
73
+}
74
+body.chat .message-widget-content.error .failed-message {
75
+ display: flex;
76
+ flex-direction: column;
77
+}
78
+body.chat .message-widget-content.error .failed-message textarea {
79
+ min-height: 5rem;
80
+}
81
+
6382
/* User name and timestamp (a LEGEND-like element) */
6483
body.chat .message-widget .message-widget-tab {
6584
border-radius: 0.25em 0.25em 0 0;
6685
margin: 0 0.25em 0em 0.15em;
6786
padding: 0 0.5em 0.15em 0.5em;
@@ -181,28 +200,40 @@
181200
/* Safari user reports that 2em is necessary to keep the file selection
182201
widget from overlapping the page footer, whereas a margin of 0 is fine
183202
for FF/Chrome (and 2em is a *huge* waste of space for those). */
184203
margin-bottom: 0;
185204
}
186
-#chat-input-field {
187
- display: inline-block/*supposed workaround for Chrome weirdness*/;
188
- padding: 0.2em;
205
+.chat-input-field {
189206
flex: 10 1 auto;
190
- background-color: rgba(156,156,156,0.3);
207
+ margin: 0;
208
+}
209
+#chat-input-field-x,
210
+#chat-input-field-multi {
191211
overflow: auto;
192212
resize: vertical;
193213
}
194
-#chat-input-field:empty::before {
214
+#chat-input-field-x {
215
+ display: inline-block/*supposed workaround for Chrome weirdness*/;
216
+ padding: 0.2em;
217
+ background-color: rgba(156,156,156,0.3);
218
+ white-space: pre-wrap;
219
+ /* ^^^ Firefox, when pasting plain text into a contenteditable field,
220
+ loses all newlines unless we explicitly set this. Chrome does not. */
221
+ cursor: text;
222
+ /* ^^^ In some browsers the cursor may not change for a contenteditable
223
+ element until it has focus, causing potential confusion. */
224
+}
225
+#chat-input-field-x:empty::before {
195226
content: attr(data-placeholder);
196227
opacity: 0.6;
197228
}
198
-#chat-input-field:not(:focus){
229
+.chat-input-field:not(:focus){
199230
border-width: 1px;
200231
border-style: solid;
201232
border-radius: 0.25em;
202233
}
203
-#chat-input-field:focus{
234
+.chat-input-field:focus{
204235
/* This transparent border helps avoid the text shifting around
205236
when the contenteditable attribute causes a border (which we
206237
apparently cannot style) to be added. */
207238
border-width: 1px;
208239
border-style: solid;
@@ -209,20 +240,20 @@
209240
border-color: transparent;
210241
border-radius: 0.25em;
211242
}
212243
/* Widget holding the chat message input field, send button, and
213244
settings button. */
214
-body.chat #chat-input-line {
245
+body.chat #chat-input-line-wrapper {
215246
display: flex;
216247
flex-direction: row;
217248
align-items: stretch;
218249
flex-wrap: nowrap;
219250
}
220
-/*body.chat #chat-input-line:not(.compact) {
251
+/*body.chat #chat-input-line-wrapper:not(.compact) {
221252
flex-wrap: nowrap;
222253
}*/
223
-body.chat #chat-input-line.compact {
254
+body.chat #chat-input-line-wrapper.compact {
224255
/* "The problem" with wrapping, together with a contenteditable input
225256
field, is that the latter grows as the user types, so causes
226257
wrapping to happen while they type, then to unwrap as soon as the
227258
input field is cleared (when the message is sent). When we stay
228259
wrapped in compact mode, the wrapped buttons simply take up too
@@ -235,11 +266,11 @@
235266
only way to eliminate the possibility that (A) the buttons
236267
get truncated in very narrow windows and (B) that they keep
237268
stable positions.
238269
*/
239270
}
240
-body.chat #chat-input-line.compact #chat-input-field {
271
+body.chat #chat-input-line-wrapper.compact #chat-input-field-x {
241272
}
242273
243274
body.chat #chat-buttons-wrapper {
244275
flex: 0 1 auto;
245276
display: flex;
@@ -249,11 +280,11 @@
249280
min-height: 1.5em;
250281
align-self: flex-end
251282
/*keep buttons stable at bottom/right even when input field
252283
resizes */;
253284
}
254
-body.chat #chat-input-line.compact #chat-buttons-wrapper {
285
+body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper {
255286
flex-direction: row;
256287
flex: 1 1 auto;
257288
align-self: stretch;
258289
justify-content: flex-end;
259290
/*flex-wrap: wrap;*/
@@ -267,12 +298,12 @@
267298
border-width: 1px;
268299
border-style: solid;
269300
border-radius: 0.25em;
270301
min-width: 4ex;
271302
max-width: 4ex;
272
- min-height: 4ex;
273
- max-height: 4ex;
303
+ min-height: 3ex;
304
+ max-height: 3ex;
274305
margin: 0.125em;
275306
display: inline-flex;
276307
justify-content: center;
277308
align-items: center;
278309
cursor: pointer;
@@ -279,28 +310,27 @@
279310
font-size: 130%;
280311
}
281312
body.chat #chat-buttons-wrapper > .cbutton:hover {
282313
background-color: rgba(200,200,200,0.3);
283314
}
284
-body.chat #chat-input-line.compact #chat-buttons-wrapper > .cbutton {
315
+body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper > .cbutton {
285316
margin: 2px 0.125em 0 0.125em;
286317
min-width: 6ex;
287318
max-width: 6ex;
288319
min-height: 2.3ex;
289320
max-height: 2.3ex;
290321
font-size: 120%;
291322
}
292
-body.chat #chat-input-line.compact #chat-buttons-wrapper #chat-button-submit {
323
+body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper #chat-button-submit {
293324
min-width: 12ex;
294325
}
295
-body.chat #chat-input-line:not(.compact) #chat-input-field {
296
- /*border-left-style: double;
297
- border-left-width: 3px;
298
- border-right-style: double;
299
- border-right-width: 3px;*/
326
+.chat-input-field {
327
+ font-family: inherit
328
+}
329
+body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-multi,
330
+body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-x {
300331
min-height: 4rem;
301
- /*max-height: 50rem;*/
302332
/*
303333
Problems related to max-height:
304334
305335
- If we do NOT set a max-height then pasting/typing a large amount
306336
of text can cause this element to grow without bounds, larger than
@@ -311,25 +341,25 @@
311341
312342
- If we DO set a max-height then its growth is bounded but it also
313343
cannot manually expanded by the user.
314344
315345
The lesser of the two evils seems to be to rely on the browser
316
- feature that a manual resize of the element will pin its sits.
346
+ feature that a manual resize of the element will pin its size.
317347
*/
318348
}
319349
320
-body.chat #chat-input-line > #chat-button-settings{
350
+body.chat #chat-input-line-wrapper > #chat-button-settings{
321351
margin: 0 0 0 0.25em;
322352
max-width: 2em;
323353
}
324
-body.chat #chat-input-line > input[type=text],
325
-body.chat #chat-input-line > textarea {
354
+body.chat #chat-input-line-wrapper > input[type=text],
355
+body.chat #chat-input-line-wrapper > textarea {
326356
flex: 20 1 auto;
327357
max-width: revert;
328358
min-width: 20em;
329359
}
330
-body.chat #chat-input-line.compact > input[type=text] {
360
+body.chat #chat-input-line-wrapper.compact > input[type=text] {
331361
margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
332362
}
333363
/* Widget holding the file selection control and preview */
334364
body.chat #chat-input-file-area {
335365
display: flex;
@@ -361,11 +391,14 @@
361391
white-space: pre;
362392
font-family: monospace;
363393
margin: auto;
364394
flex: 0;
365395
}
366
-
396
+body.chat #chat-drop-details:empty {
397
+ padding: 0;
398
+ margin: 0;
399
+}
367400
body.chat #chat-drop-details img {
368401
max-width: 45%;
369402
max-height: 45%;
370403
}
371404
body.chat .chat-view {
@@ -389,37 +422,69 @@
389422
/* /chat config options go here */
390423
flex: 1 1 auto;
391424
display: flex;
392425
flex-direction: column;
393426
overflow: auto;
427
+ align-items: stretch;
394428
}
395429
body.chat #chat-config #chat-config-options .menu-entry {
396430
display: flex;
397
- align-items: baseline;
398
- flex-direction: row;
431
+ align-items: center;
432
+ flex-direction: row-reverse;
399433
flex-wrap: nowrap;
400434
padding: 1em;
435
+ flex: 1 1 auto;
436
+ align-self: stretch;
437
+}
438
+body.chat #chat-config #chat-config-options .menu-entry.parent{
439
+ border-radius: 1em 1em 0 1em;
440
+ margin-top: 1em;
441
+}
442
+body.chat #chat-config #chat-config-options .menu-entry.child {
443
+ /*padding-left: 2.5em;*/
444
+ margin-left: 2em;
445
+}
446
+body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){
447
+ background-color: rgba(175,175,175,0.15);
448
+}
449
+body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){
450
+ background-color: rgba(175,175,175,0.35);
451
+}
452
+body.chat #chat-config #chat-config-options .menu-entry:first-child {
453
+ /* Config list header */
454
+ border-radius: 0 0 1em 1em;
455
+}
456
+body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper {
457
+ align-items: start;
458
+}
459
+body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper {
460
+ /* Holder for a checkbox, if any */
461
+ min-width: 1.5rem;
462
+ margin-right: 1rem;
463
+}
464
+body.chat #chat-config #chat-config-options .menu-entry .label-wrapper {
465
+ /* Wrapper for a LABEL and a .hint element. */
466
+ display: flex;
467
+ flex-direction: column;
468
+ align-self: baseline;
469
+ flex: 1 1 auto;
470
+}
471
+body.chat #chat-config #chat-config-options .menu-entry label {
472
+ /* Config option label. */
473
+ font-weight: bold;
474
+ white-space: initial;
401475
}
402476
body.chat #chat-config #chat-config-options .menu-entry label[for] {
403477
cursor: pointer;
404478
}
405
-body.chat #chat-config #chat-config-options .menu-entry > *:first-child {
406
- min-width: 1.5rem;
407
-}
408
-body.chat #chat-config #chat-config-options .menu-entry span.hint {
479
+body.chat #chat-config #chat-config-options .menu-entry .hint {
409480
/* Config menu hint text */
410
- font-size: 80%;
481
+ font-size: 85%;
482
+ font-weight: normal;
411483
white-space: pre-wrap;
412484
display: inline-block;
413
-}
414
-body.chat #chat-config #chat-config-options .menu-entry:first-child {
415
-}
416
-body.chat #chat-config #chat-config-options .menu-entry div.label-wrapper {
417
- display: flex;
418
- flex-direction: column;
419
- align-self: baseline;
420
- margin-left: 1em;
485
+ opacity: 0.85;
421486
}
422487
body.chat #chat-config #chat-config-options .menu-entry select {
423488
}
424489
body.chat #chat-preview #chat-preview-content {
425490
overflow: auto;
426491
--- src/style.chat.css
+++ src/style.chat.css
@@ -40,13 +40,11 @@
40 min-width: 9em /*avoid unsightly "underlap" with the neighboring
41 .message-widget-tab element*/;
42 white-space: normal;
43 }
44 body.chat.monospace-messages .message-widget-content,
45 /*body.chat.monospace-messages textarea,*/
46 /*body.chat.monospace-messages input[type=text],*/
47 body.chat.monospace-messages #chat-input-field{
48 font-family: monospace;
49 }
50 body.chat .message-widget-content > * {
51 margin: 0;
52 padding: 0;
@@ -58,10 +56,31 @@
58 margin-top: 0;
59 }
60 body.chat .message-widget-content > .markdown > *:last-child {
61 margin-bottom: 0;
62 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63 /* User name and timestamp (a LEGEND-like element) */
64 body.chat .message-widget .message-widget-tab {
65 border-radius: 0.25em 0.25em 0 0;
66 margin: 0 0.25em 0em 0.15em;
67 padding: 0 0.5em 0.15em 0.5em;
@@ -181,28 +200,40 @@
181 /* Safari user reports that 2em is necessary to keep the file selection
182 widget from overlapping the page footer, whereas a margin of 0 is fine
183 for FF/Chrome (and 2em is a *huge* waste of space for those). */
184 margin-bottom: 0;
185 }
186 #chat-input-field {
187 display: inline-block/*supposed workaround for Chrome weirdness*/;
188 padding: 0.2em;
189 flex: 10 1 auto;
190 background-color: rgba(156,156,156,0.3);
 
 
 
191 overflow: auto;
192 resize: vertical;
193 }
194 #chat-input-field:empty::before {
 
 
 
 
 
 
 
 
 
 
 
195 content: attr(data-placeholder);
196 opacity: 0.6;
197 }
198 #chat-input-field:not(:focus){
199 border-width: 1px;
200 border-style: solid;
201 border-radius: 0.25em;
202 }
203 #chat-input-field:focus{
204 /* This transparent border helps avoid the text shifting around
205 when the contenteditable attribute causes a border (which we
206 apparently cannot style) to be added. */
207 border-width: 1px;
208 border-style: solid;
@@ -209,20 +240,20 @@
209 border-color: transparent;
210 border-radius: 0.25em;
211 }
212 /* Widget holding the chat message input field, send button, and
213 settings button. */
214 body.chat #chat-input-line {
215 display: flex;
216 flex-direction: row;
217 align-items: stretch;
218 flex-wrap: nowrap;
219 }
220 /*body.chat #chat-input-line:not(.compact) {
221 flex-wrap: nowrap;
222 }*/
223 body.chat #chat-input-line.compact {
224 /* "The problem" with wrapping, together with a contenteditable input
225 field, is that the latter grows as the user types, so causes
226 wrapping to happen while they type, then to unwrap as soon as the
227 input field is cleared (when the message is sent). When we stay
228 wrapped in compact mode, the wrapped buttons simply take up too
@@ -235,11 +266,11 @@
235 only way to eliminate the possibility that (A) the buttons
236 get truncated in very narrow windows and (B) that they keep
237 stable positions.
238 */
239 }
240 body.chat #chat-input-line.compact #chat-input-field {
241 }
242
243 body.chat #chat-buttons-wrapper {
244 flex: 0 1 auto;
245 display: flex;
@@ -249,11 +280,11 @@
249 min-height: 1.5em;
250 align-self: flex-end
251 /*keep buttons stable at bottom/right even when input field
252 resizes */;
253 }
254 body.chat #chat-input-line.compact #chat-buttons-wrapper {
255 flex-direction: row;
256 flex: 1 1 auto;
257 align-self: stretch;
258 justify-content: flex-end;
259 /*flex-wrap: wrap;*/
@@ -267,12 +298,12 @@
267 border-width: 1px;
268 border-style: solid;
269 border-radius: 0.25em;
270 min-width: 4ex;
271 max-width: 4ex;
272 min-height: 4ex;
273 max-height: 4ex;
274 margin: 0.125em;
275 display: inline-flex;
276 justify-content: center;
277 align-items: center;
278 cursor: pointer;
@@ -279,28 +310,27 @@
279 font-size: 130%;
280 }
281 body.chat #chat-buttons-wrapper > .cbutton:hover {
282 background-color: rgba(200,200,200,0.3);
283 }
284 body.chat #chat-input-line.compact #chat-buttons-wrapper > .cbutton {
285 margin: 2px 0.125em 0 0.125em;
286 min-width: 6ex;
287 max-width: 6ex;
288 min-height: 2.3ex;
289 max-height: 2.3ex;
290 font-size: 120%;
291 }
292 body.chat #chat-input-line.compact #chat-buttons-wrapper #chat-button-submit {
293 min-width: 12ex;
294 }
295 body.chat #chat-input-line:not(.compact) #chat-input-field {
296 /*border-left-style: double;
297 border-left-width: 3px;
298 border-right-style: double;
299 border-right-width: 3px;*/
300 min-height: 4rem;
301 /*max-height: 50rem;*/
302 /*
303 Problems related to max-height:
304
305 - If we do NOT set a max-height then pasting/typing a large amount
306 of text can cause this element to grow without bounds, larger than
@@ -311,25 +341,25 @@
311
312 - If we DO set a max-height then its growth is bounded but it also
313 cannot manually expanded by the user.
314
315 The lesser of the two evils seems to be to rely on the browser
316 feature that a manual resize of the element will pin its sits.
317 */
318 }
319
320 body.chat #chat-input-line > #chat-button-settings{
321 margin: 0 0 0 0.25em;
322 max-width: 2em;
323 }
324 body.chat #chat-input-line > input[type=text],
325 body.chat #chat-input-line > textarea {
326 flex: 20 1 auto;
327 max-width: revert;
328 min-width: 20em;
329 }
330 body.chat #chat-input-line.compact > input[type=text] {
331 margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
332 }
333 /* Widget holding the file selection control and preview */
334 body.chat #chat-input-file-area {
335 display: flex;
@@ -361,11 +391,14 @@
361 white-space: pre;
362 font-family: monospace;
363 margin: auto;
364 flex: 0;
365 }
366
 
 
 
367 body.chat #chat-drop-details img {
368 max-width: 45%;
369 max-height: 45%;
370 }
371 body.chat .chat-view {
@@ -389,37 +422,69 @@
389 /* /chat config options go here */
390 flex: 1 1 auto;
391 display: flex;
392 flex-direction: column;
393 overflow: auto;
 
394 }
395 body.chat #chat-config #chat-config-options .menu-entry {
396 display: flex;
397 align-items: baseline;
398 flex-direction: row;
399 flex-wrap: nowrap;
400 padding: 1em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401 }
402 body.chat #chat-config #chat-config-options .menu-entry label[for] {
403 cursor: pointer;
404 }
405 body.chat #chat-config #chat-config-options .menu-entry > *:first-child {
406 min-width: 1.5rem;
407 }
408 body.chat #chat-config #chat-config-options .menu-entry span.hint {
409 /* Config menu hint text */
410 font-size: 80%;
 
411 white-space: pre-wrap;
412 display: inline-block;
413 }
414 body.chat #chat-config #chat-config-options .menu-entry:first-child {
415 }
416 body.chat #chat-config #chat-config-options .menu-entry div.label-wrapper {
417 display: flex;
418 flex-direction: column;
419 align-self: baseline;
420 margin-left: 1em;
421 }
422 body.chat #chat-config #chat-config-options .menu-entry select {
423 }
424 body.chat #chat-preview #chat-preview-content {
425 overflow: auto;
426
--- src/style.chat.css
+++ src/style.chat.css
@@ -40,13 +40,11 @@
40 min-width: 9em /*avoid unsightly "underlap" with the neighboring
41 .message-widget-tab element*/;
42 white-space: normal;
43 }
44 body.chat.monospace-messages .message-widget-content,
45 body.chat.monospace-messages .chat-input-field{
 
 
46 font-family: monospace;
47 }
48 body.chat .message-widget-content > * {
49 margin: 0;
50 padding: 0;
@@ -58,10 +56,31 @@
56 margin-top: 0;
57 }
58 body.chat .message-widget-content > .markdown > *:last-child {
59 margin-bottom: 0;
60 }
61 body.chat .message-widget-content.error .buttons {
62 display: flex;
63 flex-direction: row;
64 justify-content: space-around;
65 flex-wrap: wrap;
66 }
67 body.chat .message-widget-content.error .buttons > button {
68 margin: 0.25em;
69 }
70
71 body.chat .message-widget-content.error a {
72 color: inherit;
73 }
74 body.chat .message-widget-content.error .failed-message {
75 display: flex;
76 flex-direction: column;
77 }
78 body.chat .message-widget-content.error .failed-message textarea {
79 min-height: 5rem;
80 }
81
82 /* User name and timestamp (a LEGEND-like element) */
83 body.chat .message-widget .message-widget-tab {
84 border-radius: 0.25em 0.25em 0 0;
85 margin: 0 0.25em 0em 0.15em;
86 padding: 0 0.5em 0.15em 0.5em;
@@ -181,28 +200,40 @@
200 /* Safari user reports that 2em is necessary to keep the file selection
201 widget from overlapping the page footer, whereas a margin of 0 is fine
202 for FF/Chrome (and 2em is a *huge* waste of space for those). */
203 margin-bottom: 0;
204 }
205 .chat-input-field {
 
 
206 flex: 10 1 auto;
207 margin: 0;
208 }
209 #chat-input-field-x,
210 #chat-input-field-multi {
211 overflow: auto;
212 resize: vertical;
213 }
214 #chat-input-field-x {
215 display: inline-block/*supposed workaround for Chrome weirdness*/;
216 padding: 0.2em;
217 background-color: rgba(156,156,156,0.3);
218 white-space: pre-wrap;
219 /* ^^^ Firefox, when pasting plain text into a contenteditable field,
220 loses all newlines unless we explicitly set this. Chrome does not. */
221 cursor: text;
222 /* ^^^ In some browsers the cursor may not change for a contenteditable
223 element until it has focus, causing potential confusion. */
224 }
225 #chat-input-field-x:empty::before {
226 content: attr(data-placeholder);
227 opacity: 0.6;
228 }
229 .chat-input-field:not(:focus){
230 border-width: 1px;
231 border-style: solid;
232 border-radius: 0.25em;
233 }
234 .chat-input-field:focus{
235 /* This transparent border helps avoid the text shifting around
236 when the contenteditable attribute causes a border (which we
237 apparently cannot style) to be added. */
238 border-width: 1px;
239 border-style: solid;
@@ -209,20 +240,20 @@
240 border-color: transparent;
241 border-radius: 0.25em;
242 }
243 /* Widget holding the chat message input field, send button, and
244 settings button. */
245 body.chat #chat-input-line-wrapper {
246 display: flex;
247 flex-direction: row;
248 align-items: stretch;
249 flex-wrap: nowrap;
250 }
251 /*body.chat #chat-input-line-wrapper:not(.compact) {
252 flex-wrap: nowrap;
253 }*/
254 body.chat #chat-input-line-wrapper.compact {
255 /* "The problem" with wrapping, together with a contenteditable input
256 field, is that the latter grows as the user types, so causes
257 wrapping to happen while they type, then to unwrap as soon as the
258 input field is cleared (when the message is sent). When we stay
259 wrapped in compact mode, the wrapped buttons simply take up too
@@ -235,11 +266,11 @@
266 only way to eliminate the possibility that (A) the buttons
267 get truncated in very narrow windows and (B) that they keep
268 stable positions.
269 */
270 }
271 body.chat #chat-input-line-wrapper.compact #chat-input-field-x {
272 }
273
274 body.chat #chat-buttons-wrapper {
275 flex: 0 1 auto;
276 display: flex;
@@ -249,11 +280,11 @@
280 min-height: 1.5em;
281 align-self: flex-end
282 /*keep buttons stable at bottom/right even when input field
283 resizes */;
284 }
285 body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper {
286 flex-direction: row;
287 flex: 1 1 auto;
288 align-self: stretch;
289 justify-content: flex-end;
290 /*flex-wrap: wrap;*/
@@ -267,12 +298,12 @@
298 border-width: 1px;
299 border-style: solid;
300 border-radius: 0.25em;
301 min-width: 4ex;
302 max-width: 4ex;
303 min-height: 3ex;
304 max-height: 3ex;
305 margin: 0.125em;
306 display: inline-flex;
307 justify-content: center;
308 align-items: center;
309 cursor: pointer;
@@ -279,28 +310,27 @@
310 font-size: 130%;
311 }
312 body.chat #chat-buttons-wrapper > .cbutton:hover {
313 background-color: rgba(200,200,200,0.3);
314 }
315 body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper > .cbutton {
316 margin: 2px 0.125em 0 0.125em;
317 min-width: 6ex;
318 max-width: 6ex;
319 min-height: 2.3ex;
320 max-height: 2.3ex;
321 font-size: 120%;
322 }
323 body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper #chat-button-submit {
324 min-width: 12ex;
325 }
326 .chat-input-field {
327 font-family: inherit
328 }
329 body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-multi,
330 body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-x {
331 min-height: 4rem;
 
332 /*
333 Problems related to max-height:
334
335 - If we do NOT set a max-height then pasting/typing a large amount
336 of text can cause this element to grow without bounds, larger than
@@ -311,25 +341,25 @@
341
342 - If we DO set a max-height then its growth is bounded but it also
343 cannot manually expanded by the user.
344
345 The lesser of the two evils seems to be to rely on the browser
346 feature that a manual resize of the element will pin its size.
347 */
348 }
349
350 body.chat #chat-input-line-wrapper > #chat-button-settings{
351 margin: 0 0 0 0.25em;
352 max-width: 2em;
353 }
354 body.chat #chat-input-line-wrapper > input[type=text],
355 body.chat #chat-input-line-wrapper > textarea {
356 flex: 20 1 auto;
357 max-width: revert;
358 min-width: 20em;
359 }
360 body.chat #chat-input-line-wrapper.compact > input[type=text] {
361 margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
362 }
363 /* Widget holding the file selection control and preview */
364 body.chat #chat-input-file-area {
365 display: flex;
@@ -361,11 +391,14 @@
391 white-space: pre;
392 font-family: monospace;
393 margin: auto;
394 flex: 0;
395 }
396 body.chat #chat-drop-details:empty {
397 padding: 0;
398 margin: 0;
399 }
400 body.chat #chat-drop-details img {
401 max-width: 45%;
402 max-height: 45%;
403 }
404 body.chat .chat-view {
@@ -389,37 +422,69 @@
422 /* /chat config options go here */
423 flex: 1 1 auto;
424 display: flex;
425 flex-direction: column;
426 overflow: auto;
427 align-items: stretch;
428 }
429 body.chat #chat-config #chat-config-options .menu-entry {
430 display: flex;
431 align-items: center;
432 flex-direction: row-reverse;
433 flex-wrap: nowrap;
434 padding: 1em;
435 flex: 1 1 auto;
436 align-self: stretch;
437 }
438 body.chat #chat-config #chat-config-options .menu-entry.parent{
439 border-radius: 1em 1em 0 1em;
440 margin-top: 1em;
441 }
442 body.chat #chat-config #chat-config-options .menu-entry.child {
443 /*padding-left: 2.5em;*/
444 margin-left: 2em;
445 }
446 body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){
447 background-color: rgba(175,175,175,0.15);
448 }
449 body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){
450 background-color: rgba(175,175,175,0.35);
451 }
452 body.chat #chat-config #chat-config-options .menu-entry:first-child {
453 /* Config list header */
454 border-radius: 0 0 1em 1em;
455 }
456 body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper {
457 align-items: start;
458 }
459 body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper {
460 /* Holder for a checkbox, if any */
461 min-width: 1.5rem;
462 margin-right: 1rem;
463 }
464 body.chat #chat-config #chat-config-options .menu-entry .label-wrapper {
465 /* Wrapper for a LABEL and a .hint element. */
466 display: flex;
467 flex-direction: column;
468 align-self: baseline;
469 flex: 1 1 auto;
470 }
471 body.chat #chat-config #chat-config-options .menu-entry label {
472 /* Config option label. */
473 font-weight: bold;
474 white-space: initial;
475 }
476 body.chat #chat-config #chat-config-options .menu-entry label[for] {
477 cursor: pointer;
478 }
479 body.chat #chat-config #chat-config-options .menu-entry .hint {
 
 
 
480 /* Config menu hint text */
481 font-size: 85%;
482 font-weight: normal;
483 white-space: pre-wrap;
484 display: inline-block;
485 opacity: 0.85;
 
 
 
 
 
 
 
486 }
487 body.chat #chat-config #chat-config-options .menu-entry select {
488 }
489 body.chat #chat-preview #chat-preview-content {
490 overflow: auto;
491
+111 -46
--- src/style.chat.css
+++ src/style.chat.css
@@ -40,13 +40,11 @@
4040
min-width: 9em /*avoid unsightly "underlap" with the neighboring
4141
.message-widget-tab element*/;
4242
white-space: normal;
4343
}
4444
body.chat.monospace-messages .message-widget-content,
45
-/*body.chat.monospace-messages textarea,*/
46
-/*body.chat.monospace-messages input[type=text],*/
47
-body.chat.monospace-messages #chat-input-field{
45
+body.chat.monospace-messages .chat-input-field{
4846
font-family: monospace;
4947
}
5048
body.chat .message-widget-content > * {
5149
margin: 0;
5250
padding: 0;
@@ -58,10 +56,31 @@
5856
margin-top: 0;
5957
}
6058
body.chat .message-widget-content > .markdown > *:last-child {
6159
margin-bottom: 0;
6260
}
61
+body.chat .message-widget-content.error .buttons {
62
+ display: flex;
63
+ flex-direction: row;
64
+ justify-content: space-around;
65
+ flex-wrap: wrap;
66
+}
67
+body.chat .message-widget-content.error .buttons > button {
68
+ margin: 0.25em;
69
+}
70
+
71
+body.chat .message-widget-content.error a {
72
+ color: inherit;
73
+}
74
+body.chat .message-widget-content.error .failed-message {
75
+ display: flex;
76
+ flex-direction: column;
77
+}
78
+body.chat .message-widget-content.error .failed-message textarea {
79
+ min-height: 5rem;
80
+}
81
+
6382
/* User name and timestamp (a LEGEND-like element) */
6483
body.chat .message-widget .message-widget-tab {
6584
border-radius: 0.25em 0.25em 0 0;
6685
margin: 0 0.25em 0em 0.15em;
6786
padding: 0 0.5em 0.15em 0.5em;
@@ -181,28 +200,40 @@
181200
/* Safari user reports that 2em is necessary to keep the file selection
182201
widget from overlapping the page footer, whereas a margin of 0 is fine
183202
for FF/Chrome (and 2em is a *huge* waste of space for those). */
184203
margin-bottom: 0;
185204
}
186
-#chat-input-field {
187
- display: inline-block/*supposed workaround for Chrome weirdness*/;
188
- padding: 0.2em;
205
+.chat-input-field {
189206
flex: 10 1 auto;
190
- background-color: rgba(156,156,156,0.3);
207
+ margin: 0;
208
+}
209
+#chat-input-field-x,
210
+#chat-input-field-multi {
191211
overflow: auto;
192212
resize: vertical;
193213
}
194
-#chat-input-field:empty::before {
214
+#chat-input-field-x {
215
+ display: inline-block/*supposed workaround for Chrome weirdness*/;
216
+ padding: 0.2em;
217
+ background-color: rgba(156,156,156,0.3);
218
+ white-space: pre-wrap;
219
+ /* ^^^ Firefox, when pasting plain text into a contenteditable field,
220
+ loses all newlines unless we explicitly set this. Chrome does not. */
221
+ cursor: text;
222
+ /* ^^^ In some browsers the cursor may not change for a contenteditable
223
+ element until it has focus, causing potential confusion. */
224
+}
225
+#chat-input-field-x:empty::before {
195226
content: attr(data-placeholder);
196227
opacity: 0.6;
197228
}
198
-#chat-input-field:not(:focus){
229
+.chat-input-field:not(:focus){
199230
border-width: 1px;
200231
border-style: solid;
201232
border-radius: 0.25em;
202233
}
203
-#chat-input-field:focus{
234
+.chat-input-field:focus{
204235
/* This transparent border helps avoid the text shifting around
205236
when the contenteditable attribute causes a border (which we
206237
apparently cannot style) to be added. */
207238
border-width: 1px;
208239
border-style: solid;
@@ -209,20 +240,20 @@
209240
border-color: transparent;
210241
border-radius: 0.25em;
211242
}
212243
/* Widget holding the chat message input field, send button, and
213244
settings button. */
214
-body.chat #chat-input-line {
245
+body.chat #chat-input-line-wrapper {
215246
display: flex;
216247
flex-direction: row;
217248
align-items: stretch;
218249
flex-wrap: nowrap;
219250
}
220
-/*body.chat #chat-input-line:not(.compact) {
251
+/*body.chat #chat-input-line-wrapper:not(.compact) {
221252
flex-wrap: nowrap;
222253
}*/
223
-body.chat #chat-input-line.compact {
254
+body.chat #chat-input-line-wrapper.compact {
224255
/* "The problem" with wrapping, together with a contenteditable input
225256
field, is that the latter grows as the user types, so causes
226257
wrapping to happen while they type, then to unwrap as soon as the
227258
input field is cleared (when the message is sent). When we stay
228259
wrapped in compact mode, the wrapped buttons simply take up too
@@ -235,11 +266,11 @@
235266
only way to eliminate the possibility that (A) the buttons
236267
get truncated in very narrow windows and (B) that they keep
237268
stable positions.
238269
*/
239270
}
240
-body.chat #chat-input-line.compact #chat-input-field {
271
+body.chat #chat-input-line-wrapper.compact #chat-input-field-x {
241272
}
242273
243274
body.chat #chat-buttons-wrapper {
244275
flex: 0 1 auto;
245276
display: flex;
@@ -249,11 +280,11 @@
249280
min-height: 1.5em;
250281
align-self: flex-end
251282
/*keep buttons stable at bottom/right even when input field
252283
resizes */;
253284
}
254
-body.chat #chat-input-line.compact #chat-buttons-wrapper {
285
+body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper {
255286
flex-direction: row;
256287
flex: 1 1 auto;
257288
align-self: stretch;
258289
justify-content: flex-end;
259290
/*flex-wrap: wrap;*/
@@ -267,12 +298,12 @@
267298
border-width: 1px;
268299
border-style: solid;
269300
border-radius: 0.25em;
270301
min-width: 4ex;
271302
max-width: 4ex;
272
- min-height: 4ex;
273
- max-height: 4ex;
303
+ min-height: 3ex;
304
+ max-height: 3ex;
274305
margin: 0.125em;
275306
display: inline-flex;
276307
justify-content: center;
277308
align-items: center;
278309
cursor: pointer;
@@ -279,28 +310,27 @@
279310
font-size: 130%;
280311
}
281312
body.chat #chat-buttons-wrapper > .cbutton:hover {
282313
background-color: rgba(200,200,200,0.3);
283314
}
284
-body.chat #chat-input-line.compact #chat-buttons-wrapper > .cbutton {
315
+body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper > .cbutton {
285316
margin: 2px 0.125em 0 0.125em;
286317
min-width: 6ex;
287318
max-width: 6ex;
288319
min-height: 2.3ex;
289320
max-height: 2.3ex;
290321
font-size: 120%;
291322
}
292
-body.chat #chat-input-line.compact #chat-buttons-wrapper #chat-button-submit {
323
+body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper #chat-button-submit {
293324
min-width: 12ex;
294325
}
295
-body.chat #chat-input-line:not(.compact) #chat-input-field {
296
- /*border-left-style: double;
297
- border-left-width: 3px;
298
- border-right-style: double;
299
- border-right-width: 3px;*/
326
+.chat-input-field {
327
+ font-family: inherit
328
+}
329
+body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-multi,
330
+body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-x {
300331
min-height: 4rem;
301
- /*max-height: 50rem;*/
302332
/*
303333
Problems related to max-height:
304334
305335
- If we do NOT set a max-height then pasting/typing a large amount
306336
of text can cause this element to grow without bounds, larger than
@@ -311,25 +341,25 @@
311341
312342
- If we DO set a max-height then its growth is bounded but it also
313343
cannot manually expanded by the user.
314344
315345
The lesser of the two evils seems to be to rely on the browser
316
- feature that a manual resize of the element will pin its sits.
346
+ feature that a manual resize of the element will pin its size.
317347
*/
318348
}
319349
320
-body.chat #chat-input-line > #chat-button-settings{
350
+body.chat #chat-input-line-wrapper > #chat-button-settings{
321351
margin: 0 0 0 0.25em;
322352
max-width: 2em;
323353
}
324
-body.chat #chat-input-line > input[type=text],
325
-body.chat #chat-input-line > textarea {
354
+body.chat #chat-input-line-wrapper > input[type=text],
355
+body.chat #chat-input-line-wrapper > textarea {
326356
flex: 20 1 auto;
327357
max-width: revert;
328358
min-width: 20em;
329359
}
330
-body.chat #chat-input-line.compact > input[type=text] {
360
+body.chat #chat-input-line-wrapper.compact > input[type=text] {
331361
margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
332362
}
333363
/* Widget holding the file selection control and preview */
334364
body.chat #chat-input-file-area {
335365
display: flex;
@@ -361,11 +391,14 @@
361391
white-space: pre;
362392
font-family: monospace;
363393
margin: auto;
364394
flex: 0;
365395
}
366
-
396
+body.chat #chat-drop-details:empty {
397
+ padding: 0;
398
+ margin: 0;
399
+}
367400
body.chat #chat-drop-details img {
368401
max-width: 45%;
369402
max-height: 45%;
370403
}
371404
body.chat .chat-view {
@@ -389,37 +422,69 @@
389422
/* /chat config options go here */
390423
flex: 1 1 auto;
391424
display: flex;
392425
flex-direction: column;
393426
overflow: auto;
427
+ align-items: stretch;
394428
}
395429
body.chat #chat-config #chat-config-options .menu-entry {
396430
display: flex;
397
- align-items: baseline;
398
- flex-direction: row;
431
+ align-items: center;
432
+ flex-direction: row-reverse;
399433
flex-wrap: nowrap;
400434
padding: 1em;
435
+ flex: 1 1 auto;
436
+ align-self: stretch;
437
+}
438
+body.chat #chat-config #chat-config-options .menu-entry.parent{
439
+ border-radius: 1em 1em 0 1em;
440
+ margin-top: 1em;
441
+}
442
+body.chat #chat-config #chat-config-options .menu-entry.child {
443
+ /*padding-left: 2.5em;*/
444
+ margin-left: 2em;
445
+}
446
+body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){
447
+ background-color: rgba(175,175,175,0.15);
448
+}
449
+body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){
450
+ background-color: rgba(175,175,175,0.35);
451
+}
452
+body.chat #chat-config #chat-config-options .menu-entry:first-child {
453
+ /* Config list header */
454
+ border-radius: 0 0 1em 1em;
455
+}
456
+body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper {
457
+ align-items: start;
458
+}
459
+body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper {
460
+ /* Holder for a checkbox, if any */
461
+ min-width: 1.5rem;
462
+ margin-right: 1rem;
463
+}
464
+body.chat #chat-config #chat-config-options .menu-entry .label-wrapper {
465
+ /* Wrapper for a LABEL and a .hint element. */
466
+ display: flex;
467
+ flex-direction: column;
468
+ align-self: baseline;
469
+ flex: 1 1 auto;
470
+}
471
+body.chat #chat-config #chat-config-options .menu-entry label {
472
+ /* Config option label. */
473
+ font-weight: bold;
474
+ white-space: initial;
401475
}
402476
body.chat #chat-config #chat-config-options .menu-entry label[for] {
403477
cursor: pointer;
404478
}
405
-body.chat #chat-config #chat-config-options .menu-entry > *:first-child {
406
- min-width: 1.5rem;
407
-}
408
-body.chat #chat-config #chat-config-options .menu-entry span.hint {
479
+body.chat #chat-config #chat-config-options .menu-entry .hint {
409480
/* Config menu hint text */
410
- font-size: 80%;
481
+ font-size: 85%;
482
+ font-weight: normal;
411483
white-space: pre-wrap;
412484
display: inline-block;
413
-}
414
-body.chat #chat-config #chat-config-options .menu-entry:first-child {
415
-}
416
-body.chat #chat-config #chat-config-options .menu-entry div.label-wrapper {
417
- display: flex;
418
- flex-direction: column;
419
- align-self: baseline;
420
- margin-left: 1em;
485
+ opacity: 0.85;
421486
}
422487
body.chat #chat-config #chat-config-options .menu-entry select {
423488
}
424489
body.chat #chat-preview #chat-preview-content {
425490
overflow: auto;
426491
--- src/style.chat.css
+++ src/style.chat.css
@@ -40,13 +40,11 @@
40 min-width: 9em /*avoid unsightly "underlap" with the neighboring
41 .message-widget-tab element*/;
42 white-space: normal;
43 }
44 body.chat.monospace-messages .message-widget-content,
45 /*body.chat.monospace-messages textarea,*/
46 /*body.chat.monospace-messages input[type=text],*/
47 body.chat.monospace-messages #chat-input-field{
48 font-family: monospace;
49 }
50 body.chat .message-widget-content > * {
51 margin: 0;
52 padding: 0;
@@ -58,10 +56,31 @@
58 margin-top: 0;
59 }
60 body.chat .message-widget-content > .markdown > *:last-child {
61 margin-bottom: 0;
62 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63 /* User name and timestamp (a LEGEND-like element) */
64 body.chat .message-widget .message-widget-tab {
65 border-radius: 0.25em 0.25em 0 0;
66 margin: 0 0.25em 0em 0.15em;
67 padding: 0 0.5em 0.15em 0.5em;
@@ -181,28 +200,40 @@
181 /* Safari user reports that 2em is necessary to keep the file selection
182 widget from overlapping the page footer, whereas a margin of 0 is fine
183 for FF/Chrome (and 2em is a *huge* waste of space for those). */
184 margin-bottom: 0;
185 }
186 #chat-input-field {
187 display: inline-block/*supposed workaround for Chrome weirdness*/;
188 padding: 0.2em;
189 flex: 10 1 auto;
190 background-color: rgba(156,156,156,0.3);
 
 
 
191 overflow: auto;
192 resize: vertical;
193 }
194 #chat-input-field:empty::before {
 
 
 
 
 
 
 
 
 
 
 
195 content: attr(data-placeholder);
196 opacity: 0.6;
197 }
198 #chat-input-field:not(:focus){
199 border-width: 1px;
200 border-style: solid;
201 border-radius: 0.25em;
202 }
203 #chat-input-field:focus{
204 /* This transparent border helps avoid the text shifting around
205 when the contenteditable attribute causes a border (which we
206 apparently cannot style) to be added. */
207 border-width: 1px;
208 border-style: solid;
@@ -209,20 +240,20 @@
209 border-color: transparent;
210 border-radius: 0.25em;
211 }
212 /* Widget holding the chat message input field, send button, and
213 settings button. */
214 body.chat #chat-input-line {
215 display: flex;
216 flex-direction: row;
217 align-items: stretch;
218 flex-wrap: nowrap;
219 }
220 /*body.chat #chat-input-line:not(.compact) {
221 flex-wrap: nowrap;
222 }*/
223 body.chat #chat-input-line.compact {
224 /* "The problem" with wrapping, together with a contenteditable input
225 field, is that the latter grows as the user types, so causes
226 wrapping to happen while they type, then to unwrap as soon as the
227 input field is cleared (when the message is sent). When we stay
228 wrapped in compact mode, the wrapped buttons simply take up too
@@ -235,11 +266,11 @@
235 only way to eliminate the possibility that (A) the buttons
236 get truncated in very narrow windows and (B) that they keep
237 stable positions.
238 */
239 }
240 body.chat #chat-input-line.compact #chat-input-field {
241 }
242
243 body.chat #chat-buttons-wrapper {
244 flex: 0 1 auto;
245 display: flex;
@@ -249,11 +280,11 @@
249 min-height: 1.5em;
250 align-self: flex-end
251 /*keep buttons stable at bottom/right even when input field
252 resizes */;
253 }
254 body.chat #chat-input-line.compact #chat-buttons-wrapper {
255 flex-direction: row;
256 flex: 1 1 auto;
257 align-self: stretch;
258 justify-content: flex-end;
259 /*flex-wrap: wrap;*/
@@ -267,12 +298,12 @@
267 border-width: 1px;
268 border-style: solid;
269 border-radius: 0.25em;
270 min-width: 4ex;
271 max-width: 4ex;
272 min-height: 4ex;
273 max-height: 4ex;
274 margin: 0.125em;
275 display: inline-flex;
276 justify-content: center;
277 align-items: center;
278 cursor: pointer;
@@ -279,28 +310,27 @@
279 font-size: 130%;
280 }
281 body.chat #chat-buttons-wrapper > .cbutton:hover {
282 background-color: rgba(200,200,200,0.3);
283 }
284 body.chat #chat-input-line.compact #chat-buttons-wrapper > .cbutton {
285 margin: 2px 0.125em 0 0.125em;
286 min-width: 6ex;
287 max-width: 6ex;
288 min-height: 2.3ex;
289 max-height: 2.3ex;
290 font-size: 120%;
291 }
292 body.chat #chat-input-line.compact #chat-buttons-wrapper #chat-button-submit {
293 min-width: 12ex;
294 }
295 body.chat #chat-input-line:not(.compact) #chat-input-field {
296 /*border-left-style: double;
297 border-left-width: 3px;
298 border-right-style: double;
299 border-right-width: 3px;*/
300 min-height: 4rem;
301 /*max-height: 50rem;*/
302 /*
303 Problems related to max-height:
304
305 - If we do NOT set a max-height then pasting/typing a large amount
306 of text can cause this element to grow without bounds, larger than
@@ -311,25 +341,25 @@
311
312 - If we DO set a max-height then its growth is bounded but it also
313 cannot manually expanded by the user.
314
315 The lesser of the two evils seems to be to rely on the browser
316 feature that a manual resize of the element will pin its sits.
317 */
318 }
319
320 body.chat #chat-input-line > #chat-button-settings{
321 margin: 0 0 0 0.25em;
322 max-width: 2em;
323 }
324 body.chat #chat-input-line > input[type=text],
325 body.chat #chat-input-line > textarea {
326 flex: 20 1 auto;
327 max-width: revert;
328 min-width: 20em;
329 }
330 body.chat #chat-input-line.compact > input[type=text] {
331 margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
332 }
333 /* Widget holding the file selection control and preview */
334 body.chat #chat-input-file-area {
335 display: flex;
@@ -361,11 +391,14 @@
361 white-space: pre;
362 font-family: monospace;
363 margin: auto;
364 flex: 0;
365 }
366
 
 
 
367 body.chat #chat-drop-details img {
368 max-width: 45%;
369 max-height: 45%;
370 }
371 body.chat .chat-view {
@@ -389,37 +422,69 @@
389 /* /chat config options go here */
390 flex: 1 1 auto;
391 display: flex;
392 flex-direction: column;
393 overflow: auto;
 
394 }
395 body.chat #chat-config #chat-config-options .menu-entry {
396 display: flex;
397 align-items: baseline;
398 flex-direction: row;
399 flex-wrap: nowrap;
400 padding: 1em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401 }
402 body.chat #chat-config #chat-config-options .menu-entry label[for] {
403 cursor: pointer;
404 }
405 body.chat #chat-config #chat-config-options .menu-entry > *:first-child {
406 min-width: 1.5rem;
407 }
408 body.chat #chat-config #chat-config-options .menu-entry span.hint {
409 /* Config menu hint text */
410 font-size: 80%;
 
411 white-space: pre-wrap;
412 display: inline-block;
413 }
414 body.chat #chat-config #chat-config-options .menu-entry:first-child {
415 }
416 body.chat #chat-config #chat-config-options .menu-entry div.label-wrapper {
417 display: flex;
418 flex-direction: column;
419 align-self: baseline;
420 margin-left: 1em;
421 }
422 body.chat #chat-config #chat-config-options .menu-entry select {
423 }
424 body.chat #chat-preview #chat-preview-content {
425 overflow: auto;
426
--- src/style.chat.css
+++ src/style.chat.css
@@ -40,13 +40,11 @@
40 min-width: 9em /*avoid unsightly "underlap" with the neighboring
41 .message-widget-tab element*/;
42 white-space: normal;
43 }
44 body.chat.monospace-messages .message-widget-content,
45 body.chat.monospace-messages .chat-input-field{
 
 
46 font-family: monospace;
47 }
48 body.chat .message-widget-content > * {
49 margin: 0;
50 padding: 0;
@@ -58,10 +56,31 @@
56 margin-top: 0;
57 }
58 body.chat .message-widget-content > .markdown > *:last-child {
59 margin-bottom: 0;
60 }
61 body.chat .message-widget-content.error .buttons {
62 display: flex;
63 flex-direction: row;
64 justify-content: space-around;
65 flex-wrap: wrap;
66 }
67 body.chat .message-widget-content.error .buttons > button {
68 margin: 0.25em;
69 }
70
71 body.chat .message-widget-content.error a {
72 color: inherit;
73 }
74 body.chat .message-widget-content.error .failed-message {
75 display: flex;
76 flex-direction: column;
77 }
78 body.chat .message-widget-content.error .failed-message textarea {
79 min-height: 5rem;
80 }
81
82 /* User name and timestamp (a LEGEND-like element) */
83 body.chat .message-widget .message-widget-tab {
84 border-radius: 0.25em 0.25em 0 0;
85 margin: 0 0.25em 0em 0.15em;
86 padding: 0 0.5em 0.15em 0.5em;
@@ -181,28 +200,40 @@
200 /* Safari user reports that 2em is necessary to keep the file selection
201 widget from overlapping the page footer, whereas a margin of 0 is fine
202 for FF/Chrome (and 2em is a *huge* waste of space for those). */
203 margin-bottom: 0;
204 }
205 .chat-input-field {
 
 
206 flex: 10 1 auto;
207 margin: 0;
208 }
209 #chat-input-field-x,
210 #chat-input-field-multi {
211 overflow: auto;
212 resize: vertical;
213 }
214 #chat-input-field-x {
215 display: inline-block/*supposed workaround for Chrome weirdness*/;
216 padding: 0.2em;
217 background-color: rgba(156,156,156,0.3);
218 white-space: pre-wrap;
219 /* ^^^ Firefox, when pasting plain text into a contenteditable field,
220 loses all newlines unless we explicitly set this. Chrome does not. */
221 cursor: text;
222 /* ^^^ In some browsers the cursor may not change for a contenteditable
223 element until it has focus, causing potential confusion. */
224 }
225 #chat-input-field-x:empty::before {
226 content: attr(data-placeholder);
227 opacity: 0.6;
228 }
229 .chat-input-field:not(:focus){
230 border-width: 1px;
231 border-style: solid;
232 border-radius: 0.25em;
233 }
234 .chat-input-field:focus{
235 /* This transparent border helps avoid the text shifting around
236 when the contenteditable attribute causes a border (which we
237 apparently cannot style) to be added. */
238 border-width: 1px;
239 border-style: solid;
@@ -209,20 +240,20 @@
240 border-color: transparent;
241 border-radius: 0.25em;
242 }
243 /* Widget holding the chat message input field, send button, and
244 settings button. */
245 body.chat #chat-input-line-wrapper {
246 display: flex;
247 flex-direction: row;
248 align-items: stretch;
249 flex-wrap: nowrap;
250 }
251 /*body.chat #chat-input-line-wrapper:not(.compact) {
252 flex-wrap: nowrap;
253 }*/
254 body.chat #chat-input-line-wrapper.compact {
255 /* "The problem" with wrapping, together with a contenteditable input
256 field, is that the latter grows as the user types, so causes
257 wrapping to happen while they type, then to unwrap as soon as the
258 input field is cleared (when the message is sent). When we stay
259 wrapped in compact mode, the wrapped buttons simply take up too
@@ -235,11 +266,11 @@
266 only way to eliminate the possibility that (A) the buttons
267 get truncated in very narrow windows and (B) that they keep
268 stable positions.
269 */
270 }
271 body.chat #chat-input-line-wrapper.compact #chat-input-field-x {
272 }
273
274 body.chat #chat-buttons-wrapper {
275 flex: 0 1 auto;
276 display: flex;
@@ -249,11 +280,11 @@
280 min-height: 1.5em;
281 align-self: flex-end
282 /*keep buttons stable at bottom/right even when input field
283 resizes */;
284 }
285 body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper {
286 flex-direction: row;
287 flex: 1 1 auto;
288 align-self: stretch;
289 justify-content: flex-end;
290 /*flex-wrap: wrap;*/
@@ -267,12 +298,12 @@
298 border-width: 1px;
299 border-style: solid;
300 border-radius: 0.25em;
301 min-width: 4ex;
302 max-width: 4ex;
303 min-height: 3ex;
304 max-height: 3ex;
305 margin: 0.125em;
306 display: inline-flex;
307 justify-content: center;
308 align-items: center;
309 cursor: pointer;
@@ -279,28 +310,27 @@
310 font-size: 130%;
311 }
312 body.chat #chat-buttons-wrapper > .cbutton:hover {
313 background-color: rgba(200,200,200,0.3);
314 }
315 body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper > .cbutton {
316 margin: 2px 0.125em 0 0.125em;
317 min-width: 6ex;
318 max-width: 6ex;
319 min-height: 2.3ex;
320 max-height: 2.3ex;
321 font-size: 120%;
322 }
323 body.chat #chat-input-line-wrapper.compact #chat-buttons-wrapper #chat-button-submit {
324 min-width: 12ex;
325 }
326 .chat-input-field {
327 font-family: inherit
328 }
329 body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-multi,
330 body.chat #chat-input-line-wrapper:not(.compact) #chat-input-field-x {
331 min-height: 4rem;
 
332 /*
333 Problems related to max-height:
334
335 - If we do NOT set a max-height then pasting/typing a large amount
336 of text can cause this element to grow without bounds, larger than
@@ -311,25 +341,25 @@
341
342 - If we DO set a max-height then its growth is bounded but it also
343 cannot manually expanded by the user.
344
345 The lesser of the two evils seems to be to rely on the browser
346 feature that a manual resize of the element will pin its size.
347 */
348 }
349
350 body.chat #chat-input-line-wrapper > #chat-button-settings{
351 margin: 0 0 0 0.25em;
352 max-width: 2em;
353 }
354 body.chat #chat-input-line-wrapper > input[type=text],
355 body.chat #chat-input-line-wrapper > textarea {
356 flex: 20 1 auto;
357 max-width: revert;
358 min-width: 20em;
359 }
360 body.chat #chat-input-line-wrapper.compact > input[type=text] {
361 margin: 0 0 0.25em 0/* gap for if/when buttons wrap*/;
362 }
363 /* Widget holding the file selection control and preview */
364 body.chat #chat-input-file-area {
365 display: flex;
@@ -361,11 +391,14 @@
391 white-space: pre;
392 font-family: monospace;
393 margin: auto;
394 flex: 0;
395 }
396 body.chat #chat-drop-details:empty {
397 padding: 0;
398 margin: 0;
399 }
400 body.chat #chat-drop-details img {
401 max-width: 45%;
402 max-height: 45%;
403 }
404 body.chat .chat-view {
@@ -389,37 +422,69 @@
422 /* /chat config options go here */
423 flex: 1 1 auto;
424 display: flex;
425 flex-direction: column;
426 overflow: auto;
427 align-items: stretch;
428 }
429 body.chat #chat-config #chat-config-options .menu-entry {
430 display: flex;
431 align-items: center;
432 flex-direction: row-reverse;
433 flex-wrap: nowrap;
434 padding: 1em;
435 flex: 1 1 auto;
436 align-self: stretch;
437 }
438 body.chat #chat-config #chat-config-options .menu-entry.parent{
439 border-radius: 1em 1em 0 1em;
440 margin-top: 1em;
441 }
442 body.chat #chat-config #chat-config-options .menu-entry.child {
443 /*padding-left: 2.5em;*/
444 margin-left: 2em;
445 }
446 body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(even){
447 background-color: rgba(175,175,175,0.15);
448 }
449 body.chat #chat-config #chat-config-options .menu-entry:nth-of-type(odd){
450 background-color: rgba(175,175,175,0.35);
451 }
452 body.chat #chat-config #chat-config-options .menu-entry:first-child {
453 /* Config list header */
454 border-radius: 0 0 1em 1em;
455 }
456 body.chat #chat-config #chat-config-options .menu-entry:first-child .label-wrapper {
457 align-items: start;
458 }
459 body.chat #chat-config #chat-config-options .menu-entry > .toggle-wrapper {
460 /* Holder for a checkbox, if any */
461 min-width: 1.5rem;
462 margin-right: 1rem;
463 }
464 body.chat #chat-config #chat-config-options .menu-entry .label-wrapper {
465 /* Wrapper for a LABEL and a .hint element. */
466 display: flex;
467 flex-direction: column;
468 align-self: baseline;
469 flex: 1 1 auto;
470 }
471 body.chat #chat-config #chat-config-options .menu-entry label {
472 /* Config option label. */
473 font-weight: bold;
474 white-space: initial;
475 }
476 body.chat #chat-config #chat-config-options .menu-entry label[for] {
477 cursor: pointer;
478 }
479 body.chat #chat-config #chat-config-options .menu-entry .hint {
 
 
 
480 /* Config menu hint text */
481 font-size: 85%;
482 font-weight: normal;
483 white-space: pre-wrap;
484 display: inline-block;
485 opacity: 0.85;
 
 
 
 
 
 
 
486 }
487 body.chat #chat-config #chat-config-options .menu-entry select {
488 }
489 body.chat #chat-preview #chat-preview-content {
490 overflow: auto;
491
+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
+3 -1
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -537,15 +537,17 @@
537537
@ } else {
538538
@ html "<tr><td class='tktDspLabel'>User Comments:</td></tr>\n"
539539
@ html "<tr><td colspan='5' class='tktDspValue'>\n"
540540
@ set seenRow 1
541541
@ }
542
+@ html "<span class='tktDspCommenter'>"
542543
@ html "[htmlize $xlogin]"
543544
@ if {$xlogin ne $xusername && [string length $xusername]>0} {
544545
@ html " (claiming to be [htmlize $xusername])"
545546
@ }
546
-@ html " added on $xdate:\n"
547
+@ html " added on $xdate:"
548
+@ html "</span>\n"
547549
@ if {$alwaysPlaintext || $xmimetype eq "text/plain"} {
548550
@ set r [randhex]
549551
@ if {$xmimetype ne "text/plain"} {html "([htmlize $xmimetype])\n"}
550552
@ wiki "<verbatim-$r>[string trimright $xcomment]</verbatim-$r>\n"
551553
@ } elseif {$xmimetype eq "text/x-fossil-wiki"} {
552554
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -537,15 +537,17 @@
537 @ } else {
538 @ html "<tr><td class='tktDspLabel'>User Comments:</td></tr>\n"
539 @ html "<tr><td colspan='5' class='tktDspValue'>\n"
540 @ set seenRow 1
541 @ }
 
542 @ html "[htmlize $xlogin]"
543 @ if {$xlogin ne $xusername && [string length $xusername]>0} {
544 @ html " (claiming to be [htmlize $xusername])"
545 @ }
546 @ html " added on $xdate:\n"
 
547 @ if {$alwaysPlaintext || $xmimetype eq "text/plain"} {
548 @ set r [randhex]
549 @ if {$xmimetype ne "text/plain"} {html "([htmlize $xmimetype])\n"}
550 @ wiki "<verbatim-$r>[string trimright $xcomment]</verbatim-$r>\n"
551 @ } elseif {$xmimetype eq "text/x-fossil-wiki"} {
552
--- src/tktsetup.c
+++ src/tktsetup.c
@@ -537,15 +537,17 @@
537 @ } else {
538 @ html "<tr><td class='tktDspLabel'>User Comments:</td></tr>\n"
539 @ html "<tr><td colspan='5' class='tktDspValue'>\n"
540 @ set seenRow 1
541 @ }
542 @ html "<span class='tktDspCommenter'>"
543 @ html "[htmlize $xlogin]"
544 @ if {$xlogin ne $xusername && [string length $xusername]>0} {
545 @ html " (claiming to be [htmlize $xusername])"
546 @ }
547 @ html " added on $xdate:"
548 @ html "</span>\n"
549 @ if {$alwaysPlaintext || $xmimetype eq "text/plain"} {
550 @ set r [randhex]
551 @ if {$xmimetype ne "text/plain"} {html "([htmlize $xmimetype])\n"}
552 @ wiki "<verbatim-$r>[string trimright $xcomment]</verbatim-$r>\n"
553 @ } elseif {$xmimetype eq "text/x-fossil-wiki"} {
554
--- src/unversioned.c
+++ src/unversioned.c
@@ -657,11 +657,11 @@
657657
char *zSep = "[";
658658
Blob json;
659659
660660
login_check_credentials();
661661
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
662
- cgi_set_content_type("text/json");
662
+ cgi_set_content_type("application/json");
663663
etag_check(ETAG_DATA,0);
664664
if( !db_table_exists("repository","unversioned") ){
665665
blob_init(&json, "[]", -1);
666666
cgi_set_content(&json);
667667
return;
668668
--- src/unversioned.c
+++ src/unversioned.c
@@ -657,11 +657,11 @@
657 char *zSep = "[";
658 Blob json;
659
660 login_check_credentials();
661 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
662 cgi_set_content_type("text/json");
663 etag_check(ETAG_DATA,0);
664 if( !db_table_exists("repository","unversioned") ){
665 blob_init(&json, "[]", -1);
666 cgi_set_content(&json);
667 return;
668
--- src/unversioned.c
+++ src/unversioned.c
@@ -657,11 +657,11 @@
657 char *zSep = "[";
658 Blob json;
659
660 login_check_credentials();
661 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
662 cgi_set_content_type("application/json");
663 etag_check(ETAG_DATA,0);
664 if( !db_table_exists("repository","unversioned") ){
665 blob_init(&json, "[]", -1);
666 cgi_set_content(&json);
667 return;
668
+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
+50 -49
--- src/wiki.c
+++ src/wiki.c
@@ -211,12 +211,12 @@
211211
if( w>0 ){
212212
@ <div class="pikchr-svg" style="max-width:%d(w)px">
213213
@ %s(zOut)
214214
@ </div>
215215
}else{
216
- @ <pre class='error'>\n">
217
- @ %s(zOut);
216
+ @ <pre class='error'>
217
+ @ %h(zOut)
218218
@ </pre>
219219
}
220220
free(zOut);
221221
}else{
222222
@ <pre class='textPlain'>
@@ -666,11 +666,11 @@
666666
/*
667667
** Given a mimetype, return its common name.
668668
*/
669669
static const char *mimetype_common_name(const char *zMimetype){
670670
int i;
671
- for(i=4; i>=2; i-=2){
671
+ for(i=6; i>=0; i-=3){
672672
if( zMimetype && fossil_strcmp(zMimetype, azStyles[i])==0 ){
673673
return azStyles[i+1];
674674
}
675675
}
676676
return azStyles[1];
@@ -1592,97 +1592,97 @@
15921592
** Append text to the end of a wiki page.
15931593
*/
15941594
void wikiappend_page(void){
15951595
char *zTag;
15961596
int rid = 0;
1597
- int isSandbox;
15981597
const char *zPageName;
15991598
const char *zUser;
16001599
const char *zMimetype;
16011600
int goodCaptcha = 1;
16021601
const char *zFormat;
1602
+ Manifest *pWiki = 0;
1603
+ int isSandbox;
16031604
16041605
login_check_credentials();
1606
+ if( !g.perm.ApndWiki ){
1607
+ login_needed(g.anon.ApndWiki);
1608
+ return;
1609
+ }
16051610
zPageName = PD("name","");
16061611
zMimetype = wiki_filter_mimetypes(P("mimetype"));
16071612
if( check_name(zPageName) ) return;
16081613
isSandbox = is_sandbox(zPageName);
1609
- if( !isSandbox ){
1614
+ if(!isSandbox){
16101615
zTag = mprintf("wiki-%s", zPageName);
16111616
rid = db_int(0,
16121617
"SELECT rid FROM tagxref"
16131618
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
16141619
" ORDER BY mtime DESC", zTag
16151620
);
16161621
free(zTag);
1617
- if( !rid ){
1622
+ pWiki = rid ? manifest_get(rid, CFTYPE_WIKI, 0) : 0;
1623
+ if( !pWiki ){
16181624
fossil_redirect_home();
16191625
return;
16201626
}
1621
- }
1622
- if( !g.perm.ApndWiki ){
1623
- login_needed(g.anon.ApndWiki);
1624
- return;
1627
+ zMimetype = wiki_filter_mimetypes(pWiki->zMimetype)
1628
+ /* see https://fossil-scm.org/forum/forumpost/0acfdaac80 */;
16251629
}
1626
- if( P("submit")!=0 && P("r")!=0 && P("u")!=0
1630
+ if( !isSandbox && P("submit")!=0 && P("r")!=0 && P("u")!=0
16271631
&& (goodCaptcha = captcha_is_correct(0))
16281632
){
16291633
char *zDate;
16301634
Blob cksum;
16311635
Blob body;
16321636
Blob wiki;
1633
- Manifest *pWiki = 0;
16341637
16351638
blob_zero(&body);
1636
- if( isSandbox ){
1637
- blob_append(&body, db_get("sandbox",""), -1);
1638
- appendRemark(&body, zMimetype);
1639
- db_set("sandbox", blob_str(&body), 0);
1640
- }else{
1641
- login_verify_csrf_secret();
1642
- pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
1643
- if( pWiki ){
1644
- blob_append(&body, pWiki->zWiki, -1);
1645
- manifest_destroy(pWiki);
1646
- }
1647
- blob_zero(&wiki);
1648
- db_begin_transaction();
1649
- zDate = date_in_standard_format("now");
1650
- blob_appendf(&wiki, "D %s\n", zDate);
1651
- blob_appendf(&wiki, "L %F\n", zPageName);
1652
- if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")!=0 ){
1653
- blob_appendf(&wiki, "N %s\n", zMimetype);
1654
- }
1655
- if( rid ){
1656
- char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1657
- blob_appendf(&wiki, "P %s\n", zUuid);
1658
- free(zUuid);
1659
- }
1660
- if( !login_is_nobody() ){
1661
- blob_appendf(&wiki, "U %F\n", login_name());
1662
- }
1663
- appendRemark(&body, zMimetype);
1664
- blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body));
1665
- md5sum_blob(&wiki, &cksum);
1666
- blob_appendf(&wiki, "Z %b\n", &cksum);
1667
- blob_reset(&cksum);
1668
- wiki_put(&wiki, rid, wiki_need_moderation(0));
1669
- db_end_transaction(0);
1670
- }
1639
+ login_verify_csrf_secret();
1640
+ blob_append(&body, pWiki->zWiki, -1);
1641
+ blob_zero(&wiki);
1642
+ db_begin_transaction();
1643
+ zDate = date_in_standard_format("now");
1644
+ blob_appendf(&wiki, "D %s\n", zDate);
1645
+ blob_appendf(&wiki, "L %F\n", zPageName);
1646
+ if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")!=0 ){
1647
+ blob_appendf(&wiki, "N %s\n", zMimetype);
1648
+ }
1649
+ if( rid ){
1650
+ char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1651
+ blob_appendf(&wiki, "P %s\n", zUuid);
1652
+ free(zUuid);
1653
+ }
1654
+ if( !login_is_nobody() ){
1655
+ blob_appendf(&wiki, "U %F\n", login_name());
1656
+ }
1657
+ appendRemark(&body, zMimetype);
1658
+ blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body));
1659
+ md5sum_blob(&wiki, &cksum);
1660
+ blob_appendf(&wiki, "Z %b\n", &cksum);
1661
+ blob_reset(&cksum);
1662
+ wiki_put(&wiki, rid, wiki_need_moderation(0));
1663
+ db_end_transaction(0);
1664
+ manifest_destroy(pWiki);
16711665
cgi_redirectf("wiki?name=%T", zPageName);
1666
+ return;
16721667
}
1673
- if( P("cancel")!=0 ){
1668
+ if( !isSandbox && P("cancel")!=0 ){
1669
+ manifest_destroy(pWiki);
16741670
cgi_redirectf("wiki?name=%T", zPageName);
16751671
return;
16761672
}
16771673
style_set_current_page("%T?name=%T", g.zPath, zPageName);
16781674
style_set_current_feature("wiki");
16791675
style_header("Append Comment To: %s", zPageName);
16801676
if( !goodCaptcha ){
16811677
@ <p class="generalError">Error: Incorrect security code.</p>
16821678
}
1683
- if( P("preview")!=0 ){
1679
+ if( isSandbox ){
1680
+ @ <p class="generalError">Error: the Sandbox page may not
1681
+ @ be appended to.</p>
1682
+ }
1683
+ if( !isSandbox && P("preview")!=0 ){
16841684
Blob preview;
16851685
blob_zero(&preview);
16861686
appendRemark(&preview, zMimetype);
16871687
@ Preview:<hr />
16881688
safe_html_context(DOCSRC_WIKI);
@@ -1705,10 +1705,11 @@
17051705
@ <input type="submit" name="preview" value="Preview Your Comment" />
17061706
@ <input type="submit" name="submit" value="Append Your Changes" />
17071707
@ <input type="submit" name="cancel" value="Cancel" />
17081708
captcha_generate(0);
17091709
@ </form>
1710
+ manifest_destroy(pWiki);
17101711
style_finish_page();
17111712
}
17121713
17131714
/*
17141715
** WEBPAGE: whistory
17151716
--- src/wiki.c
+++ src/wiki.c
@@ -211,12 +211,12 @@
211 if( w>0 ){
212 @ <div class="pikchr-svg" style="max-width:%d(w)px">
213 @ %s(zOut)
214 @ </div>
215 }else{
216 @ <pre class='error'>\n">
217 @ %s(zOut);
218 @ </pre>
219 }
220 free(zOut);
221 }else{
222 @ <pre class='textPlain'>
@@ -666,11 +666,11 @@
666 /*
667 ** Given a mimetype, return its common name.
668 */
669 static const char *mimetype_common_name(const char *zMimetype){
670 int i;
671 for(i=4; i>=2; i-=2){
672 if( zMimetype && fossil_strcmp(zMimetype, azStyles[i])==0 ){
673 return azStyles[i+1];
674 }
675 }
676 return azStyles[1];
@@ -1592,97 +1592,97 @@
1592 ** Append text to the end of a wiki page.
1593 */
1594 void wikiappend_page(void){
1595 char *zTag;
1596 int rid = 0;
1597 int isSandbox;
1598 const char *zPageName;
1599 const char *zUser;
1600 const char *zMimetype;
1601 int goodCaptcha = 1;
1602 const char *zFormat;
 
 
1603
1604 login_check_credentials();
 
 
 
 
1605 zPageName = PD("name","");
1606 zMimetype = wiki_filter_mimetypes(P("mimetype"));
1607 if( check_name(zPageName) ) return;
1608 isSandbox = is_sandbox(zPageName);
1609 if( !isSandbox ){
1610 zTag = mprintf("wiki-%s", zPageName);
1611 rid = db_int(0,
1612 "SELECT rid FROM tagxref"
1613 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
1614 " ORDER BY mtime DESC", zTag
1615 );
1616 free(zTag);
1617 if( !rid ){
 
1618 fossil_redirect_home();
1619 return;
1620 }
1621 }
1622 if( !g.perm.ApndWiki ){
1623 login_needed(g.anon.ApndWiki);
1624 return;
1625 }
1626 if( P("submit")!=0 && P("r")!=0 && P("u")!=0
1627 && (goodCaptcha = captcha_is_correct(0))
1628 ){
1629 char *zDate;
1630 Blob cksum;
1631 Blob body;
1632 Blob wiki;
1633 Manifest *pWiki = 0;
1634
1635 blob_zero(&body);
1636 if( isSandbox ){
1637 blob_append(&body, db_get("sandbox",""), -1);
1638 appendRemark(&body, zMimetype);
1639 db_set("sandbox", blob_str(&body), 0);
1640 }else{
1641 login_verify_csrf_secret();
1642 pWiki = manifest_get(rid, CFTYPE_WIKI, 0);
1643 if( pWiki ){
1644 blob_append(&body, pWiki->zWiki, -1);
1645 manifest_destroy(pWiki);
1646 }
1647 blob_zero(&wiki);
1648 db_begin_transaction();
1649 zDate = date_in_standard_format("now");
1650 blob_appendf(&wiki, "D %s\n", zDate);
1651 blob_appendf(&wiki, "L %F\n", zPageName);
1652 if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")!=0 ){
1653 blob_appendf(&wiki, "N %s\n", zMimetype);
1654 }
1655 if( rid ){
1656 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1657 blob_appendf(&wiki, "P %s\n", zUuid);
1658 free(zUuid);
1659 }
1660 if( !login_is_nobody() ){
1661 blob_appendf(&wiki, "U %F\n", login_name());
1662 }
1663 appendRemark(&body, zMimetype);
1664 blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body));
1665 md5sum_blob(&wiki, &cksum);
1666 blob_appendf(&wiki, "Z %b\n", &cksum);
1667 blob_reset(&cksum);
1668 wiki_put(&wiki, rid, wiki_need_moderation(0));
1669 db_end_transaction(0);
1670 }
1671 cgi_redirectf("wiki?name=%T", zPageName);
 
1672 }
1673 if( P("cancel")!=0 ){
 
1674 cgi_redirectf("wiki?name=%T", zPageName);
1675 return;
1676 }
1677 style_set_current_page("%T?name=%T", g.zPath, zPageName);
1678 style_set_current_feature("wiki");
1679 style_header("Append Comment To: %s", zPageName);
1680 if( !goodCaptcha ){
1681 @ <p class="generalError">Error: Incorrect security code.</p>
1682 }
1683 if( P("preview")!=0 ){
 
 
 
 
1684 Blob preview;
1685 blob_zero(&preview);
1686 appendRemark(&preview, zMimetype);
1687 @ Preview:<hr />
1688 safe_html_context(DOCSRC_WIKI);
@@ -1705,10 +1705,11 @@
1705 @ <input type="submit" name="preview" value="Preview Your Comment" />
1706 @ <input type="submit" name="submit" value="Append Your Changes" />
1707 @ <input type="submit" name="cancel" value="Cancel" />
1708 captcha_generate(0);
1709 @ </form>
 
1710 style_finish_page();
1711 }
1712
1713 /*
1714 ** WEBPAGE: whistory
1715
--- src/wiki.c
+++ src/wiki.c
@@ -211,12 +211,12 @@
211 if( w>0 ){
212 @ <div class="pikchr-svg" style="max-width:%d(w)px">
213 @ %s(zOut)
214 @ </div>
215 }else{
216 @ <pre class='error'>
217 @ %h(zOut)
218 @ </pre>
219 }
220 free(zOut);
221 }else{
222 @ <pre class='textPlain'>
@@ -666,11 +666,11 @@
666 /*
667 ** Given a mimetype, return its common name.
668 */
669 static const char *mimetype_common_name(const char *zMimetype){
670 int i;
671 for(i=6; i>=0; i-=3){
672 if( zMimetype && fossil_strcmp(zMimetype, azStyles[i])==0 ){
673 return azStyles[i+1];
674 }
675 }
676 return azStyles[1];
@@ -1592,97 +1592,97 @@
1592 ** Append text to the end of a wiki page.
1593 */
1594 void wikiappend_page(void){
1595 char *zTag;
1596 int rid = 0;
 
1597 const char *zPageName;
1598 const char *zUser;
1599 const char *zMimetype;
1600 int goodCaptcha = 1;
1601 const char *zFormat;
1602 Manifest *pWiki = 0;
1603 int isSandbox;
1604
1605 login_check_credentials();
1606 if( !g.perm.ApndWiki ){
1607 login_needed(g.anon.ApndWiki);
1608 return;
1609 }
1610 zPageName = PD("name","");
1611 zMimetype = wiki_filter_mimetypes(P("mimetype"));
1612 if( check_name(zPageName) ) return;
1613 isSandbox = is_sandbox(zPageName);
1614 if(!isSandbox){
1615 zTag = mprintf("wiki-%s", zPageName);
1616 rid = db_int(0,
1617 "SELECT rid FROM tagxref"
1618 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
1619 " ORDER BY mtime DESC", zTag
1620 );
1621 free(zTag);
1622 pWiki = rid ? manifest_get(rid, CFTYPE_WIKI, 0) : 0;
1623 if( !pWiki ){
1624 fossil_redirect_home();
1625 return;
1626 }
1627 zMimetype = wiki_filter_mimetypes(pWiki->zMimetype)
1628 /* see https://fossil-scm.org/forum/forumpost/0acfdaac80 */;
 
 
1629 }
1630 if( !isSandbox && P("submit")!=0 && P("r")!=0 && P("u")!=0
1631 && (goodCaptcha = captcha_is_correct(0))
1632 ){
1633 char *zDate;
1634 Blob cksum;
1635 Blob body;
1636 Blob wiki;
 
1637
1638 blob_zero(&body);
1639 login_verify_csrf_secret();
1640 blob_append(&body, pWiki->zWiki, -1);
1641 blob_zero(&wiki);
1642 db_begin_transaction();
1643 zDate = date_in_standard_format("now");
1644 blob_appendf(&wiki, "D %s\n", zDate);
1645 blob_appendf(&wiki, "L %F\n", zPageName);
1646 if( fossil_strcmp(zMimetype, "text/x-fossil-wiki")!=0 ){
1647 blob_appendf(&wiki, "N %s\n", zMimetype);
1648 }
1649 if( rid ){
1650 char *zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
1651 blob_appendf(&wiki, "P %s\n", zUuid);
1652 free(zUuid);
1653 }
1654 if( !login_is_nobody() ){
1655 blob_appendf(&wiki, "U %F\n", login_name());
1656 }
1657 appendRemark(&body, zMimetype);
1658 blob_appendf(&wiki, "W %d\n%s\n", blob_size(&body), blob_str(&body));
1659 md5sum_blob(&wiki, &cksum);
1660 blob_appendf(&wiki, "Z %b\n", &cksum);
1661 blob_reset(&cksum);
1662 wiki_put(&wiki, rid, wiki_need_moderation(0));
1663 db_end_transaction(0);
1664 manifest_destroy(pWiki);
 
 
 
 
 
 
 
 
 
1665 cgi_redirectf("wiki?name=%T", zPageName);
1666 return;
1667 }
1668 if( !isSandbox && P("cancel")!=0 ){
1669 manifest_destroy(pWiki);
1670 cgi_redirectf("wiki?name=%T", zPageName);
1671 return;
1672 }
1673 style_set_current_page("%T?name=%T", g.zPath, zPageName);
1674 style_set_current_feature("wiki");
1675 style_header("Append Comment To: %s", zPageName);
1676 if( !goodCaptcha ){
1677 @ <p class="generalError">Error: Incorrect security code.</p>
1678 }
1679 if( isSandbox ){
1680 @ <p class="generalError">Error: the Sandbox page may not
1681 @ be appended to.</p>
1682 }
1683 if( !isSandbox && P("preview")!=0 ){
1684 Blob preview;
1685 blob_zero(&preview);
1686 appendRemark(&preview, zMimetype);
1687 @ Preview:<hr />
1688 safe_html_context(DOCSRC_WIKI);
@@ -1705,10 +1705,11 @@
1705 @ <input type="submit" name="preview" value="Preview Your Comment" />
1706 @ <input type="submit" name="submit" value="Append Your Changes" />
1707 @ <input type="submit" name="cancel" value="Cancel" />
1708 captcha_generate(0);
1709 @ </form>
1710 manifest_destroy(pWiki);
1711 style_finish_page();
1712 }
1713
1714 /*
1715 ** WEBPAGE: whistory
1716
+2 -2
--- src/winhttp.c
+++ src/winhttp.c
@@ -949,11 +949,11 @@
949949
** which means you need to start the service yourself with the
950950
** 'fossil winsrv start' command or with the "net start" command
951951
** from the operating system. If TYPE is set to "auto", the service
952952
** will be started automatically by the system during startup.
953953
**
954
-** -U|--username USERNAME
954
+** --username USERNAME
955955
**
956956
** Specifies the user account which will be used to run the
957957
** service. The account needs the "Logon as a service" right
958958
** enabled in its profile. Specify local accounts as follows:
959959
** ".\\USERNAME". By default, the "LocalSystem" account will be
@@ -1053,11 +1053,11 @@
10531053
svcDescr = {L"Fossil - Distributed Software Configuration Management"};
10541054
DWORD dwStartType = SERVICE_DEMAND_START;
10551055
const char *zAltBase = find_option("baseurl", 0, 1);
10561056
const char *zDisplay = find_option("display", "D", 1);
10571057
const char *zStart = find_option("start", "S", 1);
1058
- const char *zUsername = find_option("username", "U", 1);
1058
+ const char *zUsername = find_option("username", 0, 1);
10591059
const char *zPassword = find_option("password", "W", 1);
10601060
const char *zPort = find_option("port", "P", 1);
10611061
const char *zNotFound = find_option("notfound", 0, 1);
10621062
const char *zFileGlob = find_option("files", 0, 1);
10631063
const char *zLocalAuth = find_option("localauth", 0, 0);
10641064
--- src/winhttp.c
+++ src/winhttp.c
@@ -949,11 +949,11 @@
949 ** which means you need to start the service yourself with the
950 ** 'fossil winsrv start' command or with the "net start" command
951 ** from the operating system. If TYPE is set to "auto", the service
952 ** will be started automatically by the system during startup.
953 **
954 ** -U|--username USERNAME
955 **
956 ** Specifies the user account which will be used to run the
957 ** service. The account needs the "Logon as a service" right
958 ** enabled in its profile. Specify local accounts as follows:
959 ** ".\\USERNAME". By default, the "LocalSystem" account will be
@@ -1053,11 +1053,11 @@
1053 svcDescr = {L"Fossil - Distributed Software Configuration Management"};
1054 DWORD dwStartType = SERVICE_DEMAND_START;
1055 const char *zAltBase = find_option("baseurl", 0, 1);
1056 const char *zDisplay = find_option("display", "D", 1);
1057 const char *zStart = find_option("start", "S", 1);
1058 const char *zUsername = find_option("username", "U", 1);
1059 const char *zPassword = find_option("password", "W", 1);
1060 const char *zPort = find_option("port", "P", 1);
1061 const char *zNotFound = find_option("notfound", 0, 1);
1062 const char *zFileGlob = find_option("files", 0, 1);
1063 const char *zLocalAuth = find_option("localauth", 0, 0);
1064
--- src/winhttp.c
+++ src/winhttp.c
@@ -949,11 +949,11 @@
949 ** which means you need to start the service yourself with the
950 ** 'fossil winsrv start' command or with the "net start" command
951 ** from the operating system. If TYPE is set to "auto", the service
952 ** will be started automatically by the system during startup.
953 **
954 ** --username USERNAME
955 **
956 ** Specifies the user account which will be used to run the
957 ** service. The account needs the "Logon as a service" right
958 ** enabled in its profile. Specify local accounts as follows:
959 ** ".\\USERNAME". By default, the "LocalSystem" account will be
@@ -1053,11 +1053,11 @@
1053 svcDescr = {L"Fossil - Distributed Software Configuration Management"};
1054 DWORD dwStartType = SERVICE_DEMAND_START;
1055 const char *zAltBase = find_option("baseurl", 0, 1);
1056 const char *zDisplay = find_option("display", "D", 1);
1057 const char *zStart = find_option("start", "S", 1);
1058 const char *zUsername = find_option("username", 0, 1);
1059 const char *zPassword = find_option("password", "W", 1);
1060 const char *zPort = find_option("port", "P", 1);
1061 const char *zNotFound = find_option("notfound", 0, 1);
1062 const char *zFileGlob = find_option("files", 0, 1);
1063 const char *zLocalAuth = find_option("localauth", 0, 0);
1064
+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
--- www/bugtheory.wiki
+++ www/bugtheory.wiki
@@ -112,14 +112,12 @@
112112
and is not shared with other repositories during a sync, push, or pull.
113113
114114
Each repository also defines scripts used to generate web pages for
115115
creating new tickets, viewing existing tickets, and modifying an
116116
existing ticket. These scripts consist of HTML with an embedded
117
-scripts written a Tcl-like language called "TH1". Every new fossil
118
-repository is created with default scripts. Paul Ruizendaal has written
119
-documentation on the TH1 language that is available at
120
-[http://www.sqliteconcepts.org/THManual.pdf]. Administrators wishing to
117
+scripts written a Tcl-like language called "[./th1.md|TH1]". Every new fossil
118
+repository is created with default scripts. Administrators wishing to
121119
customize their ticket entry, viewing, and editing screens should
122120
modify the default scripts to suit their needs. These screen generator
123121
scripts are part of the local state of a repository and are not shared
124122
with other repositories during a sync, push, or pull.
125123
126124
--- www/bugtheory.wiki
+++ www/bugtheory.wiki
@@ -112,14 +112,12 @@
112 and is not shared with other repositories during a sync, push, or pull.
113
114 Each repository also defines scripts used to generate web pages for
115 creating new tickets, viewing existing tickets, and modifying an
116 existing ticket. These scripts consist of HTML with an embedded
117 scripts written a Tcl-like language called "TH1". Every new fossil
118 repository is created with default scripts. Paul Ruizendaal has written
119 documentation on the TH1 language that is available at
120 [http://www.sqliteconcepts.org/THManual.pdf]. Administrators wishing to
121 customize their ticket entry, viewing, and editing screens should
122 modify the default scripts to suit their needs. These screen generator
123 scripts are part of the local state of a repository and are not shared
124 with other repositories during a sync, push, or pull.
125
126
--- www/bugtheory.wiki
+++ www/bugtheory.wiki
@@ -112,14 +112,12 @@
112 and is not shared with other repositories during a sync, push, or pull.
113
114 Each repository also defines scripts used to generate web pages for
115 creating new tickets, viewing existing tickets, and modifying an
116 existing ticket. These scripts consist of HTML with an embedded
117 scripts written a Tcl-like language called "[./th1.md|TH1]". Every new fossil
118 repository is created with default scripts. Administrators wishing to
 
 
119 customize their ticket entry, viewing, and editing screens should
120 modify the default scripts to suit their needs. These screen generator
121 scripts are part of the local state of a repository and are not shared
122 with other repositories during a sync, push, or pull.
123
124
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,15 @@
11
<title>Change Log</title>
22
3
-<h2 id='v2_17'>Changes for version 2.17 (pending)</h2>
3
+<h2 id='v2_18'>Changes for version 2.18 (pending)</h2>
4
+ * [/help?cmd=/chat|The /chat page] input options have been reworked
5
+ again for better cross-browser portability.
6
+ * When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
7
+ immediately lost and sending may optionally be retried.
8
+
9
+<h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
10
+
411
* Major improvements to the "diff" subsystem, including: <ul>
512
<li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
613
<li> Partial-line matching for unified diffs
714
<li> Better partial-line matching for side-by-side diffs
815
<li> Buttons on web-based diffs to show more context
916
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,15 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_17'>Changes for version 2.17 (pending)</h2>
 
 
 
 
 
 
 
4 * Major improvements to the "diff" subsystem, including: <ul>
5 <li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
6 <li> Partial-line matching for unified diffs
7 <li> Better partial-line matching for side-by-side diffs
8 <li> Buttons on web-based diffs to show more context
9
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,15 @@
1 <title>Change Log</title>
2
3 <h2 id='v2_18'>Changes for version 2.18 (pending)</h2>
4 * [/help?cmd=/chat|The /chat page] input options have been reworked
5 again for better cross-browser portability.
6 * When sending a [/help?cmd=/chat|/chat] message fails, it is no longer
7 immediately lost and sending may optionally be retried.
8
9 <h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
10
11 * Major improvements to the "diff" subsystem, including: <ul>
12 <li> Added new [/help?cmd=diff|formatting options]: --by, -b, --webpage, --json, --tcl.
13 <li> Partial-line matching for unified diffs
14 <li> Better partial-line matching for side-by-side diffs
15 <li> Buttons on web-based diffs to show more context
16
+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
@@ -15,25 +15,25 @@
1515
This document is intended as a quick introduction to the concepts
1616
behind Fossil.
1717
1818
See also:
1919
20
- * [./whyusefossil.wiki#definitions|Definitions]
21
- * [./quickstart.wiki|Quick start guide]
20
+ * [./glossary.md | Glossary]
21
+ * [./quickstart.wiki | Quick start guide]
2222
2323
<h2>2.0 Composition Of A Project</h2>
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
@@ -15,25 +15,25 @@
15 This document is intended as a quick introduction to the concepts
16 behind Fossil.
17
18 See also:
19
20 * [./whyusefossil.wiki#definitions|Definitions]
21 * [./quickstart.wiki|Quick start guide]
22
23 <h2>2.0 Composition Of A Project</h2>
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
@@ -15,25 +15,25 @@
15 This document is intended as a quick introduction to the concepts
16 behind Fossil.
17
18 See also:
19
20 * [./glossary.md | Glossary]
21 * [./quickstart.wiki | Quick start guide]
22
23 <h2>2.0 Composition Of A Project</h2>
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
+16 -60
--- www/gitusers.md
+++ www/gitusers.md
@@ -130,56 +130,10 @@
130130
131131
[fpull]: /help?cmd=pull
132132
[gpull]: https://git-scm.com/docs/git-pull
133133
[gcokoan]: https://stevelosh.com/blog/2013/04/git-koans/#s2-one-thing-well
134134
135
-
136
-#### <a id="rname"></a> Naming Repositories
137
-
138
-The Fossil repository database file can be named anything
139
-you want, with a single exception: if you’re going to use the
140
-[`fossil server DIRECTORY`][server] feature, the repositories you wish
141
-to serve need to be stored together in a flat directory and have
142
-"`.fossil`" suffixes. That aside, you can follow any other convention that
143
-makes sense to you.
144
-
145
-This author uses a scheme like the following on mobile machines that
146
-shuttle between home and the office:
147
-
148
-``` pikchr toggle indent
149
-scale=0.8
150
-box "~/museum/" fit
151
-move right 0.1
152
-line right dotted
153
-move right 0.05
154
-box invis "where one stores valuable fossils" ljust
155
-
156
-arrow down 50% from first box.s then right 50%
157
-box "work/" fit
158
-move right 0.1
159
-line dotted
160
-move right 0.05
161
-box invis "projects from $dayjob" ljust
162
-
163
-arrow down 50% from 2nd vertex of previous arrow then right 50%
164
-box "home/" fit
165
-move right 0.1
166
-line dotted right until even with previous line.end
167
-move right 0.05
168
-box invis "personal at-home projects" ljust
169
-
170
-arrow down 50% from 2nd vertex of previous arrow then right 50%
171
-box "other/" fit
172
-move right 0.1
173
-line dotted right until even with previous line.end
174
-move right 0.05
175
-box invis "clones of Fossil itself, SQLite, etc." ljust
176
-```
177
-
178
-On a Windows box, you might instead choose "`C:\Fossils`"
179
-and do without the subdirectory scheme, for example.
180
-
181135
182136
#### <a id="close" name="dotfile"></a> Closing a Check-Out
183137
184138
The [`fossil close`][close] command dissociates a check-out directory from the
185139
Fossil repository database, nondestructively inverting [`fossil open`][open].
@@ -324,11 +278,11 @@
324278
repo DB file or what you name it.
325279
326280
327281
[clone]: /help?cmd=clone
328282
[close]: /help?cmd=close
329
-[gloss]: ./whyusefossil.wiki#definitions
283
+[gloss]: ./glossary.md
330284
[open]: /help?cmd=open
331285
[set]: /help?cmd=setting
332286
[server]: /help?cmd=server
333287
[stash]: /help?cmd=stash
334288
[undo]: /help?cmd=undo
@@ -486,23 +440,25 @@
486440
487441
488442
## <a id="slcom"></a> Summary Line Convention In Commit Comments
489443
490444
The Git convention of a [length-limited summary line][lsl] at the start
491
-of commit comments has no equivalent in Fossil. You’re welcome to style
492
-your commit comments thus, but the convention isn’t used or enforced
493
-anywhere in Fossil. For instance, setting `EDITOR=vim` and making a
494
-commit doesn’t do syntax highlighting on the commit message to warn that
495
-you’ve gone over the conventional limit on the first line, and the
496
-Fossil web timeline display doesn’t show the summary line in bold.
497
-
498
-If you wish to follow such conventions in a Fossil project, you may want
499
-to enable the “Allow block-markup in timeline” setting under Admin →
500
-Timeline in the web UI to prevent Fossil from showing the message as a
501
-single paragraph, sans line breaks. [Skin customization][cskin] would
502
-allow you to style the first line of the commit message in bold in
503
-`/timeline` views.
445
+of commit comments is not enforced or obeyed by default in Fossil.
446
+However, there is a setting under Admin → Timeline → “Truncate comment
447
+at first blank line (Git-style)” to change this for `/timeline`
448
+displays. Alternately, you could enable the “Allow block-markup in
449
+timeline” setting under Admin → Timeline, then apply [local skin
450
+customizations][cskin] to put that first comment in in bold or whatever
451
+suits.
452
+
453
+Because this isn’t a typical Fossil convention, you’re likely to find
454
+other odd differences between it and Git-based infrastructure. For
455
+instance, Vim doesn’t ship with syntax support for Fossil commit
456
+messages if you set `EDITOR=vim` in your shell environment, so you won’t
457
+get over-limit highlighting for first-line text beyond the 50th
458
+character and such, because it doesn’t recognize Fossil commit messages
459
+and apply similar rules as to Git commit messages.
504460
505461
[cskin]: ./customskin.md
506462
[lsl]: https://chris.beams.io/posts/git-commit/#limit-50
507463
508464
509465
510466
ADDED www/glossary.md
--- www/gitusers.md
+++ www/gitusers.md
@@ -130,56 +130,10 @@
130
131 [fpull]: /help?cmd=pull
132 [gpull]: https://git-scm.com/docs/git-pull
133 [gcokoan]: https://stevelosh.com/blog/2013/04/git-koans/#s2-one-thing-well
134
135
136 #### <a id="rname"></a> Naming Repositories
137
138 The Fossil repository database file can be named anything
139 you want, with a single exception: if you’re going to use the
140 [`fossil server DIRECTORY`][server] feature, the repositories you wish
141 to serve need to be stored together in a flat directory and have
142 "`.fossil`" suffixes. That aside, you can follow any other convention that
143 makes sense to you.
144
145 This author uses a scheme like the following on mobile machines that
146 shuttle between home and the office:
147
148 ``` pikchr toggle indent
149 scale=0.8
150 box "~/museum/" fit
151 move right 0.1
152 line right dotted
153 move right 0.05
154 box invis "where one stores valuable fossils" ljust
155
156 arrow down 50% from first box.s then right 50%
157 box "work/" fit
158 move right 0.1
159 line dotted
160 move right 0.05
161 box invis "projects from $dayjob" ljust
162
163 arrow down 50% from 2nd vertex of previous arrow then right 50%
164 box "home/" fit
165 move right 0.1
166 line dotted right until even with previous line.end
167 move right 0.05
168 box invis "personal at-home projects" ljust
169
170 arrow down 50% from 2nd vertex of previous arrow then right 50%
171 box "other/" fit
172 move right 0.1
173 line dotted right until even with previous line.end
174 move right 0.05
175 box invis "clones of Fossil itself, SQLite, etc." ljust
176 ```
177
178 On a Windows box, you might instead choose "`C:\Fossils`"
179 and do without the subdirectory scheme, for example.
180
181
182 #### <a id="close" name="dotfile"></a> Closing a Check-Out
183
184 The [`fossil close`][close] command dissociates a check-out directory from the
185 Fossil repository database, nondestructively inverting [`fossil open`][open].
@@ -324,11 +278,11 @@
324 repo DB file or what you name it.
325
326
327 [clone]: /help?cmd=clone
328 [close]: /help?cmd=close
329 [gloss]: ./whyusefossil.wiki#definitions
330 [open]: /help?cmd=open
331 [set]: /help?cmd=setting
332 [server]: /help?cmd=server
333 [stash]: /help?cmd=stash
334 [undo]: /help?cmd=undo
@@ -486,23 +440,25 @@
486
487
488 ## <a id="slcom"></a> Summary Line Convention In Commit Comments
489
490 The Git convention of a [length-limited summary line][lsl] at the start
491 of commit comments has no equivalent in Fossil. You’re welcome to style
492 your commit comments thus, but the convention isn’t used or enforced
493 anywhere in Fossil. For instance, setting `EDITOR=vim` and making a
494 commit doesn’t do syntax highlighting on the commit message to warn that
495 you’ve gone over the conventional limit on the first line, and the
496 Fossil web timeline display doesn’t show the summary line in bold.
497
498 If you wish to follow such conventions in a Fossil project, you may want
499 to enable the “Allow block-markup in timeline” setting under Admin →
500 Timeline in the web UI to prevent Fossil from showing the message as a
501 single paragraph, sans line breaks. [Skin customization][cskin] would
502 allow you to style the first line of the commit message in bold in
503 `/timeline` views.
 
 
504
505 [cskin]: ./customskin.md
506 [lsl]: https://chris.beams.io/posts/git-commit/#limit-50
507
508
509
510 DDED www/glossary.md
--- www/gitusers.md
+++ www/gitusers.md
@@ -130,56 +130,10 @@
130
131 [fpull]: /help?cmd=pull
132 [gpull]: https://git-scm.com/docs/git-pull
133 [gcokoan]: https://stevelosh.com/blog/2013/04/git-koans/#s2-one-thing-well
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
136 #### <a id="close" name="dotfile"></a> Closing a Check-Out
137
138 The [`fossil close`][close] command dissociates a check-out directory from the
139 Fossil repository database, nondestructively inverting [`fossil open`][open].
@@ -324,11 +278,11 @@
278 repo DB file or what you name it.
279
280
281 [clone]: /help?cmd=clone
282 [close]: /help?cmd=close
283 [gloss]: ./glossary.md
284 [open]: /help?cmd=open
285 [set]: /help?cmd=setting
286 [server]: /help?cmd=server
287 [stash]: /help?cmd=stash
288 [undo]: /help?cmd=undo
@@ -486,23 +440,25 @@
440
441
442 ## <a id="slcom"></a> Summary Line Convention In Commit Comments
443
444 The Git convention of a [length-limited summary line][lsl] at the start
445 of commit comments is not enforced or obeyed by default in Fossil.
446 However, there is a setting under Admin → Timeline → “Truncate comment
447 at first blank line (Git-style)” to change this for `/timeline`
448 displays. Alternately, you could enable the “Allow block-markup in
449 timeline” setting under Admin → Timeline, then apply [local skin
450 customizations][cskin] to put that first comment in in bold or whatever
451 suits.
452
453 Because this isn’t a typical Fossil convention, you’re likely to find
454 other odd differences between it and Git-based infrastructure. For
455 instance, Vim doesn’t ship with syntax support for Fossil commit
456 messages if you set `EDITOR=vim` in your shell environment, so you won’t
457 get over-limit highlighting for first-line text beyond the 50th
458 character and such, because it doesn’t recognize Fossil commit messages
459 and apply similar rules as to Git commit messages.
460
461 [cskin]: ./customskin.md
462 [lsl]: https://chris.beams.io/posts/git-commit/#limit-50
463
464
465
466 DDED www/glossary.md
--- a/www/glossary.md
+++ b/www/glossary.md
@@ -0,0 +1,229 @@
1
+# Glossary
2
+
3
+There are several terms-of-art in Fossil that have specific meanings
4
+which are either not immediately obvious to an outsider or which have
5
+technical associations that can lead someone to either use the terms
6
+incorrectly or to get the wrong idea from someone using those terms
7
+correctly. We hope to teach users how to properly “speak FossEach definition is followed by a bullet-point list of clarifying
8
+details. These are not part of the definition itself.project"></a>Project
9
+
10
+A collection of one or more computer files that serve some conceptually
11
+unified purpose, which purpose changes and evolves over time, with the
12
+history of that project being a valuable record.
13
+
14
+* We qualify the Fossil definition of this common word like this to
15
+ set aside cases where a zip file or tarball would suffice. If you
16
+ can pack your project up into such an archive once and be done with
17
+ it, Fossil is overkill.
18
+
19
+ And yet that is often just the beginning, since there is often a
20
+ need for something to be changed, so now you have “version 2” of the
21
+ archive file. If you can foresee yourself creating versioned archive
22
+ files for your project, then you probably should be using Fossil for
23
+ it instead, then using Fossil’s [zip] or [tarball] command to
24
+ automatically produce archives of the latest version rather than
25
+ manually produce and track versions of the archive. The web version
26
+ of these commands ([`/zip`][zw] and [`/tarball`][tw]) are
27
+ particularly useful for public distribution of the latest version of
28
+ a project’s files.
29
+
30
+* Fossil was designed to host the SQLite software project, which is
31
+ comprised of source code, makefiles, scripts, documentation files,
32
+ and so forth. Fossil is also useful for many other purposes, such as
33
+ a fiction book project where each chapter is held in a separate file
34
+ and assembled into a finished whole deliverable.
35
+
36
+* We speak of projects being more than one file because even though
37
+ Fossil can be made to track the history of a single file, it is far
38
+ more often the case that when you get to something of a scale
39
+ sufficient to be called a “project,” there is more than one
40
+ version-tracked file involved, if not at the start, then certainly
41
+ by thWe usedose changeswith one chapter per
42
+ file. That implies scripts for combining those chapters into the
43
+ finished book and converting that into PDF and ePub outputs, each of
44
+ which benefit from being version-tracked.
45
+
46
+ You could instead use a Word DOCX file for common word like this t,
47
+ with these implicit scripts replaced by Word menu commands. Fossil
48
+ will happily track that single file’s evolution for you, though
49
+ ./image-format-vs-re?cmd=tarba) to *not* do
50
+ that.
51
+
52
+ Let us say you choose to solve the primary problems brought up in
53
+ that document by using a format like AsciiDoc instead. You could
54
+ still use a single file for the entire book’s proseoresee yourself creating versioned archive
55
+ files for your project, then you probably should be using Fossil for
56
+ it instead, then using Fossil’s [zip] or [tarball] command to
57
+ automatically produce archives of the latest version rather than
58
+ manually produce and track versions of the archive. The web version
59
+ of these commands ([`/zip`][zw] and [`/tarball`][tw]) are
60
+ particularly useful for public distribution of the latest version of
61
+ a project’s files.
62
+
63
+* Fossil was designed to host the SQLite software project, which is
64
+ comprised of source code, makefiles, scripts, documentation files,
65
+ and so forth. Fossil is also useful for many other purposes, such as
66
+ a fiction book project where each chapter is held in a separate file
67
+ and assembled into a finished whole deliverable.
68
+
69
+* We speak of projects being more than one file because even though
70
+ Fossil can be made to track the history of a single file, it is far
71
+ more often the case that when you get to something of a scale
72
+ sufficient to be called a “project,” there is more than one
73
+ version-tracked file involved, if not at the start, then certainly
74
+ by the end of the project.
75
+
76
+ To take the example of a fiction book above, instead of putting each
77
+ chapter in a separate file, you could use a single AsciiDoc file for
78
+ the entire book project rather than make use of its [include
79
+ facility][AIF] to assemble it from chapter files, since that does at
80
+ least solve the [key problemsrting the
81
+ source document to HTML, scripts to convert that intermediate output
82
+ to PDF and ePub in a reliably repeatable fashion, a `README` file
83
+ containing instructions to the printing house, and so forth.
84
+
85
+* Fossil requires that all the files for a project be collected into a
86
+ single directory hierarchy, owned by a single user with full rights
87
+ to modify those files. Fossil is not a good choice for managing a
88
+ project that has files scattered hither and yon all over the file
89
+ system, nor of collections of files with complicated ownership and
90
+ access rights.
91
+
92
+ A project made of an operating system
93
+ ins zip archivsystem
94
+ installation’s configuration file set is not a good use of Fossil,
95
+ because you’ll have all of your OS’s *other* files intermixejust as with a zip archive,so even if you were to
96
+ try to use Fossil as a system deployment tool by archiving versions
97
+ of the OS configuration files and then unpacking them on a neappending “`.fossil`would have read/write access by
98
+ the user who did the extraction, which’s required, being the “directory
99
+ name” form of [the `fossil server l clean --verily` on such a system?
100
+ You can constrain that with [the `ignore-glob` setting][IGS], but
101
+ are you prepared to write and maintain all the rules needed to keep
102
+ Fossil from blowing away the untracked portions of the file system?
103
+ We believe Fossil is a poor choice for a whole-system configuration
104
+ backup utility.
105
+
106
+ As a counterexample, a project tracking your [Vim] configuration
107
+ history is a much better use of Fossil, because it’s all held within
108
+ `~/.vim`, and your user has full rights to that subdirectory.
109
+
110
+[AIF]: https://docs.asciidoctor.org/asciidoc/latest/directive?cmd=/include/
111
+[IGS]: /help/ignore-glob
112
+[IFRS]: ./image-format-vs-re?cmd=tarball
113
+[tw]: /help?cmd=/tarball
114
+[Vim]: https://ww?cmd=zip
115
+[zw]: /help?cmd=
116
+which are either not immediately obvious to an outsider or which have
117
+technical associations that can lead someone to either use the terms
118
+incorrectly or to get the wrong idea from someone using those terms
119
+correctly. We hope to teach users how to properly “speak Fossil” with
120
+this glossary.
121
+
122
+The bullet-point lists following each definition are meant to be
123
+clarifying and illustrative. They are not part of the definitions
124
+themselves.
125
+
126
+
127
+## <a id="project"></a>Project
128
+
129
+A collection of one or more computer files that serve some conceptually
130
+unified purpose, which purpose changes and evolves over time, with the
131
+history of that project being a valuable record.
132
+
133
+* We qualify the Fossil definition of this common word like this to
134
+ set aside cases where a zip file or tarball would suffice. If you
135
+ can pack your project up into such an archive once and be done with
136
+ it, Fossil is overkill.
137
+
138
+ And yet that is often just the beginning, since there is often a
139
+ need for something to be changed, so now you have “version 2” of the
140
+ archive file. If you can foresee yourself creating versioned archive
141
+ files for your project, then you probably should be using Fossil for
142
+ it instead, then using Fossil’s [zip] or [tarball] command to
143
+ automatically produce archives of the latest version rather than
144
+ manually produce and track versions of the archive. The web version
145
+ of these commands ([`/zip`][zw] and [`/tarball`][tw]) are
146
+ particularly useful for public distribution of the latest version of
147
+ a project’s files.
148
+
149
+* Fossil was designed to host the SQLite software project, which is
150
+ comprised of source code, makefiles, scripts, documentation files,
151
+ and so forth. Fossil is also useful for many other purposes, such as
152
+ a fiction book project where each chapter is held in a separate file
153
+ and assembled into a finished whole deliverable.
154
+
155
+* We speak of projects being more than one file because even though
156
+ Fossil can be made to track the history of a single file, it is far
157
+ more often the case that when you get to something of a scale
158
+ sufficient to be called a “project,” there is more than one
159
+ version-tracked file involved, if not at the start, then certainly
160
+ by the end of the project.
161
+
162
+ To take the example of a fiction book above, instead of putting each
163
+ chapter in a separate file, you could use a single AsciiDoc file for
164
+ the entire book project rather than make use of its [include
165
+ facility][AIF] to assemble it from chapter files, since that does at
166
+ least solve the [key problems][IFRS] inherent in./backup.md
167
+[CAP]:rent in version-tracking
168
+ soormat with Fossil instead./help?cmd=pull
169
+[push]:ad.
170
+
171
+ While Fossil will h containing the prose
172
+ o/help?cmd=sync��re s yorepositoryobleversion e the terms
173
+incorrectly o of the
174
+ man. It which Fossil follows, not e
175
+seen from ) format, the tySynonyms: version,
176
+snapshot, revision, commit. Sometimes styled HA1 synonyms for
177
+ people ex
178
+ vice
179
+ bits reserved in the UU
180
+ bits reserved in the UUID format
181
+used.
182
+
183
+* Theliterated from use since there are columns in the Fossil
184
+ repository format that use the obsolete term; we cannot change this
185
+ without breaking backwards compatibility.)
186
+
187
+You will find all of these synonyms used in the Fossil documentation.
188
+Some day we may settle on a single term, but it doesn’t seem likely.
189
+
190
+[CVS]
191
+ e the terms
192
+incorrectly or to# Glossary
193
+
194
+There are several terms-of-art in Fossil that have spgher doesn’t help with this confusion, making a Fossil version
195
+ hash twice as large as a proper UUID. Alas, the term will never be
196
+ fully obliterated from use since there are columns in the Fossil
197
+ repository format that use the obsolete term; we cannot change this
198
+ without breaking backwards compatibility.)
199
+
200
+You will find all of these synonyms used in the Fossil documentation.
201
+Some day we may settle on a single term, but it doesn’t seem likely.
202
+
203
+[CVS]: https://en.wikipedia.org/wiki/ SHA
204
+ hashd the extraction, which probably isn’t what yorepositoryoblem
205
+ with using this as a synonym for a Fossil-managed versio of the
206
+ managed files is that there are [standards][UUID] defining the
207
+ format of a “UUID,” none of which Fossil follows, not even the
208
+ [version 4][ruuid] (random) format, the type of UUID closeso a Fossil hash.(^Ail 2.0 style SHA1 synonyms for
209
+ people expect for a proper
210
+ UU and vice
211
+ bits reserved in the UUID format for
212
+ the variant code cannot make a correct declaration except by a
213
+ random 1:64 chance. The SHA3-256 option allowed in Fossil 2.0 and
214
+ higher doesn’t help with this confusion, making a Fossil version
215
+ hash twice as large as a proper UUID. Alas, the term will never be
216
+ fully obliterated from use since there are columns in the Fossil
217
+ repository format that use the obsolete term; we cannot change this
218
+ without breaking backwards compatibility.)
219
+
220
+You will find all of these synonyms used in the Fossil documentation.
221
+Some day we may settle on a single term, but it doesn’t seem likely.
222
+
223
+[CVS]
224
+ e the terms
225
+incorrectly or to# Glossary
226
+
227
+There are several terms-of-art in Fossil that have spgher doesn’t help with this confusion, help with this confusion, making a Fossil version
228
+ hash twice as large as a proper UUID. Alas, the term will never be
229
+ fully obliterated from use since there are columns in
--- a/www/glossary.md
+++ b/www/glossary.md
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/www/glossary.md
+++ b/www/glossary.md
@@ -0,0 +1,229 @@
1 # Glossary
2
3 There are several terms-of-art in Fossil that have specific meanings
4 which are either not immediately obvious to an outsider or which have
5 technical associations that can lead someone to either use the terms
6 incorrectly or to get the wrong idea from someone using those terms
7 correctly. We hope to teach users how to properly “speak FossEach definition is followed by a bullet-point list of clarifying
8 details. These are not part of the definition itself.project"></a>Project
9
10 A collection of one or more computer files that serve some conceptually
11 unified purpose, which purpose changes and evolves over time, with the
12 history of that project being a valuable record.
13
14 * We qualify the Fossil definition of this common word like this to
15 set aside cases where a zip file or tarball would suffice. If you
16 can pack your project up into such an archive once and be done with
17 it, Fossil is overkill.
18
19 And yet that is often just the beginning, since there is often a
20 need for something to be changed, so now you have “version 2” of the
21 archive file. If you can foresee yourself creating versioned archive
22 files for your project, then you probably should be using Fossil for
23 it instead, then using Fossil’s [zip] or [tarball] command to
24 automatically produce archives of the latest version rather than
25 manually produce and track versions of the archive. The web version
26 of these commands ([`/zip`][zw] and [`/tarball`][tw]) are
27 particularly useful for public distribution of the latest version of
28 a project’s files.
29
30 * Fossil was designed to host the SQLite software project, which is
31 comprised of source code, makefiles, scripts, documentation files,
32 and so forth. Fossil is also useful for many other purposes, such as
33 a fiction book project where each chapter is held in a separate file
34 and assembled into a finished whole deliverable.
35
36 * We speak of projects being more than one file because even though
37 Fossil can be made to track the history of a single file, it is far
38 more often the case that when you get to something of a scale
39 sufficient to be called a “project,” there is more than one
40 version-tracked file involved, if not at the start, then certainly
41 by thWe usedose changeswith one chapter per
42 file. That implies scripts for combining those chapters into the
43 finished book and converting that into PDF and ePub outputs, each of
44 which benefit from being version-tracked.
45
46 You could instead use a Word DOCX file for common word like this t,
47 with these implicit scripts replaced by Word menu commands. Fossil
48 will happily track that single file’s evolution for you, though
49 ./image-format-vs-re?cmd=tarba) to *not* do
50 that.
51
52 Let us say you choose to solve the primary problems brought up in
53 that document by using a format like AsciiDoc instead. You could
54 still use a single file for the entire book’s proseoresee yourself creating versioned archive
55 files for your project, then you probably should be using Fossil for
56 it instead, then using Fossil’s [zip] or [tarball] command to
57 automatically produce archives of the latest version rather than
58 manually produce and track versions of the archive. The web version
59 of these commands ([`/zip`][zw] and [`/tarball`][tw]) are
60 particularly useful for public distribution of the latest version of
61 a project’s files.
62
63 * Fossil was designed to host the SQLite software project, which is
64 comprised of source code, makefiles, scripts, documentation files,
65 and so forth. Fossil is also useful for many other purposes, such as
66 a fiction book project where each chapter is held in a separate file
67 and assembled into a finished whole deliverable.
68
69 * We speak of projects being more than one file because even though
70 Fossil can be made to track the history of a single file, it is far
71 more often the case that when you get to something of a scale
72 sufficient to be called a “project,” there is more than one
73 version-tracked file involved, if not at the start, then certainly
74 by the end of the project.
75
76 To take the example of a fiction book above, instead of putting each
77 chapter in a separate file, you could use a single AsciiDoc file for
78 the entire book project rather than make use of its [include
79 facility][AIF] to assemble it from chapter files, since that does at
80 least solve the [key problemsrting the
81 source document to HTML, scripts to convert that intermediate output
82 to PDF and ePub in a reliably repeatable fashion, a `README` file
83 containing instructions to the printing house, and so forth.
84
85 * Fossil requires that all the files for a project be collected into a
86 single directory hierarchy, owned by a single user with full rights
87 to modify those files. Fossil is not a good choice for managing a
88 project that has files scattered hither and yon all over the file
89 system, nor of collections of files with complicated ownership and
90 access rights.
91
92 A project made of an operating system
93 ins zip archivsystem
94 installation’s configuration file set is not a good use of Fossil,
95 because you’ll have all of your OS’s *other* files intermixejust as with a zip archive,so even if you were to
96 try to use Fossil as a system deployment tool by archiving versions
97 of the OS configuration files and then unpacking them on a neappending “`.fossil`would have read/write access by
98 the user who did the extraction, which’s required, being the “directory
99 name” form of [the `fossil server l clean --verily` on such a system?
100 You can constrain that with [the `ignore-glob` setting][IGS], but
101 are you prepared to write and maintain all the rules needed to keep
102 Fossil from blowing away the untracked portions of the file system?
103 We believe Fossil is a poor choice for a whole-system configuration
104 backup utility.
105
106 As a counterexample, a project tracking your [Vim] configuration
107 history is a much better use of Fossil, because it’s all held within
108 `~/.vim`, and your user has full rights to that subdirectory.
109
110 [AIF]: https://docs.asciidoctor.org/asciidoc/latest/directive?cmd=/include/
111 [IGS]: /help/ignore-glob
112 [IFRS]: ./image-format-vs-re?cmd=tarball
113 [tw]: /help?cmd=/tarball
114 [Vim]: https://ww?cmd=zip
115 [zw]: /help?cmd=
116 which are either not immediately obvious to an outsider or which have
117 technical associations that can lead someone to either use the terms
118 incorrectly or to get the wrong idea from someone using those terms
119 correctly. We hope to teach users how to properly “speak Fossil” with
120 this glossary.
121
122 The bullet-point lists following each definition are meant to be
123 clarifying and illustrative. They are not part of the definitions
124 themselves.
125
126
127 ## <a id="project"></a>Project
128
129 A collection of one or more computer files that serve some conceptually
130 unified purpose, which purpose changes and evolves over time, with the
131 history of that project being a valuable record.
132
133 * We qualify the Fossil definition of this common word like this to
134 set aside cases where a zip file or tarball would suffice. If you
135 can pack your project up into such an archive once and be done with
136 it, Fossil is overkill.
137
138 And yet that is often just the beginning, since there is often a
139 need for something to be changed, so now you have “version 2” of the
140 archive file. If you can foresee yourself creating versioned archive
141 files for your project, then you probably should be using Fossil for
142 it instead, then using Fossil’s [zip] or [tarball] command to
143 automatically produce archives of the latest version rather than
144 manually produce and track versions of the archive. The web version
145 of these commands ([`/zip`][zw] and [`/tarball`][tw]) are
146 particularly useful for public distribution of the latest version of
147 a project’s files.
148
149 * Fossil was designed to host the SQLite software project, which is
150 comprised of source code, makefiles, scripts, documentation files,
151 and so forth. Fossil is also useful for many other purposes, such as
152 a fiction book project where each chapter is held in a separate file
153 and assembled into a finished whole deliverable.
154
155 * We speak of projects being more than one file because even though
156 Fossil can be made to track the history of a single file, it is far
157 more often the case that when you get to something of a scale
158 sufficient to be called a “project,” there is more than one
159 version-tracked file involved, if not at the start, then certainly
160 by the end of the project.
161
162 To take the example of a fiction book above, instead of putting each
163 chapter in a separate file, you could use a single AsciiDoc file for
164 the entire book project rather than make use of its [include
165 facility][AIF] to assemble it from chapter files, since that does at
166 least solve the [key problems][IFRS] inherent in./backup.md
167 [CAP]:rent in version-tracking
168 soormat with Fossil instead./help?cmd=pull
169 [push]:ad.
170
171 While Fossil will h containing the prose
172 o/help?cmd=sync��re s yorepositoryobleversion e the terms
173 incorrectly o of the
174 man. It which Fossil follows, not e
175 seen from ) format, the tySynonyms: version,
176 snapshot, revision, commit. Sometimes styled HA1 synonyms for
177 people ex
178 vice
179 bits reserved in the UU
180 bits reserved in the UUID format
181 used.
182
183 * Theliterated from use since there are columns in the Fossil
184 repository format that use the obsolete term; we cannot change this
185 without breaking backwards compatibility.)
186
187 You will find all of these synonyms used in the Fossil documentation.
188 Some day we may settle on a single term, but it doesn’t seem likely.
189
190 [CVS]
191 e the terms
192 incorrectly or to# Glossary
193
194 There are several terms-of-art in Fossil that have spgher doesn’t help with this confusion, making a Fossil version
195 hash twice as large as a proper UUID. Alas, the term will never be
196 fully obliterated from use since there are columns in the Fossil
197 repository format that use the obsolete term; we cannot change this
198 without breaking backwards compatibility.)
199
200 You will find all of these synonyms used in the Fossil documentation.
201 Some day we may settle on a single term, but it doesn’t seem likely.
202
203 [CVS]: https://en.wikipedia.org/wiki/ SHA
204 hashd the extraction, which probably isn’t what yorepositoryoblem
205 with using this as a synonym for a Fossil-managed versio of the
206 managed files is that there are [standards][UUID] defining the
207 format of a “UUID,” none of which Fossil follows, not even the
208 [version 4][ruuid] (random) format, the type of UUID closeso a Fossil hash.(^Ail 2.0 style SHA1 synonyms for
209 people expect for a proper
210 UU and vice
211 bits reserved in the UUID format for
212 the variant code cannot make a correct declaration except by a
213 random 1:64 chance. The SHA3-256 option allowed in Fossil 2.0 and
214 higher doesn’t help with this confusion, making a Fossil version
215 hash twice as large as a proper UUID. Alas, the term will never be
216 fully obliterated from use since there are columns in the Fossil
217 repository format that use the obsolete term; we cannot change this
218 without breaking backwards compatibility.)
219
220 You will find all of these synonyms used in the Fossil documentation.
221 Some day we may settle on a single term, but it doesn’t seem likely.
222
223 [CVS]
224 e the terms
225 incorrectly or to# Glossary
226
227 There are several terms-of-art in Fossil that have spgher doesn’t help with this confusion, help with this confusion, making a Fossil version
228 hash twice as large as a proper UUID. Alas, the term will never be
229 fully obliterated from use since there are columns in
+4 -4
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
8383
the repository are consistent prior to each commit.
8484
8585
8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
8686
8787
<hr>
88
-<h3>Latest Release: 2.16 ([/timeline?c=version-2.16|2021-07-02])</h3>
88
+<h3>Latest Release: 2.17 ([/timeline?c=version-2.17|2021-10-09])</h3>
8989
9090
* [/uv/download.html|Download]
91
- * [./changes.wiki#v2_16|Change Summary]
92
- * [/timeline?p=version-2.16&bt=version-2.15&y=ci|Check-ins in version 2.16]
93
- * [/timeline?df=version-2.16&y=ci|Check-ins derived from the 2.16 release]
91
+ * [./changes.wiki#v2_17|Change Summary]
92
+ * [/timeline?p=version-2.17&bt=version-2.16&y=ci|Check-ins in version 2.17]
93
+ * [/timeline?df=version-2.17&y=ci|Check-ins derived from the 2.17 release]
9494
* [/timeline?t=release|Timeline of all past releases]
9595
9696
<hr>
9797
<h3>Quick Start</h3>
9898
9999
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
83 the repository are consistent prior to each commit.
84
85 8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
86
87 <hr>
88 <h3>Latest Release: 2.16 ([/timeline?c=version-2.16|2021-07-02])</h3>
89
90 * [/uv/download.html|Download]
91 * [./changes.wiki#v2_16|Change Summary]
92 * [/timeline?p=version-2.16&bt=version-2.15&y=ci|Check-ins in version 2.16]
93 * [/timeline?df=version-2.16&y=ci|Check-ins derived from the 2.16 release]
94 * [/timeline?t=release|Timeline of all past releases]
95
96 <hr>
97 <h3>Quick Start</h3>
98
99
--- www/index.wiki
+++ www/index.wiki
@@ -83,16 +83,16 @@
83 the repository are consistent prior to each commit.
84
85 8. <b>Free and Open-Source</b> - [../COPYRIGHT-BSD2.txt|2-clause BSD license].
86
87 <hr>
88 <h3>Latest Release: 2.17 ([/timeline?c=version-2.17|2021-10-09])</h3>
89
90 * [/uv/download.html|Download]
91 * [./changes.wiki#v2_17|Change Summary]
92 * [/timeline?p=version-2.17&bt=version-2.16&y=ci|Check-ins in version 2.17]
93 * [/timeline?df=version-2.17&y=ci|Check-ins derived from the 2.17 release]
94 * [/timeline?t=release|Timeline of all past releases]
95
96 <hr>
97 <h3>Quick Start</h3>
98
99
--- www/interwiki.md
+++ www/interwiki.md
@@ -111,8 +111,7 @@
111111
value for each such entry is a JSON string that defines the base URL
112112
and extensions for Hash and Wiki links.
113113
114114
## See Also
115115
116
- 1. [](https://en.wikipedia.org/wiki/Interwiki_links)
117
- 2. [](https://www.mediawiki.org/wiki/Manual:Interwiki)
118
- 3. [](https://duckduckgo.com/?q=interwiki+links&ia=web)
116
+ 1. [](https://www.mediawiki.org/wiki/Manual:Interwiki)
117
+ 2. [](https://duckduckgo.com/?q=interwiki+links&ia=web)
119118
--- www/interwiki.md
+++ www/interwiki.md
@@ -111,8 +111,7 @@
111 value for each such entry is a JSON string that defines the base URL
112 and extensions for Hash and Wiki links.
113
114 ## See Also
115
116 1. [](https://en.wikipedia.org/wiki/Interwiki_links)
117 2. [](https://www.mediawiki.org/wiki/Manual:Interwiki)
118 3. [](https://duckduckgo.com/?q=interwiki+links&ia=web)
119
--- www/interwiki.md
+++ www/interwiki.md
@@ -111,8 +111,7 @@
111 value for each such entry is a JSON string that defines the base URL
112 and extensions for Hash and Wiki links.
113
114 ## See Also
115
116 1. [](https://www.mediawiki.org/wiki/Manual:Interwiki)
117 2. [](https://duckduckgo.com/?q=interwiki+links&ia=web)
 
118
+2 -1
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -62,12 +62,13 @@
6262
foss-cklist.wiki {Checklist For Successful Open-Source Projects}
6363
fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
6464
fossil-is-not-relational.md {Introduction to the (Non-relational) Fossil Data Model}
6565
fossil_prompt.wiki {Fossilized Bash Prompt}
6666
fossil-v-git.wiki {Fossil Versus Git}
67
- globs.md {File Name Glob Patterns}
6867
gitusers.md {Git to Fossil Translation Guide}
68
+ globs.md {File Name Glob Patterns}
69
+ glossary.md {Glossary}
6970
grep.md {Fossil grep vs POSIX grep}
7071
hacker-howto.wiki {Hacker How-To}
7172
hacker-howto.wiki {Fossil Developers Guide}
7273
hashes.md {Hashes: Fossil Artifact Identification}
7374
hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
7475
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -62,12 +62,13 @@
62 foss-cklist.wiki {Checklist For Successful Open-Source Projects}
63 fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
64 fossil-is-not-relational.md {Introduction to the (Non-relational) Fossil Data Model}
65 fossil_prompt.wiki {Fossilized Bash Prompt}
66 fossil-v-git.wiki {Fossil Versus Git}
67 globs.md {File Name Glob Patterns}
68 gitusers.md {Git to Fossil Translation Guide}
 
 
69 grep.md {Fossil grep vs POSIX grep}
70 hacker-howto.wiki {Hacker How-To}
71 hacker-howto.wiki {Fossil Developers Guide}
72 hashes.md {Hashes: Fossil Artifact Identification}
73 hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
74
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -62,12 +62,13 @@
62 foss-cklist.wiki {Checklist For Successful Open-Source Projects}
63 fossil-from-msvc.wiki {Integrating Fossil in the Microsoft Express 2010 IDE}
64 fossil-is-not-relational.md {Introduction to the (Non-relational) Fossil Data Model}
65 fossil_prompt.wiki {Fossilized Bash Prompt}
66 fossil-v-git.wiki {Fossil Versus Git}
 
67 gitusers.md {Git to Fossil Translation Guide}
68 globs.md {File Name Glob Patterns}
69 glossary.md {Glossary}
70 grep.md {Fossil grep vs POSIX grep}
71 hacker-howto.wiki {Hacker How-To}
72 hacker-howto.wiki {Fossil Developers Guide}
73 hashes.md {Hashes: Fossil Artifact Identification}
74 hashpolicy.wiki {Hash Policy: Choosing Between SHA1 and SHA3-256}
75
--- www/newrepo.wiki
+++ www/newrepo.wiki
@@ -112,11 +112,11 @@
112112
Making your repository available over the web is trivial to do. We
113113
assume you have some web space where you can store your fossil file
114114
and run a CGI script. If not, then this option is not for you. If
115115
you do, then here's how...
116116
117
-Copy copy the fossil repository file to your web server (it doesn't
117
+Copy the fossil repository file to your web server (it doesn't
118118
matter where, really).
119119
120120
In your <tt>cgi-bin</tt> (or equivalent) directory, create a file
121121
which looks like this:
122122
123123
--- www/newrepo.wiki
+++ www/newrepo.wiki
@@ -112,11 +112,11 @@
112 Making your repository available over the web is trivial to do. We
113 assume you have some web space where you can store your fossil file
114 and run a CGI script. If not, then this option is not for you. If
115 you do, then here's how...
116
117 Copy copy the fossil repository file to your web server (it doesn't
118 matter where, really).
119
120 In your <tt>cgi-bin</tt> (or equivalent) directory, create a file
121 which looks like this:
122
123
--- www/newrepo.wiki
+++ www/newrepo.wiki
@@ -112,11 +112,11 @@
112 Making your repository available over the web is trivial to do. We
113 assume you have some web space where you can store your fossil file
114 and run a CGI script. If not, then this option is not for you. If
115 you do, then here's how...
116
117 Copy the fossil repository file to your web server (it doesn't
118 matter where, really).
119
120 In your <tt>cgi-bin</tt> (or equivalent) directory, create a file
121 which looks like this:
122
123
--- www/password.wiki
+++ www/password.wiki
@@ -26,15 +26,14 @@
2626
2727
<blockquote>
2828
CE59BB9F186226D80E49D1FA2DB29F935CCA0333/alice/asdfg
2929
</blockquote>
3030
31
-That hash value is "f1b699cc9af3eeb98e5de244ca7802ae38e77bae". Note
32
-that by including the project-code and the login as part of the hash,
33
-a different USER.PW value results even if two or more users on the
34
-repository select the same "asdfg" password or if user alice reuses the
35
-same password on multiple projects.
31
+Note that by including the project-code and the login as part of the
32
+hash, a different USER.PW value results even if two or more users on
33
+the repository select the same "asdfg" password or if user alice
34
+reuses the same password on multiple projects.
3635
3736
Whenever a password is changed using the web interface or using the
3837
"user" command-line method, the new password is stored using the SHA1
3938
encoding. Thus, cleartext passwords will gradually migrate to become
4039
SHA1 passwords. All remaining cleartext passwords can be converted to
@@ -77,24 +76,10 @@
7776
The USER.CEXPIRE field holds an expiration date
7877
for the cookie, encoded as a Julian day number. On all subsequent
7978
HTTP requests, the cookie value is matched against the USER table to
8079
enable access to the repository.
8180
82
-A login cookie will only work if the IP address matches. This feature
83
-is designed to make it more difficult for an attacker to sniff the cookie
84
-and take over the connection. A cookie-sniffing attack will only work
85
-if the attacker is able to send and receive from the same IP address as
86
-the original login. However, we found that doing an exact IP match
87
-caused problems for some users who are behind proxy firewalls where the proxy
88
-might use a different IP address for each query. To work around this
89
-problem, newer versions of fossil only check the first 16 bits of the
90
-32-bit IP address. This makes a cookie sniffing attack easier since now
91
-the attacker only has to send and receive from any IP address in a range
92
-of IPs that are similar to the initial login. But that is seen as an
93
-acceptable compromise in exchange for ease of use. If higher security
94
-is really needed, then HTTPS can be used instead of HTTP.
95
-
9681
Note that in order to log into a Fossil server, it is necessary to
9782
write information into the repository database. Hence, login is not
9883
possible on a Fossil repository with a read-only database file.
9984
10085
The user password is sent over the wire as cleartext on the initial
10186
--- www/password.wiki
+++ www/password.wiki
@@ -26,15 +26,14 @@
26
27 <blockquote>
28 CE59BB9F186226D80E49D1FA2DB29F935CCA0333/alice/asdfg
29 </blockquote>
30
31 That hash value is "f1b699cc9af3eeb98e5de244ca7802ae38e77bae". Note
32 that by including the project-code and the login as part of the hash,
33 a different USER.PW value results even if two or more users on the
34 repository select the same "asdfg" password or if user alice reuses the
35 same password on multiple projects.
36
37 Whenever a password is changed using the web interface or using the
38 "user" command-line method, the new password is stored using the SHA1
39 encoding. Thus, cleartext passwords will gradually migrate to become
40 SHA1 passwords. All remaining cleartext passwords can be converted to
@@ -77,24 +76,10 @@
77 The USER.CEXPIRE field holds an expiration date
78 for the cookie, encoded as a Julian day number. On all subsequent
79 HTTP requests, the cookie value is matched against the USER table to
80 enable access to the repository.
81
82 A login cookie will only work if the IP address matches. This feature
83 is designed to make it more difficult for an attacker to sniff the cookie
84 and take over the connection. A cookie-sniffing attack will only work
85 if the attacker is able to send and receive from the same IP address as
86 the original login. However, we found that doing an exact IP match
87 caused problems for some users who are behind proxy firewalls where the proxy
88 might use a different IP address for each query. To work around this
89 problem, newer versions of fossil only check the first 16 bits of the
90 32-bit IP address. This makes a cookie sniffing attack easier since now
91 the attacker only has to send and receive from any IP address in a range
92 of IPs that are similar to the initial login. But that is seen as an
93 acceptable compromise in exchange for ease of use. If higher security
94 is really needed, then HTTPS can be used instead of HTTP.
95
96 Note that in order to log into a Fossil server, it is necessary to
97 write information into the repository database. Hence, login is not
98 possible on a Fossil repository with a read-only database file.
99
100 The user password is sent over the wire as cleartext on the initial
101
--- www/password.wiki
+++ www/password.wiki
@@ -26,15 +26,14 @@
26
27 <blockquote>
28 CE59BB9F186226D80E49D1FA2DB29F935CCA0333/alice/asdfg
29 </blockquote>
30
31 Note that by including the project-code and the login as part of the
32 hash, a different USER.PW value results even if two or more users on
33 the repository select the same "asdfg" password or if user alice
34 reuses the same password on multiple projects.
 
35
36 Whenever a password is changed using the web interface or using the
37 "user" command-line method, the new password is stored using the SHA1
38 encoding. Thus, cleartext passwords will gradually migrate to become
39 SHA1 passwords. All remaining cleartext passwords can be converted to
@@ -77,24 +76,10 @@
76 The USER.CEXPIRE field holds an expiration date
77 for the cookie, encoded as a Julian day number. On all subsequent
78 HTTP requests, the cookie value is matched against the USER table to
79 enable access to the repository.
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81 Note that in order to log into a Fossil server, it is necessary to
82 write information into the repository database. Hence, login is not
83 possible on a Fossil repository with a read-only database file.
84
85 The user password is sent over the wire as cleartext on the initial
86
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -69,10 +69,11 @@
6969
<li><a href="hints.wiki">Fossil Tips And Usage Hints</a></li>
7070
<li><a href="fossil-v-git.wiki">Fossil Versus Git</a></li>
7171
<li><a href="fossil_prompt.wiki">Fossilized Bash Prompt</a></li>
7272
<li><a href="faq.wiki">Frequently Asked Questions</a></li>
7373
<li><a href="gitusers.md">Git to Fossil Translation Guide</a></li>
74
+<li><a href="glossary.md">Glossary</a></li>
7475
<li><a href="hacker-howto.wiki">Hacker How-To</a></li>
7576
<li><a href="adding_code.wiki">Hacking Fossil</a></li>
7677
<li><a href="hashpolicy.wiki">Hash Policy: Choosing Between SHA1 and SHA3-256</a></li>
7778
<li><a href="hashes.md">Hashes: Fossil Artifact Identification</a></li>
7879
<li><a href="index.wiki">Home Page</a></li>
7980
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -69,10 +69,11 @@
69 <li><a href="hints.wiki">Fossil Tips And Usage Hints</a></li>
70 <li><a href="fossil-v-git.wiki">Fossil Versus Git</a></li>
71 <li><a href="fossil_prompt.wiki">Fossilized Bash Prompt</a></li>
72 <li><a href="faq.wiki">Frequently Asked Questions</a></li>
73 <li><a href="gitusers.md">Git to Fossil Translation Guide</a></li>
 
74 <li><a href="hacker-howto.wiki">Hacker How-To</a></li>
75 <li><a href="adding_code.wiki">Hacking Fossil</a></li>
76 <li><a href="hashpolicy.wiki">Hash Policy: Choosing Between SHA1 and SHA3-256</a></li>
77 <li><a href="hashes.md">Hashes: Fossil Artifact Identification</a></li>
78 <li><a href="index.wiki">Home Page</a></li>
79
--- www/permutedindex.html
+++ www/permutedindex.html
@@ -69,10 +69,11 @@
69 <li><a href="hints.wiki">Fossil Tips And Usage Hints</a></li>
70 <li><a href="fossil-v-git.wiki">Fossil Versus Git</a></li>
71 <li><a href="fossil_prompt.wiki">Fossilized Bash Prompt</a></li>
72 <li><a href="faq.wiki">Frequently Asked Questions</a></li>
73 <li><a href="gitusers.md">Git to Fossil Translation Guide</a></li>
74 <li><a href="glossary.md">Glossary</a></li>
75 <li><a href="hacker-howto.wiki">Hacker How-To</a></li>
76 <li><a href="adding_code.wiki">Hacking Fossil</a></li>
77 <li><a href="hashpolicy.wiki">Hash Policy: Choosing Between SHA1 and SHA3-256</a></li>
78 <li><a href="hashes.md">Hashes: Fossil Artifact Identification</a></li>
79 <li><a href="index.wiki">Home Page</a></li>
80
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -25,11 +25,11 @@
2525
<h2 id="workflow" name="fslclone">General Work Flow</h2>
2626
2727
<p>Fossil works with repository files (a database in a single file with the project's
2828
complete history) and with checked-out local trees (the working directory
2929
you use to do your work).
30
-(See [./whyusefossil.wiki#definitions | definitions] for more background.)
30
+(See [./glossary.md | the glossary] for more background.)
3131
The workflow looks like this:</p>
3232
3333
<ul>
3434
<li>Create or clone a repository file. ([/help/init|fossil init] or
3535
[/help/clone | fossil clone])
3636
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -25,11 +25,11 @@
25 <h2 id="workflow" name="fslclone">General Work Flow</h2>
26
27 <p>Fossil works with repository files (a database in a single file with the project's
28 complete history) and with checked-out local trees (the working directory
29 you use to do your work).
30 (See [./whyusefossil.wiki#definitions | definitions] for more background.)
31 The workflow looks like this:</p>
32
33 <ul>
34 <li>Create or clone a repository file. ([/help/init|fossil init] or
35 [/help/clone | fossil clone])
36
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -25,11 +25,11 @@
25 <h2 id="workflow" name="fslclone">General Work Flow</h2>
26
27 <p>Fossil works with repository files (a database in a single file with the project's
28 complete history) and with checked-out local trees (the working directory
29 you use to do your work).
30 (See [./glossary.md | the glossary] for more background.)
31 The workflow looks like this:</p>
32
33 <ul>
34 <li>Create or clone a repository file. ([/help/init|fossil init] or
35 [/help/clone | fossil clone])
36
--- 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
+2 -2
--- www/sync.wiki
+++ www/sync.wiki
@@ -704,11 +704,11 @@
704704
705705
<li><p><b>uv-push-ok</b></i>
706706
<p>A server sends the uv-push-ok pragma to the client in response
707707
to a uv-hash pragma with a mismatched content hash argument. This
708708
pragma indicates that there are differences in unversioned content
709
-between the client and server and that content can only be transferred
709
+between the client and server and that content can be transferred
710710
in either direction. The server is willing to accept content from
711711
the client because the client login has the "write-unversioned"
712712
permission.</p>
713713
714714
<li><p><b>ci-lock</b> <i>CHECKIN-HASH CLIENT-ID</i></p>
@@ -718,11 +718,11 @@
718718
If some other client has already indicated that it was also
719719
trying to commit against CHECKIN-HASH, that indicates that a
720720
fork is about to occur, and the server will reply with
721721
a "ci-lock-fail" pragma (see below). Check-in locks
722722
automatically expire when the check-in actually occurs, or
723
-after a timeout (currently 24-hours but subject to change).
723
+after a timeout (currently one minute but subject to change).
724724
725725
<li><p><b>ci-lock-fail</b> <i>LOGIN MTIME</i></p>
726726
<p>When a server receives two or more "ci-lock" pragma messages
727727
for the same check-in but from different clients, the second a
728728
subsequent ci-lock will provoke a ci-lock-fail pragma in the
729729
--- www/sync.wiki
+++ www/sync.wiki
@@ -704,11 +704,11 @@
704
705 <li><p><b>uv-push-ok</b></i>
706 <p>A server sends the uv-push-ok pragma to the client in response
707 to a uv-hash pragma with a mismatched content hash argument. This
708 pragma indicates that there are differences in unversioned content
709 between the client and server and that content can only be transferred
710 in either direction. The server is willing to accept content from
711 the client because the client login has the "write-unversioned"
712 permission.</p>
713
714 <li><p><b>ci-lock</b> <i>CHECKIN-HASH CLIENT-ID</i></p>
@@ -718,11 +718,11 @@
718 If some other client has already indicated that it was also
719 trying to commit against CHECKIN-HASH, that indicates that a
720 fork is about to occur, and the server will reply with
721 a "ci-lock-fail" pragma (see below). Check-in locks
722 automatically expire when the check-in actually occurs, or
723 after a timeout (currently 24-hours but subject to change).
724
725 <li><p><b>ci-lock-fail</b> <i>LOGIN MTIME</i></p>
726 <p>When a server receives two or more "ci-lock" pragma messages
727 for the same check-in but from different clients, the second a
728 subsequent ci-lock will provoke a ci-lock-fail pragma in the
729
--- www/sync.wiki
+++ www/sync.wiki
@@ -704,11 +704,11 @@
704
705 <li><p><b>uv-push-ok</b></i>
706 <p>A server sends the uv-push-ok pragma to the client in response
707 to a uv-hash pragma with a mismatched content hash argument. This
708 pragma indicates that there are differences in unversioned content
709 between the client and server and that content can be transferred
710 in either direction. The server is willing to accept content from
711 the client because the client login has the "write-unversioned"
712 permission.</p>
713
714 <li><p><b>ci-lock</b> <i>CHECKIN-HASH CLIENT-ID</i></p>
@@ -718,11 +718,11 @@
718 If some other client has already indicated that it was also
719 trying to commit against CHECKIN-HASH, that indicates that a
720 fork is about to occur, and the server will reply with
721 a "ci-lock-fail" pragma (see below). Check-in locks
722 automatically expire when the check-in actually occurs, or
723 after a timeout (currently one minute but subject to change).
724
725 <li><p><b>ci-lock-fail</b> <i>LOGIN MTIME</i></p>
726 <p>When a server receives two or more "ci-lock" pragma messages
727 for the same check-in but from different clients, the second a
728 subsequent ci-lock will provoke a ci-lock-fail pragma in the
729
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -3,11 +3,11 @@
33
* [./permutedindex.html | Documentation index] with [/search?c=d | full text search].
44
* [./reviews.wiki | Testimonials] from satisfied Fossil users and
55
[./quotes.wiki | Quotes] about Fossil and other DVCSes.
66
* [./faq.wiki | Frequently Asked Questions]
77
* The [./concepts.wiki | concepts] behind Fossil.
8
- [./whyusefossil.wiki#definitions | Another viewpoint].
8
+ [./glossary.md | Another viewpoint].
99
* [./quickstart.wiki | Quick Start] guide to using Fossil.
1010
* [./qandc.wiki | Questions &amp; Criticisms] directed at Fossil.
1111
* [./build.wiki | Compiling and Installing]
1212
* Fossil supports [./embeddeddoc.wiki | embedded documentation]
1313
that is versioned along with project source code.
1414
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -3,11 +3,11 @@
3 * [./permutedindex.html | Documentation index] with [/search?c=d | full text search].
4 * [./reviews.wiki | Testimonials] from satisfied Fossil users and
5 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
6 * [./faq.wiki | Frequently Asked Questions]
7 * The [./concepts.wiki | concepts] behind Fossil.
8 [./whyusefossil.wiki#definitions | Another viewpoint].
9 * [./quickstart.wiki | Quick Start] guide to using Fossil.
10 * [./qandc.wiki | Questions &amp; Criticisms] directed at Fossil.
11 * [./build.wiki | Compiling and Installing]
12 * Fossil supports [./embeddeddoc.wiki | embedded documentation]
13 that is versioned along with project source code.
14
--- www/userlinks.wiki
+++ www/userlinks.wiki
@@ -3,11 +3,11 @@
3 * [./permutedindex.html | Documentation index] with [/search?c=d | full text search].
4 * [./reviews.wiki | Testimonials] from satisfied Fossil users and
5 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
6 * [./faq.wiki | Frequently Asked Questions]
7 * The [./concepts.wiki | concepts] behind Fossil.
8 [./glossary.md | Another viewpoint].
9 * [./quickstart.wiki | Quick Start] guide to using Fossil.
10 * [./qandc.wiki | Questions &amp; Criticisms] directed at Fossil.
11 * [./build.wiki | Compiling and Installing]
12 * Fossil supports [./embeddeddoc.wiki | embedded documentation]
13 that is versioned along with project source code.
14
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -39,107 +39,11 @@
3939
</ol>
4040
</ol>
4141
4242
<p id="definitions"><b>II. Definitions</b></p>
4343
44
-<ul>
45
-<li><p><b>Project</b> &rarr;
46
- a collection of computer files that serve some common
47
- purpose. Often the project is a software application and the
48
- individual files are source code together with makefiles, scripts, and
49
- "README.txt" files. Other examples of projects include books or
50
- manuals in which each chapter or section is held in a separate file.
51
- <ul>
52
- <li><p>Projects change and evolve. The whole purpose of version
53
- control is to track and manage that evolution.
54
- <li><p>Most projects contain many files, but it is possible
55
- to have a project consisting of just a single file.
56
- <li><p>Fossil requires that
57
- all the files for a project must be collected into a single
58
- directory hierarchy - a single folder possibly with layers
59
- of subfolders. Fossil is not a good choice for managing a
60
- project that has files scattered hither and yon all over
61
- the disk. In other words, Fossil only works for projects
62
- where the files are laid out such that they can be archived
63
- into a ZIP file or tarball.
64
- </ul>
65
-<li><p><b>Repository</b> &rarr;
66
- (also called "repo") a single file that contains
67
- all historical versions of all files in a project. A repo is similar
68
- to a ZIP archive in that it is a single file that stores compressed
69
- versions of many other files. Files can be extracted from the
70
- repo and new files can be added to the repo, just as with a ZIP
71
- archive. But a repo has other capabilities above and beyond
72
- what a ZIP archive can do.
73
- <ul>
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
- repository per computer. But this is not a requirement. It is
86
- ok to have multiple copies of the same repository on the same
87
- computer.
88
- <li><p>Fossil works fine with just a single copy of the repository.
89
- But in that case there is no redundancy. If that one repository
90
- file is lost due to a hardware malfunction, then there is no way
91
- to recover the project.
92
- <li><p>Best practice is to keep all repositories for a user in a single
93
- folder. Folders such as "~/Fossils" or "%USERPROFILE%\Fossils"
94
- are recommended. Fossil itself does not care where the repositories
95
- are stored. Nor does Fossil require repositories to be
96
- kept in the same folder. But it is easier to organize your work
97
- if all repositories are kept in the same place.
98
- </ul>
99
-<li><p><b>Check-out</b> &rarr;
100
- a set of files that have been extracted from a
101
- repository and that represent a particular version or snapshot of
102
- the project.
103
- <ul>
104
- <li><p>Check-outs must be on the same computer as the repository from
105
- which they are extracted. This is just like with a ZIP archive:
106
- one must have the ZIP archive file on the local machine before
107
- extracting files from ZIP archive.
108
- <li><p>There can be multiple check-outs (in different folders) from
109
- the same repository.
110
- <li><p>The repository must be on the same computer as the check-out, but
111
- the relative locations of the repo and the check-out are arbitrary.
112
- The repository may be located inside the folder holding the
113
- check-out, but it certainly does not have to be and usually is
114
- not.
115
- <li><p>A special file exists in every check-out that tells Fossil from
116
- which repository the check-out was extracted, and which version of
117
- the project the check-out represents. This is the ".fslckout" file
118
- on unix systems or the "_FOSSIL_" file on Windows.
119
- </ul>
120
-<li><p><b>Check-in</b> &rarr;
121
- another name for a particular version of the project.
122
- A check-in is a collection of files inside of a repository that
123
- represent a snapshot of the project for an instant in time.
124
- Check-ins exist only inside of the repository. This contrasts with
125
- a check-out which is a collection of files outside of the repository.
126
- <ul>
127
- <li><p>Every check-out knows the check-in from which it was derived.
128
- But check-outs might have been edited and so might not exactly
129
- match their associated check-in.
130
- <li><p>Check-ins are immutable. They can never be changed. But
131
- check-outs are collections of ordinary files on disk. The
132
- files of a check-out can be edited just like any other file.
133
- <li><p>A check-in can be thought of as an historical snapshot of a
134
- check-out.
135
- <li><p>"Check-in", "version", "snapshot", and "revision" are synonyms.
136
- <li><p> When used as a noun, the word "commit" is another synonym
137
- for "check-in". When used as a verb, the word "commit"
138
- means to create a new check-in.
139
- </ul>
140
-</ul>
44
+Moved to [./glossary.md | a separate document].
14145
14246
<p><b>III. Basic Fossil commands</b>
14347
14448
<ul>
14549
<li><p><b>clone</b> &rarr;
14650
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -39,107 +39,11 @@
39 </ol>
40 </ol>
41
42 <p id="definitions"><b>II. Definitions</b></p>
43
44 <ul>
45 <li><p><b>Project</b> &rarr;
46 a collection of computer files that serve some common
47 purpose. Often the project is a software application and the
48 individual files are source code together with makefiles, scripts, and
49 "README.txt" files. Other examples of projects include books or
50 manuals in which each chapter or section is held in a separate file.
51 <ul>
52 <li><p>Projects change and evolve. The whole purpose of version
53 control is to track and manage that evolution.
54 <li><p>Most projects contain many files, but it is possible
55 to have a project consisting of just a single file.
56 <li><p>Fossil requires that
57 all the files for a project must be collected into a single
58 directory hierarchy - a single folder possibly with layers
59 of subfolders. Fossil is not a good choice for managing a
60 project that has files scattered hither and yon all over
61 the disk. In other words, Fossil only works for projects
62 where the files are laid out such that they can be archived
63 into a ZIP file or tarball.
64 </ul>
65 <li><p><b>Repository</b> &rarr;
66 (also called "repo") a single file that contains
67 all historical versions of all files in a project. A repo is similar
68 to a ZIP archive in that it is a single file that stores compressed
69 versions of many other files. Files can be extracted from the
70 repo and new files can be added to the repo, just as with a ZIP
71 archive. But a repo has other capabilities above and beyond
72 what a ZIP archive can do.
73 <ul>
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 repository per computer. But this is not a requirement. It is
86 ok to have multiple copies of the same repository on the same
87 computer.
88 <li><p>Fossil works fine with just a single copy of the repository.
89 But in that case there is no redundancy. If that one repository
90 file is lost due to a hardware malfunction, then there is no way
91 to recover the project.
92 <li><p>Best practice is to keep all repositories for a user in a single
93 folder. Folders such as "~/Fossils" or "%USERPROFILE%\Fossils"
94 are recommended. Fossil itself does not care where the repositories
95 are stored. Nor does Fossil require repositories to be
96 kept in the same folder. But it is easier to organize your work
97 if all repositories are kept in the same place.
98 </ul>
99 <li><p><b>Check-out</b> &rarr;
100 a set of files that have been extracted from a
101 repository and that represent a particular version or snapshot of
102 the project.
103 <ul>
104 <li><p>Check-outs must be on the same computer as the repository from
105 which they are extracted. This is just like with a ZIP archive:
106 one must have the ZIP archive file on the local machine before
107 extracting files from ZIP archive.
108 <li><p>There can be multiple check-outs (in different folders) from
109 the same repository.
110 <li><p>The repository must be on the same computer as the check-out, but
111 the relative locations of the repo and the check-out are arbitrary.
112 The repository may be located inside the folder holding the
113 check-out, but it certainly does not have to be and usually is
114 not.
115 <li><p>A special file exists in every check-out that tells Fossil from
116 which repository the check-out was extracted, and which version of
117 the project the check-out represents. This is the ".fslckout" file
118 on unix systems or the "_FOSSIL_" file on Windows.
119 </ul>
120 <li><p><b>Check-in</b> &rarr;
121 another name for a particular version of the project.
122 A check-in is a collection of files inside of a repository that
123 represent a snapshot of the project for an instant in time.
124 Check-ins exist only inside of the repository. This contrasts with
125 a check-out which is a collection of files outside of the repository.
126 <ul>
127 <li><p>Every check-out knows the check-in from which it was derived.
128 But check-outs might have been edited and so might not exactly
129 match their associated check-in.
130 <li><p>Check-ins are immutable. They can never be changed. But
131 check-outs are collections of ordinary files on disk. The
132 files of a check-out can be edited just like any other file.
133 <li><p>A check-in can be thought of as an historical snapshot of a
134 check-out.
135 <li><p>"Check-in", "version", "snapshot", and "revision" are synonyms.
136 <li><p> When used as a noun, the word "commit" is another synonym
137 for "check-in". When used as a verb, the word "commit"
138 means to create a new check-in.
139 </ul>
140 </ul>
141
142 <p><b>III. Basic Fossil commands</b>
143
144 <ul>
145 <li><p><b>clone</b> &rarr;
146
--- www/whyusefossil.wiki
+++ www/whyusefossil.wiki
@@ -39,107 +39,11 @@
39 </ol>
40 </ol>
41
42 <p id="definitions"><b>II. Definitions</b></p>
43
44 Moved to [./glossary.md | a separate document].
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
46 <p><b>III. Basic Fossil commands</b>
47
48 <ul>
49 <li><p><b>clone</b> &rarr;
50

Keyboard Shortcuts

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