Fossil SCM

pulled in trunk for clean slate on subsequent changes.

stephan 2011-10-20 14:39 UTC stephan-hack merge
Commit a37d80e8afa5cb2a10d3a2ac5abcf67776fcd9a4
+1 -1
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1
-1.19
1
+1.20
22
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.19
2
--- VERSION
+++ VERSION
@@ -1,1 +1,1 @@
1 1.20
2
+3 -3
--- src/allrepo.c
+++ src/allrepo.c
@@ -74,13 +74,13 @@
7474
** rebuild Rebuild on all repositories
7575
**
7676
** sync Run a "sync" on all repositories
7777
**
7878
** Respositories are automatically added to the set of known repositories
79
-** when one of the following commands against the repository: clone, info,
80
-** pull, push, or sync. Even previously ignored repositories are added back
81
-** to the list of repositories by these commands.
79
+** when one of the following commands are run against the repository: clone,
80
+** info, pull, push, or sync. Even previously ignored repositories are
81
+** added back to the list of repositories by these commands.
8282
*/
8383
void all_cmd(void){
8484
int n;
8585
Stmt q;
8686
const char *zCmd;
8787
--- src/allrepo.c
+++ src/allrepo.c
@@ -74,13 +74,13 @@
74 ** rebuild Rebuild on all repositories
75 **
76 ** sync Run a "sync" on all repositories
77 **
78 ** Respositories are automatically added to the set of known repositories
79 ** when one of the following commands against the repository: clone, info,
80 ** pull, push, or sync. Even previously ignored repositories are added back
81 ** to the list of repositories by these commands.
82 */
83 void all_cmd(void){
84 int n;
85 Stmt q;
86 const char *zCmd;
87
--- src/allrepo.c
+++ src/allrepo.c
@@ -74,13 +74,13 @@
74 ** rebuild Rebuild on all repositories
75 **
76 ** sync Run a "sync" on all repositories
77 **
78 ** Respositories are automatically added to the set of known repositories
79 ** when one of the following commands are run against the repository: clone,
80 ** info, pull, push, or sync. Even previously ignored repositories are
81 ** added back to the list of repositories by these commands.
82 */
83 void all_cmd(void){
84 int n;
85 Stmt q;
86 const char *zCmd;
87
+2 -2
--- src/blob.c
+++ src/blob.c
@@ -330,12 +330,12 @@
330330
blob_is_init(pB);
331331
szA = blob_size(pA);
332332
szB = blob_size(pB);
333333
if( szA!=szB || szA==0 ) return 1;
334334
335
- buf1 = blob_buffer(pA);
336
- buf2 = blob_buffer(pB);
335
+ buf1 = (unsigned char*)blob_buffer(pA);
336
+ buf2 = (unsigned char*)blob_buffer(pB);
337337
338338
for( i=0; i<szA; i++ ){
339339
rc = rc | (buf1[i] ^ buf2[i]);
340340
}
341341
342342
--- src/blob.c
+++ src/blob.c
@@ -330,12 +330,12 @@
330 blob_is_init(pB);
331 szA = blob_size(pA);
332 szB = blob_size(pB);
333 if( szA!=szB || szA==0 ) return 1;
334
335 buf1 = blob_buffer(pA);
336 buf2 = blob_buffer(pB);
337
338 for( i=0; i<szA; i++ ){
339 rc = rc | (buf1[i] ^ buf2[i]);
340 }
341
342
--- src/blob.c
+++ src/blob.c
@@ -330,12 +330,12 @@
330 blob_is_init(pB);
331 szA = blob_size(pA);
332 szB = blob_size(pB);
333 if( szA!=szB || szA==0 ) return 1;
334
335 buf1 = (unsigned char*)blob_buffer(pA);
336 buf2 = (unsigned char*)blob_buffer(pB);
337
338 for( i=0; i<szA; i++ ){
339 rc = rc | (buf1[i] ^ buf2[i]);
340 }
341
342
+3 -1
--- src/browse.c
+++ src/browse.c
@@ -249,11 +249,13 @@
249249
/* Generate a multi-column table listing the contents of zD[]
250250
** directory.
251251
*/
252252
mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
253253
cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
254
- nCol = 4;
254
+ nCol = 100/mxLen;
255
+ if( nCol<1 ) nCol = 1;
256
+ if( nCol>5 ) nCol = 5;
255257
nRow = (cnt+nCol-1)/nCol;
256258
db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
257259
@ <table class="browser"><tr><td class="browser"><ul class="browser">
258260
i = 0;
259261
while( db_step(&q)==SQLITE_ROW ){
260262
--- src/browse.c
+++ src/browse.c
@@ -249,11 +249,13 @@
249 /* Generate a multi-column table listing the contents of zD[]
250 ** directory.
251 */
252 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
253 cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
254 nCol = 4;
 
 
255 nRow = (cnt+nCol-1)/nCol;
256 db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
257 @ <table class="browser"><tr><td class="browser"><ul class="browser">
258 i = 0;
259 while( db_step(&q)==SQLITE_ROW ){
260
--- src/browse.c
+++ src/browse.c
@@ -249,11 +249,13 @@
249 /* Generate a multi-column table listing the contents of zD[]
250 ** directory.
251 */
252 mxLen = db_int(12, "SELECT max(length(x)) FROM localfiles /*scan*/");
253 cnt = db_int(0, "SELECT count(*) FROM localfiles /*scan*/");
254 nCol = 100/mxLen;
255 if( nCol<1 ) nCol = 1;
256 if( nCol>5 ) nCol = 5;
257 nRow = (cnt+nCol-1)/nCol;
258 db_prepare(&q, "SELECT x, u FROM localfiles ORDER BY x /*scan*/");
259 @ <table class="browser"><tr><td class="browser"><ul class="browser">
260 i = 0;
261 while( db_step(&q)==SQLITE_ROW ){
262
+14 -16
--- src/cgi.c
+++ src/cgi.c
@@ -135,11 +135,11 @@
135135
}
136136
137137
/*
138138
** Return a pointer to the HTTP reply text.
139139
*/
140
-char *cgi_extract_content(int *pnAmt){
140
+char *cgi_extract_content(void){
141141
cgi_combine_header_and_body();
142142
return blob_buffer(&cgiContent[0]);
143143
}
144144
145145
/*
@@ -362,11 +362,11 @@
362362
/*
363363
** Do a redirect request to the URL given in the argument.
364364
**
365365
** The URL must be relative to the base of the fossil server.
366366
*/
367
-void cgi_redirect(const char *zURL){
367
+NORETURN void cgi_redirect(const char *zURL){
368368
char *zLocation;
369369
CGIDEBUG(("redirect to %s\n", zURL));
370370
if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 ){
371371
zLocation = mprintf("Location: %s\r\n", zURL);
372372
}else if( *zURL=='/' ){
@@ -381,11 +381,11 @@
381381
cgi_set_status(302, "Moved Temporarily");
382382
free(zLocation);
383383
cgi_reply();
384384
fossil_exit(0);
385385
}
386
-void cgi_redirectf(const char *zFormat, ...){
386
+NORETURN void cgi_redirectf(const char *zFormat, ...){
387387
va_list ap;
388388
va_start(ap, zFormat);
389389
cgi_redirect(vmprintf(zFormat, ap));
390390
va_end(ap);
391391
}
@@ -888,26 +888,23 @@
888888
}
889889
890890
/*
891891
** Print all query parameters on standard output. Format the
892892
** parameters as HTML. This is used for testing and debugging.
893
-** Release builds omit the values of the cookies to avoid defeating
894
-** the purpose of setting HttpOnly cookies.
893
+**
894
+** Omit the values of the cookies unless showAll is true.
895895
*/
896
-void cgi_print_all(void){
896
+void cgi_print_all(int showAll){
897897
int i;
898
- int showAll = 0;
899
-#ifdef FOSSIL_DEBUG
900
- /* Show the values of cookies in debug mode. */
901
- showAll = 1;
902
-#endif
903898
cgi_parameter("",""); /* Force the parameters into sorted order */
904899
for(i=0; i<nUsedQP; i++){
905
- if( showAll || (fossil_stricmp("HTTP_COOKIE",aParamQP[i].zName)!=0 && fossil_strnicmp("fossil-",aParamQP[i].zName,7)!=0) ){
906
- cgi_printf("%s = %s <br />\n",
907
- htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1));
900
+ const char *zName = aParamQP[i].zName;
901
+ if( !showAll ){
902
+ if( fossil_stricmp("HTTP_COOKIE",zName)==0 ) continue;
903
+ if( fossil_strnicmp("fossil-",zName,7)==0 ) continue;
908904
}
905
+ cgi_printf("%h = %h <br />\n", zName, aParamQP[i].zValue);
909906
}
910907
}
911908
912909
/*
913910
** This routine works like "printf" except that it has the
@@ -930,11 +927,11 @@
930927
931928
932929
/*
933930
** Send a reply indicating that the HTTP request was malformed
934931
*/
935
-static void malformed_request(void){
932
+static NORETURN void malformed_request(void){
936933
cgi_set_status(501, "Not Implemented");
937934
cgi_printf(
938935
"<html><body>Unrecognized HTTP Request</body></html>\n"
939936
);
940937
cgi_reply();
@@ -942,11 +939,11 @@
942939
}
943940
944941
/*
945942
** Panic and die while processing a webpage.
946943
*/
947
-void cgi_panic(const char *zFormat, ...){
944
+NORETURN void cgi_panic(const char *zFormat, ...){
948945
va_list ap;
949946
cgi_reset_content();
950947
cgi_set_status(500, "Internal Server Error");
951948
cgi_printf(
952949
"<html><body><h1>Internal Server Error</h1>\n"
@@ -1165,10 +1162,11 @@
11651162
sleep( nchildren-MAX_PARALLEL );
11661163
}
11671164
delay.tv_sec = 60;
11681165
delay.tv_usec = 0;
11691166
FD_ZERO(&readfds);
1167
+ assert( listener>=0 );
11701168
FD_SET( listener, &readfds);
11711169
select( listener+1, &readfds, 0, 0, &delay);
11721170
if( FD_ISSET(listener, &readfds) ){
11731171
lenaddr = sizeof(inaddr);
11741172
connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
11751173
--- src/cgi.c
+++ src/cgi.c
@@ -135,11 +135,11 @@
135 }
136
137 /*
138 ** Return a pointer to the HTTP reply text.
139 */
140 char *cgi_extract_content(int *pnAmt){
141 cgi_combine_header_and_body();
142 return blob_buffer(&cgiContent[0]);
143 }
144
145 /*
@@ -362,11 +362,11 @@
362 /*
363 ** Do a redirect request to the URL given in the argument.
364 **
365 ** The URL must be relative to the base of the fossil server.
366 */
367 void cgi_redirect(const char *zURL){
368 char *zLocation;
369 CGIDEBUG(("redirect to %s\n", zURL));
370 if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 ){
371 zLocation = mprintf("Location: %s\r\n", zURL);
372 }else if( *zURL=='/' ){
@@ -381,11 +381,11 @@
381 cgi_set_status(302, "Moved Temporarily");
382 free(zLocation);
383 cgi_reply();
384 fossil_exit(0);
385 }
386 void cgi_redirectf(const char *zFormat, ...){
387 va_list ap;
388 va_start(ap, zFormat);
389 cgi_redirect(vmprintf(zFormat, ap));
390 va_end(ap);
391 }
@@ -888,26 +888,23 @@
888 }
889
890 /*
891 ** Print all query parameters on standard output. Format the
892 ** parameters as HTML. This is used for testing and debugging.
893 ** Release builds omit the values of the cookies to avoid defeating
894 ** the purpose of setting HttpOnly cookies.
895 */
896 void cgi_print_all(void){
897 int i;
898 int showAll = 0;
899 #ifdef FOSSIL_DEBUG
900 /* Show the values of cookies in debug mode. */
901 showAll = 1;
902 #endif
903 cgi_parameter("",""); /* Force the parameters into sorted order */
904 for(i=0; i<nUsedQP; i++){
905 if( showAll || (fossil_stricmp("HTTP_COOKIE",aParamQP[i].zName)!=0 && fossil_strnicmp("fossil-",aParamQP[i].zName,7)!=0) ){
906 cgi_printf("%s = %s <br />\n",
907 htmlize(aParamQP[i].zName, -1), htmlize(aParamQP[i].zValue, -1));
 
908 }
 
909 }
910 }
911
912 /*
913 ** This routine works like "printf" except that it has the
@@ -930,11 +927,11 @@
930
931
932 /*
933 ** Send a reply indicating that the HTTP request was malformed
934 */
935 static void malformed_request(void){
936 cgi_set_status(501, "Not Implemented");
937 cgi_printf(
938 "<html><body>Unrecognized HTTP Request</body></html>\n"
939 );
940 cgi_reply();
@@ -942,11 +939,11 @@
942 }
943
944 /*
945 ** Panic and die while processing a webpage.
946 */
947 void cgi_panic(const char *zFormat, ...){
948 va_list ap;
949 cgi_reset_content();
950 cgi_set_status(500, "Internal Server Error");
951 cgi_printf(
952 "<html><body><h1>Internal Server Error</h1>\n"
@@ -1165,10 +1162,11 @@
1165 sleep( nchildren-MAX_PARALLEL );
1166 }
1167 delay.tv_sec = 60;
1168 delay.tv_usec = 0;
1169 FD_ZERO(&readfds);
 
1170 FD_SET( listener, &readfds);
1171 select( listener+1, &readfds, 0, 0, &delay);
1172 if( FD_ISSET(listener, &readfds) ){
1173 lenaddr = sizeof(inaddr);
1174 connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
1175
--- src/cgi.c
+++ src/cgi.c
@@ -135,11 +135,11 @@
135 }
136
137 /*
138 ** Return a pointer to the HTTP reply text.
139 */
140 char *cgi_extract_content(void){
141 cgi_combine_header_and_body();
142 return blob_buffer(&cgiContent[0]);
143 }
144
145 /*
@@ -362,11 +362,11 @@
362 /*
363 ** Do a redirect request to the URL given in the argument.
364 **
365 ** The URL must be relative to the base of the fossil server.
366 */
367 NORETURN void cgi_redirect(const char *zURL){
368 char *zLocation;
369 CGIDEBUG(("redirect to %s\n", zURL));
370 if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 ){
371 zLocation = mprintf("Location: %s\r\n", zURL);
372 }else if( *zURL=='/' ){
@@ -381,11 +381,11 @@
381 cgi_set_status(302, "Moved Temporarily");
382 free(zLocation);
383 cgi_reply();
384 fossil_exit(0);
385 }
386 NORETURN void cgi_redirectf(const char *zFormat, ...){
387 va_list ap;
388 va_start(ap, zFormat);
389 cgi_redirect(vmprintf(zFormat, ap));
390 va_end(ap);
391 }
@@ -888,26 +888,23 @@
888 }
889
890 /*
891 ** Print all query parameters on standard output. Format the
892 ** parameters as HTML. This is used for testing and debugging.
893 **
894 ** Omit the values of the cookies unless showAll is true.
895 */
896 void cgi_print_all(int showAll){
897 int i;
 
 
 
 
 
898 cgi_parameter("",""); /* Force the parameters into sorted order */
899 for(i=0; i<nUsedQP; i++){
900 const char *zName = aParamQP[i].zName;
901 if( !showAll ){
902 if( fossil_stricmp("HTTP_COOKIE",zName)==0 ) continue;
903 if( fossil_strnicmp("fossil-",zName,7)==0 ) continue;
904 }
905 cgi_printf("%h = %h <br />\n", zName, aParamQP[i].zValue);
906 }
907 }
908
909 /*
910 ** This routine works like "printf" except that it has the
@@ -930,11 +927,11 @@
927
928
929 /*
930 ** Send a reply indicating that the HTTP request was malformed
931 */
932 static NORETURN void malformed_request(void){
933 cgi_set_status(501, "Not Implemented");
934 cgi_printf(
935 "<html><body>Unrecognized HTTP Request</body></html>\n"
936 );
937 cgi_reply();
@@ -942,11 +939,11 @@
939 }
940
941 /*
942 ** Panic and die while processing a webpage.
943 */
944 NORETURN void cgi_panic(const char *zFormat, ...){
945 va_list ap;
946 cgi_reset_content();
947 cgi_set_status(500, "Internal Server Error");
948 cgi_printf(
949 "<html><body><h1>Internal Server Error</h1>\n"
@@ -1165,10 +1162,11 @@
1162 sleep( nchildren-MAX_PARALLEL );
1163 }
1164 delay.tv_sec = 60;
1165 delay.tv_usec = 0;
1166 FD_ZERO(&readfds);
1167 assert( listener>=0 );
1168 FD_SET( listener, &readfds);
1169 select( listener+1, &readfds, 0, 0, &delay);
1170 if( FD_ISSET(listener, &readfds) ){
1171 lenaddr = sizeof(inaddr);
1172 connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
1173
--- src/checkin.c
+++ src/checkin.c
@@ -282,18 +282,16 @@
282282
Stmt q;
283283
int n;
284284
const char *zIgnoreFlag = find_option("ignore",0,1);
285285
int allFlag = find_option("dotfiles",0,0)!=0;
286286
int cwdRelative = 0;
287
- int outputManifest;
288287
Glob *pIgnore;
289288
Blob rewrittenPathname;
290289
const char *zPathname, *zDisplayName;
291290
292291
db_must_be_within_tree();
293292
cwdRelative = determine_cwd_relative_option();
294
- outputManifest = db_get_boolean("manifest",0);
295293
db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
296294
n = strlen(g.zLocalRoot);
297295
blob_init(&path, g.zLocalRoot, n-1);
298296
if( zIgnoreFlag==0 ){
299297
zIgnoreFlag = db_get("ignore-glob", 0);
300298
--- src/checkin.c
+++ src/checkin.c
@@ -282,18 +282,16 @@
282 Stmt q;
283 int n;
284 const char *zIgnoreFlag = find_option("ignore",0,1);
285 int allFlag = find_option("dotfiles",0,0)!=0;
286 int cwdRelative = 0;
287 int outputManifest;
288 Glob *pIgnore;
289 Blob rewrittenPathname;
290 const char *zPathname, *zDisplayName;
291
292 db_must_be_within_tree();
293 cwdRelative = determine_cwd_relative_option();
294 outputManifest = db_get_boolean("manifest",0);
295 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
296 n = strlen(g.zLocalRoot);
297 blob_init(&path, g.zLocalRoot, n-1);
298 if( zIgnoreFlag==0 ){
299 zIgnoreFlag = db_get("ignore-glob", 0);
300
--- src/checkin.c
+++ src/checkin.c
@@ -282,18 +282,16 @@
282 Stmt q;
283 int n;
284 const char *zIgnoreFlag = find_option("ignore",0,1);
285 int allFlag = find_option("dotfiles",0,0)!=0;
286 int cwdRelative = 0;
 
287 Glob *pIgnore;
288 Blob rewrittenPathname;
289 const char *zPathname, *zDisplayName;
290
291 db_must_be_within_tree();
292 cwdRelative = determine_cwd_relative_option();
 
293 db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
294 n = strlen(g.zLocalRoot);
295 blob_init(&path, g.zLocalRoot, n-1);
296 if( zIgnoreFlag==0 ){
297 zIgnoreFlag = db_get("ignore-glob", 0);
298
--- src/config.h
+++ src/config.h
@@ -134,6 +134,15 @@
134134
#else /* Generates a warning - but it always works */
135135
# define FOSSIL_INT_TO_PTR(X) ((void*)(X))
136136
# define FOSSIL_PTR_TO_INT(X) ((int)(X))
137137
#endif
138138
139
+/*
140
+** A marker for functions that never return.
141
+*/
142
+#if defined(__GNUC__) || defined(__clang__)
143
+# define NORETURN __attribute__((__noreturn__))
144
+#else
145
+# define NORETURN
146
+#endif
147
+
139148
#endif /* _RC_COMPILE_ */
140149
--- src/config.h
+++ src/config.h
@@ -134,6 +134,15 @@
134 #else /* Generates a warning - but it always works */
135 # define FOSSIL_INT_TO_PTR(X) ((void*)(X))
136 # define FOSSIL_PTR_TO_INT(X) ((int)(X))
137 #endif
138
 
 
 
 
 
 
 
 
 
139 #endif /* _RC_COMPILE_ */
140
--- src/config.h
+++ src/config.h
@@ -134,6 +134,15 @@
134 #else /* Generates a warning - but it always works */
135 # define FOSSIL_INT_TO_PTR(X) ((void*)(X))
136 # define FOSSIL_PTR_TO_INT(X) ((int)(X))
137 #endif
138
139 /*
140 ** A marker for functions that never return.
141 */
142 #if defined(__GNUC__) || defined(__clang__)
143 # define NORETURN __attribute__((__noreturn__))
144 #else
145 # define NORETURN
146 #endif
147
148 #endif /* _RC_COMPILE_ */
149
--- src/configure.c
+++ src/configure.c
@@ -785,10 +785,11 @@
785785
const char *zMethod;
786786
if( g.argc<3 ){
787787
usage("export|import|merge|pull|reset ...");
788788
}
789789
db_find_and_open_repository(0, 0);
790
+ db_open_config(0);
790791
zMethod = g.argv[2];
791792
n = strlen(zMethod);
792793
if( strncmp(zMethod, "export", n)==0 ){
793794
int mask;
794795
const char *zSince = find_option("since",0,1);
795796
--- src/configure.c
+++ src/configure.c
@@ -785,10 +785,11 @@
785 const char *zMethod;
786 if( g.argc<3 ){
787 usage("export|import|merge|pull|reset ...");
788 }
789 db_find_and_open_repository(0, 0);
 
790 zMethod = g.argv[2];
791 n = strlen(zMethod);
792 if( strncmp(zMethod, "export", n)==0 ){
793 int mask;
794 const char *zSince = find_option("since",0,1);
795
--- src/configure.c
+++ src/configure.c
@@ -785,10 +785,11 @@
785 const char *zMethod;
786 if( g.argc<3 ){
787 usage("export|import|merge|pull|reset ...");
788 }
789 db_find_and_open_repository(0, 0);
790 db_open_config(0);
791 zMethod = g.argv[2];
792 n = strlen(zMethod);
793 if( strncmp(zMethod, "export", n)==0 ){
794 int mask;
795 const char *zSince = find_option("since",0,1);
796
+2 -2
--- src/db.c
+++ src/db.c
@@ -742,20 +742,20 @@
742742
/*
743743
* * Returns TRUE if zTable exists in the local database.
744744
*/
745745
static int db_local_table_exists(const char *zTable){
746746
return db_exists("SELECT 1 FROM %s.sqlite_master"
747
- " WHERE name=='%s'",
747
+ " WHERE name=='%s' /*scan*/",
748748
db_name("localdb"), zTable);
749749
}
750750
751751
/*
752752
** Returns TRUE if zColumn exists in zTable in the local database.
753753
*/
754754
static int db_local_column_exists(const char *zTable, const char *zColumn){
755755
return db_exists("SELECT 1 FROM %s.sqlite_master"
756
- " WHERE name=='%s' AND sql GLOB '* %s *'",
756
+ " WHERE name=='%s' AND sql GLOB '* %s *' /*scan*/",
757757
db_name("localdb"), zTable, zColumn);
758758
}
759759
760760
/*
761761
** If zDbName is a valid local database file, open it and return
762762
--- src/db.c
+++ src/db.c
@@ -742,20 +742,20 @@
742 /*
743 * * Returns TRUE if zTable exists in the local database.
744 */
745 static int db_local_table_exists(const char *zTable){
746 return db_exists("SELECT 1 FROM %s.sqlite_master"
747 " WHERE name=='%s'",
748 db_name("localdb"), zTable);
749 }
750
751 /*
752 ** Returns TRUE if zColumn exists in zTable in the local database.
753 */
754 static int db_local_column_exists(const char *zTable, const char *zColumn){
755 return db_exists("SELECT 1 FROM %s.sqlite_master"
756 " WHERE name=='%s' AND sql GLOB '* %s *'",
757 db_name("localdb"), zTable, zColumn);
758 }
759
760 /*
761 ** If zDbName is a valid local database file, open it and return
762
--- src/db.c
+++ src/db.c
@@ -742,20 +742,20 @@
742 /*
743 * * Returns TRUE if zTable exists in the local database.
744 */
745 static int db_local_table_exists(const char *zTable){
746 return db_exists("SELECT 1 FROM %s.sqlite_master"
747 " WHERE name=='%s' /*scan*/",
748 db_name("localdb"), zTable);
749 }
750
751 /*
752 ** Returns TRUE if zColumn exists in zTable in the local database.
753 */
754 static int db_local_column_exists(const char *zTable, const char *zColumn){
755 return db_exists("SELECT 1 FROM %s.sqlite_master"
756 " WHERE name=='%s' AND sql GLOB '* %s *' /*scan*/",
757 db_name("localdb"), zTable, zColumn);
758 }
759
760 /*
761 ** If zDbName is a valid local database file, open it and return
762
--- src/descendants.c
+++ src/descendants.c
@@ -202,11 +202,12 @@
202202
void compute_direct_ancestors(int rid, int N){
203203
Stmt ins;
204204
Stmt q;
205205
int gen = 0;
206206
db_multi_exec(
207
- "CREATE TEMP TABLE ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);"
207
+ "CREATE TEMP TABLE IF NOT EXISTS ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);"
208
+ "DELETE FROM ancestor;"
208209
"INSERT INTO ancestor VALUES(%d, 0);", rid
209210
);
210211
db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)");
211212
db_prepare(&q,
212213
"SELECT pid FROM plink"
213214
--- src/descendants.c
+++ src/descendants.c
@@ -202,11 +202,12 @@
202 void compute_direct_ancestors(int rid, int N){
203 Stmt ins;
204 Stmt q;
205 int gen = 0;
206 db_multi_exec(
207 "CREATE TEMP TABLE ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);"
 
208 "INSERT INTO ancestor VALUES(%d, 0);", rid
209 );
210 db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)");
211 db_prepare(&q,
212 "SELECT pid FROM plink"
213
--- src/descendants.c
+++ src/descendants.c
@@ -202,11 +202,12 @@
202 void compute_direct_ancestors(int rid, int N){
203 Stmt ins;
204 Stmt q;
205 int gen = 0;
206 db_multi_exec(
207 "CREATE TEMP TABLE IF NOT EXISTS ancestor(rid INTEGER, generation INTEGER PRIMARY KEY);"
208 "DELETE FROM ancestor;"
209 "INSERT INTO ancestor VALUES(%d, 0);", rid
210 );
211 db_prepare(&ins, "INSERT INTO ancestor VALUES(:rid, :gen)");
212 db_prepare(&q,
213 "SELECT pid FROM plink"
214
+195 -2
--- src/diff.c
+++ src/diff.c
@@ -578,10 +578,194 @@
578578
free(c.aFrom);
579579
free(c.aTo);
580580
return c.aEdit;
581581
}
582582
}
583
+
584
+/*
585
+** Copy a line with a limit. Used for side-by-side diffs to enforce a maximum
586
+** line length limit.
587
+*/
588
+static char *copylimline(char *out, DLine *dl, int lim){
589
+ int len;
590
+ len = dl->h & LENGTH_MASK;
591
+ if( lim && len > lim ){
592
+ memcpy(out, dl->z, lim-3);
593
+ strcpy(&out[lim-3], "...");
594
+ }else{
595
+ memcpy(out, dl->z, len);
596
+ out[len] = '\0';
597
+ }
598
+ return out;
599
+}
600
+
601
+/*
602
+** Output table body of a side-by-side diff. Prior to the call, the caller
603
+** should have output:
604
+** <table class="sbsdiff">
605
+** <tr><th colspan="2" class="diffhdr">Old title</th><th/>
606
+** <th colspan="2" class="diffhdr">New title</th></tr>
607
+**
608
+** And after the call, it should output:
609
+** </table>
610
+**
611
+** Some good reference diffs in the fossil repository for testing:
612
+** /vdiff?from=080d27a&to=4b0f813&detail=1
613
+** /vdiff?from=636804745b&to=c1d78e0556&detail=1
614
+** /vdiff?from=c0b6c28d29&to=25169506b7&detail=1
615
+** /vdiff?from=e3d022dffa&to=48bcfbd47b&detail=1
616
+*/
617
+int html_sbsdiff(
618
+ Blob *pA_Blob, /* FROM file */
619
+ Blob *pB_Blob, /* TO file */
620
+ int nContext, /* Amount of context to unified diff */
621
+ int ignoreEolWs /* Ignore whitespace at the end of lines */
622
+){
623
+ DContext c;
624
+ int i;
625
+ int iFrom, iTo;
626
+ char *linebuf;
627
+ int collim=0; /* Currently not settable; allows a column limit for diffs */
628
+ int allowExp=0; /* Currently not settable; (dis)allow expansion of rows */
629
+
630
+ /* Prepare the input files */
631
+ memset(&c, 0, sizeof(c));
632
+ c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
633
+ &c.nFrom, ignoreEolWs);
634
+ c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
635
+ &c.nTo, ignoreEolWs);
636
+ if( c.aFrom==0 || c.aTo==0 ){
637
+ free(c.aFrom);
638
+ free(c.aTo);
639
+ /* Note: This would be generated within a table. */
640
+ @ <p class="generalError" style="white-space: nowrap">cannot compute
641
+ @ difference between binary files</p>
642
+ return 0;
643
+ }
644
+
645
+ collim = collim < 4 ? 0 : collim;
646
+
647
+ /* Compute the difference */
648
+ diff_all(&c);
649
+
650
+ linebuf = fossil_malloc(LENGTH_MASK+1);
651
+ if( !linebuf ){
652
+ free(c.aFrom);
653
+ free(c.aTo);
654
+ free(c.aEdit);
655
+ return 0;
656
+ }
657
+
658
+ iFrom=iTo=0;
659
+ i=0;
660
+ while( i<c.nEdit ){
661
+ int j;
662
+ /* Copied lines */
663
+ for( j=0; j<c.aEdit[i]; j++){
664
+ /* Hide lines which are copied and are further away from block boundaries
665
+ ** than nConext lines. For each block with hidden lines, show a row
666
+ ** notifying the user about the hidden rows.
667
+ */
668
+ if( j<nContext || j>c.aEdit[i]-nContext-1 ){
669
+ @ <tr>
670
+ }else if( j==nContext && j<c.aEdit[i]-nContext-1 ){
671
+ @ <tr>
672
+ @ <td class="meta" colspan="5" style="white-space: nowrap;">
673
+ @ %d(c.aEdit[i]-2*nContext) hidden lines</td>
674
+ @ </tr>
675
+ if( !allowExp )
676
+ continue;
677
+ @ <tr style="display:none;">
678
+ }else{
679
+ if( !allowExp )
680
+ continue;
681
+ @ <tr style="display:none;">
682
+ }
683
+
684
+ copylimline(linebuf, &c.aFrom[iFrom+j], collim);
685
+ @ <td class="lineno">%d(iFrom+j+1)</td>
686
+ @ <td class="srcline">%h(linebuf)</td>
687
+
688
+ @ <td> </td>
689
+
690
+ copylimline(linebuf, &c.aTo[iTo+j], collim);
691
+ @ <td class="lineno">%d(iTo+j+1)</td>
692
+ @ <td class="srcline">%h(linebuf)</td>
693
+
694
+ @ </tr>
695
+ }
696
+ iFrom+=c.aEdit[i];
697
+ iTo+=c.aEdit[i];
698
+
699
+ if( c.aEdit[i+1]!=0 && c.aEdit[i+2]!=0 ){
700
+ int lim;
701
+ lim = c.aEdit[i+1] > c.aEdit[i+2] ? c.aEdit[i+1] : c.aEdit[i+2];
702
+
703
+ /* Assume changed lines */
704
+ for( j=0; j<lim; j++ ){
705
+ @ <tr>
706
+
707
+ if( j<c.aEdit[i+1] ){
708
+ copylimline(linebuf, &c.aFrom[iFrom+j], collim);
709
+ @ <td class="changed lineno">%d(iFrom+j+1)</td>
710
+ @ <td class="changed srcline">%h(linebuf)</td>
711
+ }else{
712
+ @ <td colspan="2" class="changedvoid"/>
713
+ }
714
+
715
+ @ <td class="changed">|</td>
716
+
717
+ if( j<c.aEdit[i+2] ){
718
+ copylimline(linebuf, &c.aTo[iTo+j], collim);
719
+ @ <td class="changed lineno">%d(iTo+j+1)</td>
720
+ @ <td class="changed srcline">%h(linebuf)</td>
721
+ }else{
722
+ @ <td colspan="2" class="changedvoid"/>
723
+ }
724
+
725
+ @ </tr>
726
+ }
727
+ iFrom+=c.aEdit[i+1];
728
+ iTo+=c.aEdit[i+2];
729
+ }else{
730
+
731
+ /* Process deleted lines */
732
+ for( j=0; j<c.aEdit[i+1]; j++ ){
733
+ @ <tr>
734
+
735
+ copylimline(linebuf, &c.aFrom[iFrom+j], collim);
736
+ @ <td class="removed lineno">%d(iFrom+j+1)</td>
737
+ @ <td class="removed srcline">%h(linebuf)</td>
738
+ @ <td>&lt;</td>
739
+ @ <td colspan="2" class="removedvoid"/>
740
+ @ </tr>
741
+ }
742
+ iFrom+=c.aEdit[i+1];
743
+
744
+ /* Process inserted lines */
745
+ for( j=0; j<c.aEdit[i+2]; j++ ){
746
+ @ <tr>
747
+ @ <td colspan="2" class="addedvoid"/>
748
+ @ <td>&gt;</td>
749
+ copylimline(linebuf, &c.aTo[iTo+j], collim);
750
+ @ <td class="added lineno">%d(iTo+j+1)</td>
751
+ @ <td class="added srcline">%h(linebuf)</td>
752
+ @ </tr>
753
+ }
754
+ iTo+=c.aEdit[i+2];
755
+ }
756
+
757
+ i+=3;
758
+ }
759
+
760
+ free(linebuf);
761
+ free(c.aFrom);
762
+ free(c.aTo);
763
+ free(c.aEdit);
764
+ return 1;
765
+}
766
+
583767
584768
/*
585769
** COMMAND: test-rawdiff
586770
*/
587771
void test_rawdiff_cmd(void){
@@ -711,11 +895,10 @@
711895
p->c.nEdit = 0;
712896
p->c.nEditAlloc = 0;
713897
714898
/* Clear out the from file */
715899
free(p->c.aFrom);
716
- blob_zero(pParent);
717900
718901
/* Return no errors */
719902
return 0;
720903
}
721904
@@ -885,10 +1068,11 @@
8851068
*/
8861069
void annotate_cmd(void){
8871070
int fnid; /* Filename ID */
8881071
int fid; /* File instance ID */
8891072
int mid; /* Manifest where file was checked in */
1073
+ int cid; /* Checkout ID */
8901074
Blob treename; /* FILENAME translated to canonical form */
8911075
char *zFilename; /* Cannonical filename */
8921076
Annotator ann; /* The annotation of the file */
8931077
int i; /* Loop counter */
8941078
const char *zLimit; /* The value to the --limit option */
@@ -914,11 +1098,20 @@
9141098
}
9151099
fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
9161100
if( fid==0 ){
9171101
fossil_fatal("not part of current checkout: %s", zFilename);
9181102
}
919
- mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
1103
+ cid = db_lget_int("checkout", 0);
1104
+ if (cid == 0){
1105
+ fossil_fatal("Not in a checkout");
1106
+ }
1107
+ if( iLimit<=0 ) iLimit = 1000000000;
1108
+ compute_direct_ancestors(cid, iLimit);
1109
+ mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
1110
+ " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid"
1111
+ " ORDER BY ancestor.generation ASC LIMIT 1",
1112
+ fid, fnid);
9201113
if( mid==0 ){
9211114
fossil_panic("unable to find manifest");
9221115
}
9231116
if( fileVers ) annFlags |= ANN_FILE_VERS;
9241117
annotate_file(&ann, fnid, mid, 0, iLimit, annFlags);
9251118
--- src/diff.c
+++ src/diff.c
@@ -578,10 +578,194 @@
578 free(c.aFrom);
579 free(c.aTo);
580 return c.aEdit;
581 }
582 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
583
584 /*
585 ** COMMAND: test-rawdiff
586 */
587 void test_rawdiff_cmd(void){
@@ -711,11 +895,10 @@
711 p->c.nEdit = 0;
712 p->c.nEditAlloc = 0;
713
714 /* Clear out the from file */
715 free(p->c.aFrom);
716 blob_zero(pParent);
717
718 /* Return no errors */
719 return 0;
720 }
721
@@ -885,10 +1068,11 @@
885 */
886 void annotate_cmd(void){
887 int fnid; /* Filename ID */
888 int fid; /* File instance ID */
889 int mid; /* Manifest where file was checked in */
 
890 Blob treename; /* FILENAME translated to canonical form */
891 char *zFilename; /* Cannonical filename */
892 Annotator ann; /* The annotation of the file */
893 int i; /* Loop counter */
894 const char *zLimit; /* The value to the --limit option */
@@ -914,11 +1098,20 @@
914 }
915 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
916 if( fid==0 ){
917 fossil_fatal("not part of current checkout: %s", zFilename);
918 }
919 mid = db_int(0, "SELECT mid FROM mlink WHERE fid=%d AND fnid=%d", fid, fnid);
 
 
 
 
 
 
 
 
 
920 if( mid==0 ){
921 fossil_panic("unable to find manifest");
922 }
923 if( fileVers ) annFlags |= ANN_FILE_VERS;
924 annotate_file(&ann, fnid, mid, 0, iLimit, annFlags);
925
--- src/diff.c
+++ src/diff.c
@@ -578,10 +578,194 @@
578 free(c.aFrom);
579 free(c.aTo);
580 return c.aEdit;
581 }
582 }
583
584 /*
585 ** Copy a line with a limit. Used for side-by-side diffs to enforce a maximum
586 ** line length limit.
587 */
588 static char *copylimline(char *out, DLine *dl, int lim){
589 int len;
590 len = dl->h & LENGTH_MASK;
591 if( lim && len > lim ){
592 memcpy(out, dl->z, lim-3);
593 strcpy(&out[lim-3], "...");
594 }else{
595 memcpy(out, dl->z, len);
596 out[len] = '\0';
597 }
598 return out;
599 }
600
601 /*
602 ** Output table body of a side-by-side diff. Prior to the call, the caller
603 ** should have output:
604 ** <table class="sbsdiff">
605 ** <tr><th colspan="2" class="diffhdr">Old title</th><th/>
606 ** <th colspan="2" class="diffhdr">New title</th></tr>
607 **
608 ** And after the call, it should output:
609 ** </table>
610 **
611 ** Some good reference diffs in the fossil repository for testing:
612 ** /vdiff?from=080d27a&to=4b0f813&detail=1
613 ** /vdiff?from=636804745b&to=c1d78e0556&detail=1
614 ** /vdiff?from=c0b6c28d29&to=25169506b7&detail=1
615 ** /vdiff?from=e3d022dffa&to=48bcfbd47b&detail=1
616 */
617 int html_sbsdiff(
618 Blob *pA_Blob, /* FROM file */
619 Blob *pB_Blob, /* TO file */
620 int nContext, /* Amount of context to unified diff */
621 int ignoreEolWs /* Ignore whitespace at the end of lines */
622 ){
623 DContext c;
624 int i;
625 int iFrom, iTo;
626 char *linebuf;
627 int collim=0; /* Currently not settable; allows a column limit for diffs */
628 int allowExp=0; /* Currently not settable; (dis)allow expansion of rows */
629
630 /* Prepare the input files */
631 memset(&c, 0, sizeof(c));
632 c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
633 &c.nFrom, ignoreEolWs);
634 c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
635 &c.nTo, ignoreEolWs);
636 if( c.aFrom==0 || c.aTo==0 ){
637 free(c.aFrom);
638 free(c.aTo);
639 /* Note: This would be generated within a table. */
640 @ <p class="generalError" style="white-space: nowrap">cannot compute
641 @ difference between binary files</p>
642 return 0;
643 }
644
645 collim = collim < 4 ? 0 : collim;
646
647 /* Compute the difference */
648 diff_all(&c);
649
650 linebuf = fossil_malloc(LENGTH_MASK+1);
651 if( !linebuf ){
652 free(c.aFrom);
653 free(c.aTo);
654 free(c.aEdit);
655 return 0;
656 }
657
658 iFrom=iTo=0;
659 i=0;
660 while( i<c.nEdit ){
661 int j;
662 /* Copied lines */
663 for( j=0; j<c.aEdit[i]; j++){
664 /* Hide lines which are copied and are further away from block boundaries
665 ** than nConext lines. For each block with hidden lines, show a row
666 ** notifying the user about the hidden rows.
667 */
668 if( j<nContext || j>c.aEdit[i]-nContext-1 ){
669 @ <tr>
670 }else if( j==nContext && j<c.aEdit[i]-nContext-1 ){
671 @ <tr>
672 @ <td class="meta" colspan="5" style="white-space: nowrap;">
673 @ %d(c.aEdit[i]-2*nContext) hidden lines</td>
674 @ </tr>
675 if( !allowExp )
676 continue;
677 @ <tr style="display:none;">
678 }else{
679 if( !allowExp )
680 continue;
681 @ <tr style="display:none;">
682 }
683
684 copylimline(linebuf, &c.aFrom[iFrom+j], collim);
685 @ <td class="lineno">%d(iFrom+j+1)</td>
686 @ <td class="srcline">%h(linebuf)</td>
687
688 @ <td> </td>
689
690 copylimline(linebuf, &c.aTo[iTo+j], collim);
691 @ <td class="lineno">%d(iTo+j+1)</td>
692 @ <td class="srcline">%h(linebuf)</td>
693
694 @ </tr>
695 }
696 iFrom+=c.aEdit[i];
697 iTo+=c.aEdit[i];
698
699 if( c.aEdit[i+1]!=0 && c.aEdit[i+2]!=0 ){
700 int lim;
701 lim = c.aEdit[i+1] > c.aEdit[i+2] ? c.aEdit[i+1] : c.aEdit[i+2];
702
703 /* Assume changed lines */
704 for( j=0; j<lim; j++ ){
705 @ <tr>
706
707 if( j<c.aEdit[i+1] ){
708 copylimline(linebuf, &c.aFrom[iFrom+j], collim);
709 @ <td class="changed lineno">%d(iFrom+j+1)</td>
710 @ <td class="changed srcline">%h(linebuf)</td>
711 }else{
712 @ <td colspan="2" class="changedvoid"/>
713 }
714
715 @ <td class="changed">|</td>
716
717 if( j<c.aEdit[i+2] ){
718 copylimline(linebuf, &c.aTo[iTo+j], collim);
719 @ <td class="changed lineno">%d(iTo+j+1)</td>
720 @ <td class="changed srcline">%h(linebuf)</td>
721 }else{
722 @ <td colspan="2" class="changedvoid"/>
723 }
724
725 @ </tr>
726 }
727 iFrom+=c.aEdit[i+1];
728 iTo+=c.aEdit[i+2];
729 }else{
730
731 /* Process deleted lines */
732 for( j=0; j<c.aEdit[i+1]; j++ ){
733 @ <tr>
734
735 copylimline(linebuf, &c.aFrom[iFrom+j], collim);
736 @ <td class="removed lineno">%d(iFrom+j+1)</td>
737 @ <td class="removed srcline">%h(linebuf)</td>
738 @ <td>&lt;</td>
739 @ <td colspan="2" class="removedvoid"/>
740 @ </tr>
741 }
742 iFrom+=c.aEdit[i+1];
743
744 /* Process inserted lines */
745 for( j=0; j<c.aEdit[i+2]; j++ ){
746 @ <tr>
747 @ <td colspan="2" class="addedvoid"/>
748 @ <td>&gt;</td>
749 copylimline(linebuf, &c.aTo[iTo+j], collim);
750 @ <td class="added lineno">%d(iTo+j+1)</td>
751 @ <td class="added srcline">%h(linebuf)</td>
752 @ </tr>
753 }
754 iTo+=c.aEdit[i+2];
755 }
756
757 i+=3;
758 }
759
760 free(linebuf);
761 free(c.aFrom);
762 free(c.aTo);
763 free(c.aEdit);
764 return 1;
765 }
766
767
768 /*
769 ** COMMAND: test-rawdiff
770 */
771 void test_rawdiff_cmd(void){
@@ -711,11 +895,10 @@
895 p->c.nEdit = 0;
896 p->c.nEditAlloc = 0;
897
898 /* Clear out the from file */
899 free(p->c.aFrom);
 
900
901 /* Return no errors */
902 return 0;
903 }
904
@@ -885,10 +1068,11 @@
1068 */
1069 void annotate_cmd(void){
1070 int fnid; /* Filename ID */
1071 int fid; /* File instance ID */
1072 int mid; /* Manifest where file was checked in */
1073 int cid; /* Checkout ID */
1074 Blob treename; /* FILENAME translated to canonical form */
1075 char *zFilename; /* Cannonical filename */
1076 Annotator ann; /* The annotation of the file */
1077 int i; /* Loop counter */
1078 const char *zLimit; /* The value to the --limit option */
@@ -914,11 +1098,20 @@
1098 }
1099 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
1100 if( fid==0 ){
1101 fossil_fatal("not part of current checkout: %s", zFilename);
1102 }
1103 cid = db_lget_int("checkout", 0);
1104 if (cid == 0){
1105 fossil_fatal("Not in a checkout");
1106 }
1107 if( iLimit<=0 ) iLimit = 1000000000;
1108 compute_direct_ancestors(cid, iLimit);
1109 mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
1110 " WHERE mlink.fid=%d AND mlink.fnid=%d AND mlink.mid=ancestor.rid"
1111 " ORDER BY ancestor.generation ASC LIMIT 1",
1112 fid, fnid);
1113 if( mid==0 ){
1114 fossil_panic("unable to find manifest");
1115 }
1116 if( fileVers ) annFlags |= ANN_FILE_VERS;
1117 annotate_file(&ann, fnid, mid, 0, iLimit, annFlags);
1118
+1 -1
--- src/file.c
+++ src/file.c
@@ -34,11 +34,11 @@
3434
** The file status information from the most recent stat() call.
3535
**
3636
** Use _stati64 rather than stat on windows, in order to handle files
3737
** larger than 2GB.
3838
*/
39
-#if defined(_WIN32) && defined(__MSVCRT__)
39
+#if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
4040
# define stat _stati64
4141
#endif
4242
/*
4343
** On Windows S_ISLNK always returns FALSE.
4444
*/
4545
--- src/file.c
+++ src/file.c
@@ -34,11 +34,11 @@
34 ** The file status information from the most recent stat() call.
35 **
36 ** Use _stati64 rather than stat on windows, in order to handle files
37 ** larger than 2GB.
38 */
39 #if defined(_WIN32) && defined(__MSVCRT__)
40 # define stat _stati64
41 #endif
42 /*
43 ** On Windows S_ISLNK always returns FALSE.
44 */
45
--- src/file.c
+++ src/file.c
@@ -34,11 +34,11 @@
34 ** The file status information from the most recent stat() call.
35 **
36 ** Use _stati64 rather than stat on windows, in order to handle files
37 ** larger than 2GB.
38 */
39 #if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
40 # define stat _stati64
41 #endif
42 /*
43 ** On Windows S_ISLNK always returns FALSE.
44 */
45
+1 -1
--- src/http.c
+++ src/http.c
@@ -136,11 +136,11 @@
136136
Blob login; /* The login card */
137137
Blob payload; /* The complete payload including login card */
138138
Blob hdr; /* The HTTP request header */
139139
int closeConnection; /* True to close the connection when done */
140140
int iLength; /* Length of the reply payload */
141
- int rc; /* Result code */
141
+ int rc = 0; /* Result code */
142142
int iHttpVersion; /* Which version of HTTP protocol server uses */
143143
char *zLine; /* A single line of the reply header */
144144
int i; /* Loop counter */
145145
int isError = 0; /* True if the reply is an error message */
146146
int isCompressed = 1; /* True if the reply is compressed */
147147
--- src/http.c
+++ src/http.c
@@ -136,11 +136,11 @@
136 Blob login; /* The login card */
137 Blob payload; /* The complete payload including login card */
138 Blob hdr; /* The HTTP request header */
139 int closeConnection; /* True to close the connection when done */
140 int iLength; /* Length of the reply payload */
141 int rc; /* Result code */
142 int iHttpVersion; /* Which version of HTTP protocol server uses */
143 char *zLine; /* A single line of the reply header */
144 int i; /* Loop counter */
145 int isError = 0; /* True if the reply is an error message */
146 int isCompressed = 1; /* True if the reply is compressed */
147
--- src/http.c
+++ src/http.c
@@ -136,11 +136,11 @@
136 Blob login; /* The login card */
137 Blob payload; /* The complete payload including login card */
138 Blob hdr; /* The HTTP request header */
139 int closeConnection; /* True to close the connection when done */
140 int iLength; /* Length of the reply payload */
141 int rc = 0; /* Result code */
142 int iHttpVersion; /* Which version of HTTP protocol server uses */
143 char *zLine; /* A single line of the reply header */
144 int i; /* Loop counter */
145 int isError = 0; /* True if the reply is an error message */
146 int isCompressed = 1; /* True if the reply is compressed */
147
+54 -23
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -97,10 +97,11 @@
9797
** Call this routine once before any other use of the SSL interface.
9898
** This routine does initial configuration of the SSL module.
9999
*/
100100
void ssl_global_init(void){
101101
const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
102
+ const char *identityFile;
102103
103104
if( sslIsInit==0 ){
104105
SSL_library_init();
105106
SSL_load_error_strings();
106107
ERR_load_BIO_strings();
@@ -135,19 +136,26 @@
135136
fossil_fatal("Failed to use CA root certificates from "
136137
"ssl-ca-location '%s'", zCaSetting);
137138
}
138139
}
139140
140
- /* Load client SSL identity, preferring the filename specified on the command line */
141
- const char *identityFile = ( g.zSSLIdentity!= 0) ? g.zSSLIdentity : db_get("ssl-identity", 0);
141
+ /* Load client SSL identity, preferring the filename specified on the
142
+ ** command line */
143
+ if( g.zSSLIdentity!=0 ){
144
+ identityFile = g.zSSLIdentity;
145
+ }else{
146
+ identityFile = db_get("ssl-identity", 0);
147
+ }
142148
if( identityFile!=0 && identityFile[0]!='\0' ){
143
- if( SSL_CTX_use_certificate_file(sslCtx, identityFile, SSL_FILETYPE_PEM)!= 1
144
- || SSL_CTX_use_PrivateKey_file(sslCtx, identityFile, SSL_FILETYPE_PEM)!=1 ){
149
+ if( SSL_CTX_use_certificate_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1
150
+ || SSL_CTX_use_PrivateKey_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1
151
+ ){
145152
fossil_fatal("Could not load SSL identity from %s", identityFile);
146153
}
147154
}
148
- /* Register a callback to tell the user what to do when the server asks for a cert */
155
+ /* Register a callback to tell the user what to do when the server asks
156
+ ** for a cert */
149157
SSL_CTX_set_client_cert_cb(sslCtx, ssl_client_cert_callback);
150158
151159
sslIsInit = 1;
152160
}
153161
}
@@ -184,17 +192,20 @@
184192
** Return the number of errors.
185193
*/
186194
int ssl_open(void){
187195
X509 *cert;
188196
int hasSavedCertificate = 0;
189
-char *connStr ;
197
+ int trusted = 0;
198
+ char *connStr ;
199
+ unsigned long e;
200
+
190201
ssl_global_init();
191202
192203
/* Get certificate for current server from global config and
193204
* (if we have it in config) add it to certificate store.
194205
*/
195
- cert = ssl_get_certificate();
206
+ cert = ssl_get_certificate(&trusted);
196207
if ( cert!=NULL ){
197208
X509_STORE_add_cert(SSL_CTX_get_cert_store(sslCtx), cert);
198209
X509_free(cert);
199210
hasSavedCertificate = 1;
200211
}
@@ -232,11 +243,11 @@
232243
ssl_set_errmsg("No SSL certificate was presented by the peer");
233244
ssl_close();
234245
return 1;
235246
}
236247
237
- if( SSL_get_verify_result(ssl) != X509_V_OK ){
248
+ if( trusted<=0 && (e = SSL_get_verify_result(ssl)) != X509_V_OK ){
238249
char *desc, *prompt;
239250
char *warning = "";
240251
Blob ans;
241252
BIO *mem;
242253
unsigned char md[32];
@@ -258,19 +269,22 @@
258269
259270
if( hasSavedCertificate ){
260271
warning = "WARNING: Certificate doesn't match the "
261272
"saved certificate for this host!";
262273
}
263
- prompt = mprintf("\nUnknown SSL certificate:\n\n%s\n\n%s\n"
264
- "Either:\n"
265
- " * verify the certificate is correct using the "
266
- "SHA1 fingerprint above\n"
267
- " * use the global ssl-ca-location setting to specify your CA root\n"
268
- " certificates list\n\n"
269
- "If you are not expecting this message, answer no and "
270
- "contact your server\nadministrator.\n\n"
271
- "Accept certificate [a=always/y/N]? ", desc, warning);
274
+ prompt = mprintf("\nSSL verification failed: %s\n"
275
+ "Certificate received: \n\n%s\n\n%s\n"
276
+ "Either:\n"
277
+ " * verify the certificate is correct using the "
278
+ "SHA1 fingerprint above\n"
279
+ " * use the global ssl-ca-location setting to specify your CA root\n"
280
+ " certificates list\n\n"
281
+ "If you are not expecting this message, answer no and "
282
+ "contact your server\nadministrator.\n\n"
283
+ "Accept certificate for host %s [a=always/y/N]? ",
284
+ X509_verify_cert_error_string(e), desc, warning,
285
+ g.urlName);
272286
BIO_free(mem);
273287
274288
prompt_user(prompt, &ans);
275289
free(prompt);
276290
if( blob_str(&ans)[0]!='y' && blob_str(&ans)[0]!='a' ) {
@@ -278,33 +292,40 @@
278292
ssl_set_errmsg("SSL certificate declined");
279293
ssl_close();
280294
return 1;
281295
}
282296
if( blob_str(&ans)[0]=='a' ) {
283
- ssl_save_certificate(cert);
297
+ if ( trusted==0 ){
298
+ Blob ans2;
299
+ prompt_user("\nSave this certificate as fully trusted [a=always/N]? ",
300
+ &ans2);
301
+ trusted = (blob_str(&ans2)[0]=='a');
302
+ blob_reset(&ans2);
303
+ }
304
+ ssl_save_certificate(cert, trusted);
284305
}
285306
blob_reset(&ans);
286307
}
287308
288309
/* Set the Global.zIpAddr variable to the server we are talking to.
289310
** This is used to populate the ipaddr column of the rcvfrom table,
290311
** if any files are received from the server.
291312
*/
292313
{
293
- /* IPv4 only code */
294
- const unsigned char *ip = (const unsigned char *) BIO_get_conn_ip(iBio);
295
- g.zIpAddr = mprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
314
+ /* IPv4 only code */
315
+ const unsigned char *ip = (const unsigned char *) BIO_get_conn_ip(iBio);
316
+ g.zIpAddr = mprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
296317
}
297318
298319
X509_free(cert);
299320
return 0;
300321
}
301322
302323
/*
303324
** Save certificate to global config.
304325
*/
305
-void ssl_save_certificate(X509 *cert){
326
+void ssl_save_certificate(X509 *cert, int trusted){
306327
BIO *mem;
307328
char *zCert, *zHost;
308329
309330
mem = BIO_new(BIO_s_mem());
310331
PEM_write_bio_X509(mem, cert);
@@ -311,27 +332,37 @@
311332
BIO_write(mem, "", 1); /* nul-terminate mem buffer */
312333
BIO_get_mem_data(mem, &zCert);
313334
zHost = mprintf("cert:%s", g.urlName);
314335
db_set(zHost, zCert, 1);
315336
free(zHost);
337
+ zHost = mprintf("trusted:%s", g.urlName);
338
+ db_set_int(zHost, trusted, 1);
339
+ free(zHost);
316340
BIO_free(mem);
317341
}
318342
319343
/*
320344
** Get certificate for g.urlName from global config.
321345
** Return NULL if no certificate found.
322346
*/
323
-X509 *ssl_get_certificate(void){
347
+X509 *ssl_get_certificate(int *pTrusted){
324348
char *zHost, *zCert;
325349
BIO *mem;
326350
X509 *cert;
327351
328352
zHost = mprintf("cert:%s", g.urlName);
329353
zCert = db_get(zHost, NULL);
330354
free(zHost);
331355
if ( zCert==NULL )
332356
return NULL;
357
+
358
+ if ( pTrusted!=0 ){
359
+ zHost = mprintf("trusted:%s", g.urlName);
360
+ *pTrusted = db_get_int(zHost, 0);
361
+ free(zHost);
362
+ }
363
+
333364
mem = BIO_new(BIO_s_mem());
334365
BIO_puts(mem, zCert);
335366
cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
336367
free(zCert);
337368
BIO_free(mem);
338369
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -97,10 +97,11 @@
97 ** Call this routine once before any other use of the SSL interface.
98 ** This routine does initial configuration of the SSL module.
99 */
100 void ssl_global_init(void){
101 const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
 
102
103 if( sslIsInit==0 ){
104 SSL_library_init();
105 SSL_load_error_strings();
106 ERR_load_BIO_strings();
@@ -135,19 +136,26 @@
135 fossil_fatal("Failed to use CA root certificates from "
136 "ssl-ca-location '%s'", zCaSetting);
137 }
138 }
139
140 /* Load client SSL identity, preferring the filename specified on the command line */
141 const char *identityFile = ( g.zSSLIdentity!= 0) ? g.zSSLIdentity : db_get("ssl-identity", 0);
 
 
 
 
 
142 if( identityFile!=0 && identityFile[0]!='\0' ){
143 if( SSL_CTX_use_certificate_file(sslCtx, identityFile, SSL_FILETYPE_PEM)!= 1
144 || SSL_CTX_use_PrivateKey_file(sslCtx, identityFile, SSL_FILETYPE_PEM)!=1 ){
 
145 fossil_fatal("Could not load SSL identity from %s", identityFile);
146 }
147 }
148 /* Register a callback to tell the user what to do when the server asks for a cert */
 
149 SSL_CTX_set_client_cert_cb(sslCtx, ssl_client_cert_callback);
150
151 sslIsInit = 1;
152 }
153 }
@@ -184,17 +192,20 @@
184 ** Return the number of errors.
185 */
186 int ssl_open(void){
187 X509 *cert;
188 int hasSavedCertificate = 0;
189 char *connStr ;
 
 
 
190 ssl_global_init();
191
192 /* Get certificate for current server from global config and
193 * (if we have it in config) add it to certificate store.
194 */
195 cert = ssl_get_certificate();
196 if ( cert!=NULL ){
197 X509_STORE_add_cert(SSL_CTX_get_cert_store(sslCtx), cert);
198 X509_free(cert);
199 hasSavedCertificate = 1;
200 }
@@ -232,11 +243,11 @@
232 ssl_set_errmsg("No SSL certificate was presented by the peer");
233 ssl_close();
234 return 1;
235 }
236
237 if( SSL_get_verify_result(ssl) != X509_V_OK ){
238 char *desc, *prompt;
239 char *warning = "";
240 Blob ans;
241 BIO *mem;
242 unsigned char md[32];
@@ -258,19 +269,22 @@
258
259 if( hasSavedCertificate ){
260 warning = "WARNING: Certificate doesn't match the "
261 "saved certificate for this host!";
262 }
263 prompt = mprintf("\nUnknown SSL certificate:\n\n%s\n\n%s\n"
264 "Either:\n"
265 " * verify the certificate is correct using the "
266 "SHA1 fingerprint above\n"
267 " * use the global ssl-ca-location setting to specify your CA root\n"
268 " certificates list\n\n"
269 "If you are not expecting this message, answer no and "
270 "contact your server\nadministrator.\n\n"
271 "Accept certificate [a=always/y/N]? ", desc, warning);
 
 
 
272 BIO_free(mem);
273
274 prompt_user(prompt, &ans);
275 free(prompt);
276 if( blob_str(&ans)[0]!='y' && blob_str(&ans)[0]!='a' ) {
@@ -278,33 +292,40 @@
278 ssl_set_errmsg("SSL certificate declined");
279 ssl_close();
280 return 1;
281 }
282 if( blob_str(&ans)[0]=='a' ) {
283 ssl_save_certificate(cert);
 
 
 
 
 
 
 
284 }
285 blob_reset(&ans);
286 }
287
288 /* Set the Global.zIpAddr variable to the server we are talking to.
289 ** This is used to populate the ipaddr column of the rcvfrom table,
290 ** if any files are received from the server.
291 */
292 {
293 /* IPv4 only code */
294 const unsigned char *ip = (const unsigned char *) BIO_get_conn_ip(iBio);
295 g.zIpAddr = mprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
296 }
297
298 X509_free(cert);
299 return 0;
300 }
301
302 /*
303 ** Save certificate to global config.
304 */
305 void ssl_save_certificate(X509 *cert){
306 BIO *mem;
307 char *zCert, *zHost;
308
309 mem = BIO_new(BIO_s_mem());
310 PEM_write_bio_X509(mem, cert);
@@ -311,27 +332,37 @@
311 BIO_write(mem, "", 1); /* nul-terminate mem buffer */
312 BIO_get_mem_data(mem, &zCert);
313 zHost = mprintf("cert:%s", g.urlName);
314 db_set(zHost, zCert, 1);
315 free(zHost);
 
 
 
316 BIO_free(mem);
317 }
318
319 /*
320 ** Get certificate for g.urlName from global config.
321 ** Return NULL if no certificate found.
322 */
323 X509 *ssl_get_certificate(void){
324 char *zHost, *zCert;
325 BIO *mem;
326 X509 *cert;
327
328 zHost = mprintf("cert:%s", g.urlName);
329 zCert = db_get(zHost, NULL);
330 free(zHost);
331 if ( zCert==NULL )
332 return NULL;
 
 
 
 
 
 
 
333 mem = BIO_new(BIO_s_mem());
334 BIO_puts(mem, zCert);
335 cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
336 free(zCert);
337 BIO_free(mem);
338
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -97,10 +97,11 @@
97 ** Call this routine once before any other use of the SSL interface.
98 ** This routine does initial configuration of the SSL module.
99 */
100 void ssl_global_init(void){
101 const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
102 const char *identityFile;
103
104 if( sslIsInit==0 ){
105 SSL_library_init();
106 SSL_load_error_strings();
107 ERR_load_BIO_strings();
@@ -135,19 +136,26 @@
136 fossil_fatal("Failed to use CA root certificates from "
137 "ssl-ca-location '%s'", zCaSetting);
138 }
139 }
140
141 /* Load client SSL identity, preferring the filename specified on the
142 ** command line */
143 if( g.zSSLIdentity!=0 ){
144 identityFile = g.zSSLIdentity;
145 }else{
146 identityFile = db_get("ssl-identity", 0);
147 }
148 if( identityFile!=0 && identityFile[0]!='\0' ){
149 if( SSL_CTX_use_certificate_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1
150 || SSL_CTX_use_PrivateKey_file(sslCtx,identityFile,SSL_FILETYPE_PEM)!=1
151 ){
152 fossil_fatal("Could not load SSL identity from %s", identityFile);
153 }
154 }
155 /* Register a callback to tell the user what to do when the server asks
156 ** for a cert */
157 SSL_CTX_set_client_cert_cb(sslCtx, ssl_client_cert_callback);
158
159 sslIsInit = 1;
160 }
161 }
@@ -184,17 +192,20 @@
192 ** Return the number of errors.
193 */
194 int ssl_open(void){
195 X509 *cert;
196 int hasSavedCertificate = 0;
197 int trusted = 0;
198 char *connStr ;
199 unsigned long e;
200
201 ssl_global_init();
202
203 /* Get certificate for current server from global config and
204 * (if we have it in config) add it to certificate store.
205 */
206 cert = ssl_get_certificate(&trusted);
207 if ( cert!=NULL ){
208 X509_STORE_add_cert(SSL_CTX_get_cert_store(sslCtx), cert);
209 X509_free(cert);
210 hasSavedCertificate = 1;
211 }
@@ -232,11 +243,11 @@
243 ssl_set_errmsg("No SSL certificate was presented by the peer");
244 ssl_close();
245 return 1;
246 }
247
248 if( trusted<=0 && (e = SSL_get_verify_result(ssl)) != X509_V_OK ){
249 char *desc, *prompt;
250 char *warning = "";
251 Blob ans;
252 BIO *mem;
253 unsigned char md[32];
@@ -258,19 +269,22 @@
269
270 if( hasSavedCertificate ){
271 warning = "WARNING: Certificate doesn't match the "
272 "saved certificate for this host!";
273 }
274 prompt = mprintf("\nSSL verification failed: %s\n"
275 "Certificate received: \n\n%s\n\n%s\n"
276 "Either:\n"
277 " * verify the certificate is correct using the "
278 "SHA1 fingerprint above\n"
279 " * use the global ssl-ca-location setting to specify your CA root\n"
280 " certificates list\n\n"
281 "If you are not expecting this message, answer no and "
282 "contact your server\nadministrator.\n\n"
283 "Accept certificate for host %s [a=always/y/N]? ",
284 X509_verify_cert_error_string(e), desc, warning,
285 g.urlName);
286 BIO_free(mem);
287
288 prompt_user(prompt, &ans);
289 free(prompt);
290 if( blob_str(&ans)[0]!='y' && blob_str(&ans)[0]!='a' ) {
@@ -278,33 +292,40 @@
292 ssl_set_errmsg("SSL certificate declined");
293 ssl_close();
294 return 1;
295 }
296 if( blob_str(&ans)[0]=='a' ) {
297 if ( trusted==0 ){
298 Blob ans2;
299 prompt_user("\nSave this certificate as fully trusted [a=always/N]? ",
300 &ans2);
301 trusted = (blob_str(&ans2)[0]=='a');
302 blob_reset(&ans2);
303 }
304 ssl_save_certificate(cert, trusted);
305 }
306 blob_reset(&ans);
307 }
308
309 /* Set the Global.zIpAddr variable to the server we are talking to.
310 ** This is used to populate the ipaddr column of the rcvfrom table,
311 ** if any files are received from the server.
312 */
313 {
314 /* IPv4 only code */
315 const unsigned char *ip = (const unsigned char *) BIO_get_conn_ip(iBio);
316 g.zIpAddr = mprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
317 }
318
319 X509_free(cert);
320 return 0;
321 }
322
323 /*
324 ** Save certificate to global config.
325 */
326 void ssl_save_certificate(X509 *cert, int trusted){
327 BIO *mem;
328 char *zCert, *zHost;
329
330 mem = BIO_new(BIO_s_mem());
331 PEM_write_bio_X509(mem, cert);
@@ -311,27 +332,37 @@
332 BIO_write(mem, "", 1); /* nul-terminate mem buffer */
333 BIO_get_mem_data(mem, &zCert);
334 zHost = mprintf("cert:%s", g.urlName);
335 db_set(zHost, zCert, 1);
336 free(zHost);
337 zHost = mprintf("trusted:%s", g.urlName);
338 db_set_int(zHost, trusted, 1);
339 free(zHost);
340 BIO_free(mem);
341 }
342
343 /*
344 ** Get certificate for g.urlName from global config.
345 ** Return NULL if no certificate found.
346 */
347 X509 *ssl_get_certificate(int *pTrusted){
348 char *zHost, *zCert;
349 BIO *mem;
350 X509 *cert;
351
352 zHost = mprintf("cert:%s", g.urlName);
353 zCert = db_get(zHost, NULL);
354 free(zHost);
355 if ( zCert==NULL )
356 return NULL;
357
358 if ( pTrusted!=0 ){
359 zHost = mprintf("trusted:%s", g.urlName);
360 *pTrusted = db_get_int(zHost, 0);
361 free(zHost);
362 }
363
364 mem = BIO_new(BIO_s_mem());
365 BIO_puts(mem, zCert);
366 cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
367 free(zCert);
368 BIO_free(mem);
369
--- src/http_transport.c
+++ src/http_transport.c
@@ -265,14 +265,12 @@
265265
void transport_send(Blob *toSend){
266266
char *z = blob_buffer(toSend);
267267
int n = blob_size(toSend);
268268
transport.nSent += n;
269269
if( g.urlIsSsh ){
270
- int sent;
271
- sent = fwrite(z, 1, n, sshOut);
270
+ fwrite(z, 1, n, sshOut);
272271
fflush(sshOut);
273
- /* printf("sent %d of %d bytes\n", sent, n); fflush(stdout); */
274272
}else if( g.urlIsHttps ){
275273
#ifdef FOSSIL_ENABLE_SSL
276274
int sent;
277275
while( n>0 ){
278276
sent = ssl_send(0, z, n);
279277
--- src/http_transport.c
+++ src/http_transport.c
@@ -265,14 +265,12 @@
265 void transport_send(Blob *toSend){
266 char *z = blob_buffer(toSend);
267 int n = blob_size(toSend);
268 transport.nSent += n;
269 if( g.urlIsSsh ){
270 int sent;
271 sent = fwrite(z, 1, n, sshOut);
272 fflush(sshOut);
273 /* printf("sent %d of %d bytes\n", sent, n); fflush(stdout); */
274 }else if( g.urlIsHttps ){
275 #ifdef FOSSIL_ENABLE_SSL
276 int sent;
277 while( n>0 ){
278 sent = ssl_send(0, z, n);
279
--- src/http_transport.c
+++ src/http_transport.c
@@ -265,14 +265,12 @@
265 void transport_send(Blob *toSend){
266 char *z = blob_buffer(toSend);
267 int n = blob_size(toSend);
268 transport.nSent += n;
269 if( g.urlIsSsh ){
270 fwrite(z, 1, n, sshOut);
 
271 fflush(sshOut);
 
272 }else if( g.urlIsHttps ){
273 #ifdef FOSSIL_ENABLE_SSL
274 int sent;
275 while( n>0 ){
276 sent = ssl_send(0, z, n);
277
+159 -33
--- src/info.c
+++ src/info.c
@@ -276,10 +276,40 @@
276276
@ %h(blob_str(&out))
277277
blob_reset(&from);
278278
blob_reset(&to);
279279
blob_reset(&out);
280280
}
281
+
282
+
283
+/*
284
+** Write the difference between two RIDs to the output
285
+*/
286
+static void generate_sbsdiff(const char *zFrom, const char *zTo){
287
+ int fromid;
288
+ int toid;
289
+ Blob from, to;
290
+ if( zFrom ){
291
+ fromid = uuid_to_rid(zFrom, 0);
292
+ content_get(fromid, &from);
293
+ }else{
294
+ blob_zero(&from);
295
+ }
296
+ if( zTo ){
297
+ toid = uuid_to_rid(zTo, 0);
298
+ content_get(toid, &to);
299
+ }else{
300
+ blob_zero(&to);
301
+ }
302
+ @ <table class="sbsdiff">
303
+ @ <tr><th colspan="2" class="diffhdr">Old (%S(zFrom))</th><th/>
304
+ @ <th colspan="2" class="diffhdr">New (%S(zTo))</th></tr>
305
+ html_sbsdiff(&from, &to, 5, 1);
306
+ @ </table>
307
+ blob_reset(&from);
308
+ blob_reset(&to);
309
+}
310
+
281311
282312
/*
283313
** Write a line of web-page output that shows changes that have occurred
284314
** to a file between two check-ins.
285315
*/
@@ -287,10 +317,11 @@
287317
const char *zName, /* Name of the file that has changed */
288318
const char *zOld, /* blob.uuid before change. NULL for added files */
289319
const char *zNew, /* blob.uuid after change. NULL for deletes */
290320
const char *zOldName, /* Prior name. NULL if no name change. */
291321
int showDiff, /* Show edit diffs if true */
322
+ int sideBySide, /* Show diffs side-by-side */
292323
int mperm /* executable or symlink permission for zNew */
293324
){
294325
if( !g.perm.History ){
295326
if( zNew==0 ){
296327
@ <p>Deleted %h(zName)</p>
@@ -303,13 +334,17 @@
303334
@ for %h(zName)</p>
304335
}else{
305336
@ <p>Changes to %h(zName)</p>
306337
}
307338
if( showDiff ){
308
- @ <blockquote><pre>
309
- append_diff(zOld, zNew);
310
- @ </pre></blockquote>
339
+ if( sideBySide ){
340
+ generate_sbsdiff(zOld, zNew);
341
+ }else{
342
+ @ <blockquote><pre>
343
+ append_diff(zOld, zNew);
344
+ @ </pre></blockquote>
345
+ }
311346
}
312347
}else{
313348
if( zOld && zNew ){
314349
if( fossil_strcmp(zOld, zNew)!=0 ){
315350
@ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -329,13 +364,17 @@
329364
}else{
330365
@ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
331366
@ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a>
332367
}
333368
if( showDiff ){
334
- @ <blockquote><pre>
335
- append_diff(zOld, zNew);
336
- @ </pre></blockquote>
369
+ if( sideBySide ){
370
+ generate_sbsdiff(zOld, zNew);
371
+ }else{
372
+ @ <blockquote><pre>
373
+ append_diff(zOld, zNew);
374
+ @ </pre></blockquote>
375
+ }
337376
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
338377
@ &nbsp;&nbsp;
339378
@ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&amp;v2=%S(zNew)">[diff]</a>
340379
}
341380
@ </p>
@@ -361,10 +400,11 @@
361400
void ci_page(void){
362401
Stmt q;
363402
int rid;
364403
int isLeaf;
365404
int showDiff;
405
+ int sideBySide;
366406
const char *zName; /* Name of the checkin to be displayed */
367407
const char *zUuid; /* UUID of zName */
368408
const char *zParent; /* UUID of the parent checkin (if any) */
369409
370410
login_check_credentials();
@@ -390,10 +430,11 @@
390430
" FROM blob, event"
391431
" WHERE blob.rid=%d"
392432
" AND event.objid=%d",
393433
rid, rid
394434
);
435
+ sideBySide = atoi(PD("sbs","1"));
395436
if( db_step(&q)==SQLITE_ROW ){
396437
const char *zUuid = db_column_text(&q, 0);
397438
char *zTitle = mprintf("Check-in [%.10s]", zUuid);
398439
char *zEUser, *zEComment;
399440
const char *zUser;
@@ -467,11 +508,11 @@
467508
}
468509
if( !isLeaf ){
469510
@ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a>
470511
}
471512
if( zParent && !isLeaf ){
472
- @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)&amp;p=%S(zUuid)">both</a>
513
+ @ | <a href="%s(g.zTop)/timeline?dp=%S(zUuid)">both</a>
473514
}
474515
db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
475516
" WHERE rid=%d AND tagtype>0 "
476517
" AND tag.tagid=tagxref.tagid "
477518
" AND +tag.tagname GLOB 'sym-*'", rid);
@@ -506,27 +547,49 @@
506547
}
507548
db_finalize(&q);
508549
showTags(rid, "");
509550
if( zParent ){
510551
@ <div class="section">Changes</div>
552
+ @ <div class="sectionmenu">
511553
showDiff = g.zPath[0]!='c';
512554
if( db_get_boolean("show-version-diffs", 0)==0 ){
513555
showDiff = !showDiff;
514556
if( showDiff ){
515
- @ <a href="%s(g.zTop)/vinfo/%T(zName)">[hide&nbsp;diffs]</a>
557
+ @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)">
558
+ @ hide&nbsp;diffs</a>
559
+ if( sideBySide ){
560
+ @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0">
561
+ @ unified&nbsp;diffs</a>
562
+ }else{
563
+ @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1">
564
+ @ side-by-side&nbsp;diffs</a>
565
+ }
516566
}else{
517
- @ <a href="%s(g.zTop)/ci/%T(zName)">[show&nbsp;diffs]</a>
567
+ @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0">
568
+ @ show&nbsp;unified&nbsp;diffs</a>
569
+ @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1">
570
+ @ show&nbsp;side-by-side&nbsp;diffs</a>
518571
}
519572
}else{
520573
if( showDiff ){
521
- @ <a href="%s(g.zTop)/ci/%T(zName)">[hide&nbsp;diffs]</a>
574
+ @ <a class="button" href="%s(g.zTop)/ci/%T(zName)">hide&nbsp;diffs</a>
575
+ if( sideBySide ){
576
+ @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=0">
577
+ @ unified&nbsp;diffs</a>
578
+ }else{
579
+ @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=1">
580
+ @ side-by-side&nbsp;diffs</a>
581
+ }
522582
}else{
523
- @ <a href="%s(g.zTop)/vinfo/%T(zName)">[show&nbsp;diffs]</a>
583
+ @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=0">
584
+ @ show&nbsp;unified&nbsp;diffs</a>
585
+ @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=1">
586
+ @ show&nbsp;side-by-side&nbsp;diffs</a>
524587
}
525588
}
526
- @ &nbsp;&nbsp;
527
- @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/>
589
+ @ <a class="button" href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">
590
+ @ patch</a></div>
528591
db_prepare(&q,
529592
"SELECT name,"
530593
" mperm,"
531594
" (SELECT uuid FROM blob WHERE rid=mlink.pid),"
532595
" (SELECT uuid FROM blob WHERE rid=mlink.fid),"
@@ -540,11 +603,12 @@
540603
const char *zName = db_column_text(&q,0);
541604
int mperm = db_column_int(&q, 1);
542605
const char *zOld = db_column_text(&q,2);
543606
const char *zNew = db_column_text(&q,3);
544607
const char *zOldName = db_column_text(&q, 4);
545
- append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm);
608
+ append_file_change_line(zName, zOld, zNew, zOldName, showDiff,
609
+ sideBySide, mperm);
546610
}
547611
db_finalize(&q);
548612
}
549613
style_footer();
550614
}
@@ -690,17 +754,18 @@
690754
}
691755
692756
693757
/*
694758
** WEBPAGE: vdiff
695
-** URL: /vdiff?from=UUID&amp;to=UUID&amp;detail=BOOLEAN
759
+** URL: /vdiff?from=UUID&amp;to=UUID&amp;detail=BOOLEAN;sbs=BOOLEAN
696760
**
697761
** Show all differences between two checkins.
698762
*/
699763
void vdiff_page(void){
700764
int ridFrom, ridTo;
701765
int showDetail = 0;
766
+ int sideBySide = 0;
702767
Manifest *pFrom, *pTo;
703768
ManifestFile *pFileFrom, *pFileTo;
704769
705770
login_check_credentials();
706771
if( !g.perm.Read ){ login_needed(); return; }
@@ -709,10 +774,20 @@
709774
pFrom = vdiff_parse_manifest("from", &ridFrom);
710775
if( pFrom==0 ) return;
711776
pTo = vdiff_parse_manifest("to", &ridTo);
712777
if( pTo==0 ) return;
713778
showDetail = atoi(PD("detail","0"));
779
+ sideBySide = atoi(PD("sbs","1"));
780
+ if( !sideBySide ){
781
+ style_submenu_element("Side-by-side Diff", "sbsdiff",
782
+ "%s/vdiff?from=%T&to=%T&detail=%d&sbs=1",
783
+ g.zTop, P("from"), P("to"), showDetail);
784
+ }else{
785
+ style_submenu_element("Unified Diff", "udiff",
786
+ "%s/vdiff?from=%T&to=%T&detail=%d&sbs=0",
787
+ g.zTop, P("from"), P("to"), showDetail);
788
+ }
714789
style_header("Check-in Differences");
715790
@ <h2>Difference From:</h2><blockquote>
716791
checkin_description(ridFrom);
717792
@ </blockquote><h2>To:</h2><blockquote>
718793
checkin_description(ridTo);
@@ -731,25 +806,25 @@
731806
}else{
732807
cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
733808
}
734809
if( cmp<0 ){
735810
append_file_change_line(pFileFrom->zName,
736
- pFileFrom->zUuid, 0, 0, 0, 0);
811
+ pFileFrom->zUuid, 0, 0, 0, 0, 0);
737812
pFileFrom = manifest_file_next(pFrom, 0);
738813
}else if( cmp>0 ){
739814
append_file_change_line(pFileTo->zName,
740
- 0, pFileTo->zUuid, 0, 0,
815
+ 0, pFileTo->zUuid, 0, 0, 0,
741816
manifest_file_mperm(pFileTo));
742817
pFileTo = manifest_file_next(pTo, 0);
743818
}else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
744819
/* No changes */
745820
pFileFrom = manifest_file_next(pFrom, 0);
746821
pFileTo = manifest_file_next(pTo, 0);
747822
}else{
748823
append_file_change_line(pFileFrom->zName,
749824
pFileFrom->zUuid,
750
- pFileTo->zUuid, 0, showDetail,
825
+ pFileTo->zUuid, 0, showDetail, sideBySide,
751826
manifest_file_mperm(pFileTo));
752827
pFileFrom = manifest_file_next(pFrom, 0);
753828
pFileTo = manifest_file_next(pTo, 0);
754829
}
755830
}
@@ -797,11 +872,11 @@
797872
" WHERE filename.fnid=mlink.fnid"
798873
" AND event.objid=mlink.mid"
799874
" AND a.rid=mlink.fid"
800875
" AND b.rid=mlink.mid"
801876
" AND mlink.fid=%d"
802
- " ORDER BY filename.name, event.mtime",
877
+ " ORDER BY filename.name, event.mtime /*sort*/",
803878
TAG_BRANCH, rid
804879
);
805880
@ <ul>
806881
while( db_step(&q)==SQLITE_ROW ){
807882
const char *zName = db_column_text(&q, 0);
@@ -983,28 +1058,30 @@
9831058
}
9841059
9851060
9861061
/*
9871062
** WEBPAGE: fdiff
988
-** URL: fdiff?v1=UUID&v2=UUID&patch
1063
+** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN
9891064
**
990
-** Two arguments, v1 and v2, identify the files to be diffed. Show the
991
-** difference between the two artifacts. Generate plaintext if "patch"
992
-** is present.
1065
+** Two arguments, v1 and v2, identify the files to be diffed. Show the
1066
+** difference between the two artifacts. Show diff side by side unless sbs
1067
+** is 0. Generate plaintext if "patch" is present.
9931068
*/
9941069
void diff_page(void){
9951070
int v1, v2;
9961071
int isPatch;
1072
+ int sideBySide;
9971073
Blob c1, c2, diff, *pOut;
9981074
char *zV1;
9991075
char *zV2;
10001076
10011077
login_check_credentials();
10021078
if( !g.perm.Read ){ login_needed(); return; }
10031079
v1 = name_to_rid_www("v1");
10041080
v2 = name_to_rid_www("v2");
10051081
if( v1==0 || v2==0 ) fossil_redirect_home();
1082
+ sideBySide = atoi(PD("sbs","1"));
10061083
zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
10071084
zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
10081085
isPatch = P("patch")!=0;
10091086
if( isPatch ){
10101087
pOut = cgi_output_blob();
@@ -1011,28 +1088,44 @@
10111088
cgi_set_content_type("text/plain");
10121089
}else{
10131090
blob_zero(&diff);
10141091
pOut = &diff;
10151092
}
1016
- content_get(v1, &c1);
1017
- content_get(v2, &c2);
1018
- text_diff(&c1, &c2, pOut, 4, 1);
1019
- blob_reset(&c1);
1020
- blob_reset(&c2);
1093
+ if( !sideBySide || isPatch ){
1094
+ content_get(v1, &c1);
1095
+ content_get(v2, &c2);
1096
+ text_diff(&c1, &c2, pOut, 4, 1);
1097
+ blob_reset(&c1);
1098
+ blob_reset(&c2);
1099
+ }
10211100
if( !isPatch ){
10221101
style_header("Diff");
10231102
style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
10241103
g.zTop, P("v1"), P("v2"));
1104
+ if( !sideBySide ){
1105
+ style_submenu_element("Side-by-side Diff", "sbsdiff",
1106
+ "%s/fdiff?v1=%T&v2=%T&sbs=1",
1107
+ g.zTop, P("v1"), P("v2"));
1108
+ }else{
1109
+ style_submenu_element("Unified Diff", "udiff",
1110
+ "%s/fdiff?v1=%T&v2=%T&sbs=0",
1111
+ g.zTop, P("v1"), P("v2"));
1112
+ }
1113
+
10251114
@ <h2>Differences From
10261115
@ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
10271116
object_description(v1, 0, 0);
10281117
@ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
10291118
object_description(v2, 0, 0);
10301119
@ <hr />
1031
- @ <blockquote><pre>
1032
- @ %h(blob_str(&diff))
1033
- @ </pre></blockquote>
1120
+ if( sideBySide ){
1121
+ generate_sbsdiff(zV1, zV2);
1122
+ }else{
1123
+ @ <blockquote><pre>
1124
+ @ %h(blob_str(&diff))
1125
+ @ </pre></blockquote>
1126
+ }
10341127
blob_reset(&diff);
10351128
style_footer();
10361129
}
10371130
}
10381131
@@ -1584,10 +1677,42 @@
15841677
@ value="%h(stdClrFound?"":zDefaultColor)" />
15851678
@ </td>
15861679
@ </tr>
15871680
@ </table>
15881681
}
1682
+
1683
+/*
1684
+** Do a comment comparison.
1685
+**
1686
+** + Leading and trailing whitespace are ignored.
1687
+** + \r\n characters compare equal to \n
1688
+**
1689
+** Return true if equal and false if not equal.
1690
+*/
1691
+static int comment_compare(const char *zA, const char *zB){
1692
+ if( zA==0 ) zA = "";
1693
+ if( zB==0 ) zB = "";
1694
+ while( fossil_isspace(zA[0]) ) zA++;
1695
+ while( fossil_isspace(zB[0]) ) zB++;
1696
+ while( zA[0] && zB[0] ){
1697
+ if( zA[0]==zB[0] ){ zA++; zB++; continue; }
1698
+ if( zA[0]=='\r' && zA[1]=='\n' && zB[0]=='\n' ){
1699
+ zA += 2;
1700
+ zB++;
1701
+ continue;
1702
+ }
1703
+ if( zB[0]=='\r' && zB[1]=='\n' && zA[0]=='\n' ){
1704
+ zB += 2;
1705
+ zA++;
1706
+ continue;
1707
+ }
1708
+ return 0;
1709
+ }
1710
+ while( fossil_isspace(zB[0]) ) zB++;
1711
+ while( fossil_isspace(zA[0]) ) zA++;
1712
+ return zA[0]==0 && zB[0]==0;
1713
+}
15891714
15901715
/*
15911716
** WEBPAGE: ci_edit
15921717
** URL: ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
15931718
**
@@ -1661,11 +1786,12 @@
16611786
blob_zero(&ctrl);
16621787
zNow = date_in_standard_format("now");
16631788
blob_appendf(&ctrl, "D %s\n", zNow);
16641789
db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
16651790
if( zNewColor[0]
1666
- && (fPropagateColor!=fNewPropagateColor || fossil_strcmp(zColor,zNewColor)!=0)
1791
+ && (fPropagateColor!=fNewPropagateColor
1792
+ || fossil_strcmp(zColor,zNewColor)!=0)
16671793
){
16681794
char *zPrefix = "+";
16691795
if( fNewPropagateColor ){
16701796
zPrefix = "*";
16711797
}
@@ -1673,11 +1799,11 @@
16731799
zPrefix, zNewColor);
16741800
}
16751801
if( zNewColor[0]==0 && zColor[0]!=0 ){
16761802
db_multi_exec("REPLACE INTO newtags VALUES('bgcolor','-',NULL)");
16771803
}
1678
- if( fossil_strcmp(zComment,zNewComment)!=0 ){
1804
+ if( comment_compare(zComment,zNewComment)==0 ){
16791805
db_multi_exec("REPLACE INTO newtags VALUES('comment','+',%Q)",
16801806
zNewComment);
16811807
}
16821808
if( fossil_strcmp(zDate,zNewDate)!=0 ){
16831809
db_multi_exec("REPLACE INTO newtags VALUES('date','+',%Q)",
16841810
--- src/info.c
+++ src/info.c
@@ -276,10 +276,40 @@
276 @ %h(blob_str(&out))
277 blob_reset(&from);
278 blob_reset(&to);
279 blob_reset(&out);
280 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
282 /*
283 ** Write a line of web-page output that shows changes that have occurred
284 ** to a file between two check-ins.
285 */
@@ -287,10 +317,11 @@
287 const char *zName, /* Name of the file that has changed */
288 const char *zOld, /* blob.uuid before change. NULL for added files */
289 const char *zNew, /* blob.uuid after change. NULL for deletes */
290 const char *zOldName, /* Prior name. NULL if no name change. */
291 int showDiff, /* Show edit diffs if true */
 
292 int mperm /* executable or symlink permission for zNew */
293 ){
294 if( !g.perm.History ){
295 if( zNew==0 ){
296 @ <p>Deleted %h(zName)</p>
@@ -303,13 +334,17 @@
303 @ for %h(zName)</p>
304 }else{
305 @ <p>Changes to %h(zName)</p>
306 }
307 if( showDiff ){
308 @ <blockquote><pre>
309 append_diff(zOld, zNew);
310 @ </pre></blockquote>
 
 
 
 
311 }
312 }else{
313 if( zOld && zNew ){
314 if( fossil_strcmp(zOld, zNew)!=0 ){
315 @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -329,13 +364,17 @@
329 }else{
330 @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
331 @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a>
332 }
333 if( showDiff ){
334 @ <blockquote><pre>
335 append_diff(zOld, zNew);
336 @ </pre></blockquote>
 
 
 
 
337 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
338 @ &nbsp;&nbsp;
339 @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&amp;v2=%S(zNew)">[diff]</a>
340 }
341 @ </p>
@@ -361,10 +400,11 @@
361 void ci_page(void){
362 Stmt q;
363 int rid;
364 int isLeaf;
365 int showDiff;
 
366 const char *zName; /* Name of the checkin to be displayed */
367 const char *zUuid; /* UUID of zName */
368 const char *zParent; /* UUID of the parent checkin (if any) */
369
370 login_check_credentials();
@@ -390,10 +430,11 @@
390 " FROM blob, event"
391 " WHERE blob.rid=%d"
392 " AND event.objid=%d",
393 rid, rid
394 );
 
395 if( db_step(&q)==SQLITE_ROW ){
396 const char *zUuid = db_column_text(&q, 0);
397 char *zTitle = mprintf("Check-in [%.10s]", zUuid);
398 char *zEUser, *zEComment;
399 const char *zUser;
@@ -467,11 +508,11 @@
467 }
468 if( !isLeaf ){
469 @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a>
470 }
471 if( zParent && !isLeaf ){
472 @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)&amp;p=%S(zUuid)">both</a>
473 }
474 db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
475 " WHERE rid=%d AND tagtype>0 "
476 " AND tag.tagid=tagxref.tagid "
477 " AND +tag.tagname GLOB 'sym-*'", rid);
@@ -506,27 +547,49 @@
506 }
507 db_finalize(&q);
508 showTags(rid, "");
509 if( zParent ){
510 @ <div class="section">Changes</div>
 
511 showDiff = g.zPath[0]!='c';
512 if( db_get_boolean("show-version-diffs", 0)==0 ){
513 showDiff = !showDiff;
514 if( showDiff ){
515 @ <a href="%s(g.zTop)/vinfo/%T(zName)">[hide&nbsp;diffs]</a>
 
 
 
 
 
 
 
 
516 }else{
517 @ <a href="%s(g.zTop)/ci/%T(zName)">[show&nbsp;diffs]</a>
 
 
 
518 }
519 }else{
520 if( showDiff ){
521 @ <a href="%s(g.zTop)/ci/%T(zName)">[hide&nbsp;diffs]</a>
 
 
 
 
 
 
 
522 }else{
523 @ <a href="%s(g.zTop)/vinfo/%T(zName)">[show&nbsp;diffs]</a>
 
 
 
524 }
525 }
526 @ &nbsp;&nbsp;
527 @ <a href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">[patch]</a><br/>
528 db_prepare(&q,
529 "SELECT name,"
530 " mperm,"
531 " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
532 " (SELECT uuid FROM blob WHERE rid=mlink.fid),"
@@ -540,11 +603,12 @@
540 const char *zName = db_column_text(&q,0);
541 int mperm = db_column_int(&q, 1);
542 const char *zOld = db_column_text(&q,2);
543 const char *zNew = db_column_text(&q,3);
544 const char *zOldName = db_column_text(&q, 4);
545 append_file_change_line(zName, zOld, zNew, zOldName, showDiff, mperm);
 
546 }
547 db_finalize(&q);
548 }
549 style_footer();
550 }
@@ -690,17 +754,18 @@
690 }
691
692
693 /*
694 ** WEBPAGE: vdiff
695 ** URL: /vdiff?from=UUID&amp;to=UUID&amp;detail=BOOLEAN
696 **
697 ** Show all differences between two checkins.
698 */
699 void vdiff_page(void){
700 int ridFrom, ridTo;
701 int showDetail = 0;
 
702 Manifest *pFrom, *pTo;
703 ManifestFile *pFileFrom, *pFileTo;
704
705 login_check_credentials();
706 if( !g.perm.Read ){ login_needed(); return; }
@@ -709,10 +774,20 @@
709 pFrom = vdiff_parse_manifest("from", &ridFrom);
710 if( pFrom==0 ) return;
711 pTo = vdiff_parse_manifest("to", &ridTo);
712 if( pTo==0 ) return;
713 showDetail = atoi(PD("detail","0"));
 
 
 
 
 
 
 
 
 
 
714 style_header("Check-in Differences");
715 @ <h2>Difference From:</h2><blockquote>
716 checkin_description(ridFrom);
717 @ </blockquote><h2>To:</h2><blockquote>
718 checkin_description(ridTo);
@@ -731,25 +806,25 @@
731 }else{
732 cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
733 }
734 if( cmp<0 ){
735 append_file_change_line(pFileFrom->zName,
736 pFileFrom->zUuid, 0, 0, 0, 0);
737 pFileFrom = manifest_file_next(pFrom, 0);
738 }else if( cmp>0 ){
739 append_file_change_line(pFileTo->zName,
740 0, pFileTo->zUuid, 0, 0,
741 manifest_file_mperm(pFileTo));
742 pFileTo = manifest_file_next(pTo, 0);
743 }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
744 /* No changes */
745 pFileFrom = manifest_file_next(pFrom, 0);
746 pFileTo = manifest_file_next(pTo, 0);
747 }else{
748 append_file_change_line(pFileFrom->zName,
749 pFileFrom->zUuid,
750 pFileTo->zUuid, 0, showDetail,
751 manifest_file_mperm(pFileTo));
752 pFileFrom = manifest_file_next(pFrom, 0);
753 pFileTo = manifest_file_next(pTo, 0);
754 }
755 }
@@ -797,11 +872,11 @@
797 " WHERE filename.fnid=mlink.fnid"
798 " AND event.objid=mlink.mid"
799 " AND a.rid=mlink.fid"
800 " AND b.rid=mlink.mid"
801 " AND mlink.fid=%d"
802 " ORDER BY filename.name, event.mtime",
803 TAG_BRANCH, rid
804 );
805 @ <ul>
806 while( db_step(&q)==SQLITE_ROW ){
807 const char *zName = db_column_text(&q, 0);
@@ -983,28 +1058,30 @@
983 }
984
985
986 /*
987 ** WEBPAGE: fdiff
988 ** URL: fdiff?v1=UUID&v2=UUID&patch
989 **
990 ** Two arguments, v1 and v2, identify the files to be diffed. Show the
991 ** difference between the two artifacts. Generate plaintext if "patch"
992 ** is present.
993 */
994 void diff_page(void){
995 int v1, v2;
996 int isPatch;
 
997 Blob c1, c2, diff, *pOut;
998 char *zV1;
999 char *zV2;
1000
1001 login_check_credentials();
1002 if( !g.perm.Read ){ login_needed(); return; }
1003 v1 = name_to_rid_www("v1");
1004 v2 = name_to_rid_www("v2");
1005 if( v1==0 || v2==0 ) fossil_redirect_home();
 
1006 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1007 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1008 isPatch = P("patch")!=0;
1009 if( isPatch ){
1010 pOut = cgi_output_blob();
@@ -1011,28 +1088,44 @@
1011 cgi_set_content_type("text/plain");
1012 }else{
1013 blob_zero(&diff);
1014 pOut = &diff;
1015 }
1016 content_get(v1, &c1);
1017 content_get(v2, &c2);
1018 text_diff(&c1, &c2, pOut, 4, 1);
1019 blob_reset(&c1);
1020 blob_reset(&c2);
 
 
1021 if( !isPatch ){
1022 style_header("Diff");
1023 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1024 g.zTop, P("v1"), P("v2"));
 
 
 
 
 
 
 
 
 
 
1025 @ <h2>Differences From
1026 @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
1027 object_description(v1, 0, 0);
1028 @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
1029 object_description(v2, 0, 0);
1030 @ <hr />
1031 @ <blockquote><pre>
1032 @ %h(blob_str(&diff))
1033 @ </pre></blockquote>
 
 
 
 
1034 blob_reset(&diff);
1035 style_footer();
1036 }
1037 }
1038
@@ -1584,10 +1677,42 @@
1584 @ value="%h(stdClrFound?"":zDefaultColor)" />
1585 @ </td>
1586 @ </tr>
1587 @ </table>
1588 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1589
1590 /*
1591 ** WEBPAGE: ci_edit
1592 ** URL: ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
1593 **
@@ -1661,11 +1786,12 @@
1661 blob_zero(&ctrl);
1662 zNow = date_in_standard_format("now");
1663 blob_appendf(&ctrl, "D %s\n", zNow);
1664 db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
1665 if( zNewColor[0]
1666 && (fPropagateColor!=fNewPropagateColor || fossil_strcmp(zColor,zNewColor)!=0)
 
1667 ){
1668 char *zPrefix = "+";
1669 if( fNewPropagateColor ){
1670 zPrefix = "*";
1671 }
@@ -1673,11 +1799,11 @@
1673 zPrefix, zNewColor);
1674 }
1675 if( zNewColor[0]==0 && zColor[0]!=0 ){
1676 db_multi_exec("REPLACE INTO newtags VALUES('bgcolor','-',NULL)");
1677 }
1678 if( fossil_strcmp(zComment,zNewComment)!=0 ){
1679 db_multi_exec("REPLACE INTO newtags VALUES('comment','+',%Q)",
1680 zNewComment);
1681 }
1682 if( fossil_strcmp(zDate,zNewDate)!=0 ){
1683 db_multi_exec("REPLACE INTO newtags VALUES('date','+',%Q)",
1684
--- src/info.c
+++ src/info.c
@@ -276,10 +276,40 @@
276 @ %h(blob_str(&out))
277 blob_reset(&from);
278 blob_reset(&to);
279 blob_reset(&out);
280 }
281
282
283 /*
284 ** Write the difference between two RIDs to the output
285 */
286 static void generate_sbsdiff(const char *zFrom, const char *zTo){
287 int fromid;
288 int toid;
289 Blob from, to;
290 if( zFrom ){
291 fromid = uuid_to_rid(zFrom, 0);
292 content_get(fromid, &from);
293 }else{
294 blob_zero(&from);
295 }
296 if( zTo ){
297 toid = uuid_to_rid(zTo, 0);
298 content_get(toid, &to);
299 }else{
300 blob_zero(&to);
301 }
302 @ <table class="sbsdiff">
303 @ <tr><th colspan="2" class="diffhdr">Old (%S(zFrom))</th><th/>
304 @ <th colspan="2" class="diffhdr">New (%S(zTo))</th></tr>
305 html_sbsdiff(&from, &to, 5, 1);
306 @ </table>
307 blob_reset(&from);
308 blob_reset(&to);
309 }
310
311
312 /*
313 ** Write a line of web-page output that shows changes that have occurred
314 ** to a file between two check-ins.
315 */
@@ -287,10 +317,11 @@
317 const char *zName, /* Name of the file that has changed */
318 const char *zOld, /* blob.uuid before change. NULL for added files */
319 const char *zNew, /* blob.uuid after change. NULL for deletes */
320 const char *zOldName, /* Prior name. NULL if no name change. */
321 int showDiff, /* Show edit diffs if true */
322 int sideBySide, /* Show diffs side-by-side */
323 int mperm /* executable or symlink permission for zNew */
324 ){
325 if( !g.perm.History ){
326 if( zNew==0 ){
327 @ <p>Deleted %h(zName)</p>
@@ -303,13 +334,17 @@
334 @ for %h(zName)</p>
335 }else{
336 @ <p>Changes to %h(zName)</p>
337 }
338 if( showDiff ){
339 if( sideBySide ){
340 generate_sbsdiff(zOld, zNew);
341 }else{
342 @ <blockquote><pre>
343 append_diff(zOld, zNew);
344 @ </pre></blockquote>
345 }
346 }
347 }else{
348 if( zOld && zNew ){
349 if( fossil_strcmp(zOld, zNew)!=0 ){
350 @ <p>Modified <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
@@ -329,13 +364,17 @@
364 }else{
365 @ <p>Added <a href="%s(g.zTop)/finfo?name=%T(zName)">%h(zName)</a>
366 @ version <a href="%s(g.zTop)/artifact/%s(zNew)">[%S(zNew)]</a>
367 }
368 if( showDiff ){
369 if( sideBySide ){
370 generate_sbsdiff(zOld, zNew);
371 }else{
372 @ <blockquote><pre>
373 append_diff(zOld, zNew);
374 @ </pre></blockquote>
375 }
376 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
377 @ &nbsp;&nbsp;
378 @ <a href="%s(g.zTop)/fdiff?v1=%S(zOld)&amp;v2=%S(zNew)">[diff]</a>
379 }
380 @ </p>
@@ -361,10 +400,11 @@
400 void ci_page(void){
401 Stmt q;
402 int rid;
403 int isLeaf;
404 int showDiff;
405 int sideBySide;
406 const char *zName; /* Name of the checkin to be displayed */
407 const char *zUuid; /* UUID of zName */
408 const char *zParent; /* UUID of the parent checkin (if any) */
409
410 login_check_credentials();
@@ -390,10 +430,11 @@
430 " FROM blob, event"
431 " WHERE blob.rid=%d"
432 " AND event.objid=%d",
433 rid, rid
434 );
435 sideBySide = atoi(PD("sbs","1"));
436 if( db_step(&q)==SQLITE_ROW ){
437 const char *zUuid = db_column_text(&q, 0);
438 char *zTitle = mprintf("Check-in [%.10s]", zUuid);
439 char *zEUser, *zEComment;
440 const char *zUser;
@@ -467,11 +508,11 @@
508 }
509 if( !isLeaf ){
510 @ | <a href="%s(g.zTop)/timeline?d=%S(zUuid)">descendants</a>
511 }
512 if( zParent && !isLeaf ){
513 @ | <a href="%s(g.zTop)/timeline?dp=%S(zUuid)">both</a>
514 }
515 db_prepare(&q, "SELECT substr(tag.tagname,5) FROM tagxref, tag "
516 " WHERE rid=%d AND tagtype>0 "
517 " AND tag.tagid=tagxref.tagid "
518 " AND +tag.tagname GLOB 'sym-*'", rid);
@@ -506,27 +547,49 @@
547 }
548 db_finalize(&q);
549 showTags(rid, "");
550 if( zParent ){
551 @ <div class="section">Changes</div>
552 @ <div class="sectionmenu">
553 showDiff = g.zPath[0]!='c';
554 if( db_get_boolean("show-version-diffs", 0)==0 ){
555 showDiff = !showDiff;
556 if( showDiff ){
557 @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)">
558 @ hide&nbsp;diffs</a>
559 if( sideBySide ){
560 @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0">
561 @ unified&nbsp;diffs</a>
562 }else{
563 @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1">
564 @ side-by-side&nbsp;diffs</a>
565 }
566 }else{
567 @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=0">
568 @ show&nbsp;unified&nbsp;diffs</a>
569 @ <a class="button" href="%s(g.zTop)/ci/%T(zName)?sbs=1">
570 @ show&nbsp;side-by-side&nbsp;diffs</a>
571 }
572 }else{
573 if( showDiff ){
574 @ <a class="button" href="%s(g.zTop)/ci/%T(zName)">hide&nbsp;diffs</a>
575 if( sideBySide ){
576 @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=0">
577 @ unified&nbsp;diffs</a>
578 }else{
579 @ <a class="button" href="%s(g.zTop)/info/%T(zName)?sbs=1">
580 @ side-by-side&nbsp;diffs</a>
581 }
582 }else{
583 @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=0">
584 @ show&nbsp;unified&nbsp;diffs</a>
585 @ <a class="button" href="%s(g.zTop)/vinfo/%T(zName)?sbs=1">
586 @ show&nbsp;side-by-side&nbsp;diffs</a>
587 }
588 }
589 @ <a class="button" href="%s(g.zTop)/vpatch?from=%S(zParent)&to=%S(zUuid)">
590 @ patch</a></div>
591 db_prepare(&q,
592 "SELECT name,"
593 " mperm,"
594 " (SELECT uuid FROM blob WHERE rid=mlink.pid),"
595 " (SELECT uuid FROM blob WHERE rid=mlink.fid),"
@@ -540,11 +603,12 @@
603 const char *zName = db_column_text(&q,0);
604 int mperm = db_column_int(&q, 1);
605 const char *zOld = db_column_text(&q,2);
606 const char *zNew = db_column_text(&q,3);
607 const char *zOldName = db_column_text(&q, 4);
608 append_file_change_line(zName, zOld, zNew, zOldName, showDiff,
609 sideBySide, mperm);
610 }
611 db_finalize(&q);
612 }
613 style_footer();
614 }
@@ -690,17 +754,18 @@
754 }
755
756
757 /*
758 ** WEBPAGE: vdiff
759 ** URL: /vdiff?from=UUID&amp;to=UUID&amp;detail=BOOLEAN;sbs=BOOLEAN
760 **
761 ** Show all differences between two checkins.
762 */
763 void vdiff_page(void){
764 int ridFrom, ridTo;
765 int showDetail = 0;
766 int sideBySide = 0;
767 Manifest *pFrom, *pTo;
768 ManifestFile *pFileFrom, *pFileTo;
769
770 login_check_credentials();
771 if( !g.perm.Read ){ login_needed(); return; }
@@ -709,10 +774,20 @@
774 pFrom = vdiff_parse_manifest("from", &ridFrom);
775 if( pFrom==0 ) return;
776 pTo = vdiff_parse_manifest("to", &ridTo);
777 if( pTo==0 ) return;
778 showDetail = atoi(PD("detail","0"));
779 sideBySide = atoi(PD("sbs","1"));
780 if( !sideBySide ){
781 style_submenu_element("Side-by-side Diff", "sbsdiff",
782 "%s/vdiff?from=%T&to=%T&detail=%d&sbs=1",
783 g.zTop, P("from"), P("to"), showDetail);
784 }else{
785 style_submenu_element("Unified Diff", "udiff",
786 "%s/vdiff?from=%T&to=%T&detail=%d&sbs=0",
787 g.zTop, P("from"), P("to"), showDetail);
788 }
789 style_header("Check-in Differences");
790 @ <h2>Difference From:</h2><blockquote>
791 checkin_description(ridFrom);
792 @ </blockquote><h2>To:</h2><blockquote>
793 checkin_description(ridTo);
@@ -731,25 +806,25 @@
806 }else{
807 cmp = fossil_strcmp(pFileFrom->zName, pFileTo->zName);
808 }
809 if( cmp<0 ){
810 append_file_change_line(pFileFrom->zName,
811 pFileFrom->zUuid, 0, 0, 0, 0, 0);
812 pFileFrom = manifest_file_next(pFrom, 0);
813 }else if( cmp>0 ){
814 append_file_change_line(pFileTo->zName,
815 0, pFileTo->zUuid, 0, 0, 0,
816 manifest_file_mperm(pFileTo));
817 pFileTo = manifest_file_next(pTo, 0);
818 }else if( fossil_strcmp(pFileFrom->zUuid, pFileTo->zUuid)==0 ){
819 /* No changes */
820 pFileFrom = manifest_file_next(pFrom, 0);
821 pFileTo = manifest_file_next(pTo, 0);
822 }else{
823 append_file_change_line(pFileFrom->zName,
824 pFileFrom->zUuid,
825 pFileTo->zUuid, 0, showDetail, sideBySide,
826 manifest_file_mperm(pFileTo));
827 pFileFrom = manifest_file_next(pFrom, 0);
828 pFileTo = manifest_file_next(pTo, 0);
829 }
830 }
@@ -797,11 +872,11 @@
872 " WHERE filename.fnid=mlink.fnid"
873 " AND event.objid=mlink.mid"
874 " AND a.rid=mlink.fid"
875 " AND b.rid=mlink.mid"
876 " AND mlink.fid=%d"
877 " ORDER BY filename.name, event.mtime /*sort*/",
878 TAG_BRANCH, rid
879 );
880 @ <ul>
881 while( db_step(&q)==SQLITE_ROW ){
882 const char *zName = db_column_text(&q, 0);
@@ -983,28 +1058,30 @@
1058 }
1059
1060
1061 /*
1062 ** WEBPAGE: fdiff
1063 ** URL: fdiff?v1=UUID&v2=UUID&patch&sbs=BOOLEAN
1064 **
1065 ** Two arguments, v1 and v2, identify the files to be diffed. Show the
1066 ** difference between the two artifacts. Show diff side by side unless sbs
1067 ** is 0. Generate plaintext if "patch" is present.
1068 */
1069 void diff_page(void){
1070 int v1, v2;
1071 int isPatch;
1072 int sideBySide;
1073 Blob c1, c2, diff, *pOut;
1074 char *zV1;
1075 char *zV2;
1076
1077 login_check_credentials();
1078 if( !g.perm.Read ){ login_needed(); return; }
1079 v1 = name_to_rid_www("v1");
1080 v2 = name_to_rid_www("v2");
1081 if( v1==0 || v2==0 ) fossil_redirect_home();
1082 sideBySide = atoi(PD("sbs","1"));
1083 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1084 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1085 isPatch = P("patch")!=0;
1086 if( isPatch ){
1087 pOut = cgi_output_blob();
@@ -1011,28 +1088,44 @@
1088 cgi_set_content_type("text/plain");
1089 }else{
1090 blob_zero(&diff);
1091 pOut = &diff;
1092 }
1093 if( !sideBySide || isPatch ){
1094 content_get(v1, &c1);
1095 content_get(v2, &c2);
1096 text_diff(&c1, &c2, pOut, 4, 1);
1097 blob_reset(&c1);
1098 blob_reset(&c2);
1099 }
1100 if( !isPatch ){
1101 style_header("Diff");
1102 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1103 g.zTop, P("v1"), P("v2"));
1104 if( !sideBySide ){
1105 style_submenu_element("Side-by-side Diff", "sbsdiff",
1106 "%s/fdiff?v1=%T&v2=%T&sbs=1",
1107 g.zTop, P("v1"), P("v2"));
1108 }else{
1109 style_submenu_element("Unified Diff", "udiff",
1110 "%s/fdiff?v1=%T&v2=%T&sbs=0",
1111 g.zTop, P("v1"), P("v2"));
1112 }
1113
1114 @ <h2>Differences From
1115 @ Artifact <a href="%s(g.zTop)/artifact/%S(zV1)">[%S(zV1)]</a>:</h2>
1116 object_description(v1, 0, 0);
1117 @ <h2>To Artifact <a href="%s(g.zTop)/artifact/%S(zV2)">[%S(zV2)]</a>:</h2>
1118 object_description(v2, 0, 0);
1119 @ <hr />
1120 if( sideBySide ){
1121 generate_sbsdiff(zV1, zV2);
1122 }else{
1123 @ <blockquote><pre>
1124 @ %h(blob_str(&diff))
1125 @ </pre></blockquote>
1126 }
1127 blob_reset(&diff);
1128 style_footer();
1129 }
1130 }
1131
@@ -1584,10 +1677,42 @@
1677 @ value="%h(stdClrFound?"":zDefaultColor)" />
1678 @ </td>
1679 @ </tr>
1680 @ </table>
1681 }
1682
1683 /*
1684 ** Do a comment comparison.
1685 **
1686 ** + Leading and trailing whitespace are ignored.
1687 ** + \r\n characters compare equal to \n
1688 **
1689 ** Return true if equal and false if not equal.
1690 */
1691 static int comment_compare(const char *zA, const char *zB){
1692 if( zA==0 ) zA = "";
1693 if( zB==0 ) zB = "";
1694 while( fossil_isspace(zA[0]) ) zA++;
1695 while( fossil_isspace(zB[0]) ) zB++;
1696 while( zA[0] && zB[0] ){
1697 if( zA[0]==zB[0] ){ zA++; zB++; continue; }
1698 if( zA[0]=='\r' && zA[1]=='\n' && zB[0]=='\n' ){
1699 zA += 2;
1700 zB++;
1701 continue;
1702 }
1703 if( zB[0]=='\r' && zB[1]=='\n' && zA[0]=='\n' ){
1704 zB += 2;
1705 zA++;
1706 continue;
1707 }
1708 return 0;
1709 }
1710 while( fossil_isspace(zB[0]) ) zB++;
1711 while( fossil_isspace(zA[0]) ) zA++;
1712 return zA[0]==0 && zB[0]==0;
1713 }
1714
1715 /*
1716 ** WEBPAGE: ci_edit
1717 ** URL: ci_edit?r=RID&c=NEWCOMMENT&u=NEWUSER
1718 **
@@ -1661,11 +1786,12 @@
1786 blob_zero(&ctrl);
1787 zNow = date_in_standard_format("now");
1788 blob_appendf(&ctrl, "D %s\n", zNow);
1789 db_multi_exec("CREATE TEMP TABLE newtags(tag UNIQUE, prefix, value)");
1790 if( zNewColor[0]
1791 && (fPropagateColor!=fNewPropagateColor
1792 || fossil_strcmp(zColor,zNewColor)!=0)
1793 ){
1794 char *zPrefix = "+";
1795 if( fNewPropagateColor ){
1796 zPrefix = "*";
1797 }
@@ -1673,11 +1799,11 @@
1799 zPrefix, zNewColor);
1800 }
1801 if( zNewColor[0]==0 && zColor[0]!=0 ){
1802 db_multi_exec("REPLACE INTO newtags VALUES('bgcolor','-',NULL)");
1803 }
1804 if( comment_compare(zComment,zNewComment)==0 ){
1805 db_multi_exec("REPLACE INTO newtags VALUES('comment','+',%Q)",
1806 zNewComment);
1807 }
1808 if( fossil_strcmp(zDate,zNewDate)!=0 ){
1809 db_multi_exec("REPLACE INTO newtags VALUES('date','+',%Q)",
1810
+33 -29
--- src/login.c
+++ src/login.c
@@ -91,11 +91,11 @@
9191
if( zCookieName==0 ){
9292
zCookieName = db_text(0,
9393
"SELECT 'fossil-' || substr(value,1,16)"
9494
" FROM config"
9595
" WHERE name IN ('project-code','login-group-code')"
96
- " ORDER BY name;"
96
+ " ORDER BY name /*sort*/"
9797
);
9898
}
9999
return zCookieName;
100100
}
101101
@@ -192,10 +192,37 @@
192192
"INSERT INTO accesslog(uname,ipaddr,success,mtime)"
193193
"VALUES(%Q,%Q,%d,julianday('now'));",
194194
zUsername, zIpAddr, bSuccess
195195
);
196196
}
197
+
198
+/*
199
+** SQL function for constant time comparison of two values.
200
+** Sets result to 0 if two values are equal.
201
+*/
202
+static void constant_time_cmp_function(
203
+ sqlite3_context *context,
204
+ int argc,
205
+ sqlite3_value **argv
206
+){
207
+ const unsigned char *buf1, *buf2;
208
+ int len, i;
209
+ unsigned char rc = 0;
210
+
211
+ assert( argc==2 );
212
+ len = sqlite3_value_bytes(argv[0]);
213
+ if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
214
+ rc = 1;
215
+ }else{
216
+ buf1 = sqlite3_value_text(argv[0]);
217
+ buf2 = sqlite3_value_text(argv[1]);
218
+ for( i=0; i<len; i++ ){
219
+ rc = rc | (buf1[i] ^ buf2[i]);
220
+ }
221
+ }
222
+ sqlite3_result_int(context, rc);
223
+}
197224
198225
/*
199226
** WEBPAGE: login
200227
** WEBPAGE: logout
201228
** WEBPAGE: my
@@ -217,20 +244,24 @@
217244
char *zSha1Pw;
218245
const char *zIpAddr; /* IP address of requestor */
219246
char *zRemoteAddr; /* Abbreviated IP address of requestor */
220247
221248
login_check_credentials();
249
+ sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
250
+ constant_time_cmp_function, 0, 0);
222251
zUsername = P("u");
223252
zPasswd = P("p");
224253
anonFlag = P("anon")!=0;
225254
if( P("out")!=0 ){
226255
/* To logout, change the cookie value to an empty string */
227256
const char *zCookieName = login_cookie_name();
228257
cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400);
229258
redirect_to_g();
230259
}
231
- if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
260
+ if( g.perm.Password && zPasswd
261
+ && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0
262
+ ){
232263
/* The user requests a password change */
233264
zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
234265
if( db_int(1, "SELECT 0 FROM user"
235266
" WHERE uid=%d"
236267
" AND (constant_time_cmp(pw,%Q)=0"
@@ -454,37 +485,10 @@
454485
@ </form>
455486
}
456487
style_footer();
457488
}
458489
459
-/*
460
-** SQL function for constant time comparison of two values.
461
-** Sets result to 0 if two values are equal.
462
-*/
463
-static void constant_time_cmp_function(
464
- sqlite3_context *context,
465
- int argc,
466
- sqlite3_value **argv
467
-){
468
- const unsigned char *buf1, *buf2;
469
- int len, i;
470
- unsigned char rc = 0;
471
-
472
- assert( argc==2 );
473
- len = sqlite3_value_bytes(argv[0]);
474
- if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
475
- rc = 1;
476
- }else{
477
- buf1 = sqlite3_value_text(argv[0]);
478
- buf2 = sqlite3_value_text(argv[1]);
479
- for( i=0; i<len; i++ ){
480
- rc = rc | (buf1[i] ^ buf2[i]);
481
- }
482
- }
483
- sqlite3_result_int(context, rc);
484
-}
485
-
486490
/*
487491
** Attempt to find login credentials for user zLogin on a peer repository
488492
** with project code zCode. Transfer those credentials to the local
489493
** repository.
490494
**
491495
--- src/login.c
+++ src/login.c
@@ -91,11 +91,11 @@
91 if( zCookieName==0 ){
92 zCookieName = db_text(0,
93 "SELECT 'fossil-' || substr(value,1,16)"
94 " FROM config"
95 " WHERE name IN ('project-code','login-group-code')"
96 " ORDER BY name;"
97 );
98 }
99 return zCookieName;
100 }
101
@@ -192,10 +192,37 @@
192 "INSERT INTO accesslog(uname,ipaddr,success,mtime)"
193 "VALUES(%Q,%Q,%d,julianday('now'));",
194 zUsername, zIpAddr, bSuccess
195 );
196 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
197
198 /*
199 ** WEBPAGE: login
200 ** WEBPAGE: logout
201 ** WEBPAGE: my
@@ -217,20 +244,24 @@
217 char *zSha1Pw;
218 const char *zIpAddr; /* IP address of requestor */
219 char *zRemoteAddr; /* Abbreviated IP address of requestor */
220
221 login_check_credentials();
 
 
222 zUsername = P("u");
223 zPasswd = P("p");
224 anonFlag = P("anon")!=0;
225 if( P("out")!=0 ){
226 /* To logout, change the cookie value to an empty string */
227 const char *zCookieName = login_cookie_name();
228 cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400);
229 redirect_to_g();
230 }
231 if( g.perm.Password && zPasswd && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0 ){
 
 
232 /* The user requests a password change */
233 zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
234 if( db_int(1, "SELECT 0 FROM user"
235 " WHERE uid=%d"
236 " AND (constant_time_cmp(pw,%Q)=0"
@@ -454,37 +485,10 @@
454 @ </form>
455 }
456 style_footer();
457 }
458
459 /*
460 ** SQL function for constant time comparison of two values.
461 ** Sets result to 0 if two values are equal.
462 */
463 static void constant_time_cmp_function(
464 sqlite3_context *context,
465 int argc,
466 sqlite3_value **argv
467 ){
468 const unsigned char *buf1, *buf2;
469 int len, i;
470 unsigned char rc = 0;
471
472 assert( argc==2 );
473 len = sqlite3_value_bytes(argv[0]);
474 if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
475 rc = 1;
476 }else{
477 buf1 = sqlite3_value_text(argv[0]);
478 buf2 = sqlite3_value_text(argv[1]);
479 for( i=0; i<len; i++ ){
480 rc = rc | (buf1[i] ^ buf2[i]);
481 }
482 }
483 sqlite3_result_int(context, rc);
484 }
485
486 /*
487 ** Attempt to find login credentials for user zLogin on a peer repository
488 ** with project code zCode. Transfer those credentials to the local
489 ** repository.
490 **
491
--- src/login.c
+++ src/login.c
@@ -91,11 +91,11 @@
91 if( zCookieName==0 ){
92 zCookieName = db_text(0,
93 "SELECT 'fossil-' || substr(value,1,16)"
94 " FROM config"
95 " WHERE name IN ('project-code','login-group-code')"
96 " ORDER BY name /*sort*/"
97 );
98 }
99 return zCookieName;
100 }
101
@@ -192,10 +192,37 @@
192 "INSERT INTO accesslog(uname,ipaddr,success,mtime)"
193 "VALUES(%Q,%Q,%d,julianday('now'));",
194 zUsername, zIpAddr, bSuccess
195 );
196 }
197
198 /*
199 ** SQL function for constant time comparison of two values.
200 ** Sets result to 0 if two values are equal.
201 */
202 static void constant_time_cmp_function(
203 sqlite3_context *context,
204 int argc,
205 sqlite3_value **argv
206 ){
207 const unsigned char *buf1, *buf2;
208 int len, i;
209 unsigned char rc = 0;
210
211 assert( argc==2 );
212 len = sqlite3_value_bytes(argv[0]);
213 if( len==0 || len!=sqlite3_value_bytes(argv[1]) ){
214 rc = 1;
215 }else{
216 buf1 = sqlite3_value_text(argv[0]);
217 buf2 = sqlite3_value_text(argv[1]);
218 for( i=0; i<len; i++ ){
219 rc = rc | (buf1[i] ^ buf2[i]);
220 }
221 }
222 sqlite3_result_int(context, rc);
223 }
224
225 /*
226 ** WEBPAGE: login
227 ** WEBPAGE: logout
228 ** WEBPAGE: my
@@ -217,20 +244,24 @@
244 char *zSha1Pw;
245 const char *zIpAddr; /* IP address of requestor */
246 char *zRemoteAddr; /* Abbreviated IP address of requestor */
247
248 login_check_credentials();
249 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
250 constant_time_cmp_function, 0, 0);
251 zUsername = P("u");
252 zPasswd = P("p");
253 anonFlag = P("anon")!=0;
254 if( P("out")!=0 ){
255 /* To logout, change the cookie value to an empty string */
256 const char *zCookieName = login_cookie_name();
257 cgi_set_cookie(zCookieName, "", login_cookie_path(), -86400);
258 redirect_to_g();
259 }
260 if( g.perm.Password && zPasswd
261 && (zNew1 = P("n1"))!=0 && (zNew2 = P("n2"))!=0
262 ){
263 /* The user requests a password change */
264 zSha1Pw = sha1_shared_secret(zPasswd, g.zLogin, 0);
265 if( db_int(1, "SELECT 0 FROM user"
266 " WHERE uid=%d"
267 " AND (constant_time_cmp(pw,%Q)=0"
@@ -454,37 +485,10 @@
485 @ </form>
486 }
487 style_footer();
488 }
489
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490 /*
491 ** Attempt to find login credentials for user zLogin on a peer repository
492 ** with project code zCode. Transfer those credentials to the local
493 ** repository.
494 **
495
+23 -6
--- src/main.c
+++ src/main.c
@@ -249,11 +249,12 @@
249249
unsigned int nLine; /* Number of lines in the file*/
250250
unsigned int i, j, k; /* Loop counters */
251251
int n; /* Number of bytes in one line */
252252
char *z; /* General use string pointer */
253253
char **newArgv; /* New expanded g.argv under construction */
254
-
254
+ char const * zFileName; /* input file name */
255
+ FILE * zInFile; /* input FILE */
255256
for(i=1; i<g.argc-1; i++){
256257
z = g.argv[i];
257258
if( z[0]!='-' ) continue;
258259
z++;
259260
if( z[0]=='-' ) z++;
@@ -260,11 +261,23 @@
260261
if( z[0]==0 ) return; /* Stop searching at "--" */
261262
if( fossil_strcmp(z, "args")==0 ) break;
262263
}
263264
if( i>=g.argc-1 ) return;
264265
265
- blob_read_from_file(&file, g.argv[i+1]);
266
+ zFileName = g.argv[i+1];
267
+ zInFile = (0==strcmp("-",zFileName))
268
+ ? stdin
269
+ : fopen(zFileName,"rb");
270
+ if(!zInFile){
271
+ fossil_panic("Cannot open -args file [%s]", zFileName);
272
+ }else{
273
+ blob_read_from_channel(&file, zInFile, -1);
274
+ if(stdin != zInFile){
275
+ fclose(zInFile);
276
+ }
277
+ zInFile = NULL;
278
+ }
266279
z = blob_str(&file);
267280
for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
268281
newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
269282
for(j=0; j<i; j++) newArgv[j] = g.argv[j];
270283
@@ -271,10 +284,14 @@
271284
blob_rewind(&file);
272285
while( (n = blob_line(&file, &line))>0 ){
273286
if( n<=1 ) continue;
274287
z = blob_buffer(&line);
275288
z[n-1] = 0;
289
+ if((n>1) && ('\r'==z[n-2])){
290
+ if(n==2) continue /*empty line*/;
291
+ z[n-2] = 0;
292
+ }
276293
newArgv[j++] = z;
277294
if( z[0]=='-' ){
278295
for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
279296
if( z[k] ){
280297
z[k] = 0;
@@ -383,20 +400,20 @@
383400
}
384401
385402
/*
386403
** Exit. Take care to close the database first.
387404
*/
388
-void fossil_exit(int rc){
405
+NORETURN void fossil_exit(int rc){
389406
db_close(1);
390407
exit(rc);
391408
}
392409
393410
/*
394411
** Print an error message, rollback all databases, and quit. These
395412
** routines never return.
396413
*/
397
-void fossil_panic(const char *zFormat, ...){
414
+NORETURN void fossil_panic(const char *zFormat, ...){
398415
char *z;
399416
va_list ap;
400417
static int once = 1;
401418
mainInFatalError = 1;
402419
va_start(ap, zFormat);
@@ -411,11 +428,11 @@
411428
fossil_puts(zOut, 1);
412429
}
413430
db_force_rollback();
414431
fossil_exit(1);
415432
}
416
-void fossil_fatal(const char *zFormat, ...){
433
+NORETURN void fossil_fatal(const char *zFormat, ...){
417434
char *z;
418435
va_list ap;
419436
mainInFatalError = 1;
420437
va_start(ap, zFormat);
421438
z = vmprintf(zFormat, ap);
@@ -899,11 +916,11 @@
899916
}
900917
901918
/*
902919
** Send an HTTP redirect back to the designated Index Page.
903920
*/
904
-void fossil_redirect_home(void){
921
+NORETURN void fossil_redirect_home(void){
905922
cgi_redirectf("%s%s", g.zTop, db_get("index-page", "/index"));
906923
}
907924
908925
/*
909926
** If running as root, chroot to the directory containing the
910927
--- src/main.c
+++ src/main.c
@@ -249,11 +249,12 @@
249 unsigned int nLine; /* Number of lines in the file*/
250 unsigned int i, j, k; /* Loop counters */
251 int n; /* Number of bytes in one line */
252 char *z; /* General use string pointer */
253 char **newArgv; /* New expanded g.argv under construction */
254
 
255 for(i=1; i<g.argc-1; i++){
256 z = g.argv[i];
257 if( z[0]!='-' ) continue;
258 z++;
259 if( z[0]=='-' ) z++;
@@ -260,11 +261,23 @@
260 if( z[0]==0 ) return; /* Stop searching at "--" */
261 if( fossil_strcmp(z, "args")==0 ) break;
262 }
263 if( i>=g.argc-1 ) return;
264
265 blob_read_from_file(&file, g.argv[i+1]);
 
 
 
 
 
 
 
 
 
 
 
 
266 z = blob_str(&file);
267 for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
268 newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
269 for(j=0; j<i; j++) newArgv[j] = g.argv[j];
270
@@ -271,10 +284,14 @@
271 blob_rewind(&file);
272 while( (n = blob_line(&file, &line))>0 ){
273 if( n<=1 ) continue;
274 z = blob_buffer(&line);
275 z[n-1] = 0;
 
 
 
 
276 newArgv[j++] = z;
277 if( z[0]=='-' ){
278 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
279 if( z[k] ){
280 z[k] = 0;
@@ -383,20 +400,20 @@
383 }
384
385 /*
386 ** Exit. Take care to close the database first.
387 */
388 void fossil_exit(int rc){
389 db_close(1);
390 exit(rc);
391 }
392
393 /*
394 ** Print an error message, rollback all databases, and quit. These
395 ** routines never return.
396 */
397 void fossil_panic(const char *zFormat, ...){
398 char *z;
399 va_list ap;
400 static int once = 1;
401 mainInFatalError = 1;
402 va_start(ap, zFormat);
@@ -411,11 +428,11 @@
411 fossil_puts(zOut, 1);
412 }
413 db_force_rollback();
414 fossil_exit(1);
415 }
416 void fossil_fatal(const char *zFormat, ...){
417 char *z;
418 va_list ap;
419 mainInFatalError = 1;
420 va_start(ap, zFormat);
421 z = vmprintf(zFormat, ap);
@@ -899,11 +916,11 @@
899 }
900
901 /*
902 ** Send an HTTP redirect back to the designated Index Page.
903 */
904 void fossil_redirect_home(void){
905 cgi_redirectf("%s%s", g.zTop, db_get("index-page", "/index"));
906 }
907
908 /*
909 ** If running as root, chroot to the directory containing the
910
--- src/main.c
+++ src/main.c
@@ -249,11 +249,12 @@
249 unsigned int nLine; /* Number of lines in the file*/
250 unsigned int i, j, k; /* Loop counters */
251 int n; /* Number of bytes in one line */
252 char *z; /* General use string pointer */
253 char **newArgv; /* New expanded g.argv under construction */
254 char const * zFileName; /* input file name */
255 FILE * zInFile; /* input FILE */
256 for(i=1; i<g.argc-1; i++){
257 z = g.argv[i];
258 if( z[0]!='-' ) continue;
259 z++;
260 if( z[0]=='-' ) z++;
@@ -260,11 +261,23 @@
261 if( z[0]==0 ) return; /* Stop searching at "--" */
262 if( fossil_strcmp(z, "args")==0 ) break;
263 }
264 if( i>=g.argc-1 ) return;
265
266 zFileName = g.argv[i+1];
267 zInFile = (0==strcmp("-",zFileName))
268 ? stdin
269 : fopen(zFileName,"rb");
270 if(!zInFile){
271 fossil_panic("Cannot open -args file [%s]", zFileName);
272 }else{
273 blob_read_from_channel(&file, zInFile, -1);
274 if(stdin != zInFile){
275 fclose(zInFile);
276 }
277 zInFile = NULL;
278 }
279 z = blob_str(&file);
280 for(k=0, nLine=1; z[k]; k++) if( z[k]=='\n' ) nLine++;
281 newArgv = fossil_malloc( sizeof(char*)*(g.argc + nLine*2) );
282 for(j=0; j<i; j++) newArgv[j] = g.argv[j];
283
@@ -271,10 +284,14 @@
284 blob_rewind(&file);
285 while( (n = blob_line(&file, &line))>0 ){
286 if( n<=1 ) continue;
287 z = blob_buffer(&line);
288 z[n-1] = 0;
289 if((n>1) && ('\r'==z[n-2])){
290 if(n==2) continue /*empty line*/;
291 z[n-2] = 0;
292 }
293 newArgv[j++] = z;
294 if( z[0]=='-' ){
295 for(k=1; z[k] && !fossil_isspace(z[k]); k++){}
296 if( z[k] ){
297 z[k] = 0;
@@ -383,20 +400,20 @@
400 }
401
402 /*
403 ** Exit. Take care to close the database first.
404 */
405 NORETURN void fossil_exit(int rc){
406 db_close(1);
407 exit(rc);
408 }
409
410 /*
411 ** Print an error message, rollback all databases, and quit. These
412 ** routines never return.
413 */
414 NORETURN void fossil_panic(const char *zFormat, ...){
415 char *z;
416 va_list ap;
417 static int once = 1;
418 mainInFatalError = 1;
419 va_start(ap, zFormat);
@@ -411,11 +428,11 @@
428 fossil_puts(zOut, 1);
429 }
430 db_force_rollback();
431 fossil_exit(1);
432 }
433 NORETURN void fossil_fatal(const char *zFormat, ...){
434 char *z;
435 va_list ap;
436 mainInFatalError = 1;
437 va_start(ap, zFormat);
438 z = vmprintf(zFormat, ap);
@@ -899,11 +916,11 @@
916 }
917
918 /*
919 ** Send an HTTP redirect back to the designated Index Page.
920 */
921 NORETURN void fossil_redirect_home(void){
922 cgi_redirectf("%s%s", g.zTop, db_get("index-page", "/index"));
923 }
924
925 /*
926 ** If running as root, chroot to the directory containing the
927
+2 -2
--- src/main.mk
+++ src/main.mk
@@ -287,12 +287,12 @@
287287
$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
288288
289289
# WARNING. DANGER. Running the testsuite modifies the repository the
290290
# build is done from, i.e. the checkout belongs to. Do not sync/push
291291
# the repository after running the tests.
292
-test: $(APPNAME)
293
- $(TCLSH) test/tester.tcl $(APPNAME)
292
+test: $(OBJDIR) $(APPNAME)
293
+ $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
294294
295295
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
296296
$(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
297297
298298
# The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
299299
--- src/main.mk
+++ src/main.mk
@@ -287,12 +287,12 @@
287 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
288
289 # WARNING. DANGER. Running the testsuite modifies the repository the
290 # build is done from, i.e. the checkout belongs to. Do not sync/push
291 # the repository after running the tests.
292 test: $(APPNAME)
293 $(TCLSH) test/tester.tcl $(APPNAME)
294
295 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
296 $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
297
298 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
299
--- src/main.mk
+++ src/main.mk
@@ -287,12 +287,12 @@
287 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
288
289 # WARNING. DANGER. Running the testsuite modifies the repository the
290 # build is done from, i.e. the checkout belongs to. Do not sync/push
291 # the repository after running the tests.
292 test: $(OBJDIR) $(APPNAME)
293 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
294
295 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
296 $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
297
298 # The USE_SYSTEM_SQLITE variable may be undefined, set to 0, or set
299
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -182,12 +182,12 @@
182182
$(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
183183
184184
# WARNING. DANGER. Running the testsuite modifies the repository the
185185
# build is done from, i.e. the checkout belongs to. Do not sync/push
186186
# the repository after running the tests.
187
-test: $(APPNAME)
188
- $(TCLSH) test/tester.tcl $(APPNAME)
187
+test: $(OBJDIR) $(APPNAME)
188
+ $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
189189
190190
$(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
191191
$(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \
192192
$(SRCDIR)/../manifest \
193193
$(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
194194
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -182,12 +182,12 @@
182 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
183
184 # WARNING. DANGER. Running the testsuite modifies the repository the
185 # build is done from, i.e. the checkout belongs to. Do not sync/push
186 # the repository after running the tests.
187 test: $(APPNAME)
188 $(TCLSH) test/tester.tcl $(APPNAME)
189
190 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
191 $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \
192 $(SRCDIR)/../manifest \
193 $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
194
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -182,12 +182,12 @@
182 $(BCC) -o $(OBJDIR)/mkversion $(SRCDIR)/mkversion.c
183
184 # WARNING. DANGER. Running the testsuite modifies the repository the
185 # build is done from, i.e. the checkout belongs to. Do not sync/push
186 # the repository after running the tests.
187 test: $(OBJDIR) $(APPNAME)
188 $(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)
189
190 $(OBJDIR)/VERSION.h: $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION $(OBJDIR)/mkversion
191 $(OBJDIR)/mkversion $(SRCDIR)/../manifest.uuid \
192 $(SRCDIR)/../manifest \
193 $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h
194
--- src/manifest.c
+++ src/manifest.c
@@ -1819,10 +1819,48 @@
18191819
"VALUES('t',%.17g,%d,%Q,%Q)",
18201820
p->rDate, rid, p->zUser, zComment
18211821
);
18221822
free(zComment);
18231823
}
1824
+ }
1825
+ if( p->type==CFTYPE_CONTROL ){
1826
+ Blob comment;
1827
+ int i;
1828
+ const char *zName;
1829
+ const char *zValue;
1830
+ const char *zUuid;
1831
+ blob_zero(&comment);
1832
+ for(i=0; i<p->nTag; i++){
1833
+ zUuid = p->aTag[i].zUuid;
1834
+ if( i==0 || fossil_strcmp(zUuid, p->aTag[i-1].zUuid)!=0 ){
1835
+ if( i>0 ) blob_append(&comment, " ", 1);
1836
+ blob_appendf(&comment, "Tag changes on [/timeline?dp=%S&n=4 | %S]:",
1837
+ zUuid, zUuid);
1838
+ }
1839
+ zName = p->aTag[i].zName;
1840
+ zValue = p->aTag[i].zValue;
1841
+ if( zName[0]=='-' ){
1842
+ blob_appendf(&comment, " Cancel");
1843
+ }else if( zName[0]=='+' ){
1844
+ blob_appendf(&comment, " Add");
1845
+ }else{
1846
+ blob_appendf(&comment, " Add propagating");
1847
+ }
1848
+ if( memcmp(&zName[1], "sym-",4)==0 ){
1849
+ blob_appendf(&comment, " symbolic tag \"%h\".", &zName[5]);
1850
+ }else if( fossil_strcmp(&zName[1], "comment")!=0 && zValue && zValue[0] ){
1851
+ blob_appendf(&comment, " %h=%h.", &zName[1], zValue);
1852
+ }else{
1853
+ blob_appendf(&comment, " %h.", &zName[1]);
1854
+ }
1855
+ }
1856
+ db_multi_exec(
1857
+ "REPLACE INTO event(type,mtime,objid,user,comment)"
1858
+ "VALUES('g',%.17g,%d,%Q,%Q)",
1859
+ p->rDate, rid, p->zUser, blob_str(&comment)
1860
+ );
1861
+ blob_reset(&comment);
18241862
}
18251863
db_end_transaction(0);
18261864
if( p->type==CFTYPE_MANIFEST ){
18271865
manifest_cache_insert(p);
18281866
}else{
18291867
--- src/manifest.c
+++ src/manifest.c
@@ -1819,10 +1819,48 @@
1819 "VALUES('t',%.17g,%d,%Q,%Q)",
1820 p->rDate, rid, p->zUser, zComment
1821 );
1822 free(zComment);
1823 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1824 }
1825 db_end_transaction(0);
1826 if( p->type==CFTYPE_MANIFEST ){
1827 manifest_cache_insert(p);
1828 }else{
1829
--- src/manifest.c
+++ src/manifest.c
@@ -1819,10 +1819,48 @@
1819 "VALUES('t',%.17g,%d,%Q,%Q)",
1820 p->rDate, rid, p->zUser, zComment
1821 );
1822 free(zComment);
1823 }
1824 }
1825 if( p->type==CFTYPE_CONTROL ){
1826 Blob comment;
1827 int i;
1828 const char *zName;
1829 const char *zValue;
1830 const char *zUuid;
1831 blob_zero(&comment);
1832 for(i=0; i<p->nTag; i++){
1833 zUuid = p->aTag[i].zUuid;
1834 if( i==0 || fossil_strcmp(zUuid, p->aTag[i-1].zUuid)!=0 ){
1835 if( i>0 ) blob_append(&comment, " ", 1);
1836 blob_appendf(&comment, "Tag changes on [/timeline?dp=%S&n=4 | %S]:",
1837 zUuid, zUuid);
1838 }
1839 zName = p->aTag[i].zName;
1840 zValue = p->aTag[i].zValue;
1841 if( zName[0]=='-' ){
1842 blob_appendf(&comment, " Cancel");
1843 }else if( zName[0]=='+' ){
1844 blob_appendf(&comment, " Add");
1845 }else{
1846 blob_appendf(&comment, " Add propagating");
1847 }
1848 if( memcmp(&zName[1], "sym-",4)==0 ){
1849 blob_appendf(&comment, " symbolic tag \"%h\".", &zName[5]);
1850 }else if( fossil_strcmp(&zName[1], "comment")!=0 && zValue && zValue[0] ){
1851 blob_appendf(&comment, " %h=%h.", &zName[1], zValue);
1852 }else{
1853 blob_appendf(&comment, " %h.", &zName[1]);
1854 }
1855 }
1856 db_multi_exec(
1857 "REPLACE INTO event(type,mtime,objid,user,comment)"
1858 "VALUES('g',%.17g,%d,%Q,%Q)",
1859 p->rDate, rid, p->zUser, blob_str(&comment)
1860 );
1861 blob_reset(&comment);
1862 }
1863 db_end_transaction(0);
1864 if( p->type==CFTYPE_MANIFEST ){
1865 manifest_cache_insert(p);
1866 }else{
1867
+18 -4
--- src/merge.c
+++ src/merge.c
@@ -73,10 +73,11 @@
7373
int debugFlag; /* True if --debug is present */
7474
int nChng; /* Number of file name changes */
7575
int *aChng; /* An array of file name changes */
7676
int i; /* Loop counter */
7777
int nConflict = 0; /* Number of conflicts seen */
78
+ int nOverwrite = 0; /* Number of unmanaged files overwritten */
7879
int caseSensitive; /* True for case-sensitive filenames */
7980
Stmt q;
8081
8182
8283
/* Notation:
@@ -319,19 +320,27 @@
319320
while( db_step(&q)==SQLITE_ROW ){
320321
int idm = db_column_int(&q, 0);
321322
int rowid = db_column_int(&q, 1);
322323
int idv;
323324
const char *zName;
325
+ char *zFullName;
324326
db_multi_exec(
325327
"INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
326328
" SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
327329
vid, idm
328330
);
329331
idv = db_last_insert_rowid();
330332
db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
331333
zName = db_column_text(&q, 2);
332
- fossil_print("ADDED %s\n", zName);
334
+ zFullName = mprintf("%s%s", g.zLocalRoot, zName);
335
+ if( file_wd_isfile_or_link(zFullName) ){
336
+ fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName);
337
+ nOverwrite++;
338
+ }else{
339
+ fossil_print("ADDED %s\n", zName);
340
+ }
341
+ fossil_free(zFullName);
333342
if( !nochangeFlag ){
334343
undo_save(zName);
335344
vfile_to_disk(0, idm, 0, 0);
336345
}
337346
}
@@ -495,13 +504,18 @@
495504
db_finalize(&q);
496505
497506
498507
/* Report on conflicts
499508
*/
500
- if( nConflict && !nochangeFlag ){
501
- fossil_warning(
502
- "WARNING: merge conflicts - see messages above for details.\n");
509
+ if( !nochangeFlag ){
510
+ if( nConflict ){
511
+ fossil_print("WARNING: %d merge conflicts", nConflict);
512
+ }
513
+ if( nOverwrite ){
514
+ fossil_warning("WARNING: %d unmanaged files were overwritten",
515
+ nOverwrite);
516
+ }
503517
}
504518
505519
/*
506520
** Clean up the mid and pid VFILE entries. Then commit the changes.
507521
*/
508522
--- src/merge.c
+++ src/merge.c
@@ -73,10 +73,11 @@
73 int debugFlag; /* True if --debug is present */
74 int nChng; /* Number of file name changes */
75 int *aChng; /* An array of file name changes */
76 int i; /* Loop counter */
77 int nConflict = 0; /* Number of conflicts seen */
 
78 int caseSensitive; /* True for case-sensitive filenames */
79 Stmt q;
80
81
82 /* Notation:
@@ -319,19 +320,27 @@
319 while( db_step(&q)==SQLITE_ROW ){
320 int idm = db_column_int(&q, 0);
321 int rowid = db_column_int(&q, 1);
322 int idv;
323 const char *zName;
 
324 db_multi_exec(
325 "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
326 " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
327 vid, idm
328 );
329 idv = db_last_insert_rowid();
330 db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
331 zName = db_column_text(&q, 2);
332 fossil_print("ADDED %s\n", zName);
 
 
 
 
 
 
 
333 if( !nochangeFlag ){
334 undo_save(zName);
335 vfile_to_disk(0, idm, 0, 0);
336 }
337 }
@@ -495,13 +504,18 @@
495 db_finalize(&q);
496
497
498 /* Report on conflicts
499 */
500 if( nConflict && !nochangeFlag ){
501 fossil_warning(
502 "WARNING: merge conflicts - see messages above for details.\n");
 
 
 
 
 
503 }
504
505 /*
506 ** Clean up the mid and pid VFILE entries. Then commit the changes.
507 */
508
--- src/merge.c
+++ src/merge.c
@@ -73,10 +73,11 @@
73 int debugFlag; /* True if --debug is present */
74 int nChng; /* Number of file name changes */
75 int *aChng; /* An array of file name changes */
76 int i; /* Loop counter */
77 int nConflict = 0; /* Number of conflicts seen */
78 int nOverwrite = 0; /* Number of unmanaged files overwritten */
79 int caseSensitive; /* True for case-sensitive filenames */
80 Stmt q;
81
82
83 /* Notation:
@@ -319,19 +320,27 @@
320 while( db_step(&q)==SQLITE_ROW ){
321 int idm = db_column_int(&q, 0);
322 int rowid = db_column_int(&q, 1);
323 int idv;
324 const char *zName;
325 char *zFullName;
326 db_multi_exec(
327 "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
328 " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
329 vid, idm
330 );
331 idv = db_last_insert_rowid();
332 db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
333 zName = db_column_text(&q, 2);
334 zFullName = mprintf("%s%s", g.zLocalRoot, zName);
335 if( file_wd_isfile_or_link(zFullName) ){
336 fossil_print("ADDED %s (overwrites an unmanaged file)\n", zName);
337 nOverwrite++;
338 }else{
339 fossil_print("ADDED %s\n", zName);
340 }
341 fossil_free(zFullName);
342 if( !nochangeFlag ){
343 undo_save(zName);
344 vfile_to_disk(0, idm, 0, 0);
345 }
346 }
@@ -495,13 +504,18 @@
504 db_finalize(&q);
505
506
507 /* Report on conflicts
508 */
509 if( !nochangeFlag ){
510 if( nConflict ){
511 fossil_print("WARNING: %d merge conflicts", nConflict);
512 }
513 if( nOverwrite ){
514 fossil_warning("WARNING: %d unmanaged files were overwritten",
515 nOverwrite);
516 }
517 }
518
519 /*
520 ** Clean up the mid and pid VFILE entries. Then commit the changes.
521 */
522
+2 -2
--- src/name.c
+++ src/name.c
@@ -154,11 +154,11 @@
154154
" WHERE tag.tagname='sym-%q' "
155155
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
156156
" AND event.objid=tagxref.rid "
157157
" AND blob.rid=event.objid "
158158
" AND event.type GLOB '%q'"
159
- " ORDER BY event.mtime DESC ",
159
+ " ORDER BY event.mtime DESC /*sort*/",
160160
zTag, zType
161161
);
162162
if( zUuid==0 ){
163163
int nTag = strlen(zTag);
164164
int i;
@@ -180,11 +180,11 @@
180180
" AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
181181
" AND event.objid=tagxref.rid "
182182
" AND blob.rid=event.objid "
183183
" AND event.mtime<=julianday(%Q %s)"
184184
" AND event.type GLOB '%q'"
185
- " ORDER BY event.mtime DESC ",
185
+ " ORDER BY event.mtime DESC /*sort*/ ",
186186
zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType
187187
);
188188
break;
189189
}
190190
}
191191
--- src/name.c
+++ src/name.c
@@ -154,11 +154,11 @@
154 " WHERE tag.tagname='sym-%q' "
155 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
156 " AND event.objid=tagxref.rid "
157 " AND blob.rid=event.objid "
158 " AND event.type GLOB '%q'"
159 " ORDER BY event.mtime DESC ",
160 zTag, zType
161 );
162 if( zUuid==0 ){
163 int nTag = strlen(zTag);
164 int i;
@@ -180,11 +180,11 @@
180 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
181 " AND event.objid=tagxref.rid "
182 " AND blob.rid=event.objid "
183 " AND event.mtime<=julianday(%Q %s)"
184 " AND event.type GLOB '%q'"
185 " ORDER BY event.mtime DESC ",
186 zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType
187 );
188 break;
189 }
190 }
191
--- src/name.c
+++ src/name.c
@@ -154,11 +154,11 @@
154 " WHERE tag.tagname='sym-%q' "
155 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
156 " AND event.objid=tagxref.rid "
157 " AND blob.rid=event.objid "
158 " AND event.type GLOB '%q'"
159 " ORDER BY event.mtime DESC /*sort*/",
160 zTag, zType
161 );
162 if( zUuid==0 ){
163 int nTag = strlen(zTag);
164 int i;
@@ -180,11 +180,11 @@
180 " AND tagxref.tagid=tag.tagid AND tagxref.tagtype>0 "
181 " AND event.objid=tagxref.rid "
182 " AND blob.rid=event.objid "
183 " AND event.mtime<=julianday(%Q %s)"
184 " AND event.type GLOB '%q'"
185 " ORDER BY event.mtime DESC /*sort*/ ",
186 zTagBase, zDate, (useUtc ? "" : ",'utc'"), zType
187 );
188 break;
189 }
190 }
191
+2 -1
--- src/path.c
+++ src/path.c
@@ -95,12 +95,13 @@
9595
}
9696
9797
/*
9898
** Construct the path from path.pStart to path.pEnd in the u.pTo fields.
9999
*/
100
-void path_reverse_path(void){
100
+static void path_reverse_path(void){
101101
PathNode *p;
102
+ assert( path.pEnd!=0 );
102103
for(p=path.pEnd; p && p->pFrom; p = p->pFrom){
103104
p->pFrom->u.pTo = p;
104105
}
105106
path.pEnd->u.pTo = 0;
106107
assert( p==path.pStart );
107108
--- src/path.c
+++ src/path.c
@@ -95,12 +95,13 @@
95 }
96
97 /*
98 ** Construct the path from path.pStart to path.pEnd in the u.pTo fields.
99 */
100 void path_reverse_path(void){
101 PathNode *p;
 
102 for(p=path.pEnd; p && p->pFrom; p = p->pFrom){
103 p->pFrom->u.pTo = p;
104 }
105 path.pEnd->u.pTo = 0;
106 assert( p==path.pStart );
107
--- src/path.c
+++ src/path.c
@@ -95,12 +95,13 @@
95 }
96
97 /*
98 ** Construct the path from path.pStart to path.pEnd in the u.pTo fields.
99 */
100 static void path_reverse_path(void){
101 PathNode *p;
102 assert( path.pEnd!=0 );
103 for(p=path.pEnd; p && p->pFrom; p = p->pFrom){
104 p->pFrom->u.pTo = p;
105 }
106 path.pEnd->u.pTo = 0;
107 assert( p==path.pStart );
108
--- src/rebuild.c
+++ src/rebuild.c
@@ -786,10 +786,11 @@
786786
);
787787
if( bVerily ){
788788
db_multi_exec(
789789
"DELETE FROM concealed;"
790790
"UPDATE rcvfrom SET ipaddr='unknown';"
791
+ "DROP TABLE IF EXISTS accesslog;"
791792
"UPDATE user SET photo=NULL, info='';"
792793
);
793794
}
794795
}
795796
if( !bNeedRebuild ){
796797
--- src/rebuild.c
+++ src/rebuild.c
@@ -786,10 +786,11 @@
786 );
787 if( bVerily ){
788 db_multi_exec(
789 "DELETE FROM concealed;"
790 "UPDATE rcvfrom SET ipaddr='unknown';"
 
791 "UPDATE user SET photo=NULL, info='';"
792 );
793 }
794 }
795 if( !bNeedRebuild ){
796
--- src/rebuild.c
+++ src/rebuild.c
@@ -786,10 +786,11 @@
786 );
787 if( bVerily ){
788 db_multi_exec(
789 "DELETE FROM concealed;"
790 "UPDATE rcvfrom SET ipaddr='unknown';"
791 "DROP TABLE IF EXISTS accesslog;"
792 "UPDATE user SET photo=NULL, info='';"
793 );
794 }
795 }
796 if( !bNeedRebuild ){
797
+3 -19
--- src/report.c
+++ src/report.c
@@ -630,17 +630,11 @@
630630
char **azName /* Names of the columns */
631631
){
632632
struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
633633
int i;
634634
const char *zTid; /* Ticket UUID. (value of column named '#') */
635
- int rn; /* Report number */
636635
char *zBg = 0; /* Use this background color */
637
- char zPage[30]; /* Text version of the ticket number */
638
-
639
- /* Get the report number
640
- */
641
- rn = pState->rn;
642636
643637
/* Do initialization
644638
*/
645639
if( pState->nCount==0 ){
646640
/* Turn off the authorizer. It is no longer doing anything since the
@@ -719,11 +713,10 @@
719713
*/
720714
zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0;
721715
if( zBg==0 ) zBg = "white";
722716
@ <tr style="background-color:%h(zBg)">
723717
zTid = 0;
724
- zPage[0] = 0;
725718
for(i=0; i<nArg; i++){
726719
char *zData;
727720
if( i==pState->iBg ) continue;
728721
zData = azArg[i];
729722
if( zData==0 ) zData = "";
@@ -1108,41 +1101,32 @@
11081101
const char *zFilter,
11091102
tTktShowEncoding enc
11101103
){
11111104
Stmt q;
11121105
char *zSql;
1113
- const char *zTitle;
1114
- const char *zOwner;
1115
- const char *zClrKey;
11161106
char *zErr1 = 0;
11171107
char *zErr2 = 0;
11181108
int count = 0;
11191109
int rn;
11201110
11211111
if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){
1122
- zTitle = zFullTicketRptTitle;
11231112
zSql = "SELECT * FROM ticket";
1124
- zOwner = g.zLogin;
1125
- zClrKey = "";
11261113
}else{
11271114
rn = atoi(zRep);
11281115
if( rn ){
11291116
db_prepare(&q,
1130
- "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn);
1117
+ "SELECT sqlcode FROM reportfmt WHERE rn=%d", rn);
11311118
}else{
11321119
db_prepare(&q,
1133
- "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep);
1120
+ "SELECT sqlcode FROM reportfmt WHERE title='%s'", zRep);
11341121
}
11351122
if( db_step(&q)!=SQLITE_ROW ){
11361123
db_finalize(&q);
11371124
rpt_list_reports();
11381125
fossil_fatal("unknown report format(%s)!",zRep);
11391126
}
1140
- zTitle = db_column_malloc(&q, 0);
1141
- zSql = db_column_malloc(&q, 1);
1142
- zOwner = db_column_malloc(&q, 2);
1143
- zClrKey = db_column_malloc(&q, 3);
1127
+ zSql = db_column_malloc(&q, 0);
11441128
db_finalize(&q);
11451129
}
11461130
if( zFilter ){
11471131
zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter);
11481132
}
11491133
--- src/report.c
+++ src/report.c
@@ -630,17 +630,11 @@
630 char **azName /* Names of the columns */
631 ){
632 struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
633 int i;
634 const char *zTid; /* Ticket UUID. (value of column named '#') */
635 int rn; /* Report number */
636 char *zBg = 0; /* Use this background color */
637 char zPage[30]; /* Text version of the ticket number */
638
639 /* Get the report number
640 */
641 rn = pState->rn;
642
643 /* Do initialization
644 */
645 if( pState->nCount==0 ){
646 /* Turn off the authorizer. It is no longer doing anything since the
@@ -719,11 +713,10 @@
719 */
720 zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0;
721 if( zBg==0 ) zBg = "white";
722 @ <tr style="background-color:%h(zBg)">
723 zTid = 0;
724 zPage[0] = 0;
725 for(i=0; i<nArg; i++){
726 char *zData;
727 if( i==pState->iBg ) continue;
728 zData = azArg[i];
729 if( zData==0 ) zData = "";
@@ -1108,41 +1101,32 @@
1108 const char *zFilter,
1109 tTktShowEncoding enc
1110 ){
1111 Stmt q;
1112 char *zSql;
1113 const char *zTitle;
1114 const char *zOwner;
1115 const char *zClrKey;
1116 char *zErr1 = 0;
1117 char *zErr2 = 0;
1118 int count = 0;
1119 int rn;
1120
1121 if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){
1122 zTitle = zFullTicketRptTitle;
1123 zSql = "SELECT * FROM ticket";
1124 zOwner = g.zLogin;
1125 zClrKey = "";
1126 }else{
1127 rn = atoi(zRep);
1128 if( rn ){
1129 db_prepare(&q,
1130 "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE rn=%d", rn);
1131 }else{
1132 db_prepare(&q,
1133 "SELECT title, sqlcode, owner, cols FROM reportfmt WHERE title='%s'", zRep);
1134 }
1135 if( db_step(&q)!=SQLITE_ROW ){
1136 db_finalize(&q);
1137 rpt_list_reports();
1138 fossil_fatal("unknown report format(%s)!",zRep);
1139 }
1140 zTitle = db_column_malloc(&q, 0);
1141 zSql = db_column_malloc(&q, 1);
1142 zOwner = db_column_malloc(&q, 2);
1143 zClrKey = db_column_malloc(&q, 3);
1144 db_finalize(&q);
1145 }
1146 if( zFilter ){
1147 zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter);
1148 }
1149
--- src/report.c
+++ src/report.c
@@ -630,17 +630,11 @@
630 char **azName /* Names of the columns */
631 ){
632 struct GenerateHTML *pState = (struct GenerateHTML*)pUser;
633 int i;
634 const char *zTid; /* Ticket UUID. (value of column named '#') */
 
635 char *zBg = 0; /* Use this background color */
 
 
 
 
 
636
637 /* Do initialization
638 */
639 if( pState->nCount==0 ){
640 /* Turn off the authorizer. It is no longer doing anything since the
@@ -719,11 +713,10 @@
713 */
714 zBg = pState->iBg>=0 ? azArg[pState->iBg] : 0;
715 if( zBg==0 ) zBg = "white";
716 @ <tr style="background-color:%h(zBg)">
717 zTid = 0;
 
718 for(i=0; i<nArg; i++){
719 char *zData;
720 if( i==pState->iBg ) continue;
721 zData = azArg[i];
722 if( zData==0 ) zData = "";
@@ -1108,41 +1101,32 @@
1101 const char *zFilter,
1102 tTktShowEncoding enc
1103 ){
1104 Stmt q;
1105 char *zSql;
 
 
 
1106 char *zErr1 = 0;
1107 char *zErr2 = 0;
1108 int count = 0;
1109 int rn;
1110
1111 if (!zRep || !strcmp(zRep,zFullTicketRptRn) || !strcmp(zRep,zFullTicketRptTitle) ){
 
1112 zSql = "SELECT * FROM ticket";
 
 
1113 }else{
1114 rn = atoi(zRep);
1115 if( rn ){
1116 db_prepare(&q,
1117 "SELECT sqlcode FROM reportfmt WHERE rn=%d", rn);
1118 }else{
1119 db_prepare(&q,
1120 "SELECT sqlcode FROM reportfmt WHERE title='%s'", zRep);
1121 }
1122 if( db_step(&q)!=SQLITE_ROW ){
1123 db_finalize(&q);
1124 rpt_list_reports();
1125 fossil_fatal("unknown report format(%s)!",zRep);
1126 }
1127 zSql = db_column_malloc(&q, 0);
 
 
 
1128 db_finalize(&q);
1129 }
1130 if( zFilter ){
1131 zSql = mprintf("SELECT * FROM (%s) WHERE %s",zSql,zFilter);
1132 }
1133
+1 -1
--- src/schema.c
+++ src/schema.c
@@ -251,11 +251,11 @@
251251
@ CREATE TABLE leaf(rid INTEGER PRIMARY KEY);
252252
@
253253
@ -- Events used to generate a timeline
254254
@ --
255255
@ CREATE TABLE event(
256
-@ type TEXT, -- Type of event: 'ci', 'w', 'e', 't'
256
+@ type TEXT, -- Type of event: 'ci', 'w', 'e', 't', 'g'
257257
@ mtime DATETIME, -- Time of occurrence. Julian day.
258258
@ objid INTEGER PRIMARY KEY, -- Associated record ID
259259
@ tagid INTEGER, -- Associated ticket or wiki name tag
260260
@ uid INTEGER REFERENCES user, -- User who caused the event
261261
@ bgcolor TEXT, -- Color set by 'bgcolor' property
262262
--- src/schema.c
+++ src/schema.c
@@ -251,11 +251,11 @@
251 @ CREATE TABLE leaf(rid INTEGER PRIMARY KEY);
252 @
253 @ -- Events used to generate a timeline
254 @ --
255 @ CREATE TABLE event(
256 @ type TEXT, -- Type of event: 'ci', 'w', 'e', 't'
257 @ mtime DATETIME, -- Time of occurrence. Julian day.
258 @ objid INTEGER PRIMARY KEY, -- Associated record ID
259 @ tagid INTEGER, -- Associated ticket or wiki name tag
260 @ uid INTEGER REFERENCES user, -- User who caused the event
261 @ bgcolor TEXT, -- Color set by 'bgcolor' property
262
--- src/schema.c
+++ src/schema.c
@@ -251,11 +251,11 @@
251 @ CREATE TABLE leaf(rid INTEGER PRIMARY KEY);
252 @
253 @ -- Events used to generate a timeline
254 @ --
255 @ CREATE TABLE event(
256 @ type TEXT, -- Type of event: 'ci', 'w', 'e', 't', 'g'
257 @ mtime DATETIME, -- Time of occurrence. Julian day.
258 @ objid INTEGER PRIMARY KEY, -- Associated record ID
259 @ tagid INTEGER, -- Associated ticket or wiki name tag
260 @ uid INTEGER REFERENCES user, -- User who caused the event
261 @ bgcolor TEXT, -- Color set by 'bgcolor' property
262
+10 -1
--- src/setup.c
+++ src/setup.c
@@ -848,18 +848,27 @@
848848
@ <a href="%s(g.zTop)/help/server">fossil http</a> commands
849849
@ without the "--localauth" option.
850850
@ <li> The server is started from CGI without the "localauth" keyword
851851
@ in the CGI script.
852852
@ </ol>
853
+ @
854
+ @ <hr />
855
+ onoff_attribute("Enable /test_env",
856
+ "test_env_enable", "test_env_enable", 0);
857
+ @ <p>When enabled, the %h(g.zBaseURL)/test_env URL is available to all
858
+ @ users. When disabled (the default) only users Admin and Setup can visit
859
+ @ the /test_env page.
860
+ @ </p>
861
+ @
853862
@ <hr />
854863
onoff_attribute("Allow REMOTE_USER authentication",
855864
"remote_user_ok", "remote_user_ok", 0);
856865
@ <p>When enabled, if the REMOTE_USER environment variable is set to the
857866
@ login name of a valid user and no other login credentials are available,
858867
@ then the REMOTE_USER is accepted as an authenticated user.
859868
@ </p>
860
-
869
+ @
861870
@ <hr />
862871
entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
863872
@ <p>The number of hours for which a login is valid. This must be a
864873
@ positive number. The default is 8760 hours which is approximately equal
865874
@ to a year.</p>
866875
--- src/setup.c
+++ src/setup.c
@@ -848,18 +848,27 @@
848 @ <a href="%s(g.zTop)/help/server">fossil http</a> commands
849 @ without the "--localauth" option.
850 @ <li> The server is started from CGI without the "localauth" keyword
851 @ in the CGI script.
852 @ </ol>
 
 
 
 
 
 
 
 
 
853 @ <hr />
854 onoff_attribute("Allow REMOTE_USER authentication",
855 "remote_user_ok", "remote_user_ok", 0);
856 @ <p>When enabled, if the REMOTE_USER environment variable is set to the
857 @ login name of a valid user and no other login credentials are available,
858 @ then the REMOTE_USER is accepted as an authenticated user.
859 @ </p>
860
861 @ <hr />
862 entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
863 @ <p>The number of hours for which a login is valid. This must be a
864 @ positive number. The default is 8760 hours which is approximately equal
865 @ to a year.</p>
866
--- src/setup.c
+++ src/setup.c
@@ -848,18 +848,27 @@
848 @ <a href="%s(g.zTop)/help/server">fossil http</a> commands
849 @ without the "--localauth" option.
850 @ <li> The server is started from CGI without the "localauth" keyword
851 @ in the CGI script.
852 @ </ol>
853 @
854 @ <hr />
855 onoff_attribute("Enable /test_env",
856 "test_env_enable", "test_env_enable", 0);
857 @ <p>When enabled, the %h(g.zBaseURL)/test_env URL is available to all
858 @ users. When disabled (the default) only users Admin and Setup can visit
859 @ the /test_env page.
860 @ </p>
861 @
862 @ <hr />
863 onoff_attribute("Allow REMOTE_USER authentication",
864 "remote_user_ok", "remote_user_ok", 0);
865 @ <p>When enabled, if the REMOTE_USER environment variable is set to the
866 @ login name of a valid user and no other login credentials are available,
867 @ then the REMOTE_USER is accepted as an authenticated user.
868 @ </p>
869 @
870 @ <hr />
871 entry_attribute("Login expiration time", 6, "cookie-expire", "cex", "8766");
872 @ <p>The number of hours for which a login is valid. This must be a
873 @ positive number. The default is 8760 hours which is approximately equal
874 @ to a year.</p>
875
+1 -1
--- src/sha1.c
+++ src/sha1.c
@@ -82,11 +82,11 @@
8282
#define d qq[3]
8383
#define e qq[4]
8484
8585
void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
8686
{
87
- unsigned int qq[5]; // a, b, c, d, e;
87
+ unsigned int qq[5]; /* a, b, c, d, e; */
8888
static int one = 1;
8989
unsigned int block[16];
9090
memcpy(block, buffer, 64);
9191
memcpy(qq,state,5*sizeof(unsigned int));
9292
9393
--- src/sha1.c
+++ src/sha1.c
@@ -82,11 +82,11 @@
82 #define d qq[3]
83 #define e qq[4]
84
85 void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
86 {
87 unsigned int qq[5]; // a, b, c, d, e;
88 static int one = 1;
89 unsigned int block[16];
90 memcpy(block, buffer, 64);
91 memcpy(qq,state,5*sizeof(unsigned int));
92
93
--- src/sha1.c
+++ src/sha1.c
@@ -82,11 +82,11 @@
82 #define d qq[3]
83 #define e qq[4]
84
85 void SHA1Transform(unsigned int state[5], const unsigned char buffer[64])
86 {
87 unsigned int qq[5]; /* a, b, c, d, e; */
88 static int one = 1;
89 unsigned int block[16];
90 memcpy(block, buffer, 64);
91 memcpy(qq,state,5*sizeof(unsigned int));
92
93
+107 -60
--- src/shell.c
+++ src/shell.c
@@ -10,15 +10,26 @@
1010
**
1111
*************************************************************************
1212
** This file contains code to implement the "sqlite" command line
1313
** utility for accessing SQLite databases.
1414
*/
15
-#if defined(_WIN32) || defined(WIN32)
15
+#if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
1616
/* This needs to come before any includes for MSVC compiler */
1717
#define _CRT_SECURE_NO_WARNINGS
1818
#endif
1919
20
+/*
21
+** Enable large-file support for fopen() and friends on unix.
22
+*/
23
+#ifndef SQLITE_DISABLE_LFS
24
+# define _LARGE_FILE 1
25
+# ifndef _FILE_OFFSET_BITS
26
+# define _FILE_OFFSET_BITS 64
27
+# endif
28
+# define _LARGEFILE_SOURCE 1
29
+#endif
30
+
2031
#include <stdlib.h>
2132
#include <string.h>
2233
#include <stdio.h>
2334
#include <assert.h>
2435
#include "sqlite3.h"
@@ -58,11 +69,11 @@
5869
#define isatty(h) _isatty(h)
5970
#define access(f,m) _access((f),(m))
6071
#else
6172
/* Make sure isatty() has a prototype.
6273
*/
63
-extern int isatty();
74
+extern int isatty(int);
6475
#endif
6576
6677
#if defined(_WIN32_WCE)
6778
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
6879
* thus we always assume that we have a console. That can be
@@ -71,10 +82,15 @@
7182
#define isatty(x) 1
7283
#endif
7384
7485
/* True if the timer is enabled */
7586
static int enableTimer = 0;
87
+
88
+/* ctype macros that work with signed characters */
89
+#define IsSpace(X) isspace((unsigned char)X)
90
+#define IsDigit(X) isdigit((unsigned char)X)
91
+#define ToLower(X) (char)tolower((unsigned char)X)
7692
7793
#if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
7894
#include <sys/time.h>
7995
#include <sys/resource.h>
8096
@@ -263,27 +279,27 @@
263279
/*
264280
** Determines if a string is a number of not.
265281
*/
266282
static int isNumber(const char *z, int *realnum){
267283
if( *z=='-' || *z=='+' ) z++;
268
- if( !isdigit(*z) ){
284
+ if( !IsDigit(*z) ){
269285
return 0;
270286
}
271287
z++;
272288
if( realnum ) *realnum = 0;
273
- while( isdigit(*z) ){ z++; }
289
+ while( IsDigit(*z) ){ z++; }
274290
if( *z=='.' ){
275291
z++;
276
- if( !isdigit(*z) ) return 0;
277
- while( isdigit(*z) ){ z++; }
292
+ if( !IsDigit(*z) ) return 0;
293
+ while( IsDigit(*z) ){ z++; }
278294
if( realnum ) *realnum = 1;
279295
}
280296
if( *z=='e' || *z=='E' ){
281297
z++;
282298
if( *z=='+' || *z=='-' ) z++;
283
- if( !isdigit(*z) ) return 0;
284
- while( isdigit(*z) ){ z++; }
299
+ if( !IsDigit(*z) ) return 0;
300
+ while( IsDigit(*z) ){ z++; }
285301
if( realnum ) *realnum = 1;
286302
}
287303
return *z==0;
288304
}
289305
@@ -320,22 +336,20 @@
320336
*/
321337
static char *local_getline(char *zPrompt, FILE *in){
322338
char *zLine;
323339
int nLine;
324340
int n;
325
- int eol;
326341
327342
if( zPrompt && *zPrompt ){
328343
printf("%s",zPrompt);
329344
fflush(stdout);
330345
}
331346
nLine = 100;
332347
zLine = malloc( nLine );
333348
if( zLine==0 ) return 0;
334349
n = 0;
335
- eol = 0;
336
- while( !eol ){
350
+ while( 1 ){
337351
if( n+100>nLine ){
338352
nLine = nLine*2 + 100;
339353
zLine = realloc(zLine, nLine);
340354
if( zLine==0 ) return 0;
341355
}
@@ -343,19 +357,18 @@
343357
if( n==0 ){
344358
free(zLine);
345359
return 0;
346360
}
347361
zLine[n] = 0;
348
- eol = 1;
349362
break;
350363
}
351364
while( zLine[n] ){ n++; }
352365
if( n>0 && zLine[n-1]=='\n' ){
353366
n--;
354367
if( n>0 && zLine[n-1]=='\r' ) n--;
355368
zLine[n] = 0;
356
- eol = 1;
369
+ break;
357370
}
358371
}
359372
zLine = realloc( zLine, n+1 );
360373
return zLine;
361374
}
@@ -400,10 +413,11 @@
400413
sqlite3 *db; /* The database */
401414
int echoOn; /* True to echo input commands */
402415
int statsOn; /* True to display memory stats before each finalize */
403416
int cnt; /* Number of records displayed so far */
404417
FILE *out; /* Write results here */
418
+ int nErr; /* Number of errors seen */
405419
int mode; /* An output mode setting */
406420
int writableSchema; /* True if PRAGMA writable_schema=ON */
407421
int showHeader; /* True to show column names in List or Column mode */
408422
char *zDestTable; /* Name of destination table when MODE_Insert */
409423
char separator[20]; /* Separator character for MODE_List */
@@ -925,31 +939,37 @@
925939
**
926940
** This is used, for example, to show the schema of the database by
927941
** querying the SQLITE_MASTER table.
928942
*/
929943
static int run_table_dump_query(
930
- FILE *out, /* Send output here */
931
- sqlite3 *db, /* Database to query */
932
- const char *zSelect, /* SELECT statement to extract content */
933
- const char *zFirstRow /* Print before first row, if not NULL */
944
+ struct callback_data *p, /* Query context */
945
+ const char *zSelect, /* SELECT statement to extract content */
946
+ const char *zFirstRow /* Print before first row, if not NULL */
934947
){
935948
sqlite3_stmt *pSelect;
936949
int rc;
937
- rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
950
+ rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
938951
if( rc!=SQLITE_OK || !pSelect ){
952
+ fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
953
+ p->nErr++;
939954
return rc;
940955
}
941956
rc = sqlite3_step(pSelect);
942957
while( rc==SQLITE_ROW ){
943958
if( zFirstRow ){
944
- fprintf(out, "%s", zFirstRow);
959
+ fprintf(p->out, "%s", zFirstRow);
945960
zFirstRow = 0;
946961
}
947
- fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
962
+ fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0));
948963
rc = sqlite3_step(pSelect);
949964
}
950
- return sqlite3_finalize(pSelect);
965
+ rc = sqlite3_finalize(pSelect);
966
+ if( rc!=SQLITE_OK ){
967
+ fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
968
+ p->nErr++;
969
+ }
970
+ return rc;
951971
}
952972
953973
/*
954974
** Allocate space and save off current error string.
955975
*/
@@ -1027,11 +1047,16 @@
10271047
fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
10281048
sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
10291049
fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
10301050
iHiwtr = iCur = -1;
10311051
sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
1032
- fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
1052
+ fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1053
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1054
+ fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1055
+ iHiwtr = iCur = -1;
1056
+ sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1057
+ fprintf(pArg->out, "Page cache misses: %d\n", iCur);
10331058
iHiwtr = iCur = -1;
10341059
sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
10351060
fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
10361061
iHiwtr = iCur = -1;
10371062
sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
@@ -1067,10 +1092,11 @@
10671092
struct callback_data *pArg, /* Pointer to struct callback_data */
10681093
char **pzErrMsg /* Error msg written here */
10691094
){
10701095
sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
10711096
int rc = SQLITE_OK; /* Return Code */
1097
+ int rc2;
10721098
const char *zLeftover; /* Tail of unprocessed SQL */
10731099
10741100
if( pzErrMsg ){
10751101
*pzErrMsg = NULL;
10761102
}
@@ -1083,11 +1109,11 @@
10831109
}
10841110
}else{
10851111
if( !pStmt ){
10861112
/* this happens for a comment or white-space */
10871113
zSql = zLeftover;
1088
- while( isspace(zSql[0]) ) zSql++;
1114
+ while( IsSpace(zSql[0]) ) zSql++;
10891115
continue;
10901116
}
10911117
10921118
/* save off the prepared statment handle and reset row count */
10931119
if( pArg ){
@@ -1160,14 +1186,15 @@
11601186
}
11611187
11621188
/* Finalize the statement just executed. If this fails, save a
11631189
** copy of the error message. Otherwise, set zSql to point to the
11641190
** next statement to execute. */
1165
- rc = sqlite3_finalize(pStmt);
1191
+ rc2 = sqlite3_finalize(pStmt);
1192
+ if( rc!=SQLITE_NOMEM ) rc = rc2;
11661193
if( rc==SQLITE_OK ){
11671194
zSql = zLeftover;
1168
- while( isspace(zSql[0]) ) zSql++;
1195
+ while( IsSpace(zSql[0]) ) zSql++;
11691196
}else if( pzErrMsg ){
11701197
*pzErrMsg = save_err_msg(db);
11711198
}
11721199
11731200
/* clear saved stmt handle */
@@ -1266,14 +1293,14 @@
12661293
return 1;
12671294
}
12681295
zSelect = appendText(zSelect, "|| ')' FROM ", 0);
12691296
zSelect = appendText(zSelect, zTable, '"');
12701297
1271
- rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
1298
+ rc = run_table_dump_query(p, zSelect, zPrepStmt);
12721299
if( rc==SQLITE_CORRUPT ){
12731300
zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
1274
- rc = run_table_dump_query(p->out, p->db, zSelect, 0);
1301
+ run_table_dump_query(p, zSelect, 0);
12751302
}
12761303
if( zSelect ) free(zSelect);
12771304
}
12781305
return 0;
12791306
}
@@ -1285,23 +1312,34 @@
12851312
** If we get a SQLITE_CORRUPT error, rerun the query after appending
12861313
** "ORDER BY rowid DESC" to the end.
12871314
*/
12881315
static int run_schema_dump_query(
12891316
struct callback_data *p,
1290
- const char *zQuery,
1291
- char **pzErrMsg
1317
+ const char *zQuery
12921318
){
12931319
int rc;
1294
- rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
1320
+ char *zErr = 0;
1321
+ rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
12951322
if( rc==SQLITE_CORRUPT ){
12961323
char *zQ2;
12971324
int len = strlen30(zQuery);
1298
- if( pzErrMsg ) sqlite3_free(*pzErrMsg);
1325
+ fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1326
+ if( zErr ){
1327
+ fprintf(p->out, "/****** %s ******/\n", zErr);
1328
+ sqlite3_free(zErr);
1329
+ zErr = 0;
1330
+ }
12991331
zQ2 = malloc( len+100 );
13001332
if( zQ2==0 ) return rc;
13011333
sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
1302
- rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
1334
+ rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1335
+ if( rc ){
1336
+ fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1337
+ }else{
1338
+ rc = SQLITE_CORRUPT;
1339
+ }
1340
+ sqlite3_free(zErr);
13031341
free(zQ2);
13041342
}
13051343
return rc;
13061344
}
13071345
@@ -1434,11 +1472,11 @@
14341472
*/
14351473
static int booleanValue(char *zArg){
14361474
int val = atoi(zArg);
14371475
int j;
14381476
for(j=0; zArg[j]; j++){
1439
- zArg[j] = (char)tolower(zArg[j]);
1477
+ zArg[j] = ToLower(zArg[j]);
14401478
}
14411479
if( strcmp(zArg,"on")==0 ){
14421480
val = 1;
14431481
}else if( strcmp(zArg,"yes")==0 ){
14441482
val = 1;
@@ -1460,11 +1498,11 @@
14601498
char *azArg[50];
14611499
14621500
/* Parse the input line into tokens.
14631501
*/
14641502
while( zLine[i] && nArg<ArraySize(azArg) ){
1465
- while( isspace((unsigned char)zLine[i]) ){ i++; }
1503
+ while( IsSpace(zLine[i]) ){ i++; }
14661504
if( zLine[i]==0 ) break;
14671505
if( zLine[i]=='\'' || zLine[i]=='"' ){
14681506
int delim = zLine[i++];
14691507
azArg[nArg++] = &zLine[i];
14701508
while( zLine[i] && zLine[i]!=delim ){ i++; }
@@ -1472,11 +1510,11 @@
14721510
zLine[i++] = 0;
14731511
}
14741512
if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
14751513
}else{
14761514
azArg[nArg++] = &zLine[i];
1477
- while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
1515
+ while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
14781516
if( zLine[i] ) zLine[i++] = 0;
14791517
resolve_backslashes(azArg[nArg-1]);
14801518
}
14811519
}
14821520
@@ -1543,29 +1581,29 @@
15431581
rc = 1;
15441582
}
15451583
}else
15461584
15471585
if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
1548
- char *zErrMsg = 0;
15491586
open_db(p);
15501587
/* When playing back a "dump", the content might appear in an order
15511588
** which causes immediate foreign key constraints to be violated.
15521589
** So disable foreign-key constraint enforcement to prevent problems. */
15531590
fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
15541591
fprintf(p->out, "BEGIN TRANSACTION;\n");
15551592
p->writableSchema = 0;
1556
- sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
1593
+ sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
1594
+ p->nErr = 0;
15571595
if( nArg==1 ){
15581596
run_schema_dump_query(p,
15591597
"SELECT name, type, sql FROM sqlite_master "
1560
- "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1598
+ "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
15611599
);
15621600
run_schema_dump_query(p,
15631601
"SELECT name, type, sql FROM sqlite_master "
1564
- "WHERE name=='sqlite_sequence'", 0
1602
+ "WHERE name=='sqlite_sequence'"
15651603
);
1566
- run_table_dump_query(p->out, p->db,
1604
+ run_table_dump_query(p,
15671605
"SELECT sql FROM sqlite_master "
15681606
"WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
15691607
);
15701608
}else{
15711609
int i;
@@ -1572,12 +1610,12 @@
15721610
for(i=1; i<nArg; i++){
15731611
zShellStatic = azArg[i];
15741612
run_schema_dump_query(p,
15751613
"SELECT name, type, sql FROM sqlite_master "
15761614
"WHERE tbl_name LIKE shellstatic() AND type=='table'"
1577
- " AND sql NOT NULL", 0);
1578
- run_table_dump_query(p->out, p->db,
1615
+ " AND sql NOT NULL");
1616
+ run_table_dump_query(p,
15791617
"SELECT sql FROM sqlite_master "
15801618
"WHERE sql NOT NULL"
15811619
" AND type IN ('index','trigger','view')"
15821620
" AND tbl_name LIKE shellstatic()", 0
15831621
);
@@ -1586,17 +1624,13 @@
15861624
}
15871625
if( p->writableSchema ){
15881626
fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
15891627
p->writableSchema = 0;
15901628
}
1591
- sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
1592
- if( zErrMsg ){
1593
- fprintf(stderr,"Error: %s\n", zErrMsg);
1594
- sqlite3_free(zErrMsg);
1595
- }else{
1596
- fprintf(p->out, "COMMIT;\n");
1597
- }
1629
+ sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1630
+ sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
1631
+ fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
15981632
}else
15991633
16001634
if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
16011635
p->echoOn = booleanValue(azArg[1]);
16021636
}else
@@ -1671,11 +1705,11 @@
16711705
nSep = strlen30(p->separator);
16721706
if( nSep==0 ){
16731707
fprintf(stderr, "Error: non-null separator required for import\n");
16741708
return 1;
16751709
}
1676
- zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1710
+ zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
16771711
if( zSql==0 ){
16781712
fprintf(stderr, "Error: out of memory\n");
16791713
return 1;
16801714
}
16811715
nByte = strlen30(zSql);
@@ -1693,11 +1727,11 @@
16931727
zSql = malloc( nByte + 20 + nCol*2 );
16941728
if( zSql==0 ){
16951729
fprintf(stderr, "Error: out of memory\n");
16961730
return 1;
16971731
}
1698
- sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1732
+ sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
16991733
j = strlen30(zSql);
17001734
for(i=1; i<nCol; i++){
17011735
zSql[j++] = ',';
17021736
zSql[j++] = '?';
17031737
}
@@ -1725,11 +1759,10 @@
17251759
}
17261760
sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
17271761
zCommit = "COMMIT";
17281762
while( (zLine = local_getline(0, in))!=0 ){
17291763
char *z;
1730
- i = 0;
17311764
lineno++;
17321765
azCol[0] = zLine;
17331766
for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
17341767
if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
17351768
*z = 0;
@@ -2014,11 +2047,11 @@
20142047
memcpy(&data, p, sizeof(data));
20152048
data.showHeader = 0;
20162049
data.mode = MODE_Semi;
20172050
if( nArg>1 ){
20182051
int i;
2019
- for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
2052
+ for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
20202053
if( strcmp(azArg[1],"sqlite_master")==0 ){
20212054
char *new_argv[2], *new_colv[2];
20222055
new_argv[0] = "CREATE TABLE sqlite_master (\n"
20232056
" type text,\n"
20242057
" name text,\n"
@@ -2200,11 +2233,11 @@
22002233
for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
22012234
if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
22022235
if( testctrl<0 ){
22032236
testctrl = aCtrl[i].ctrlCode;
22042237
}else{
2205
- fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
2238
+ fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
22062239
testctrl = -1;
22072240
break;
22082241
}
22092242
}
22102243
}
@@ -2337,11 +2370,11 @@
23372370
/*
23382371
** Test to see if a line consists entirely of whitespace.
23392372
*/
23402373
static int _all_whitespace(const char *z){
23412374
for(; *z; z++){
2342
- if( isspace(*(unsigned char*)z) ) continue;
2375
+ if( IsSpace(z[0]) ) continue;
23432376
if( *z=='/' && z[1]=='*' ){
23442377
z += 2;
23452378
while( *z && (*z!='*' || z[1]!='/') ){ z++; }
23462379
if( *z==0 ) return 0;
23472380
z++;
@@ -2362,15 +2395,15 @@
23622395
** Return TRUE if the line typed in is an SQL command terminator other
23632396
** than a semi-colon. The SQL Server style "go" command is understood
23642397
** as is the Oracle "/".
23652398
*/
23662399
static int _is_command_terminator(const char *zLine){
2367
- while( isspace(*(unsigned char*)zLine) ){ zLine++; };
2400
+ while( IsSpace(zLine[0]) ){ zLine++; };
23682401
if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
23692402
return 1; /* Oracle */
23702403
}
2371
- if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2404
+ if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
23722405
&& _all_whitespace(&zLine[2]) ){
23732406
return 1; /* SQL Server */
23742407
}
23752408
return 0;
23762409
}
@@ -2436,11 +2469,11 @@
24362469
memcpy(zLine,";",2);
24372470
}
24382471
nSqlPrior = nSql;
24392472
if( zSql==0 ){
24402473
int i;
2441
- for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
2474
+ for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
24422475
if( zLine[i]!=0 ){
24432476
nSql = strlen30(zLine);
24442477
zSql = malloc( nSql+3 );
24452478
if( zSql==0 ){
24462479
fprintf(stderr, "Error: out of memory\n");
@@ -2630,10 +2663,13 @@
26302663
" -version show SQLite version\n"
26312664
" -vfs NAME use NAME as the default VFS\n"
26322665
#ifdef SQLITE_ENABLE_VFSTRACE
26332666
" -vfstrace enable tracing of all VFS calls\n"
26342667
#endif
2668
+#ifdef SQLITE_ENABLE_MULTIPLEX
2669
+ " -multiplex enable the multiplexor VFS\n"
2670
+#endif
26352671
;
26362672
static void usage(int showDetail){
26372673
fprintf(stderr,
26382674
"Usage: %s [OPTIONS] FILENAME [SQL]\n"
26392675
"FILENAME is the name of an SQLite database. A new database is created\n"
@@ -2705,10 +2741,11 @@
27052741
** we do the actual processing of arguments later in a second pass.
27062742
*/
27072743
}else if( strcmp(argv[i],"-batch")==0 ){
27082744
stdin_is_interactive = 0;
27092745
}else if( strcmp(argv[i],"-heap")==0 ){
2746
+#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
27102747
int j, c;
27112748
const char *zSize;
27122749
sqlite3_int64 szHeap;
27132750
27142751
zSize = argv[++i];
@@ -2717,11 +2754,10 @@
27172754
if( c=='M' ){ szHeap *= 1000000; break; }
27182755
if( c=='K' ){ szHeap *= 1000; break; }
27192756
if( c=='G' ){ szHeap *= 1000000000; break; }
27202757
}
27212758
if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2722
-#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
27232759
sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
27242760
#endif
27252761
#ifdef SQLITE_ENABLE_VFSTRACE
27262762
}else if( strcmp(argv[i],"-vfstrace")==0 ){
27272763
extern int vfstrace_register(
@@ -2731,10 +2767,15 @@
27312767
void *pOutArg,
27322768
int makeDefault
27332769
);
27342770
vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
27352771
#endif
2772
+#ifdef SQLITE_ENABLE_MULTIPLEX
2773
+ }else if( strcmp(argv[i],"-multiplex")==0 ){
2774
+ extern int sqlite3_multiple_initialize(const char*,int);
2775
+ sqlite3_multiplex_initialize(0, 1);
2776
+#endif
27362777
}else if( strcmp(argv[i],"-vfs")==0 ){
27372778
sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
27382779
if( pVfs ){
27392780
sqlite3_vfs_register(pVfs, 1);
27402781
}else{
@@ -2753,11 +2794,11 @@
27532794
#ifndef SQLITE_OMIT_MEMORYDB
27542795
data.zDbFilename = ":memory:";
27552796
#else
27562797
data.zDbFilename = 0;
27572798
#endif
2758
- /***** Begin Fossil Patch *****/
2799
+ /***** Begin Fossil Patch *****/
27592800
{
27602801
extern void fossil_open(const char **);
27612802
fossil_open(&data.zDbFilename);
27622803
}
27632804
/***** End Fossil Patch *****/
@@ -2855,12 +2896,18 @@
28552896
stdin_is_interactive = 0;
28562897
}else if( strcmp(z,"-heap")==0 ){
28572898
i++;
28582899
}else if( strcmp(z,"-vfs")==0 ){
28592900
i++;
2901
+#ifdef SQLITE_ENABLE_VFSTRACE
28602902
}else if( strcmp(z,"-vfstrace")==0 ){
28612903
i++;
2904
+#endif
2905
+#ifdef SQLITE_ENABLE_MULTIPLEX
2906
+ }else if( strcmp(z,"-multiplex")==0 ){
2907
+ i++;
2908
+#endif
28622909
}else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
28632910
usage(1);
28642911
}else{
28652912
fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
28662913
fprintf(stderr,"Use -help for a list of options.\n");
28672914
--- src/shell.c
+++ src/shell.c
@@ -10,15 +10,26 @@
10 **
11 *************************************************************************
12 ** This file contains code to implement the "sqlite" command line
13 ** utility for accessing SQLite databases.
14 */
15 #if defined(_WIN32) || defined(WIN32)
16 /* This needs to come before any includes for MSVC compiler */
17 #define _CRT_SECURE_NO_WARNINGS
18 #endif
19
 
 
 
 
 
 
 
 
 
 
 
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdio.h>
23 #include <assert.h>
24 #include "sqlite3.h"
@@ -58,11 +69,11 @@
58 #define isatty(h) _isatty(h)
59 #define access(f,m) _access((f),(m))
60 #else
61 /* Make sure isatty() has a prototype.
62 */
63 extern int isatty();
64 #endif
65
66 #if defined(_WIN32_WCE)
67 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
68 * thus we always assume that we have a console. That can be
@@ -71,10 +82,15 @@
71 #define isatty(x) 1
72 #endif
73
74 /* True if the timer is enabled */
75 static int enableTimer = 0;
 
 
 
 
 
76
77 #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
78 #include <sys/time.h>
79 #include <sys/resource.h>
80
@@ -263,27 +279,27 @@
263 /*
264 ** Determines if a string is a number of not.
265 */
266 static int isNumber(const char *z, int *realnum){
267 if( *z=='-' || *z=='+' ) z++;
268 if( !isdigit(*z) ){
269 return 0;
270 }
271 z++;
272 if( realnum ) *realnum = 0;
273 while( isdigit(*z) ){ z++; }
274 if( *z=='.' ){
275 z++;
276 if( !isdigit(*z) ) return 0;
277 while( isdigit(*z) ){ z++; }
278 if( realnum ) *realnum = 1;
279 }
280 if( *z=='e' || *z=='E' ){
281 z++;
282 if( *z=='+' || *z=='-' ) z++;
283 if( !isdigit(*z) ) return 0;
284 while( isdigit(*z) ){ z++; }
285 if( realnum ) *realnum = 1;
286 }
287 return *z==0;
288 }
289
@@ -320,22 +336,20 @@
320 */
321 static char *local_getline(char *zPrompt, FILE *in){
322 char *zLine;
323 int nLine;
324 int n;
325 int eol;
326
327 if( zPrompt && *zPrompt ){
328 printf("%s",zPrompt);
329 fflush(stdout);
330 }
331 nLine = 100;
332 zLine = malloc( nLine );
333 if( zLine==0 ) return 0;
334 n = 0;
335 eol = 0;
336 while( !eol ){
337 if( n+100>nLine ){
338 nLine = nLine*2 + 100;
339 zLine = realloc(zLine, nLine);
340 if( zLine==0 ) return 0;
341 }
@@ -343,19 +357,18 @@
343 if( n==0 ){
344 free(zLine);
345 return 0;
346 }
347 zLine[n] = 0;
348 eol = 1;
349 break;
350 }
351 while( zLine[n] ){ n++; }
352 if( n>0 && zLine[n-1]=='\n' ){
353 n--;
354 if( n>0 && zLine[n-1]=='\r' ) n--;
355 zLine[n] = 0;
356 eol = 1;
357 }
358 }
359 zLine = realloc( zLine, n+1 );
360 return zLine;
361 }
@@ -400,10 +413,11 @@
400 sqlite3 *db; /* The database */
401 int echoOn; /* True to echo input commands */
402 int statsOn; /* True to display memory stats before each finalize */
403 int cnt; /* Number of records displayed so far */
404 FILE *out; /* Write results here */
 
405 int mode; /* An output mode setting */
406 int writableSchema; /* True if PRAGMA writable_schema=ON */
407 int showHeader; /* True to show column names in List or Column mode */
408 char *zDestTable; /* Name of destination table when MODE_Insert */
409 char separator[20]; /* Separator character for MODE_List */
@@ -925,31 +939,37 @@
925 **
926 ** This is used, for example, to show the schema of the database by
927 ** querying the SQLITE_MASTER table.
928 */
929 static int run_table_dump_query(
930 FILE *out, /* Send output here */
931 sqlite3 *db, /* Database to query */
932 const char *zSelect, /* SELECT statement to extract content */
933 const char *zFirstRow /* Print before first row, if not NULL */
934 ){
935 sqlite3_stmt *pSelect;
936 int rc;
937 rc = sqlite3_prepare(db, zSelect, -1, &pSelect, 0);
938 if( rc!=SQLITE_OK || !pSelect ){
 
 
939 return rc;
940 }
941 rc = sqlite3_step(pSelect);
942 while( rc==SQLITE_ROW ){
943 if( zFirstRow ){
944 fprintf(out, "%s", zFirstRow);
945 zFirstRow = 0;
946 }
947 fprintf(out, "%s;\n", sqlite3_column_text(pSelect, 0));
948 rc = sqlite3_step(pSelect);
949 }
950 return sqlite3_finalize(pSelect);
 
 
 
 
 
951 }
952
953 /*
954 ** Allocate space and save off current error string.
955 */
@@ -1027,11 +1047,16 @@
1027 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1028 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1029 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1030 iHiwtr = iCur = -1;
1031 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
1032 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur);
 
 
 
 
 
1033 iHiwtr = iCur = -1;
1034 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1035 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1036 iHiwtr = iCur = -1;
1037 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
@@ -1067,10 +1092,11 @@
1067 struct callback_data *pArg, /* Pointer to struct callback_data */
1068 char **pzErrMsg /* Error msg written here */
1069 ){
1070 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1071 int rc = SQLITE_OK; /* Return Code */
 
1072 const char *zLeftover; /* Tail of unprocessed SQL */
1073
1074 if( pzErrMsg ){
1075 *pzErrMsg = NULL;
1076 }
@@ -1083,11 +1109,11 @@
1083 }
1084 }else{
1085 if( !pStmt ){
1086 /* this happens for a comment or white-space */
1087 zSql = zLeftover;
1088 while( isspace(zSql[0]) ) zSql++;
1089 continue;
1090 }
1091
1092 /* save off the prepared statment handle and reset row count */
1093 if( pArg ){
@@ -1160,14 +1186,15 @@
1160 }
1161
1162 /* Finalize the statement just executed. If this fails, save a
1163 ** copy of the error message. Otherwise, set zSql to point to the
1164 ** next statement to execute. */
1165 rc = sqlite3_finalize(pStmt);
 
1166 if( rc==SQLITE_OK ){
1167 zSql = zLeftover;
1168 while( isspace(zSql[0]) ) zSql++;
1169 }else if( pzErrMsg ){
1170 *pzErrMsg = save_err_msg(db);
1171 }
1172
1173 /* clear saved stmt handle */
@@ -1266,14 +1293,14 @@
1266 return 1;
1267 }
1268 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1269 zSelect = appendText(zSelect, zTable, '"');
1270
1271 rc = run_table_dump_query(p->out, p->db, zSelect, zPrepStmt);
1272 if( rc==SQLITE_CORRUPT ){
1273 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
1274 rc = run_table_dump_query(p->out, p->db, zSelect, 0);
1275 }
1276 if( zSelect ) free(zSelect);
1277 }
1278 return 0;
1279 }
@@ -1285,23 +1312,34 @@
1285 ** If we get a SQLITE_CORRUPT error, rerun the query after appending
1286 ** "ORDER BY rowid DESC" to the end.
1287 */
1288 static int run_schema_dump_query(
1289 struct callback_data *p,
1290 const char *zQuery,
1291 char **pzErrMsg
1292 ){
1293 int rc;
1294 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, pzErrMsg);
 
1295 if( rc==SQLITE_CORRUPT ){
1296 char *zQ2;
1297 int len = strlen30(zQuery);
1298 if( pzErrMsg ) sqlite3_free(*pzErrMsg);
 
 
 
 
 
1299 zQ2 = malloc( len+100 );
1300 if( zQ2==0 ) return rc;
1301 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
1302 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, pzErrMsg);
 
 
 
 
 
 
1303 free(zQ2);
1304 }
1305 return rc;
1306 }
1307
@@ -1434,11 +1472,11 @@
1434 */
1435 static int booleanValue(char *zArg){
1436 int val = atoi(zArg);
1437 int j;
1438 for(j=0; zArg[j]; j++){
1439 zArg[j] = (char)tolower(zArg[j]);
1440 }
1441 if( strcmp(zArg,"on")==0 ){
1442 val = 1;
1443 }else if( strcmp(zArg,"yes")==0 ){
1444 val = 1;
@@ -1460,11 +1498,11 @@
1460 char *azArg[50];
1461
1462 /* Parse the input line into tokens.
1463 */
1464 while( zLine[i] && nArg<ArraySize(azArg) ){
1465 while( isspace((unsigned char)zLine[i]) ){ i++; }
1466 if( zLine[i]==0 ) break;
1467 if( zLine[i]=='\'' || zLine[i]=='"' ){
1468 int delim = zLine[i++];
1469 azArg[nArg++] = &zLine[i];
1470 while( zLine[i] && zLine[i]!=delim ){ i++; }
@@ -1472,11 +1510,11 @@
1472 zLine[i++] = 0;
1473 }
1474 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
1475 }else{
1476 azArg[nArg++] = &zLine[i];
1477 while( zLine[i] && !isspace((unsigned char)zLine[i]) ){ i++; }
1478 if( zLine[i] ) zLine[i++] = 0;
1479 resolve_backslashes(azArg[nArg-1]);
1480 }
1481 }
1482
@@ -1543,29 +1581,29 @@
1543 rc = 1;
1544 }
1545 }else
1546
1547 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
1548 char *zErrMsg = 0;
1549 open_db(p);
1550 /* When playing back a "dump", the content might appear in an order
1551 ** which causes immediate foreign key constraints to be violated.
1552 ** So disable foreign-key constraint enforcement to prevent problems. */
1553 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
1554 fprintf(p->out, "BEGIN TRANSACTION;\n");
1555 p->writableSchema = 0;
1556 sqlite3_exec(p->db, "PRAGMA writable_schema=ON", 0, 0, 0);
 
1557 if( nArg==1 ){
1558 run_schema_dump_query(p,
1559 "SELECT name, type, sql FROM sqlite_master "
1560 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'", 0
1561 );
1562 run_schema_dump_query(p,
1563 "SELECT name, type, sql FROM sqlite_master "
1564 "WHERE name=='sqlite_sequence'", 0
1565 );
1566 run_table_dump_query(p->out, p->db,
1567 "SELECT sql FROM sqlite_master "
1568 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
1569 );
1570 }else{
1571 int i;
@@ -1572,12 +1610,12 @@
1572 for(i=1; i<nArg; i++){
1573 zShellStatic = azArg[i];
1574 run_schema_dump_query(p,
1575 "SELECT name, type, sql FROM sqlite_master "
1576 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
1577 " AND sql NOT NULL", 0);
1578 run_table_dump_query(p->out, p->db,
1579 "SELECT sql FROM sqlite_master "
1580 "WHERE sql NOT NULL"
1581 " AND type IN ('index','trigger','view')"
1582 " AND tbl_name LIKE shellstatic()", 0
1583 );
@@ -1586,17 +1624,13 @@
1586 }
1587 if( p->writableSchema ){
1588 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1589 p->writableSchema = 0;
1590 }
1591 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF", 0, 0, 0);
1592 if( zErrMsg ){
1593 fprintf(stderr,"Error: %s\n", zErrMsg);
1594 sqlite3_free(zErrMsg);
1595 }else{
1596 fprintf(p->out, "COMMIT;\n");
1597 }
1598 }else
1599
1600 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
1601 p->echoOn = booleanValue(azArg[1]);
1602 }else
@@ -1671,11 +1705,11 @@
1671 nSep = strlen30(p->separator);
1672 if( nSep==0 ){
1673 fprintf(stderr, "Error: non-null separator required for import\n");
1674 return 1;
1675 }
1676 zSql = sqlite3_mprintf("SELECT * FROM '%q'", zTable);
1677 if( zSql==0 ){
1678 fprintf(stderr, "Error: out of memory\n");
1679 return 1;
1680 }
1681 nByte = strlen30(zSql);
@@ -1693,11 +1727,11 @@
1693 zSql = malloc( nByte + 20 + nCol*2 );
1694 if( zSql==0 ){
1695 fprintf(stderr, "Error: out of memory\n");
1696 return 1;
1697 }
1698 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO '%q' VALUES(?", zTable);
1699 j = strlen30(zSql);
1700 for(i=1; i<nCol; i++){
1701 zSql[j++] = ',';
1702 zSql[j++] = '?';
1703 }
@@ -1725,11 +1759,10 @@
1725 }
1726 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1727 zCommit = "COMMIT";
1728 while( (zLine = local_getline(0, in))!=0 ){
1729 char *z;
1730 i = 0;
1731 lineno++;
1732 azCol[0] = zLine;
1733 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
1734 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1735 *z = 0;
@@ -2014,11 +2047,11 @@
2014 memcpy(&data, p, sizeof(data));
2015 data.showHeader = 0;
2016 data.mode = MODE_Semi;
2017 if( nArg>1 ){
2018 int i;
2019 for(i=0; azArg[1][i]; i++) azArg[1][i] = (char)tolower(azArg[1][i]);
2020 if( strcmp(azArg[1],"sqlite_master")==0 ){
2021 char *new_argv[2], *new_colv[2];
2022 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2023 " type text,\n"
2024 " name text,\n"
@@ -2200,11 +2233,11 @@
2200 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
2201 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2202 if( testctrl<0 ){
2203 testctrl = aCtrl[i].ctrlCode;
2204 }else{
2205 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[i]);
2206 testctrl = -1;
2207 break;
2208 }
2209 }
2210 }
@@ -2337,11 +2370,11 @@
2337 /*
2338 ** Test to see if a line consists entirely of whitespace.
2339 */
2340 static int _all_whitespace(const char *z){
2341 for(; *z; z++){
2342 if( isspace(*(unsigned char*)z) ) continue;
2343 if( *z=='/' && z[1]=='*' ){
2344 z += 2;
2345 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2346 if( *z==0 ) return 0;
2347 z++;
@@ -2362,15 +2395,15 @@
2362 ** Return TRUE if the line typed in is an SQL command terminator other
2363 ** than a semi-colon. The SQL Server style "go" command is understood
2364 ** as is the Oracle "/".
2365 */
2366 static int _is_command_terminator(const char *zLine){
2367 while( isspace(*(unsigned char*)zLine) ){ zLine++; };
2368 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2369 return 1; /* Oracle */
2370 }
2371 if( tolower(zLine[0])=='g' && tolower(zLine[1])=='o'
2372 && _all_whitespace(&zLine[2]) ){
2373 return 1; /* SQL Server */
2374 }
2375 return 0;
2376 }
@@ -2436,11 +2469,11 @@
2436 memcpy(zLine,";",2);
2437 }
2438 nSqlPrior = nSql;
2439 if( zSql==0 ){
2440 int i;
2441 for(i=0; zLine[i] && isspace((unsigned char)zLine[i]); i++){}
2442 if( zLine[i]!=0 ){
2443 nSql = strlen30(zLine);
2444 zSql = malloc( nSql+3 );
2445 if( zSql==0 ){
2446 fprintf(stderr, "Error: out of memory\n");
@@ -2630,10 +2663,13 @@
2630 " -version show SQLite version\n"
2631 " -vfs NAME use NAME as the default VFS\n"
2632 #ifdef SQLITE_ENABLE_VFSTRACE
2633 " -vfstrace enable tracing of all VFS calls\n"
2634 #endif
 
 
 
2635 ;
2636 static void usage(int showDetail){
2637 fprintf(stderr,
2638 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2639 "FILENAME is the name of an SQLite database. A new database is created\n"
@@ -2705,10 +2741,11 @@
2705 ** we do the actual processing of arguments later in a second pass.
2706 */
2707 }else if( strcmp(argv[i],"-batch")==0 ){
2708 stdin_is_interactive = 0;
2709 }else if( strcmp(argv[i],"-heap")==0 ){
 
2710 int j, c;
2711 const char *zSize;
2712 sqlite3_int64 szHeap;
2713
2714 zSize = argv[++i];
@@ -2717,11 +2754,10 @@
2717 if( c=='M' ){ szHeap *= 1000000; break; }
2718 if( c=='K' ){ szHeap *= 1000; break; }
2719 if( c=='G' ){ szHeap *= 1000000000; break; }
2720 }
2721 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
2722 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2723 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2724 #endif
2725 #ifdef SQLITE_ENABLE_VFSTRACE
2726 }else if( strcmp(argv[i],"-vfstrace")==0 ){
2727 extern int vfstrace_register(
@@ -2731,10 +2767,15 @@
2731 void *pOutArg,
2732 int makeDefault
2733 );
2734 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
2735 #endif
 
 
 
 
 
2736 }else if( strcmp(argv[i],"-vfs")==0 ){
2737 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
2738 if( pVfs ){
2739 sqlite3_vfs_register(pVfs, 1);
2740 }else{
@@ -2753,11 +2794,11 @@
2753 #ifndef SQLITE_OMIT_MEMORYDB
2754 data.zDbFilename = ":memory:";
2755 #else
2756 data.zDbFilename = 0;
2757 #endif
2758 /***** Begin Fossil Patch *****/
2759 {
2760 extern void fossil_open(const char **);
2761 fossil_open(&data.zDbFilename);
2762 }
2763 /***** End Fossil Patch *****/
@@ -2855,12 +2896,18 @@
2855 stdin_is_interactive = 0;
2856 }else if( strcmp(z,"-heap")==0 ){
2857 i++;
2858 }else if( strcmp(z,"-vfs")==0 ){
2859 i++;
 
2860 }else if( strcmp(z,"-vfstrace")==0 ){
2861 i++;
 
 
 
 
 
2862 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
2863 usage(1);
2864 }else{
2865 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
2866 fprintf(stderr,"Use -help for a list of options.\n");
2867
--- src/shell.c
+++ src/shell.c
@@ -10,15 +10,26 @@
10 **
11 *************************************************************************
12 ** This file contains code to implement the "sqlite" command line
13 ** utility for accessing SQLite databases.
14 */
15 #if (defined(_WIN32) || defined(WIN32)) && !defined(_CRT_SECURE_NO_WARNINGS)
16 /* This needs to come before any includes for MSVC compiler */
17 #define _CRT_SECURE_NO_WARNINGS
18 #endif
19
20 /*
21 ** Enable large-file support for fopen() and friends on unix.
22 */
23 #ifndef SQLITE_DISABLE_LFS
24 # define _LARGE_FILE 1
25 # ifndef _FILE_OFFSET_BITS
26 # define _FILE_OFFSET_BITS 64
27 # endif
28 # define _LARGEFILE_SOURCE 1
29 #endif
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <assert.h>
35 #include "sqlite3.h"
@@ -58,11 +69,11 @@
69 #define isatty(h) _isatty(h)
70 #define access(f,m) _access((f),(m))
71 #else
72 /* Make sure isatty() has a prototype.
73 */
74 extern int isatty(int);
75 #endif
76
77 #if defined(_WIN32_WCE)
78 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
79 * thus we always assume that we have a console. That can be
@@ -71,10 +82,15 @@
82 #define isatty(x) 1
83 #endif
84
85 /* True if the timer is enabled */
86 static int enableTimer = 0;
87
88 /* ctype macros that work with signed characters */
89 #define IsSpace(X) isspace((unsigned char)X)
90 #define IsDigit(X) isdigit((unsigned char)X)
91 #define ToLower(X) (char)tolower((unsigned char)X)
92
93 #if !defined(_WIN32) && !defined(WIN32) && !defined(__OS2__) && !defined(__RTP__) && !defined(_WRS_KERNEL)
94 #include <sys/time.h>
95 #include <sys/resource.h>
96
@@ -263,27 +279,27 @@
279 /*
280 ** Determines if a string is a number of not.
281 */
282 static int isNumber(const char *z, int *realnum){
283 if( *z=='-' || *z=='+' ) z++;
284 if( !IsDigit(*z) ){
285 return 0;
286 }
287 z++;
288 if( realnum ) *realnum = 0;
289 while( IsDigit(*z) ){ z++; }
290 if( *z=='.' ){
291 z++;
292 if( !IsDigit(*z) ) return 0;
293 while( IsDigit(*z) ){ z++; }
294 if( realnum ) *realnum = 1;
295 }
296 if( *z=='e' || *z=='E' ){
297 z++;
298 if( *z=='+' || *z=='-' ) z++;
299 if( !IsDigit(*z) ) return 0;
300 while( IsDigit(*z) ){ z++; }
301 if( realnum ) *realnum = 1;
302 }
303 return *z==0;
304 }
305
@@ -320,22 +336,20 @@
336 */
337 static char *local_getline(char *zPrompt, FILE *in){
338 char *zLine;
339 int nLine;
340 int n;
 
341
342 if( zPrompt && *zPrompt ){
343 printf("%s",zPrompt);
344 fflush(stdout);
345 }
346 nLine = 100;
347 zLine = malloc( nLine );
348 if( zLine==0 ) return 0;
349 n = 0;
350 while( 1 ){
 
351 if( n+100>nLine ){
352 nLine = nLine*2 + 100;
353 zLine = realloc(zLine, nLine);
354 if( zLine==0 ) return 0;
355 }
@@ -343,19 +357,18 @@
357 if( n==0 ){
358 free(zLine);
359 return 0;
360 }
361 zLine[n] = 0;
 
362 break;
363 }
364 while( zLine[n] ){ n++; }
365 if( n>0 && zLine[n-1]=='\n' ){
366 n--;
367 if( n>0 && zLine[n-1]=='\r' ) n--;
368 zLine[n] = 0;
369 break;
370 }
371 }
372 zLine = realloc( zLine, n+1 );
373 return zLine;
374 }
@@ -400,10 +413,11 @@
413 sqlite3 *db; /* The database */
414 int echoOn; /* True to echo input commands */
415 int statsOn; /* True to display memory stats before each finalize */
416 int cnt; /* Number of records displayed so far */
417 FILE *out; /* Write results here */
418 int nErr; /* Number of errors seen */
419 int mode; /* An output mode setting */
420 int writableSchema; /* True if PRAGMA writable_schema=ON */
421 int showHeader; /* True to show column names in List or Column mode */
422 char *zDestTable; /* Name of destination table when MODE_Insert */
423 char separator[20]; /* Separator character for MODE_List */
@@ -925,31 +939,37 @@
939 **
940 ** This is used, for example, to show the schema of the database by
941 ** querying the SQLITE_MASTER table.
942 */
943 static int run_table_dump_query(
944 struct callback_data *p, /* Query context */
945 const char *zSelect, /* SELECT statement to extract content */
946 const char *zFirstRow /* Print before first row, if not NULL */
 
947 ){
948 sqlite3_stmt *pSelect;
949 int rc;
950 rc = sqlite3_prepare(p->db, zSelect, -1, &pSelect, 0);
951 if( rc!=SQLITE_OK || !pSelect ){
952 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
953 p->nErr++;
954 return rc;
955 }
956 rc = sqlite3_step(pSelect);
957 while( rc==SQLITE_ROW ){
958 if( zFirstRow ){
959 fprintf(p->out, "%s", zFirstRow);
960 zFirstRow = 0;
961 }
962 fprintf(p->out, "%s;\n", sqlite3_column_text(pSelect, 0));
963 rc = sqlite3_step(pSelect);
964 }
965 rc = sqlite3_finalize(pSelect);
966 if( rc!=SQLITE_OK ){
967 fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite3_errmsg(p->db));
968 p->nErr++;
969 }
970 return rc;
971 }
972
973 /*
974 ** Allocate space and save off current error string.
975 */
@@ -1027,11 +1047,16 @@
1047 fprintf(pArg->out, "Lookaside failures due to size: %d\n", iHiwtr);
1048 sqlite3_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
1049 fprintf(pArg->out, "Lookaside failures due to OOM: %d\n", iHiwtr);
1050 iHiwtr = iCur = -1;
1051 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_USED, &iCur, &iHiwtr, bReset);
1052 fprintf(pArg->out, "Pager Heap Usage: %d bytes\n", iCur); iHiwtr = iCur = -1;
1053 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_HIT, &iCur, &iHiwtr, 1);
1054 fprintf(pArg->out, "Page cache hits: %d\n", iCur);
1055 iHiwtr = iCur = -1;
1056 sqlite3_db_status(db, SQLITE_DBSTATUS_CACHE_MISS, &iCur, &iHiwtr, 1);
1057 fprintf(pArg->out, "Page cache misses: %d\n", iCur);
1058 iHiwtr = iCur = -1;
1059 sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
1060 fprintf(pArg->out, "Schema Heap Usage: %d bytes\n", iCur);
1061 iHiwtr = iCur = -1;
1062 sqlite3_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
@@ -1067,10 +1092,11 @@
1092 struct callback_data *pArg, /* Pointer to struct callback_data */
1093 char **pzErrMsg /* Error msg written here */
1094 ){
1095 sqlite3_stmt *pStmt = NULL; /* Statement to execute. */
1096 int rc = SQLITE_OK; /* Return Code */
1097 int rc2;
1098 const char *zLeftover; /* Tail of unprocessed SQL */
1099
1100 if( pzErrMsg ){
1101 *pzErrMsg = NULL;
1102 }
@@ -1083,11 +1109,11 @@
1109 }
1110 }else{
1111 if( !pStmt ){
1112 /* this happens for a comment or white-space */
1113 zSql = zLeftover;
1114 while( IsSpace(zSql[0]) ) zSql++;
1115 continue;
1116 }
1117
1118 /* save off the prepared statment handle and reset row count */
1119 if( pArg ){
@@ -1160,14 +1186,15 @@
1186 }
1187
1188 /* Finalize the statement just executed. If this fails, save a
1189 ** copy of the error message. Otherwise, set zSql to point to the
1190 ** next statement to execute. */
1191 rc2 = sqlite3_finalize(pStmt);
1192 if( rc!=SQLITE_NOMEM ) rc = rc2;
1193 if( rc==SQLITE_OK ){
1194 zSql = zLeftover;
1195 while( IsSpace(zSql[0]) ) zSql++;
1196 }else if( pzErrMsg ){
1197 *pzErrMsg = save_err_msg(db);
1198 }
1199
1200 /* clear saved stmt handle */
@@ -1266,14 +1293,14 @@
1293 return 1;
1294 }
1295 zSelect = appendText(zSelect, "|| ')' FROM ", 0);
1296 zSelect = appendText(zSelect, zTable, '"');
1297
1298 rc = run_table_dump_query(p, zSelect, zPrepStmt);
1299 if( rc==SQLITE_CORRUPT ){
1300 zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
1301 run_table_dump_query(p, zSelect, 0);
1302 }
1303 if( zSelect ) free(zSelect);
1304 }
1305 return 0;
1306 }
@@ -1285,23 +1312,34 @@
1312 ** If we get a SQLITE_CORRUPT error, rerun the query after appending
1313 ** "ORDER BY rowid DESC" to the end.
1314 */
1315 static int run_schema_dump_query(
1316 struct callback_data *p,
1317 const char *zQuery
 
1318 ){
1319 int rc;
1320 char *zErr = 0;
1321 rc = sqlite3_exec(p->db, zQuery, dump_callback, p, &zErr);
1322 if( rc==SQLITE_CORRUPT ){
1323 char *zQ2;
1324 int len = strlen30(zQuery);
1325 fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
1326 if( zErr ){
1327 fprintf(p->out, "/****** %s ******/\n", zErr);
1328 sqlite3_free(zErr);
1329 zErr = 0;
1330 }
1331 zQ2 = malloc( len+100 );
1332 if( zQ2==0 ) return rc;
1333 sqlite3_snprintf(sizeof(zQ2), zQ2, "%s ORDER BY rowid DESC", zQuery);
1334 rc = sqlite3_exec(p->db, zQ2, dump_callback, p, &zErr);
1335 if( rc ){
1336 fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
1337 }else{
1338 rc = SQLITE_CORRUPT;
1339 }
1340 sqlite3_free(zErr);
1341 free(zQ2);
1342 }
1343 return rc;
1344 }
1345
@@ -1434,11 +1472,11 @@
1472 */
1473 static int booleanValue(char *zArg){
1474 int val = atoi(zArg);
1475 int j;
1476 for(j=0; zArg[j]; j++){
1477 zArg[j] = ToLower(zArg[j]);
1478 }
1479 if( strcmp(zArg,"on")==0 ){
1480 val = 1;
1481 }else if( strcmp(zArg,"yes")==0 ){
1482 val = 1;
@@ -1460,11 +1498,11 @@
1498 char *azArg[50];
1499
1500 /* Parse the input line into tokens.
1501 */
1502 while( zLine[i] && nArg<ArraySize(azArg) ){
1503 while( IsSpace(zLine[i]) ){ i++; }
1504 if( zLine[i]==0 ) break;
1505 if( zLine[i]=='\'' || zLine[i]=='"' ){
1506 int delim = zLine[i++];
1507 azArg[nArg++] = &zLine[i];
1508 while( zLine[i] && zLine[i]!=delim ){ i++; }
@@ -1472,11 +1510,11 @@
1510 zLine[i++] = 0;
1511 }
1512 if( delim=='"' ) resolve_backslashes(azArg[nArg-1]);
1513 }else{
1514 azArg[nArg++] = &zLine[i];
1515 while( zLine[i] && !IsSpace(zLine[i]) ){ i++; }
1516 if( zLine[i] ) zLine[i++] = 0;
1517 resolve_backslashes(azArg[nArg-1]);
1518 }
1519 }
1520
@@ -1543,29 +1581,29 @@
1581 rc = 1;
1582 }
1583 }else
1584
1585 if( c=='d' && strncmp(azArg[0], "dump", n)==0 && nArg<3 ){
 
1586 open_db(p);
1587 /* When playing back a "dump", the content might appear in an order
1588 ** which causes immediate foreign key constraints to be violated.
1589 ** So disable foreign-key constraint enforcement to prevent problems. */
1590 fprintf(p->out, "PRAGMA foreign_keys=OFF;\n");
1591 fprintf(p->out, "BEGIN TRANSACTION;\n");
1592 p->writableSchema = 0;
1593 sqlite3_exec(p->db, "SAVEPOINT dump; PRAGMA writable_schema=ON", 0, 0, 0);
1594 p->nErr = 0;
1595 if( nArg==1 ){
1596 run_schema_dump_query(p,
1597 "SELECT name, type, sql FROM sqlite_master "
1598 "WHERE sql NOT NULL AND type=='table' AND name!='sqlite_sequence'"
1599 );
1600 run_schema_dump_query(p,
1601 "SELECT name, type, sql FROM sqlite_master "
1602 "WHERE name=='sqlite_sequence'"
1603 );
1604 run_table_dump_query(p,
1605 "SELECT sql FROM sqlite_master "
1606 "WHERE sql NOT NULL AND type IN ('index','trigger','view')", 0
1607 );
1608 }else{
1609 int i;
@@ -1572,12 +1610,12 @@
1610 for(i=1; i<nArg; i++){
1611 zShellStatic = azArg[i];
1612 run_schema_dump_query(p,
1613 "SELECT name, type, sql FROM sqlite_master "
1614 "WHERE tbl_name LIKE shellstatic() AND type=='table'"
1615 " AND sql NOT NULL");
1616 run_table_dump_query(p,
1617 "SELECT sql FROM sqlite_master "
1618 "WHERE sql NOT NULL"
1619 " AND type IN ('index','trigger','view')"
1620 " AND tbl_name LIKE shellstatic()", 0
1621 );
@@ -1586,17 +1624,13 @@
1624 }
1625 if( p->writableSchema ){
1626 fprintf(p->out, "PRAGMA writable_schema=OFF;\n");
1627 p->writableSchema = 0;
1628 }
1629 sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
1630 sqlite3_exec(p->db, "RELEASE dump;", 0, 0, 0);
1631 fprintf(p->out, p->nErr ? "ROLLBACK; -- due to errors\n" : "COMMIT;\n");
 
 
 
 
1632 }else
1633
1634 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
1635 p->echoOn = booleanValue(azArg[1]);
1636 }else
@@ -1671,11 +1705,11 @@
1705 nSep = strlen30(p->separator);
1706 if( nSep==0 ){
1707 fprintf(stderr, "Error: non-null separator required for import\n");
1708 return 1;
1709 }
1710 zSql = sqlite3_mprintf("SELECT * FROM %s", zTable);
1711 if( zSql==0 ){
1712 fprintf(stderr, "Error: out of memory\n");
1713 return 1;
1714 }
1715 nByte = strlen30(zSql);
@@ -1693,11 +1727,11 @@
1727 zSql = malloc( nByte + 20 + nCol*2 );
1728 if( zSql==0 ){
1729 fprintf(stderr, "Error: out of memory\n");
1730 return 1;
1731 }
1732 sqlite3_snprintf(nByte+20, zSql, "INSERT INTO %s VALUES(?", zTable);
1733 j = strlen30(zSql);
1734 for(i=1; i<nCol; i++){
1735 zSql[j++] = ',';
1736 zSql[j++] = '?';
1737 }
@@ -1725,11 +1759,10 @@
1759 }
1760 sqlite3_exec(p->db, "BEGIN", 0, 0, 0);
1761 zCommit = "COMMIT";
1762 while( (zLine = local_getline(0, in))!=0 ){
1763 char *z;
 
1764 lineno++;
1765 azCol[0] = zLine;
1766 for(i=0, z=zLine; *z && *z!='\n' && *z!='\r'; z++){
1767 if( *z==p->separator[0] && strncmp(z, p->separator, nSep)==0 ){
1768 *z = 0;
@@ -2014,11 +2047,11 @@
2047 memcpy(&data, p, sizeof(data));
2048 data.showHeader = 0;
2049 data.mode = MODE_Semi;
2050 if( nArg>1 ){
2051 int i;
2052 for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
2053 if( strcmp(azArg[1],"sqlite_master")==0 ){
2054 char *new_argv[2], *new_colv[2];
2055 new_argv[0] = "CREATE TABLE sqlite_master (\n"
2056 " type text,\n"
2057 " name text,\n"
@@ -2200,11 +2233,11 @@
2233 for(i=0; i<(int)(sizeof(aCtrl)/sizeof(aCtrl[0])); i++){
2234 if( strncmp(azArg[1], aCtrl[i].zCtrlName, n)==0 ){
2235 if( testctrl<0 ){
2236 testctrl = aCtrl[i].ctrlCode;
2237 }else{
2238 fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
2239 testctrl = -1;
2240 break;
2241 }
2242 }
2243 }
@@ -2337,11 +2370,11 @@
2370 /*
2371 ** Test to see if a line consists entirely of whitespace.
2372 */
2373 static int _all_whitespace(const char *z){
2374 for(; *z; z++){
2375 if( IsSpace(z[0]) ) continue;
2376 if( *z=='/' && z[1]=='*' ){
2377 z += 2;
2378 while( *z && (*z!='*' || z[1]!='/') ){ z++; }
2379 if( *z==0 ) return 0;
2380 z++;
@@ -2362,15 +2395,15 @@
2395 ** Return TRUE if the line typed in is an SQL command terminator other
2396 ** than a semi-colon. The SQL Server style "go" command is understood
2397 ** as is the Oracle "/".
2398 */
2399 static int _is_command_terminator(const char *zLine){
2400 while( IsSpace(zLine[0]) ){ zLine++; };
2401 if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
2402 return 1; /* Oracle */
2403 }
2404 if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
2405 && _all_whitespace(&zLine[2]) ){
2406 return 1; /* SQL Server */
2407 }
2408 return 0;
2409 }
@@ -2436,11 +2469,11 @@
2469 memcpy(zLine,";",2);
2470 }
2471 nSqlPrior = nSql;
2472 if( zSql==0 ){
2473 int i;
2474 for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
2475 if( zLine[i]!=0 ){
2476 nSql = strlen30(zLine);
2477 zSql = malloc( nSql+3 );
2478 if( zSql==0 ){
2479 fprintf(stderr, "Error: out of memory\n");
@@ -2630,10 +2663,13 @@
2663 " -version show SQLite version\n"
2664 " -vfs NAME use NAME as the default VFS\n"
2665 #ifdef SQLITE_ENABLE_VFSTRACE
2666 " -vfstrace enable tracing of all VFS calls\n"
2667 #endif
2668 #ifdef SQLITE_ENABLE_MULTIPLEX
2669 " -multiplex enable the multiplexor VFS\n"
2670 #endif
2671 ;
2672 static void usage(int showDetail){
2673 fprintf(stderr,
2674 "Usage: %s [OPTIONS] FILENAME [SQL]\n"
2675 "FILENAME is the name of an SQLite database. A new database is created\n"
@@ -2705,10 +2741,11 @@
2741 ** we do the actual processing of arguments later in a second pass.
2742 */
2743 }else if( strcmp(argv[i],"-batch")==0 ){
2744 stdin_is_interactive = 0;
2745 }else if( strcmp(argv[i],"-heap")==0 ){
2746 #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
2747 int j, c;
2748 const char *zSize;
2749 sqlite3_int64 szHeap;
2750
2751 zSize = argv[++i];
@@ -2717,11 +2754,10 @@
2754 if( c=='M' ){ szHeap *= 1000000; break; }
2755 if( c=='K' ){ szHeap *= 1000; break; }
2756 if( c=='G' ){ szHeap *= 1000000000; break; }
2757 }
2758 if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
 
2759 sqlite3_config(SQLITE_CONFIG_HEAP, malloc((int)szHeap), (int)szHeap, 64);
2760 #endif
2761 #ifdef SQLITE_ENABLE_VFSTRACE
2762 }else if( strcmp(argv[i],"-vfstrace")==0 ){
2763 extern int vfstrace_register(
@@ -2731,10 +2767,15 @@
2767 void *pOutArg,
2768 int makeDefault
2769 );
2770 vfstrace_register("trace",0,(int(*)(const char*,void*))fputs,stderr,1);
2771 #endif
2772 #ifdef SQLITE_ENABLE_MULTIPLEX
2773 }else if( strcmp(argv[i],"-multiplex")==0 ){
2774 extern int sqlite3_multiple_initialize(const char*,int);
2775 sqlite3_multiplex_initialize(0, 1);
2776 #endif
2777 }else if( strcmp(argv[i],"-vfs")==0 ){
2778 sqlite3_vfs *pVfs = sqlite3_vfs_find(argv[++i]);
2779 if( pVfs ){
2780 sqlite3_vfs_register(pVfs, 1);
2781 }else{
@@ -2753,11 +2794,11 @@
2794 #ifndef SQLITE_OMIT_MEMORYDB
2795 data.zDbFilename = ":memory:";
2796 #else
2797 data.zDbFilename = 0;
2798 #endif
2799 /***** Begin Fossil Patch *****/
2800 {
2801 extern void fossil_open(const char **);
2802 fossil_open(&data.zDbFilename);
2803 }
2804 /***** End Fossil Patch *****/
@@ -2855,12 +2896,18 @@
2896 stdin_is_interactive = 0;
2897 }else if( strcmp(z,"-heap")==0 ){
2898 i++;
2899 }else if( strcmp(z,"-vfs")==0 ){
2900 i++;
2901 #ifdef SQLITE_ENABLE_VFSTRACE
2902 }else if( strcmp(z,"-vfstrace")==0 ){
2903 i++;
2904 #endif
2905 #ifdef SQLITE_ENABLE_MULTIPLEX
2906 }else if( strcmp(z,"-multiplex")==0 ){
2907 i++;
2908 #endif
2909 }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
2910 usage(1);
2911 }else{
2912 fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
2913 fprintf(stderr,"Use -help for a list of options.\n");
2914
+278 -68
--- src/skins.c
+++ src/skins.c
@@ -86,29 +86,30 @@
8686
@ text-align: center;
8787
@ letter-spacing: 1px;
8888
@ background-color: #404040;
8989
@ color: white;
9090
@ }
91
-@
91
+@
9292
@ /* The submenu bar that *sometimes* appears below the main menu */
93
-@ div.submenu {
93
+@ div.submenu, div.sectionmenu {
9494
@ padding: 3px 10px 3px 0px;
9595
@ font-size: 0.9em;
9696
@ text-align: center;
9797
@ background-color: #606060;
9898
@ color: white;
9999
@ }
100
-@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
100
+@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited,
101
+@ div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited {
101102
@ padding: 3px 10px 3px 10px;
102103
@ color: white;
103104
@ text-decoration: none;
104105
@ }
105
-@ div.mainmenu a:hover, div.submenu a:hover {
106
+@ div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover {
106107
@ color: #404040;
107108
@ background-color: white;
108109
@ }
109
-@
110
+@
110111
@ /* All page content from the bottom of the menu or submenu down to
111112
@ ** the footer */
112113
@ div.content {
113114
@ padding: 0ex 0ex 0ex 0ex;
114115
@ }
@@ -152,10 +153,55 @@
152153
@ /* The label/value pairs on (for example) the vinfo page */
153154
@ table.label-value th {
154155
@ vertical-align: top;
155156
@ text-align: right;
156157
@ padding: 0.2ex 2ex;
158
+@ }
159
+@
160
+@ /* Side-by-side diff */
161
+@ table.sbsdiff {
162
+@ background-color: white;
163
+@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
164
+@ font-size: 8pt;
165
+@ border-collapse:collapse;
166
+@ white-space: pre;
167
+@ width: 98%;
168
+@ border: 1px #000 dashed;
169
+@ }
170
+@
171
+@ table.sbsdiff th.diffhdr {
172
+@ border-bottom: dotted;
173
+@ border-width: 1px;
174
+@ }
175
+@
176
+@ table.sbsdiff tr td {
177
+@ white-space: pre;
178
+@ padding-left: 3px;
179
+@ padding-right: 3px;
180
+@ margin: 0px;
181
+@ }
182
+@
183
+@ table.sbsdiff tr td.lineno {
184
+@ text-align: right;
185
+@ }
186
+@
187
+@ table.sbsdiff tr td.meta {
188
+@ color: white;
189
+@ background-color: rgb(20, 20, 20);
190
+@ text-align: center;
191
+@ }
192
+@
193
+@ table.sbsdiff tr td.added {
194
+@ background-color: rgb(230, 230, 230);
195
+@ }
196
+@
197
+@ table.sbsdiff tr td.removed {
198
+@ background-color: rgb(200, 200, 200);
199
+@ }
200
+@
201
+@ table.sbsdiff tr td.changed {
202
+@ background-color: rgb(220, 220, 220);
157203
@ }');
158204
@ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
159205
@ <head>
160206
@ <title>$<project_name>: $<title></title>
161207
@ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -163,49 +209,47 @@
163209
@ <link rel="stylesheet" href="$home/style.css?blackwhite" type="text/css"
164210
@ media="screen">
165211
@ </head>
166212
@ <body>
167213
@ <div class="header">
168
-@ <div class="logo">
169
-@ <img src="$home/logo" alt="logo">
170
-@ </div>
171214
@ <div class="title"><small>$<project_name></small><br />$<title></div>
172215
@ <div class="status"><nobr><th1>
173216
@ if {[info exists login]} {
174217
@ puts "Logged in as $login"
175218
@ } else {
176219
@ puts "Not logged in"
177220
@ }
178221
@ </th1></nobr></div>
179222
@ </div>
180
-@ <div class="mainmenu"><th1>
181
-@ html "<a href=''$home$index_page''>Home</a> "
223
+@ <div class="mainmenu">
224
+@ <th1>
225
+@ html "<a href=''$home$index_page''>Home</a>\n"
182226
@ if {[anycap jor]} {
183
-@ html "<a href=''$home/timeline''>Timeline</a> "
227
+@ html "<a href=''$home/timeline''>Timeline</a>\n"
184228
@ }
185229
@ if {[hascap oh]} {
186
-@ html "<a href=''$home/dir?ci=tip''>Files</a> "
230
+@ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
187231
@ }
188232
@ if {[hascap o]} {
189
-@ html "<a href=''$home/brlist''>Branches</a> "
190
-@ html "<a href=''$home/taglist''>Tags</a> "
233
+@ html "<a href=''$home/brlist''>Branches</a>\n"
234
+@ html "<a href=''$home/taglist''>Tags</a>\n"
191235
@ }
192236
@ if {[hascap r]} {
193
-@ html "<a href=''$home/reportlist''>Tickets</a> "
237
+@ html "<a href=''$home/reportlist''>Tickets</a>\n"
194238
@ }
195239
@ if {[hascap j]} {
196
-@ html "<a href=''$home/wiki''>Wiki</a> "
240
+@ html "<a href=''$home/wiki''>Wiki</a>\n"
197241
@ }
198242
@ if {[hascap s]} {
199
-@ html "<a href=''$home/setup''>Admin</a> "
243
+@ html "<a href=''$home/setup''>Admin</a>\n"
200244
@ } elseif {[hascap a]} {
201
-@ html "<a href=''$home/setup_ulist''>Users</a> "
245
+@ html "<a href=''$home/setup_ulist''>Users</a>\n"
202246
@ }
203247
@ if {[info exists login]} {
204
-@ html "<a href=''$home/login''>Logout</a> "
248
+@ html "<a href=''$home/login''>Logout</a>\n"
205249
@ } else {
206
-@ html "<a href=''$home/login''>Login</a> "
250
+@ html "<a href=''$home/login''>Login</a>\n"
207251
@ }
208252
@ </th1></div>
209253
@ ');
210254
@ REPLACE INTO config(name,mtime,value)
211255
@ VALUES('footer',now(),'<div class="footer">
@@ -279,23 +323,24 @@
279323
@ background-color: #a09048;
280324
@ color: black;
281325
@ }
282326
@
283327
@ /* The submenu bar that *sometimes* appears below the main menu */
284
-@ div.submenu {
328
+@ div.submenu, div.sectionmenu {
285329
@ padding: 3px 10px 3px 0px;
286330
@ font-size: 0.9em;
287331
@ text-align: center;
288332
@ background-color: #c0af58;
289333
@ color: white;
290334
@ }
291
-@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
335
+@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited,
336
+@ div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited {
292337
@ padding: 3px 10px 3px 10px;
293338
@ color: white;
294339
@ text-decoration: none;
295340
@ }
296
-@ div.mainmenu a:hover, div.submenu a:hover {
341
+@ div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover {
297342
@ color: #a09048;
298343
@ background-color: white;
299344
@ }
300345
@
301346
@ /* All page content from the bottom of the menu or submenu down to
@@ -356,11 +401,54 @@
356401
@ table.label-value th {
357402
@ vertical-align: top;
358403
@ text-align: right;
359404
@ padding: 0.2ex 2ex;
360405
@ }
361
-@ ');
406
+@
407
+@ /* Side-by-side diff */
408
+@ table.sbsdiff {
409
+@ background-color: #ffffc5;
410
+@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
411
+@ font-size: 8pt;
412
+@ border-collapse:collapse;
413
+@ white-space: pre;
414
+@ width: 98%;
415
+@ border: 1px #000 dashed;
416
+@ }
417
+@
418
+@ table.sbsdiff th.diffhdr {
419
+@ border-bottom: dotted;
420
+@ border-width: 1px;
421
+@ }
422
+@
423
+@ table.sbsdiff tr td {
424
+@ white-space: pre;
425
+@ padding-left: 3px;
426
+@ padding-right: 3px;
427
+@ margin: 0px;
428
+@ }
429
+@
430
+@ table.sbsdiff tr td.lineno {
431
+@ text-align: right;
432
+@ }
433
+@
434
+@ table.sbsdiff tr td.meta {
435
+@ background-color: #a09048;
436
+@ text-align: center;
437
+@ }
438
+@
439
+@ table.sbsdiff tr td.added {
440
+@ background-color: rgb(210, 210, 100);
441
+@ }
442
+@
443
+@ table.sbsdiff tr td.removed {
444
+@ background-color: rgb(190, 200, 110);
445
+@ }
446
+@
447
+@ table.sbsdiff tr td.changed {
448
+@ background-color: rgb(200, 210, 120);
449
+@ }');
362450
@ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
363451
@ <head>
364452
@ <title>$<project_name>: $<title></title>
365453
@ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
366454
@ href="$home/timeline.rss">
@@ -378,37 +466,38 @@
378466
@ } else {
379467
@ puts "Not logged in"
380468
@ }
381469
@ </th1></nobr></div>
382470
@ </div>
383
-@ <div class="mainmenu"><th1>
384
-@ html "<a href=''$home$index_page''>Home</a> "
471
+@ <div class="mainmenu">
472
+@ <th1>
473
+@ html "<a href=''$home$index_page''>Home</a>\n"
385474
@ if {[anycap jor]} {
386
-@ html "<a href=''$home/timeline''>Timeline</a> "
475
+@ html "<a href=''$home/timeline''>Timeline</a>\n"
387476
@ }
388477
@ if {[hascap oh]} {
389
-@ html "<a href=''$home/dir?ci=tip''>Files</a> "
478
+@ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
390479
@ }
391480
@ if {[hascap o]} {
392
-@ html "<a href=''$home/brlist''>Branches</a> "
393
-@ html "<a href=''$home/taglist''>Tags</a> "
481
+@ html "<a href=''$home/brlist''>Branches</a>\n"
482
+@ html "<a href=''$home/taglist''>Tags</a>\n"
394483
@ }
395484
@ if {[hascap r]} {
396
-@ html "<a href=''$home/reportlist''>Tickets</a> "
485
+@ html "<a href=''$home/reportlist''>Tickets</a>\n"
397486
@ }
398487
@ if {[hascap j]} {
399
-@ html "<a href=''$home/wiki''>Wiki</a> "
488
+@ html "<a href=''$home/wiki''>Wiki</a>\n"
400489
@ }
401490
@ if {[hascap s]} {
402
-@ html "<a href=''$home/setup''>Admin</a> "
491
+@ html "<a href=''$home/setup''>Admin</a>\n"
403492
@ } elseif {[hascap a]} {
404
-@ html "<a href=''$home/setup_ulist''>Users</a> "
493
+@ html "<a href=''$home/setup_ulist''>Users</a>\n"
405494
@ }
406495
@ if {[info exists login]} {
407
-@ html "<a href=''$home/login''>Logout</a> "
496
+@ html "<a href=''$home/login''>Logout</a>\n"
408497
@ } else {
409
-@ html "<a href=''$home/login''>Login</a> "
498
+@ html "<a href=''$home/login''>Login</a>\n"
410499
@ }
411500
@ </th1></div>
412501
@ ');
413502
@ REPLACE INTO config(name,mtime,value)
414503
@ VALUES('footer',now(),'<div class="footer">
@@ -517,25 +606,26 @@
517606
@ #container {
518607
@ padding-left: 9em;
519608
@ }
520609
@
521610
@ /* The submenu bar that *sometimes* appears below the main menu */
522
-@ div.submenu {
611
+@ div.submenu, div.sectionmenu {
523612
@ padding: 3px 10px 3px 10px;
524613
@ font-size: 0.9em;
525614
@ text-align: center;
526615
@ border:1px solid #999;
527616
@ border-width:1px 0px;
528617
@ background-color: #eee;
529618
@ color: #333;
530619
@ }
531
-@ div.submenu a, div.submenu a:visited {
620
+@ div.submenu a, div.submenu a:visited, div.sectionmenu>a.button:link,
621
+@ div.sectionmenu>a.button:visited {
532622
@ padding: 3px 10px 3px 10px;
533623
@ color: #333;
534624
@ text-decoration: none;
535625
@ }
536
-@ div.submenu a:hover {
626
+@ div.submenu a:hover, div.sectionmenu>a.button:hover {
537627
@ color: #eee;
538628
@ background-color: #333;
539629
@ }
540630
@
541631
@ /* All page content from the bottom of the menu or submenu down to
@@ -590,10 +680,56 @@
590680
@ /* The label/value pairs on (for example) the ci page */
591681
@ table.label-value th {
592682
@ vertical-align: top;
593683
@ text-align: right;
594684
@ padding: 0.2ex 2ex;
685
+@ }
686
+@
687
+@ /* Side-by-side diff */
688
+@ table.sbsdiff {
689
+@ background-color: white;
690
+@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
691
+@ font-size: 6pt;
692
+@ border-collapse:collapse;
693
+@ white-space: pre;
694
+@ width: 98%;
695
+@ border: 1px #000 dashed;
696
+@ }
697
+@
698
+@ table.sbsdiff th.diffhdr {
699
+@ border-bottom: dotted;
700
+@ border-width: 1px;
701
+@ }
702
+@
703
+@ table.sbsdiff tr td {
704
+@ white-space: pre;
705
+@ padding-left: 3px;
706
+@ padding-right: 3px;
707
+@ margin: 0px;
708
+@ }
709
+@
710
+@ table.sbsdiff tr td.lineno {
711
+@ text-align: right;
712
+@ }
713
+@
714
+@ table.sbsdiff tr td.meta {
715
+@ color: white;
716
+@ background-color: black;
717
+@ text-align: center;
718
+@ }
719
+@
720
+@ table.sbsdiff tr td.added {
721
+@ background-color: white;
722
+@ }
723
+@
724
+@ table.sbsdiff tr td.removed {
725
+@ background-color: white;
726
+@ text-decoration: line-through;
727
+@ }
728
+@
729
+@ table.sbsdiff tr td.changed {
730
+@ background-color: white;
595731
@ }');
596732
@ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
597733
@ <head>
598734
@ <title>$<project_name>: $<title></title>
599735
@ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -614,37 +750,38 @@
614750
@ } else {
615751
@ puts "Not logged in"
616752
@ }
617753
@ </th1></nobr></div>
618754
@ </div>
619
-@ <div class="mainmenu"><th1>
620
-@ html "<li><a href=''$home$index_page''>Home</a></li>"
755
+@ <div class="mainmenu">
756
+@ <th1>
757
+@ html "<a href=''$home$index_page''>Home</a>\n"
621758
@ if {[anycap jor]} {
622
-@ html "<li><a href=''$home/timeline''>Timeline</a></li>"
759
+@ html "<a href=''$home/timeline''>Timeline</a>\n"
623760
@ }
624761
@ if {[hascap oh]} {
625
-@ html "<li><a href=''$home/dir?ci=tip''>Files</a></li>"
762
+@ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
626763
@ }
627764
@ if {[hascap o]} {
628
-@ html "<li><a href=''$home/brlist''>Branches</a></li>"
629
-@ html "<li><a href=''$home/taglist''>Tags</a></li>"
765
+@ html "<a href=''$home/brlist''>Branches</a>\n"
766
+@ html "<a href=''$home/taglist''>Tags</a>\n"
630767
@ }
631768
@ if {[hascap r]} {
632
-@ html "<li><a href=''$home/reportlist''>Tickets</a></li>"
769
+@ html "<a href=''$home/reportlist''>Tickets</a>\n"
633770
@ }
634771
@ if {[hascap j]} {
635
-@ html "<li><a href=''$home/wiki''>Wiki</a></li>"
772
+@ html "<a href=''$home/wiki''>Wiki</a>\n"
636773
@ }
637774
@ if {[hascap s]} {
638
-@ html "<li><a href=''$home/setup''>Admin</a></li>"
775
+@ html "<a href=''$home/setup''>Admin</a>\n"
639776
@ } elseif {[hascap a]} {
640
-@ html "<li><a href=''$home/setup_ulist''>Users</a></li>"
777
+@ html "<a href=''$home/setup_ulist''>Users</a>\n"
641778
@ }
642779
@ if {[info exists login]} {
643
-@ html "<li><a href=''$home/login''>Logout</a></li>"
780
+@ html "<a href=''$home/login''>Logout</a>\n"
644781
@ } else {
645
-@ html "<li><a href=''$home/login''>Login</a></li>"
782
+@ html "<a href=''$home/login''>Login</a>\n"
646783
@ }
647784
@ </th1></ul></div>
648785
@ <div id="container">
649786
@ ');
650787
@ REPLACE INTO config(name,mtime,value) VALUES('footer',now(),'</div>
@@ -725,12 +862,13 @@
725862
@ -webkit-border-top-left-radius: 5px;
726863
@ -border-top-right-radius: 5px;
727864
@ -border-top-left-radius: 5px;
728865
@ border-top-left-radius: 5px;
729866
@ border-top-right-radius: 5px;
730
-@ vertical-align: center;
731
-@ min-height: 2em;
867
+@ vertical-align: middle;
868
+@ padding-top: 8px;
869
+@ padding-bottom: 8px;
732870
@ background-color: #446979;
733871
@ background: -webkit-gradient(linear,left bottom,left top, color-stop(0.02, rgb(51,81,94)), color-stop(0.76, rgb(85,129,149)));
734872
@ background: -moz-linear-gradient(center bottom,rgb(51,81,94) 2%, rgb(85,129,149) 76%);
735873
@ -webkit-box-shadow: 0px 3px 4px #333333;
736874
@ -moz-box-shadow: 0px 3px 4px #333333;
@@ -753,11 +891,12 @@
753891
@ div.mainmenu a, div.mainmenu a:visited {
754892
@ padding: 3px 10px 3px 10px;
755893
@ color: white;
756894
@ text-decoration: none;
757895
@ }
758
-@ div.submenu a, div.submenu a:visited {
896
+@ div.submenu a, div.submenu a:visited, a.button,
897
+@ div.sectionmenu>a.button:link, div.sectinmenu>a.button:visited {
759898
@ padding: 2px 8px;
760899
@ color: #000;
761900
@ font-family: Arial;
762901
@ text-decoration: none;
763902
@ margin:auto;
@@ -775,11 +914,11 @@
775914
@ div.mainmenu a:hover {
776915
@ color: #000;
777916
@ background-color: white;
778917
@ }
779918
@
780
-@ div.submenu a:hover {
919
+@ div.submenu a:hover, div.sectionmenu>a.button:hover {
781920
@ background: -webkit-gradient(linear,left bottom, left top, color-stop(0, rgb(214,214,214)), color-stop(0.75, rgb(184,184,184)));
782921
@ background: -moz-linear-gradient(center bottom, rgb(214,214,214) 0%, rgb(184,184,184) 75%);
783922
@ background-color: #c0c0c0 ;
784923
@ }
785924
@
@@ -885,10 +1024,77 @@
8851024
@ padding: 3px 5px;
8861025
@ }
8871026
@
8881027
@ textarea {
8891028
@ font-size: 1em;
1029
+@ }
1030
+@
1031
+@ /* Side-by-side diff */
1032
+@ table.sbsdiff {
1033
+@ background-color: white;
1034
+@ font-family: Dejavu Sans Mono, Monaco, Lucida Console, monospace;
1035
+@ font-size: 6pt;
1036
+@ border-collapse:collapse;
1037
+@ width: 98%;
1038
+@ border: 1px #000 dashed;
1039
+@ margin-left: auto;
1040
+@ margin-right: auto;
1041
+@ }
1042
+@
1043
+@ table.sbsdiff th.diffhdr {
1044
+@ border-bottom: dotted;
1045
+@ border-width: 1px;
1046
+@ }
1047
+@
1048
+@ table.sbsdiff tr td {
1049
+@ padding-left: 3px;
1050
+@ padding-right: 3px;
1051
+@ margin: 0px;
1052
+@ vertical-align: top;
1053
+@ white-space: pre-wrap;
1054
+@ }
1055
+@
1056
+@ table.sbsdiff tr td.lineno {
1057
+@ text-align: right;
1058
+@ /* border-bottom: 1px solid rgb(220, 220, 220); */
1059
+@ }
1060
+@
1061
+@ table.sbsdiff tr td.srcline {
1062
+@ /* max-width: 400px; */
1063
+@ /* Note: May partially hide long lines without whitespaces */
1064
+@ /* overflow: hidden; */
1065
+@ /* border-bottom: 1px solid rgb(220, 220, 220); */
1066
+@ }
1067
+@
1068
+@ table.sbsdiff tr td.meta {
1069
+@ background-color: rgb(170, 160, 255);
1070
+@ padding-top: 0.25em;
1071
+@ padding-bottom: 0.25em;
1072
+@ text-align: center;
1073
+@ -moz-border-radius: 5px;
1074
+@ -moz-border-radius: 5px;
1075
+@ -webkit-border-radius: 5px;
1076
+@ -webkit-border-radius: 5px;
1077
+@ -border-radius: 5px;
1078
+@ -border-radius: 5px;
1079
+@ border-radius: 5px;
1080
+@ border-radius: 5px;
1081
+@ }
1082
+@
1083
+@ table.sbsdiff tr td.added {
1084
+@ background-color: rgb(180, 250, 180);
1085
+@ /* border-bottom: 1px solid rgb(160, 230, 160); */
1086
+@ }
1087
+@
1088
+@ table.sbsdiff tr td.removed {
1089
+@ background-color: rgb(250, 130, 130);
1090
+@ /* border-bottom: 1px solid rgb(230, 110, 110); */
1091
+@ }
1092
+@
1093
+@ table.sbsdiff tr td.changed {
1094
+@ background-color: rgb(210, 210, 200);
1095
+@ /* border-bottom: 1px solid rgb(190, 190, 180); */
8901096
@ }');
8911097
@ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
8921098
@ <head>
8931099
@ <title>$<project_name>: $<title></title>
8941100
@ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -909,39 +1115,40 @@
9091115
@ } else {
9101116
@ puts "Not logged in"
9111117
@ }
9121118
@ </th1></nobr></div>
9131119
@ </div>
914
-@ <div class="mainmenu"><ul><th1>
915
-@ html "<a href=''$home$index_page''>Home</a>"
1120
+@ <div class="mainmenu">
1121
+@ <th1>
1122
+@ html "<a href=''$home$index_page''>Home</a>\n"
9161123
@ if {[anycap jor]} {
917
-@ html "<a href=''$home/timeline''>Timeline</a>"
1124
+@ html "<a href=''$home/timeline''>Timeline</a>\n"
9181125
@ }
9191126
@ if {[hascap oh]} {
920
-@ html "<a href=''$home/dir?ci=tip''>Files</a>"
1127
+@ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
9211128
@ }
9221129
@ if {[hascap o]} {
923
-@ html "<a href=''$home/brlist''>Branches</a>"
924
-@ html "<a href=''$home/taglist''>Tags</a>"
1130
+@ html "<a href=''$home/brlist''>Branches</a>\n"
1131
+@ html "<a href=''$home/taglist''>Tags</a>\n"
9251132
@ }
9261133
@ if {[hascap r]} {
927
-@ html "<a href=''$home/reportlist''>Tickets</a>"
1134
+@ html "<a href=''$home/reportlist''>Tickets</a>\n"
9281135
@ }
9291136
@ if {[hascap j]} {
930
-@ html "<a href=''$home/wiki''>Wiki</a>"
1137
+@ html "<a href=''$home/wiki''>Wiki</a>\n"
9311138
@ }
9321139
@ if {[hascap s]} {
933
-@ html "<a href=''$home/setup''>Admin</a>"
1140
+@ html "<a href=''$home/setup''>Admin</a>\n"
9341141
@ } elseif {[hascap a]} {
935
-@ html "<a href=''$home/setup_ulist''>Users</a>"
1142
+@ html "<a href=''$home/setup_ulist''>Users</a>\n"
9361143
@ }
9371144
@ if {[info exists login]} {
938
-@ html "<a href=''$home/login''>Logout</a>"
1145
+@ html "<a href=''$home/login''>Logout</a>\n"
9391146
@ } else {
940
-@ html "<a href=''$home/login''>Login</a>"
1147
+@ html "<a href=''$home/login''>Login</a>\n"
9411148
@ }
942
-@ </th1></ul></div>
1149
+@ </th1></div>
9431150
@ <div id="container">
9441151
@ ');
9451152
@ REPLACE INTO config(name,mtime,value) VALUES('footer',now(),'</div>
9461153
@ <div class="footer">
9471154
@ Fossil version $manifest_version $manifest_date
@@ -1100,10 +1307,13 @@
11001307
db_multi_exec("%s", zCurrent);
11011308
}
11021309
}
11031310
11041311
style_header("Skins");
1312
+ if( zErr ){
1313
+ @ <p><font color="red">%h(zErr)</font></p>
1314
+ }
11051315
@ <p>A "skin" is a combination of
11061316
@ <a href="setup_editcss">CSS</a>,
11071317
@ <a href="setup_header">Header</a>,
11081318
@ <a href="setup_footer">Footer</a>, and
11091319
@ <a href="setup_logo">Logo</a> that determines the look and feel
11101320
--- src/skins.c
+++ src/skins.c
@@ -86,29 +86,30 @@
86 @ text-align: center;
87 @ letter-spacing: 1px;
88 @ background-color: #404040;
89 @ color: white;
90 @ }
91 @
92 @ /* The submenu bar that *sometimes* appears below the main menu */
93 @ div.submenu {
94 @ padding: 3px 10px 3px 0px;
95 @ font-size: 0.9em;
96 @ text-align: center;
97 @ background-color: #606060;
98 @ color: white;
99 @ }
100 @ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
 
101 @ padding: 3px 10px 3px 10px;
102 @ color: white;
103 @ text-decoration: none;
104 @ }
105 @ div.mainmenu a:hover, div.submenu a:hover {
106 @ color: #404040;
107 @ background-color: white;
108 @ }
109 @
110 @ /* All page content from the bottom of the menu or submenu down to
111 @ ** the footer */
112 @ div.content {
113 @ padding: 0ex 0ex 0ex 0ex;
114 @ }
@@ -152,10 +153,55 @@
152 @ /* The label/value pairs on (for example) the vinfo page */
153 @ table.label-value th {
154 @ vertical-align: top;
155 @ text-align: right;
156 @ padding: 0.2ex 2ex;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157 @ }');
158 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
159 @ <head>
160 @ <title>$<project_name>: $<title></title>
161 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -163,49 +209,47 @@
163 @ <link rel="stylesheet" href="$home/style.css?blackwhite" type="text/css"
164 @ media="screen">
165 @ </head>
166 @ <body>
167 @ <div class="header">
168 @ <div class="logo">
169 @ <img src="$home/logo" alt="logo">
170 @ </div>
171 @ <div class="title"><small>$<project_name></small><br />$<title></div>
172 @ <div class="status"><nobr><th1>
173 @ if {[info exists login]} {
174 @ puts "Logged in as $login"
175 @ } else {
176 @ puts "Not logged in"
177 @ }
178 @ </th1></nobr></div>
179 @ </div>
180 @ <div class="mainmenu"><th1>
181 @ html "<a href=''$home$index_page''>Home</a> "
 
182 @ if {[anycap jor]} {
183 @ html "<a href=''$home/timeline''>Timeline</a> "
184 @ }
185 @ if {[hascap oh]} {
186 @ html "<a href=''$home/dir?ci=tip''>Files</a> "
187 @ }
188 @ if {[hascap o]} {
189 @ html "<a href=''$home/brlist''>Branches</a> "
190 @ html "<a href=''$home/taglist''>Tags</a> "
191 @ }
192 @ if {[hascap r]} {
193 @ html "<a href=''$home/reportlist''>Tickets</a> "
194 @ }
195 @ if {[hascap j]} {
196 @ html "<a href=''$home/wiki''>Wiki</a> "
197 @ }
198 @ if {[hascap s]} {
199 @ html "<a href=''$home/setup''>Admin</a> "
200 @ } elseif {[hascap a]} {
201 @ html "<a href=''$home/setup_ulist''>Users</a> "
202 @ }
203 @ if {[info exists login]} {
204 @ html "<a href=''$home/login''>Logout</a> "
205 @ } else {
206 @ html "<a href=''$home/login''>Login</a> "
207 @ }
208 @ </th1></div>
209 @ ');
210 @ REPLACE INTO config(name,mtime,value)
211 @ VALUES('footer',now(),'<div class="footer">
@@ -279,23 +323,24 @@
279 @ background-color: #a09048;
280 @ color: black;
281 @ }
282 @
283 @ /* The submenu bar that *sometimes* appears below the main menu */
284 @ div.submenu {
285 @ padding: 3px 10px 3px 0px;
286 @ font-size: 0.9em;
287 @ text-align: center;
288 @ background-color: #c0af58;
289 @ color: white;
290 @ }
291 @ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
 
292 @ padding: 3px 10px 3px 10px;
293 @ color: white;
294 @ text-decoration: none;
295 @ }
296 @ div.mainmenu a:hover, div.submenu a:hover {
297 @ color: #a09048;
298 @ background-color: white;
299 @ }
300 @
301 @ /* All page content from the bottom of the menu or submenu down to
@@ -356,11 +401,54 @@
356 @ table.label-value th {
357 @ vertical-align: top;
358 @ text-align: right;
359 @ padding: 0.2ex 2ex;
360 @ }
361 @ ');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
362 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
363 @ <head>
364 @ <title>$<project_name>: $<title></title>
365 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
366 @ href="$home/timeline.rss">
@@ -378,37 +466,38 @@
378 @ } else {
379 @ puts "Not logged in"
380 @ }
381 @ </th1></nobr></div>
382 @ </div>
383 @ <div class="mainmenu"><th1>
384 @ html "<a href=''$home$index_page''>Home</a> "
 
385 @ if {[anycap jor]} {
386 @ html "<a href=''$home/timeline''>Timeline</a> "
387 @ }
388 @ if {[hascap oh]} {
389 @ html "<a href=''$home/dir?ci=tip''>Files</a> "
390 @ }
391 @ if {[hascap o]} {
392 @ html "<a href=''$home/brlist''>Branches</a> "
393 @ html "<a href=''$home/taglist''>Tags</a> "
394 @ }
395 @ if {[hascap r]} {
396 @ html "<a href=''$home/reportlist''>Tickets</a> "
397 @ }
398 @ if {[hascap j]} {
399 @ html "<a href=''$home/wiki''>Wiki</a> "
400 @ }
401 @ if {[hascap s]} {
402 @ html "<a href=''$home/setup''>Admin</a> "
403 @ } elseif {[hascap a]} {
404 @ html "<a href=''$home/setup_ulist''>Users</a> "
405 @ }
406 @ if {[info exists login]} {
407 @ html "<a href=''$home/login''>Logout</a> "
408 @ } else {
409 @ html "<a href=''$home/login''>Login</a> "
410 @ }
411 @ </th1></div>
412 @ ');
413 @ REPLACE INTO config(name,mtime,value)
414 @ VALUES('footer',now(),'<div class="footer">
@@ -517,25 +606,26 @@
517 @ #container {
518 @ padding-left: 9em;
519 @ }
520 @
521 @ /* The submenu bar that *sometimes* appears below the main menu */
522 @ div.submenu {
523 @ padding: 3px 10px 3px 10px;
524 @ font-size: 0.9em;
525 @ text-align: center;
526 @ border:1px solid #999;
527 @ border-width:1px 0px;
528 @ background-color: #eee;
529 @ color: #333;
530 @ }
531 @ div.submenu a, div.submenu a:visited {
 
532 @ padding: 3px 10px 3px 10px;
533 @ color: #333;
534 @ text-decoration: none;
535 @ }
536 @ div.submenu a:hover {
537 @ color: #eee;
538 @ background-color: #333;
539 @ }
540 @
541 @ /* All page content from the bottom of the menu or submenu down to
@@ -590,10 +680,56 @@
590 @ /* The label/value pairs on (for example) the ci page */
591 @ table.label-value th {
592 @ vertical-align: top;
593 @ text-align: right;
594 @ padding: 0.2ex 2ex;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
595 @ }');
596 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
597 @ <head>
598 @ <title>$<project_name>: $<title></title>
599 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -614,37 +750,38 @@
614 @ } else {
615 @ puts "Not logged in"
616 @ }
617 @ </th1></nobr></div>
618 @ </div>
619 @ <div class="mainmenu"><th1>
620 @ html "<li><a href=''$home$index_page''>Home</a></li>"
 
621 @ if {[anycap jor]} {
622 @ html "<li><a href=''$home/timeline''>Timeline</a></li>"
623 @ }
624 @ if {[hascap oh]} {
625 @ html "<li><a href=''$home/dir?ci=tip''>Files</a></li>"
626 @ }
627 @ if {[hascap o]} {
628 @ html "<li><a href=''$home/brlist''>Branches</a></li>"
629 @ html "<li><a href=''$home/taglist''>Tags</a></li>"
630 @ }
631 @ if {[hascap r]} {
632 @ html "<li><a href=''$home/reportlist''>Tickets</a></li>"
633 @ }
634 @ if {[hascap j]} {
635 @ html "<li><a href=''$home/wiki''>Wiki</a></li>"
636 @ }
637 @ if {[hascap s]} {
638 @ html "<li><a href=''$home/setup''>Admin</a></li>"
639 @ } elseif {[hascap a]} {
640 @ html "<li><a href=''$home/setup_ulist''>Users</a></li>"
641 @ }
642 @ if {[info exists login]} {
643 @ html "<li><a href=''$home/login''>Logout</a></li>"
644 @ } else {
645 @ html "<li><a href=''$home/login''>Login</a></li>"
646 @ }
647 @ </th1></ul></div>
648 @ <div id="container">
649 @ ');
650 @ REPLACE INTO config(name,mtime,value) VALUES('footer',now(),'</div>
@@ -725,12 +862,13 @@
725 @ -webkit-border-top-left-radius: 5px;
726 @ -border-top-right-radius: 5px;
727 @ -border-top-left-radius: 5px;
728 @ border-top-left-radius: 5px;
729 @ border-top-right-radius: 5px;
730 @ vertical-align: center;
731 @ min-height: 2em;
 
732 @ background-color: #446979;
733 @ background: -webkit-gradient(linear,left bottom,left top, color-stop(0.02, rgb(51,81,94)), color-stop(0.76, rgb(85,129,149)));
734 @ background: -moz-linear-gradient(center bottom,rgb(51,81,94) 2%, rgb(85,129,149) 76%);
735 @ -webkit-box-shadow: 0px 3px 4px #333333;
736 @ -moz-box-shadow: 0px 3px 4px #333333;
@@ -753,11 +891,12 @@
753 @ div.mainmenu a, div.mainmenu a:visited {
754 @ padding: 3px 10px 3px 10px;
755 @ color: white;
756 @ text-decoration: none;
757 @ }
758 @ div.submenu a, div.submenu a:visited {
 
759 @ padding: 2px 8px;
760 @ color: #000;
761 @ font-family: Arial;
762 @ text-decoration: none;
763 @ margin:auto;
@@ -775,11 +914,11 @@
775 @ div.mainmenu a:hover {
776 @ color: #000;
777 @ background-color: white;
778 @ }
779 @
780 @ div.submenu a:hover {
781 @ background: -webkit-gradient(linear,left bottom, left top, color-stop(0, rgb(214,214,214)), color-stop(0.75, rgb(184,184,184)));
782 @ background: -moz-linear-gradient(center bottom, rgb(214,214,214) 0%, rgb(184,184,184) 75%);
783 @ background-color: #c0c0c0 ;
784 @ }
785 @
@@ -885,10 +1024,77 @@
885 @ padding: 3px 5px;
886 @ }
887 @
888 @ textarea {
889 @ font-size: 1em;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
890 @ }');
891 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
892 @ <head>
893 @ <title>$<project_name>: $<title></title>
894 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -909,39 +1115,40 @@
909 @ } else {
910 @ puts "Not logged in"
911 @ }
912 @ </th1></nobr></div>
913 @ </div>
914 @ <div class="mainmenu"><ul><th1>
915 @ html "<a href=''$home$index_page''>Home</a>"
 
916 @ if {[anycap jor]} {
917 @ html "<a href=''$home/timeline''>Timeline</a>"
918 @ }
919 @ if {[hascap oh]} {
920 @ html "<a href=''$home/dir?ci=tip''>Files</a>"
921 @ }
922 @ if {[hascap o]} {
923 @ html "<a href=''$home/brlist''>Branches</a>"
924 @ html "<a href=''$home/taglist''>Tags</a>"
925 @ }
926 @ if {[hascap r]} {
927 @ html "<a href=''$home/reportlist''>Tickets</a>"
928 @ }
929 @ if {[hascap j]} {
930 @ html "<a href=''$home/wiki''>Wiki</a>"
931 @ }
932 @ if {[hascap s]} {
933 @ html "<a href=''$home/setup''>Admin</a>"
934 @ } elseif {[hascap a]} {
935 @ html "<a href=''$home/setup_ulist''>Users</a>"
936 @ }
937 @ if {[info exists login]} {
938 @ html "<a href=''$home/login''>Logout</a>"
939 @ } else {
940 @ html "<a href=''$home/login''>Login</a>"
941 @ }
942 @ </th1></ul></div>
943 @ <div id="container">
944 @ ');
945 @ REPLACE INTO config(name,mtime,value) VALUES('footer',now(),'</div>
946 @ <div class="footer">
947 @ Fossil version $manifest_version $manifest_date
@@ -1100,10 +1307,13 @@
1100 db_multi_exec("%s", zCurrent);
1101 }
1102 }
1103
1104 style_header("Skins");
 
 
 
1105 @ <p>A "skin" is a combination of
1106 @ <a href="setup_editcss">CSS</a>,
1107 @ <a href="setup_header">Header</a>,
1108 @ <a href="setup_footer">Footer</a>, and
1109 @ <a href="setup_logo">Logo</a> that determines the look and feel
1110
--- src/skins.c
+++ src/skins.c
@@ -86,29 +86,30 @@
86 @ text-align: center;
87 @ letter-spacing: 1px;
88 @ background-color: #404040;
89 @ color: white;
90 @ }
91 @
92 @ /* The submenu bar that *sometimes* appears below the main menu */
93 @ div.submenu, div.sectionmenu {
94 @ padding: 3px 10px 3px 0px;
95 @ font-size: 0.9em;
96 @ text-align: center;
97 @ background-color: #606060;
98 @ color: white;
99 @ }
100 @ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited,
101 @ div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited {
102 @ padding: 3px 10px 3px 10px;
103 @ color: white;
104 @ text-decoration: none;
105 @ }
106 @ div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover {
107 @ color: #404040;
108 @ background-color: white;
109 @ }
110 @
111 @ /* All page content from the bottom of the menu or submenu down to
112 @ ** the footer */
113 @ div.content {
114 @ padding: 0ex 0ex 0ex 0ex;
115 @ }
@@ -152,10 +153,55 @@
153 @ /* The label/value pairs on (for example) the vinfo page */
154 @ table.label-value th {
155 @ vertical-align: top;
156 @ text-align: right;
157 @ padding: 0.2ex 2ex;
158 @ }
159 @
160 @ /* Side-by-side diff */
161 @ table.sbsdiff {
162 @ background-color: white;
163 @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
164 @ font-size: 8pt;
165 @ border-collapse:collapse;
166 @ white-space: pre;
167 @ width: 98%;
168 @ border: 1px #000 dashed;
169 @ }
170 @
171 @ table.sbsdiff th.diffhdr {
172 @ border-bottom: dotted;
173 @ border-width: 1px;
174 @ }
175 @
176 @ table.sbsdiff tr td {
177 @ white-space: pre;
178 @ padding-left: 3px;
179 @ padding-right: 3px;
180 @ margin: 0px;
181 @ }
182 @
183 @ table.sbsdiff tr td.lineno {
184 @ text-align: right;
185 @ }
186 @
187 @ table.sbsdiff tr td.meta {
188 @ color: white;
189 @ background-color: rgb(20, 20, 20);
190 @ text-align: center;
191 @ }
192 @
193 @ table.sbsdiff tr td.added {
194 @ background-color: rgb(230, 230, 230);
195 @ }
196 @
197 @ table.sbsdiff tr td.removed {
198 @ background-color: rgb(200, 200, 200);
199 @ }
200 @
201 @ table.sbsdiff tr td.changed {
202 @ background-color: rgb(220, 220, 220);
203 @ }');
204 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
205 @ <head>
206 @ <title>$<project_name>: $<title></title>
207 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -163,49 +209,47 @@
209 @ <link rel="stylesheet" href="$home/style.css?blackwhite" type="text/css"
210 @ media="screen">
211 @ </head>
212 @ <body>
213 @ <div class="header">
 
 
 
214 @ <div class="title"><small>$<project_name></small><br />$<title></div>
215 @ <div class="status"><nobr><th1>
216 @ if {[info exists login]} {
217 @ puts "Logged in as $login"
218 @ } else {
219 @ puts "Not logged in"
220 @ }
221 @ </th1></nobr></div>
222 @ </div>
223 @ <div class="mainmenu">
224 @ <th1>
225 @ html "<a href=''$home$index_page''>Home</a>\n"
226 @ if {[anycap jor]} {
227 @ html "<a href=''$home/timeline''>Timeline</a>\n"
228 @ }
229 @ if {[hascap oh]} {
230 @ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
231 @ }
232 @ if {[hascap o]} {
233 @ html "<a href=''$home/brlist''>Branches</a>\n"
234 @ html "<a href=''$home/taglist''>Tags</a>\n"
235 @ }
236 @ if {[hascap r]} {
237 @ html "<a href=''$home/reportlist''>Tickets</a>\n"
238 @ }
239 @ if {[hascap j]} {
240 @ html "<a href=''$home/wiki''>Wiki</a>\n"
241 @ }
242 @ if {[hascap s]} {
243 @ html "<a href=''$home/setup''>Admin</a>\n"
244 @ } elseif {[hascap a]} {
245 @ html "<a href=''$home/setup_ulist''>Users</a>\n"
246 @ }
247 @ if {[info exists login]} {
248 @ html "<a href=''$home/login''>Logout</a>\n"
249 @ } else {
250 @ html "<a href=''$home/login''>Login</a>\n"
251 @ }
252 @ </th1></div>
253 @ ');
254 @ REPLACE INTO config(name,mtime,value)
255 @ VALUES('footer',now(),'<div class="footer">
@@ -279,23 +323,24 @@
323 @ background-color: #a09048;
324 @ color: black;
325 @ }
326 @
327 @ /* The submenu bar that *sometimes* appears below the main menu */
328 @ div.submenu, div.sectionmenu {
329 @ padding: 3px 10px 3px 0px;
330 @ font-size: 0.9em;
331 @ text-align: center;
332 @ background-color: #c0af58;
333 @ color: white;
334 @ }
335 @ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited,
336 @ div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited {
337 @ padding: 3px 10px 3px 10px;
338 @ color: white;
339 @ text-decoration: none;
340 @ }
341 @ div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover {
342 @ color: #a09048;
343 @ background-color: white;
344 @ }
345 @
346 @ /* All page content from the bottom of the menu or submenu down to
@@ -356,11 +401,54 @@
401 @ table.label-value th {
402 @ vertical-align: top;
403 @ text-align: right;
404 @ padding: 0.2ex 2ex;
405 @ }
406 @
407 @ /* Side-by-side diff */
408 @ table.sbsdiff {
409 @ background-color: #ffffc5;
410 @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
411 @ font-size: 8pt;
412 @ border-collapse:collapse;
413 @ white-space: pre;
414 @ width: 98%;
415 @ border: 1px #000 dashed;
416 @ }
417 @
418 @ table.sbsdiff th.diffhdr {
419 @ border-bottom: dotted;
420 @ border-width: 1px;
421 @ }
422 @
423 @ table.sbsdiff tr td {
424 @ white-space: pre;
425 @ padding-left: 3px;
426 @ padding-right: 3px;
427 @ margin: 0px;
428 @ }
429 @
430 @ table.sbsdiff tr td.lineno {
431 @ text-align: right;
432 @ }
433 @
434 @ table.sbsdiff tr td.meta {
435 @ background-color: #a09048;
436 @ text-align: center;
437 @ }
438 @
439 @ table.sbsdiff tr td.added {
440 @ background-color: rgb(210, 210, 100);
441 @ }
442 @
443 @ table.sbsdiff tr td.removed {
444 @ background-color: rgb(190, 200, 110);
445 @ }
446 @
447 @ table.sbsdiff tr td.changed {
448 @ background-color: rgb(200, 210, 120);
449 @ }');
450 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
451 @ <head>
452 @ <title>$<project_name>: $<title></title>
453 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
454 @ href="$home/timeline.rss">
@@ -378,37 +466,38 @@
466 @ } else {
467 @ puts "Not logged in"
468 @ }
469 @ </th1></nobr></div>
470 @ </div>
471 @ <div class="mainmenu">
472 @ <th1>
473 @ html "<a href=''$home$index_page''>Home</a>\n"
474 @ if {[anycap jor]} {
475 @ html "<a href=''$home/timeline''>Timeline</a>\n"
476 @ }
477 @ if {[hascap oh]} {
478 @ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
479 @ }
480 @ if {[hascap o]} {
481 @ html "<a href=''$home/brlist''>Branches</a>\n"
482 @ html "<a href=''$home/taglist''>Tags</a>\n"
483 @ }
484 @ if {[hascap r]} {
485 @ html "<a href=''$home/reportlist''>Tickets</a>\n"
486 @ }
487 @ if {[hascap j]} {
488 @ html "<a href=''$home/wiki''>Wiki</a>\n"
489 @ }
490 @ if {[hascap s]} {
491 @ html "<a href=''$home/setup''>Admin</a>\n"
492 @ } elseif {[hascap a]} {
493 @ html "<a href=''$home/setup_ulist''>Users</a>\n"
494 @ }
495 @ if {[info exists login]} {
496 @ html "<a href=''$home/login''>Logout</a>\n"
497 @ } else {
498 @ html "<a href=''$home/login''>Login</a>\n"
499 @ }
500 @ </th1></div>
501 @ ');
502 @ REPLACE INTO config(name,mtime,value)
503 @ VALUES('footer',now(),'<div class="footer">
@@ -517,25 +606,26 @@
606 @ #container {
607 @ padding-left: 9em;
608 @ }
609 @
610 @ /* The submenu bar that *sometimes* appears below the main menu */
611 @ div.submenu, div.sectionmenu {
612 @ padding: 3px 10px 3px 10px;
613 @ font-size: 0.9em;
614 @ text-align: center;
615 @ border:1px solid #999;
616 @ border-width:1px 0px;
617 @ background-color: #eee;
618 @ color: #333;
619 @ }
620 @ div.submenu a, div.submenu a:visited, div.sectionmenu>a.button:link,
621 @ div.sectionmenu>a.button:visited {
622 @ padding: 3px 10px 3px 10px;
623 @ color: #333;
624 @ text-decoration: none;
625 @ }
626 @ div.submenu a:hover, div.sectionmenu>a.button:hover {
627 @ color: #eee;
628 @ background-color: #333;
629 @ }
630 @
631 @ /* All page content from the bottom of the menu or submenu down to
@@ -590,10 +680,56 @@
680 @ /* The label/value pairs on (for example) the ci page */
681 @ table.label-value th {
682 @ vertical-align: top;
683 @ text-align: right;
684 @ padding: 0.2ex 2ex;
685 @ }
686 @
687 @ /* Side-by-side diff */
688 @ table.sbsdiff {
689 @ background-color: white;
690 @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
691 @ font-size: 6pt;
692 @ border-collapse:collapse;
693 @ white-space: pre;
694 @ width: 98%;
695 @ border: 1px #000 dashed;
696 @ }
697 @
698 @ table.sbsdiff th.diffhdr {
699 @ border-bottom: dotted;
700 @ border-width: 1px;
701 @ }
702 @
703 @ table.sbsdiff tr td {
704 @ white-space: pre;
705 @ padding-left: 3px;
706 @ padding-right: 3px;
707 @ margin: 0px;
708 @ }
709 @
710 @ table.sbsdiff tr td.lineno {
711 @ text-align: right;
712 @ }
713 @
714 @ table.sbsdiff tr td.meta {
715 @ color: white;
716 @ background-color: black;
717 @ text-align: center;
718 @ }
719 @
720 @ table.sbsdiff tr td.added {
721 @ background-color: white;
722 @ }
723 @
724 @ table.sbsdiff tr td.removed {
725 @ background-color: white;
726 @ text-decoration: line-through;
727 @ }
728 @
729 @ table.sbsdiff tr td.changed {
730 @ background-color: white;
731 @ }');
732 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
733 @ <head>
734 @ <title>$<project_name>: $<title></title>
735 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -614,37 +750,38 @@
750 @ } else {
751 @ puts "Not logged in"
752 @ }
753 @ </th1></nobr></div>
754 @ </div>
755 @ <div class="mainmenu">
756 @ <th1>
757 @ html "<a href=''$home$index_page''>Home</a>\n"
758 @ if {[anycap jor]} {
759 @ html "<a href=''$home/timeline''>Timeline</a>\n"
760 @ }
761 @ if {[hascap oh]} {
762 @ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
763 @ }
764 @ if {[hascap o]} {
765 @ html "<a href=''$home/brlist''>Branches</a>\n"
766 @ html "<a href=''$home/taglist''>Tags</a>\n"
767 @ }
768 @ if {[hascap r]} {
769 @ html "<a href=''$home/reportlist''>Tickets</a>\n"
770 @ }
771 @ if {[hascap j]} {
772 @ html "<a href=''$home/wiki''>Wiki</a>\n"
773 @ }
774 @ if {[hascap s]} {
775 @ html "<a href=''$home/setup''>Admin</a>\n"
776 @ } elseif {[hascap a]} {
777 @ html "<a href=''$home/setup_ulist''>Users</a>\n"
778 @ }
779 @ if {[info exists login]} {
780 @ html "<a href=''$home/login''>Logout</a>\n"
781 @ } else {
782 @ html "<a href=''$home/login''>Login</a>\n"
783 @ }
784 @ </th1></ul></div>
785 @ <div id="container">
786 @ ');
787 @ REPLACE INTO config(name,mtime,value) VALUES('footer',now(),'</div>
@@ -725,12 +862,13 @@
862 @ -webkit-border-top-left-radius: 5px;
863 @ -border-top-right-radius: 5px;
864 @ -border-top-left-radius: 5px;
865 @ border-top-left-radius: 5px;
866 @ border-top-right-radius: 5px;
867 @ vertical-align: middle;
868 @ padding-top: 8px;
869 @ padding-bottom: 8px;
870 @ background-color: #446979;
871 @ background: -webkit-gradient(linear,left bottom,left top, color-stop(0.02, rgb(51,81,94)), color-stop(0.76, rgb(85,129,149)));
872 @ background: -moz-linear-gradient(center bottom,rgb(51,81,94) 2%, rgb(85,129,149) 76%);
873 @ -webkit-box-shadow: 0px 3px 4px #333333;
874 @ -moz-box-shadow: 0px 3px 4px #333333;
@@ -753,11 +891,12 @@
891 @ div.mainmenu a, div.mainmenu a:visited {
892 @ padding: 3px 10px 3px 10px;
893 @ color: white;
894 @ text-decoration: none;
895 @ }
896 @ div.submenu a, div.submenu a:visited, a.button,
897 @ div.sectionmenu>a.button:link, div.sectinmenu>a.button:visited {
898 @ padding: 2px 8px;
899 @ color: #000;
900 @ font-family: Arial;
901 @ text-decoration: none;
902 @ margin:auto;
@@ -775,11 +914,11 @@
914 @ div.mainmenu a:hover {
915 @ color: #000;
916 @ background-color: white;
917 @ }
918 @
919 @ div.submenu a:hover, div.sectionmenu>a.button:hover {
920 @ background: -webkit-gradient(linear,left bottom, left top, color-stop(0, rgb(214,214,214)), color-stop(0.75, rgb(184,184,184)));
921 @ background: -moz-linear-gradient(center bottom, rgb(214,214,214) 0%, rgb(184,184,184) 75%);
922 @ background-color: #c0c0c0 ;
923 @ }
924 @
@@ -885,10 +1024,77 @@
1024 @ padding: 3px 5px;
1025 @ }
1026 @
1027 @ textarea {
1028 @ font-size: 1em;
1029 @ }
1030 @
1031 @ /* Side-by-side diff */
1032 @ table.sbsdiff {
1033 @ background-color: white;
1034 @ font-family: Dejavu Sans Mono, Monaco, Lucida Console, monospace;
1035 @ font-size: 6pt;
1036 @ border-collapse:collapse;
1037 @ width: 98%;
1038 @ border: 1px #000 dashed;
1039 @ margin-left: auto;
1040 @ margin-right: auto;
1041 @ }
1042 @
1043 @ table.sbsdiff th.diffhdr {
1044 @ border-bottom: dotted;
1045 @ border-width: 1px;
1046 @ }
1047 @
1048 @ table.sbsdiff tr td {
1049 @ padding-left: 3px;
1050 @ padding-right: 3px;
1051 @ margin: 0px;
1052 @ vertical-align: top;
1053 @ white-space: pre-wrap;
1054 @ }
1055 @
1056 @ table.sbsdiff tr td.lineno {
1057 @ text-align: right;
1058 @ /* border-bottom: 1px solid rgb(220, 220, 220); */
1059 @ }
1060 @
1061 @ table.sbsdiff tr td.srcline {
1062 @ /* max-width: 400px; */
1063 @ /* Note: May partially hide long lines without whitespaces */
1064 @ /* overflow: hidden; */
1065 @ /* border-bottom: 1px solid rgb(220, 220, 220); */
1066 @ }
1067 @
1068 @ table.sbsdiff tr td.meta {
1069 @ background-color: rgb(170, 160, 255);
1070 @ padding-top: 0.25em;
1071 @ padding-bottom: 0.25em;
1072 @ text-align: center;
1073 @ -moz-border-radius: 5px;
1074 @ -moz-border-radius: 5px;
1075 @ -webkit-border-radius: 5px;
1076 @ -webkit-border-radius: 5px;
1077 @ -border-radius: 5px;
1078 @ -border-radius: 5px;
1079 @ border-radius: 5px;
1080 @ border-radius: 5px;
1081 @ }
1082 @
1083 @ table.sbsdiff tr td.added {
1084 @ background-color: rgb(180, 250, 180);
1085 @ /* border-bottom: 1px solid rgb(160, 230, 160); */
1086 @ }
1087 @
1088 @ table.sbsdiff tr td.removed {
1089 @ background-color: rgb(250, 130, 130);
1090 @ /* border-bottom: 1px solid rgb(230, 110, 110); */
1091 @ }
1092 @
1093 @ table.sbsdiff tr td.changed {
1094 @ background-color: rgb(210, 210, 200);
1095 @ /* border-bottom: 1px solid rgb(190, 190, 180); */
1096 @ }');
1097 @ REPLACE INTO config(name,mtime,value) VALUES('header',now(),'<html>
1098 @ <head>
1099 @ <title>$<project_name>: $<title></title>
1100 @ <link rel="alternate" type="application/rss+xml" title="RSS Feed"
@@ -909,39 +1115,40 @@
1115 @ } else {
1116 @ puts "Not logged in"
1117 @ }
1118 @ </th1></nobr></div>
1119 @ </div>
1120 @ <div class="mainmenu">
1121 @ <th1>
1122 @ html "<a href=''$home$index_page''>Home</a>\n"
1123 @ if {[anycap jor]} {
1124 @ html "<a href=''$home/timeline''>Timeline</a>\n"
1125 @ }
1126 @ if {[hascap oh]} {
1127 @ html "<a href=''$home/dir?ci=tip''>Files</a>\n"
1128 @ }
1129 @ if {[hascap o]} {
1130 @ html "<a href=''$home/brlist''>Branches</a>\n"
1131 @ html "<a href=''$home/taglist''>Tags</a>\n"
1132 @ }
1133 @ if {[hascap r]} {
1134 @ html "<a href=''$home/reportlist''>Tickets</a>\n"
1135 @ }
1136 @ if {[hascap j]} {
1137 @ html "<a href=''$home/wiki''>Wiki</a>\n"
1138 @ }
1139 @ if {[hascap s]} {
1140 @ html "<a href=''$home/setup''>Admin</a>\n"
1141 @ } elseif {[hascap a]} {
1142 @ html "<a href=''$home/setup_ulist''>Users</a>\n"
1143 @ }
1144 @ if {[info exists login]} {
1145 @ html "<a href=''$home/login''>Logout</a>\n"
1146 @ } else {
1147 @ html "<a href=''$home/login''>Login</a>\n"
1148 @ }
1149 @ </th1></div>
1150 @ <div id="container">
1151 @ ');
1152 @ REPLACE INTO config(name,mtime,value) VALUES('footer',now(),'</div>
1153 @ <div class="footer">
1154 @ Fossil version $manifest_version $manifest_date
@@ -1100,10 +1307,13 @@
1307 db_multi_exec("%s", zCurrent);
1308 }
1309 }
1310
1311 style_header("Skins");
1312 if( zErr ){
1313 @ <p><font color="red">%h(zErr)</font></p>
1314 }
1315 @ <p>A "skin" is a combination of
1316 @ <a href="setup_editcss">CSS</a>,
1317 @ <a href="setup_header">Header</a>,
1318 @ <a href="setup_footer">Footer</a>, and
1319 @ <a href="setup_logo">Logo</a> that determines the look and feel
1320
+2024 -1248
--- 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.7.8. By combining all the individual C code files into this
3
+** version 3.7.9. 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.
@@ -394,11 +394,11 @@
394394
** assert() macro is enabled, each call into the Win32 native heap subsystem
395395
** will cause HeapValidate to be called. If heap validation should fail, an
396396
** assertion will be triggered.
397397
**
398398
** (Historical note: There used to be several other options, but we've
399
-** pared it down to just these two.)
399
+** pared it down to just these three.)
400400
**
401401
** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
402402
** the default.
403403
*/
404404
#if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
@@ -654,13 +654,13 @@
654654
**
655655
** See also: [sqlite3_libversion()],
656656
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
657657
** [sqlite_version()] and [sqlite_source_id()].
658658
*/
659
-#define SQLITE_VERSION "3.7.8"
660
-#define SQLITE_VERSION_NUMBER 3007008
661
-#define SQLITE_SOURCE_ID "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177"
659
+#define SQLITE_VERSION "3.7.9"
660
+#define SQLITE_VERSION_NUMBER 3007009
661
+#define SQLITE_SOURCE_ID "2011-10-20 00:55:54 4344483f7d7f64dffadde0053e6c745948db9486"
662662
663663
/*
664664
** CAPI3REF: Run-Time Library Version Numbers
665665
** KEYWORDS: sqlite3_version, sqlite3_sourceid
666666
**
@@ -1318,11 +1318,15 @@
13181318
** in order for the database to be readable. The fourth parameter to
13191319
** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
13201320
** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
13211321
** WAL mode. If the integer is -1, then it is overwritten with the current
13221322
** WAL persistence setting.
1323
-**
1323
+**
1324
+** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
1325
+** a write transaction to indicate that, unless it is rolled back for some
1326
+** reason, the entire database file will be overwritten by the current
1327
+** transaction. This is used by VACUUM operations.
13241328
*/
13251329
#define SQLITE_FCNTL_LOCKSTATE 1
13261330
#define SQLITE_GET_LOCKPROXYFILE 2
13271331
#define SQLITE_SET_LOCKPROXYFILE 3
13281332
#define SQLITE_LAST_ERRNO 4
@@ -1330,10 +1334,11 @@
13301334
#define SQLITE_FCNTL_CHUNK_SIZE 6
13311335
#define SQLITE_FCNTL_FILE_POINTER 7
13321336
#define SQLITE_FCNTL_SYNC_OMITTED 8
13331337
#define SQLITE_FCNTL_WIN32_AV_RETRY 9
13341338
#define SQLITE_FCNTL_PERSIST_WAL 10
1339
+#define SQLITE_FCNTL_OVERWRITE 11
13351340
13361341
/*
13371342
** CAPI3REF: Mutex Handle
13381343
**
13391344
** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1946,12 +1951,12 @@
19461951
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
19471952
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
19481953
** allocator is engaged to handle all of SQLites memory allocation needs.
19491954
** The first pointer (the memory pointer) must be aligned to an 8-byte
19501955
** boundary or subsequent behavior of SQLite will be undefined.
1951
-** The minimum allocation size is capped at 2^12. Reasonable values
1952
-** for the minimum allocation size are 2^5 through 2^8.</dd>
1956
+** The minimum allocation size is capped at 2**12. Reasonable values
1957
+** for the minimum allocation size are 2**5 through 2**8.</dd>
19531958
**
19541959
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
19551960
** <dd> ^(This option takes a single argument which is a pointer to an
19561961
** instance of the [sqlite3_mutex_methods] structure. The argument specifies
19571962
** alternative low-level mutex routines to be used in place
@@ -3346,11 +3351,12 @@
33463351
** zSql string ends at either the first '\000' or '\u0000' character or
33473352
** the nByte-th byte, whichever comes first. If the caller knows
33483353
** that the supplied string is nul-terminated, then there is a small
33493354
** performance advantage to be gained by passing an nByte parameter that
33503355
** is equal to the number of bytes in the input string <i>including</i>
3351
-** the nul-terminator bytes.
3356
+** the nul-terminator bytes as this saves SQLite from having to
3357
+** make a copy of the input string.
33523358
**
33533359
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
33543360
** past the end of the first SQL statement in zSql. These routines only
33553361
** compile the first statement in zSql, so *pzTail is left pointing to
33563362
** what remains uncompiled.
@@ -3397,11 +3403,11 @@
33973403
** a schema change, on the first [sqlite3_step()] call following any change
33983404
** to the [sqlite3_bind_text | bindings] of that [parameter].
33993405
** ^The specific value of WHERE-clause [parameter] might influence the
34003406
** choice of query plan if the parameter is the left-hand side of a [LIKE]
34013407
** or [GLOB] operator or if the parameter is compared to an indexed column
3402
-** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
3408
+** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
34033409
** the
34043410
** </li>
34053411
** </ol>
34063412
*/
34073413
SQLITE_API int sqlite3_prepare(
@@ -3567,10 +3573,17 @@
35673573
** ^(In those routines that have a fourth argument, its value is the
35683574
** number of bytes in the parameter. To be clear: the value is the
35693575
** number of <u>bytes</u> in the value, not the number of characters.)^
35703576
** ^If the fourth parameter is negative, the length of the string is
35713577
** the number of bytes up to the first zero terminator.
3578
+** If a non-negative fourth parameter is provided to sqlite3_bind_text()
3579
+** or sqlite3_bind_text16() then that parameter must be the byte offset
3580
+** where the NUL terminator would occur assuming the string were NUL
3581
+** terminated. If any NUL characters occur at byte offsets less than
3582
+** the value of the fourth parameter then the resulting string value will
3583
+** contain embedded NULs. The result of expressions involving strings
3584
+** with embedded NULs is undefined.
35723585
**
35733586
** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
35743587
** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
35753588
** string after SQLite has finished with it. ^The destructor is called
35763589
** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
@@ -3900,10 +3913,16 @@
39003913
** current row of the result set of [prepared statement] P.
39013914
** ^If prepared statement P does not have results ready to return
39023915
** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
39033916
** interfaces) then sqlite3_data_count(P) returns 0.
39043917
** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
3918
+** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
3919
+** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P)
3920
+** will return non-zero if previous call to [sqlite3_step](P) returned
3921
+** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
3922
+** where it always returns zero since each step of that multi-step
3923
+** pragma returns 0 columns of data.
39053924
**
39063925
** See also: [sqlite3_column_count()]
39073926
*/
39083927
SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
39093928
@@ -4579,11 +4598,16 @@
45794598
** is negative, then SQLite takes result text from the 2nd parameter
45804599
** through the first zero character.
45814600
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
45824601
** is non-negative, then as many bytes (not characters) of the text
45834602
** pointed to by the 2nd parameter are taken as the application-defined
4584
-** function result.
4603
+** function result. If the 3rd parameter is non-negative, then it
4604
+** must be the byte offset into the string where the NUL terminator would
4605
+** appear if the string where NUL terminated. If any NUL characters occur
4606
+** in the string at a byte offset that is less than the value of the 3rd
4607
+** parameter, then the resulting string will contain embedded NULs and the
4608
+** result of expressions operating on strings with embedded NULs is undefined.
45854609
** ^If the 4th parameter to the sqlite3_result_text* interfaces
45864610
** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
45874611
** function as the destructor on the text or BLOB result when it has
45884612
** finished using that result.
45894613
** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
@@ -6362,20 +6386,34 @@
63626386
** <dd>This parameter returns the approximate number of of bytes of heap
63636387
** and lookaside memory used by all prepared statements associated with
63646388
** the database connection.)^
63656389
** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
63666390
** </dd>
6391
+**
6392
+** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
6393
+** <dd>This parameter returns the number of pager cache hits that have
6394
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
6395
+** is always 0.
6396
+** </dd>
6397
+**
6398
+** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
6399
+** <dd>This parameter returns the number of pager cache misses that have
6400
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
6401
+** is always 0.
6402
+** </dd>
63676403
** </dl>
63686404
*/
63696405
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
63706406
#define SQLITE_DBSTATUS_CACHE_USED 1
63716407
#define SQLITE_DBSTATUS_SCHEMA_USED 2
63726408
#define SQLITE_DBSTATUS_STMT_USED 3
63736409
#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
63746410
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
63756411
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6376
-#define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */
6412
+#define SQLITE_DBSTATUS_CACHE_HIT 7
6413
+#define SQLITE_DBSTATUS_CACHE_MISS 8
6414
+#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */
63776415
63786416
63796417
/*
63806418
** CAPI3REF: Prepared Statement Status
63816419
**
@@ -6425,11 +6463,10 @@
64256463
** <dd>^This is the number of rows inserted into transient indices that
64266464
** were created automatically in order to help joins run faster.
64276465
** A non-zero value in this counter may indicate an opportunity to
64286466
** improvement performance by adding permanent indices that do not
64296467
** need to be reinitialized each time the statement is run.</dd>
6430
-**
64316468
** </dl>
64326469
*/
64336470
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
64346471
#define SQLITE_STMTSTATUS_SORT 2
64356472
#define SQLITE_STMTSTATUS_AUTOINDEX 3
@@ -7711,10 +7748,22 @@
77117748
** is 0x00000000ffffffff. But because of quirks of some compilers, we
77127749
** have to specify the value in the less intuitive manner shown:
77137750
*/
77147751
#define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
77157752
7753
+/*
7754
+** The datatype used to store estimates of the number of rows in a
7755
+** table or index. This is an unsigned integer type. For 99.9% of
7756
+** the world, a 32-bit integer is sufficient. But a 64-bit integer
7757
+** can be used at compile-time if desired.
7758
+*/
7759
+#ifdef SQLITE_64BIT_STATS
7760
+ typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */
7761
+#else
7762
+ typedef u32 tRowcnt; /* 32-bit is the default */
7763
+#endif
7764
+
77167765
/*
77177766
** Macros to determine whether the machine is big or little endian,
77187767
** evaluated at runtime.
77197768
*/
77207769
#ifdef SQLITE_AMALGAMATION
@@ -8742,10 +8791,11 @@
87428791
SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
87438792
SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
87448793
SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
87458794
SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
87468795
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
8796
+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
87478797
87488798
/* Functions used to truncate the database file. */
87498799
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
87508800
87518801
#if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
@@ -9278,18 +9328,21 @@
92789328
/*
92799329
** If this is a no-op implementation, implement everything as macros.
92809330
*/
92819331
#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
92829332
#define sqlite3_mutex_free(X)
9283
-#define sqlite3_mutex_enter(X)
9333
+#define sqlite3_mutex_enter(X)
92849334
#define sqlite3_mutex_try(X) SQLITE_OK
9285
-#define sqlite3_mutex_leave(X)
9335
+#define sqlite3_mutex_leave(X)
92869336
#define sqlite3_mutex_held(X) ((void)(X),1)
92879337
#define sqlite3_mutex_notheld(X) ((void)(X),1)
92889338
#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8)
92899339
#define sqlite3MutexInit() SQLITE_OK
92909340
#define sqlite3MutexEnd()
9341
+#define MUTEX_LOGIC(X)
9342
+#else
9343
+#define MUTEX_LOGIC(X) X
92919344
#endif /* defined(SQLITE_MUTEX_OMIT) */
92929345
92939346
/************** End of mutex.h ***********************************************/
92949347
/************** Continuing where we left off in sqliteInt.h ******************/
92959348
@@ -9918,11 +9971,11 @@
99189971
int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
99199972
int nCol; /* Number of columns in this table */
99209973
Column *aCol; /* Information about each column */
99219974
Index *pIndex; /* List of SQL indexes on this table. */
99229975
int tnum; /* Root BTree node for this table (see note above) */
9923
- unsigned nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
9976
+ tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
99249977
Select *pSelect; /* NULL for tables. Points to definition if a view. */
99259978
u16 nRef; /* Number of pointers to this Table */
99269979
u8 tabFlags; /* Mask of TF_* values */
99279980
u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
99289981
FKey *pFKey; /* Linked list of all foreign keys in this table */
@@ -10117,11 +10170,11 @@
1011710170
*/
1011810171
struct Index {
1011910172
char *zName; /* Name of this index */
1012010173
int nColumn; /* Number of columns in the table used by this index */
1012110174
int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10122
- unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10175
+ tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
1012310176
Table *pTable; /* The SQL table being indexed */
1012410177
int tnum; /* Page containing root of this index in database file */
1012510178
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
1012610179
u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
1012710180
u8 bUnordered; /* Use this index for == or IN queries only */
@@ -10128,24 +10181,32 @@
1012810181
char *zColAff; /* String defining the affinity of each column */
1012910182
Index *pNext; /* The next index associated with the same table */
1013010183
Schema *pSchema; /* Schema containing this index */
1013110184
u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
1013210185
char **azColl; /* Array of collation sequence names for index */
10133
- IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */
10186
+#ifdef SQLITE_ENABLE_STAT3
10187
+ int nSample; /* Number of elements in aSample[] */
10188
+ tRowcnt avgEq; /* Average nEq value for key values not in aSample */
10189
+ IndexSample *aSample; /* Samples of the left-most key */
10190
+#endif
1013410191
};
1013510192
1013610193
/*
1013710194
** Each sample stored in the sqlite_stat2 table is represented in memory
1013810195
** using a structure of this type.
1013910196
*/
1014010197
struct IndexSample {
1014110198
union {
1014210199
char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
10143
- double r; /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */
10200
+ double r; /* Value if eType is SQLITE_FLOAT */
10201
+ i64 i; /* Value if eType is SQLITE_INTEGER */
1014410202
} u;
1014510203
u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
10146
- u8 nByte; /* Size in byte of text or blob. */
10204
+ int nByte; /* Size in byte of text or blob. */
10205
+ tRowcnt nEq; /* Est. number of rows where the key equals this sample */
10206
+ tRowcnt nLt; /* Est. number of rows where key is less than this sample */
10207
+ tRowcnt nDLt; /* Est. number of distinct keys less than this sample */
1014710208
};
1014810209
1014910210
/*
1015010211
** Each token coming out of the lexer is an instance of
1015110212
** this structure. Tokens are also used as part of an expression.
@@ -10593,14 +10654,14 @@
1059310654
#define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
1059410655
#define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
1059510656
#define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */
1059610657
#define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
1059710658
#define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
10598
-#define WHERE_OMIT_OPEN 0x0010 /* Table cursors are already open */
10599
-#define WHERE_OMIT_CLOSE 0x0020 /* Omit close of table & index cursors */
10600
-#define WHERE_FORCE_TABLE 0x0040 /* Do not use an index-only search */
10601
-#define WHERE_ONETABLE_ONLY 0x0080 /* Only code the 1st table in pTabList */
10659
+#define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
10660
+#define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
10661
+#define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
10662
+#define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
1060210663
1060310664
/*
1060410665
** The WHERE clause processing routine has two halves. The
1060510666
** first part does the start of the WHERE loop and the second
1060610667
** half does the tail of the WHERE loop. An instance of
@@ -11350,10 +11411,11 @@
1135011411
#else
1135111412
# define sqlite3ViewGetColumnNames(A,B) 0
1135211413
#endif
1135311414
1135411415
SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
11416
+SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
1135511417
SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
1135611418
#ifndef SQLITE_OMIT_AUTOINCREMENT
1135711419
SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
1135811420
SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
1135911421
#else
@@ -11606,11 +11668,11 @@
1160611668
SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
1160711669
void(*)(void*));
1160811670
SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
1160911671
SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
1161011672
SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
11611
-#ifdef SQLITE_ENABLE_STAT2
11673
+#ifdef SQLITE_ENABLE_STAT3
1161211674
SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
1161311675
#endif
1161411676
SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
1161511677
SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
1161611678
#ifndef SQLITE_AMALGAMATION
@@ -11708,19 +11770,21 @@
1170811770
# define sqlite3VtabInSync(db) 0
1170911771
# define sqlite3VtabLock(X)
1171011772
# define sqlite3VtabUnlock(X)
1171111773
# define sqlite3VtabUnlockList(X)
1171211774
# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
11775
+# define sqlite3GetVTable(X,Y) ((VTable*)0)
1171311776
#else
1171411777
SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*);
1171511778
SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
1171611779
SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
1171711780
SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
1171811781
SQLITE_PRIVATE void sqlite3VtabLock(VTable *);
1171911782
SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *);
1172011783
SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
1172111784
SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
11785
+SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
1172211786
# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
1172311787
#endif
1172411788
SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
1172511789
SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
1172611790
SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
@@ -11736,11 +11800,10 @@
1173611800
SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
1173711801
SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
1173811802
SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
1173911803
SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
1174011804
SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
11741
-SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
1174211805
SQLITE_PRIVATE const char *sqlite3JournalModename(int);
1174311806
SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
1174411807
SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
1174511808
1174611809
/* Declarations for functions in fkey.c. All of these are replaced by
@@ -12232,10 +12295,13 @@
1223212295
#ifdef SQLITE_ENABLE_RTREE
1223312296
"ENABLE_RTREE",
1223412297
#endif
1223512298
#ifdef SQLITE_ENABLE_STAT2
1223612299
"ENABLE_STAT2",
12300
+#endif
12301
+#ifdef SQLITE_ENABLE_STAT3
12302
+ "ENABLE_STAT3",
1223712303
#endif
1223812304
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
1223912305
"ENABLE_UNLOCK_NOTIFY",
1224012306
#endif
1224112307
#ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -12445,13 +12511,10 @@
1244512511
"OMIT_WSD",
1244612512
#endif
1244712513
#ifdef SQLITE_OMIT_XFER_OPT
1244812514
"OMIT_XFER_OPT",
1244912515
#endif
12450
-#ifdef SQLITE_PAGECACHE_BLOCKALLOC
12451
- "PAGECACHE_BLOCKALLOC",
12452
-#endif
1245312516
#ifdef SQLITE_PERFORMANCE_TRACE
1245412517
"PERFORMANCE_TRACE",
1245512518
#endif
1245612519
#ifdef SQLITE_PROXY_DEBUG
1245712520
"PROXY_DEBUG",
@@ -13189,10 +13252,32 @@
1318913252
*pHighwater = 0;
1319013253
*pCurrent = nByte;
1319113254
1319213255
break;
1319313256
}
13257
+
13258
+ /*
13259
+ ** Set *pCurrent to the total cache hits or misses encountered by all
13260
+ ** pagers the database handle is connected to. *pHighwater is always set
13261
+ ** to zero.
13262
+ */
13263
+ case SQLITE_DBSTATUS_CACHE_HIT:
13264
+ case SQLITE_DBSTATUS_CACHE_MISS: {
13265
+ int i;
13266
+ int nRet = 0;
13267
+ assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
13268
+
13269
+ for(i=0; i<db->nDb; i++){
13270
+ if( db->aDb[i].pBt ){
13271
+ Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
13272
+ sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
13273
+ }
13274
+ }
13275
+ *pHighwater = 0;
13276
+ *pCurrent = nRet;
13277
+ break;
13278
+ }
1319413279
1319513280
default: {
1319613281
rc = SQLITE_ERROR;
1319713282
}
1319813283
}
@@ -13490,16 +13575,22 @@
1349013575
}
1349113576
return 0;
1349213577
}
1349313578
1349413579
/*
13495
-** Set the time to the current time reported by the VFS
13580
+** Set the time to the current time reported by the VFS.
13581
+**
13582
+** Return the number of errors.
1349613583
*/
13497
-static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
13584
+static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
1349813585
sqlite3 *db = sqlite3_context_db_handle(context);
13499
- sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD);
13500
- p->validJD = 1;
13586
+ if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
13587
+ p->validJD = 1;
13588
+ return 0;
13589
+ }else{
13590
+ return 1;
13591
+ }
1350113592
}
1350213593
1350313594
/*
1350413595
** Attempt to parse the given string into a Julian Day Number. Return
1350513596
** the number of errors.
@@ -13525,12 +13616,11 @@
1352513616
if( parseYyyyMmDd(zDate,p)==0 ){
1352613617
return 0;
1352713618
}else if( parseHhMmSs(zDate, p)==0 ){
1352813619
return 0;
1352913620
}else if( sqlite3StrICmp(zDate,"now")==0){
13530
- setDateTimeToCurrent(context, p);
13531
- return 0;
13621
+ return setDateTimeToCurrent(context, p);
1353213622
}else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
1353313623
p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
1353413624
p->validJD = 1;
1353513625
return 0;
1353613626
}
@@ -13953,12 +14043,13 @@
1395314043
int i;
1395414044
const unsigned char *z;
1395514045
int eType;
1395614046
memset(p, 0, sizeof(*p));
1395714047
if( argc==0 ){
13958
- setDateTimeToCurrent(context, p);
13959
- }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
14048
+ return setDateTimeToCurrent(context, p);
14049
+ }
14050
+ if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
1396014051
|| eType==SQLITE_INTEGER ){
1396114052
p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
1396214053
p->validJD = 1;
1396314054
}else{
1396414055
z = sqlite3_value_text(argv[0]);
@@ -14266,35 +14357,32 @@
1426614357
){
1426714358
time_t t;
1426814359
char *zFormat = (char *)sqlite3_user_data(context);
1426914360
sqlite3 *db;
1427014361
sqlite3_int64 iT;
14362
+ struct tm *pTm;
14363
+ struct tm sNow;
1427114364
char zBuf[20];
1427214365
1427314366
UNUSED_PARAMETER(argc);
1427414367
UNUSED_PARAMETER(argv);
1427514368
1427614369
db = sqlite3_context_db_handle(context);
14277
- sqlite3OsCurrentTimeInt64(db->pVfs, &iT);
14370
+ if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
1427814371
t = iT/1000 - 10000*(sqlite3_int64)21086676;
1427914372
#ifdef HAVE_GMTIME_R
14280
- {
14281
- struct tm sNow;
14282
- gmtime_r(&t, &sNow);
14373
+ pTm = gmtime_r(&t, &sNow);
14374
+#else
14375
+ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14376
+ pTm = gmtime(&t);
14377
+ if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
14378
+ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14379
+#endif
14380
+ if( pTm ){
1428314381
strftime(zBuf, 20, zFormat, &sNow);
14284
- }
14285
-#else
14286
- {
14287
- struct tm *pTm;
14288
- sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14289
- pTm = gmtime(&t);
14290
- strftime(zBuf, 20, zFormat, pTm);
14291
- sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14292
- }
14293
-#endif
14294
-
14295
- sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
14382
+ sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
14383
+ }
1429614384
}
1429714385
#endif
1429814386
1429914387
/*
1430014388
** This function registered all of the above C functions as SQL
@@ -14625,16 +14713,16 @@
1462514713
** Register a VFS with the system. It is harmless to register the same
1462614714
** VFS multiple times. The new VFS becomes the default if makeDflt is
1462714715
** true.
1462814716
*/
1462914717
SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
14630
- sqlite3_mutex *mutex = 0;
14718
+ MUTEX_LOGIC(sqlite3_mutex *mutex;)
1463114719
#ifndef SQLITE_OMIT_AUTOINIT
1463214720
int rc = sqlite3_initialize();
1463314721
if( rc ) return rc;
1463414722
#endif
14635
- mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
14723
+ MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
1463614724
sqlite3_mutex_enter(mutex);
1463714725
vfsUnlink(pVfs);
1463814726
if( makeDflt || vfsList==0 ){
1463914727
pVfs->pNext = vfsList;
1464014728
vfsList = pVfs;
@@ -18878,52 +18966,14 @@
1887818966
** an historical reference. Most of the "enhancements" have been backed
1887918967
** out so that the functionality is now the same as standard printf().
1888018968
**
1888118969
**************************************************************************
1888218970
**
18883
-** The following modules is an enhanced replacement for the "printf" subroutines
18884
-** found in the standard C library. The following enhancements are
18885
-** supported:
18886
-**
18887
-** + Additional functions. The standard set of "printf" functions
18888
-** includes printf, fprintf, sprintf, vprintf, vfprintf, and
18889
-** vsprintf. This module adds the following:
18890
-**
18891
-** * snprintf -- Works like sprintf, but has an extra argument
18892
-** which is the size of the buffer written to.
18893
-**
18894
-** * mprintf -- Similar to sprintf. Writes output to memory
18895
-** obtained from malloc.
18896
-**
18897
-** * xprintf -- Calls a function to dispose of output.
18898
-**
18899
-** * nprintf -- No output, but returns the number of characters
18900
-** that would have been output by printf.
18901
-**
18902
-** * A v- version (ex: vsnprintf) of every function is also
18903
-** supplied.
18904
-**
18905
-** + A few extensions to the formatting notation are supported:
18906
-**
18907
-** * The "=" flag (similar to "-") causes the output to be
18908
-** be centered in the appropriately sized field.
18909
-**
18910
-** * The %b field outputs an integer in binary notation.
18911
-**
18912
-** * The %c field now accepts a precision. The character output
18913
-** is repeated by the number of times the precision specifies.
18914
-**
18915
-** * The %' field works like %c, but takes as its character the
18916
-** next character of the format string, instead of the next
18917
-** argument. For example, printf("%.78'-") prints 78 minus
18918
-** signs, the same as printf("%.78c",'-').
18919
-**
18920
-** + When compiled using GCC on a SPARC, this version of printf is
18921
-** faster than the library printf for SUN OS 4.1.
18922
-**
18923
-** + All functions are fully reentrant.
18924
-**
18971
+** This file contains code for a set of "printf"-like routines. These
18972
+** routines format strings much like the printf() from the standard C
18973
+** library, though the implementation here has enhancements to support
18974
+** SQLlite.
1892518975
*/
1892618976
1892718977
/*
1892818978
** Conversion types fall into various categories as defined by the
1892918979
** following enumeration.
@@ -19057,47 +19107,19 @@
1905719107
}
1905819108
}
1905919109
1906019110
/*
1906119111
** On machines with a small stack size, you can redefine the
19062
-** SQLITE_PRINT_BUF_SIZE to be less than 350.
19112
+** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
1906319113
*/
1906419114
#ifndef SQLITE_PRINT_BUF_SIZE
19065
-# if defined(SQLITE_SMALL_STACK)
19066
-# define SQLITE_PRINT_BUF_SIZE 50
19067
-# else
19068
-# define SQLITE_PRINT_BUF_SIZE 350
19069
-# endif
19115
+# define SQLITE_PRINT_BUF_SIZE 70
1907019116
#endif
1907119117
#define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
1907219118
1907319119
/*
19074
-** The root program. All variations call this core.
19075
-**
19076
-** INPUTS:
19077
-** func This is a pointer to a function taking three arguments
19078
-** 1. A pointer to anything. Same as the "arg" parameter.
19079
-** 2. A pointer to the list of characters to be output
19080
-** (Note, this list is NOT null terminated.)
19081
-** 3. An integer number of characters to be output.
19082
-** (Note: This number might be zero.)
19083
-**
19084
-** arg This is the pointer to anything which will be passed as the
19085
-** first argument to "func". Use it for whatever you like.
19086
-**
19087
-** fmt This is the format string, as in the usual print.
19088
-**
19089
-** ap This is a pointer to a list of arguments. Same as in
19090
-** vfprint.
19091
-**
19092
-** OUTPUTS:
19093
-** The return value is the total number of characters sent to
19094
-** the function "func". Returns -1 on a error.
19095
-**
19096
-** Note that the order in which automatic variables are declared below
19097
-** seems to make a big difference in determining how fast this beast
19098
-** will run.
19120
+** Render a string given by "fmt" into the StrAccum object.
1909919121
*/
1910019122
SQLITE_PRIVATE void sqlite3VXPrintf(
1910119123
StrAccum *pAccum, /* Accumulate results here */
1910219124
int useExtended, /* Allow extended %-conversions */
1910319125
const char *fmt, /* Format string */
@@ -19116,27 +19138,27 @@
1911619138
etByte flag_altform2; /* True if "!" flag is present */
1911719139
etByte flag_zeropad; /* True if field width constant starts with zero */
1911819140
etByte flag_long; /* True if "l" flag is present */
1911919141
etByte flag_longlong; /* True if the "ll" flag is present */
1912019142
etByte done; /* Loop termination flag */
19143
+ etByte xtype = 0; /* Conversion paradigm */
19144
+ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
1912119145
sqlite_uint64 longvalue; /* Value for integer types */
1912219146
LONGDOUBLE_TYPE realvalue; /* Value for real types */
1912319147
const et_info *infop; /* Pointer to the appropriate info structure */
19124
- char buf[etBUFSIZE]; /* Conversion buffer */
19125
- char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
19126
- etByte xtype = 0; /* Conversion paradigm */
19127
- char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
19148
+ char *zOut; /* Rendering buffer */
19149
+ int nOut; /* Size of the rendering buffer */
19150
+ char *zExtra; /* Malloced memory used by some conversion */
1912819151
#ifndef SQLITE_OMIT_FLOATING_POINT
1912919152
int exp, e2; /* exponent of real numbers */
19153
+ int nsd; /* Number of significant digits returned */
1913019154
double rounder; /* Used for rounding floating point values */
1913119155
etByte flag_dp; /* True if decimal point should be shown */
1913219156
etByte flag_rtz; /* True if trailing zeros should be removed */
19133
- etByte flag_exp; /* True to force display of the exponent */
19134
- int nsd; /* Number of significant digits returned */
1913519157
#endif
19158
+ char buf[etBUFSIZE]; /* Conversion buffer */
1913619159
19137
- length = 0;
1913819160
bufpt = 0;
1913919161
for(; (c=(*fmt))!=0; ++fmt){
1914019162
if( c!='%' ){
1914119163
int amt;
1914219164
bufpt = (char *)fmt;
@@ -19177,13 +19199,10 @@
1917719199
while( c>='0' && c<='9' ){
1917819200
width = width*10 + c - '0';
1917919201
c = *++fmt;
1918019202
}
1918119203
}
19182
- if( width > etBUFSIZE-10 ){
19183
- width = etBUFSIZE-10;
19184
- }
1918519204
/* Get the precision */
1918619205
if( c=='.' ){
1918719206
precision = 0;
1918819207
c = *++fmt;
1918919208
if( c=='*' ){
@@ -19226,16 +19245,10 @@
1922619245
break;
1922719246
}
1922819247
}
1922919248
zExtra = 0;
1923019249
19231
-
19232
- /* Limit the precision to prevent overflowing buf[] during conversion */
19233
- if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
19234
- precision = etBUFSIZE-40;
19235
- }
19236
-
1923719250
/*
1923819251
** At this point, variables are initialized as follows:
1923919252
**
1924019253
** flag_alternateform TRUE if a '#' is present.
1924119254
** flag_altform2 TRUE if a '!' is present.
@@ -19296,20 +19309,30 @@
1929619309
}
1929719310
if( longvalue==0 ) flag_alternateform = 0;
1929819311
if( flag_zeropad && precision<width-(prefix!=0) ){
1929919312
precision = width-(prefix!=0);
1930019313
}
19301
- bufpt = &buf[etBUFSIZE-1];
19314
+ if( precision<etBUFSIZE-10 ){
19315
+ nOut = etBUFSIZE;
19316
+ zOut = buf;
19317
+ }else{
19318
+ nOut = precision + 10;
19319
+ zOut = zExtra = sqlite3Malloc( nOut );
19320
+ if( zOut==0 ){
19321
+ pAccum->mallocFailed = 1;
19322
+ return;
19323
+ }
19324
+ }
19325
+ bufpt = &zOut[nOut-1];
1930219326
if( xtype==etORDINAL ){
1930319327
static const char zOrd[] = "thstndrd";
1930419328
int x = (int)(longvalue % 10);
1930519329
if( x>=4 || (longvalue/10)%10==1 ){
1930619330
x = 0;
1930719331
}
19308
- buf[etBUFSIZE-3] = zOrd[x*2];
19309
- buf[etBUFSIZE-2] = zOrd[x*2+1];
19310
- bufpt -= 2;
19332
+ *(--bufpt) = zOrd[x*2+1];
19333
+ *(--bufpt) = zOrd[x*2];
1931119334
}
1931219335
{
1931319336
register const char *cset; /* Use registers for speed */
1931419337
register int base;
1931519338
cset = &aDigits[infop->charset];
@@ -19317,11 +19340,11 @@
1931719340
do{ /* Convert to ascii */
1931819341
*(--bufpt) = cset[longvalue%base];
1931919342
longvalue = longvalue/base;
1932019343
}while( longvalue>0 );
1932119344
}
19322
- length = (int)(&buf[etBUFSIZE-1]-bufpt);
19345
+ length = (int)(&zOut[nOut-1]-bufpt);
1932319346
for(idx=precision-length; idx>0; idx--){
1932419347
*(--bufpt) = '0'; /* Zero pad */
1932519348
}
1932619349
if( prefix ) *(--bufpt) = prefix; /* Add sign */
1932719350
if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
@@ -19328,21 +19351,20 @@
1932819351
const char *pre;
1932919352
char x;
1933019353
pre = &aPrefix[infop->prefix];
1933119354
for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
1933219355
}
19333
- length = (int)(&buf[etBUFSIZE-1]-bufpt);
19356
+ length = (int)(&zOut[nOut-1]-bufpt);
1933419357
break;
1933519358
case etFLOAT:
1933619359
case etEXP:
1933719360
case etGENERIC:
1933819361
realvalue = va_arg(ap,double);
1933919362
#ifdef SQLITE_OMIT_FLOATING_POINT
1934019363
length = 0;
1934119364
#else
1934219365
if( precision<0 ) precision = 6; /* Set default precision */
19343
- if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
1934419366
if( realvalue<0.0 ){
1934519367
realvalue = -realvalue;
1934619368
prefix = '-';
1934719369
}else{
1934819370
if( flag_plussign ) prefix = '+';
@@ -19386,11 +19408,10 @@
1938619408
bufpt = buf;
1938719409
/*
1938819410
** If the field type is etGENERIC, then convert to either etEXP
1938919411
** or etFLOAT, as appropriate.
1939019412
*/
19391
- flag_exp = xtype==etEXP;
1939219413
if( xtype!=etFLOAT ){
1939319414
realvalue += rounder;
1939419415
if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
1939519416
}
1939619417
if( xtype==etGENERIC ){
@@ -19407,10 +19428,18 @@
1940719428
if( xtype==etEXP ){
1940819429
e2 = 0;
1940919430
}else{
1941019431
e2 = exp;
1941119432
}
19433
+ if( e2+precision+width > etBUFSIZE - 15 ){
19434
+ bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
19435
+ if( bufpt==0 ){
19436
+ pAccum->mallocFailed = 1;
19437
+ return;
19438
+ }
19439
+ }
19440
+ zOut = bufpt;
1941219441
nsd = 0;
1941319442
flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
1941419443
/* The sign in front of the number */
1941519444
if( prefix ){
1941619445
*(bufpt++) = prefix;
@@ -19438,21 +19467,21 @@
1943819467
*(bufpt++) = et_getdigit(&realvalue,&nsd);
1943919468
}
1944019469
/* Remove trailing zeros and the "." if no digits follow the "." */
1944119470
if( flag_rtz && flag_dp ){
1944219471
while( bufpt[-1]=='0' ) *(--bufpt) = 0;
19443
- assert( bufpt>buf );
19472
+ assert( bufpt>zOut );
1944419473
if( bufpt[-1]=='.' ){
1944519474
if( flag_altform2 ){
1944619475
*(bufpt++) = '0';
1944719476
}else{
1944819477
*(--bufpt) = 0;
1944919478
}
1945019479
}
1945119480
}
1945219481
/* Add the "eNNN" suffix */
19453
- if( flag_exp || xtype==etEXP ){
19482
+ if( xtype==etEXP ){
1945419483
*(bufpt++) = aDigits[infop->charset];
1945519484
if( exp<0 ){
1945619485
*(bufpt++) = '-'; exp = -exp;
1945719486
}else{
1945819487
*(bufpt++) = '+';
@@ -19467,12 +19496,12 @@
1946719496
*bufpt = 0;
1946819497
1946919498
/* The converted number is in buf[] and zero terminated. Output it.
1947019499
** Note that the number is in the usual order, not reversed as with
1947119500
** integer conversions. */
19472
- length = (int)(bufpt-buf);
19473
- bufpt = buf;
19501
+ length = (int)(bufpt-zOut);
19502
+ bufpt = zOut;
1947419503
1947519504
/* Special case: Add leading zeros if the flag_zeropad flag is
1947619505
** set and we are not left justified */
1947719506
if( flag_zeropad && !flag_leftjustify && length < width){
1947819507
int i;
@@ -19606,13 +19635,11 @@
1960619635
nspace = width-length;
1960719636
if( nspace>0 ){
1960819637
appendSpace(pAccum, nspace);
1960919638
}
1961019639
}
19611
- if( zExtra ){
19612
- sqlite3_free(zExtra);
19613
- }
19640
+ sqlite3_free(zExtra);
1961419641
}/* End for loop over the format string */
1961519642
} /* End of function */
1961619643
1961719644
/*
1961819645
** Append N bytes of text from z to the StrAccum object.
@@ -19622,10 +19649,11 @@
1962219649
if( p->tooBig | p->mallocFailed ){
1962319650
testcase(p->tooBig);
1962419651
testcase(p->mallocFailed);
1962519652
return;
1962619653
}
19654
+ assert( p->zText!=0 || p->nChar==0 );
1962719655
if( N<0 ){
1962819656
N = sqlite3Strlen30(z);
1962919657
}
1963019658
if( N==0 || NEVER(z==0) ){
1963119659
return;
@@ -19653,19 +19681,20 @@
1965319681
zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
1965419682
}else{
1965519683
zNew = sqlite3_realloc(zOld, p->nAlloc);
1965619684
}
1965719685
if( zNew ){
19658
- if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
19686
+ if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
1965919687
p->zText = zNew;
1966019688
}else{
1966119689
p->mallocFailed = 1;
1966219690
sqlite3StrAccumReset(p);
1966319691
return;
1966419692
}
1966519693
}
1966619694
}
19695
+ assert( p->zText );
1966719696
memcpy(&p->zText[p->nChar], z, N);
1966819697
p->nChar += N;
1966919698
}
1967019699
1967119700
/*
@@ -20511,11 +20540,11 @@
2051120540
** no longer required.
2051220541
**
2051320542
** If a malloc failure occurs, NULL is returned and the db.mallocFailed
2051420543
** flag set.
2051520544
*/
20516
-#ifdef SQLITE_ENABLE_STAT2
20545
+#ifdef SQLITE_ENABLE_STAT3
2051720546
SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
2051820547
Mem m;
2051920548
memset(&m, 0, sizeof(m));
2052020549
m.db = db;
2052120550
sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
@@ -20940,11 +20969,11 @@
2094020969
}else if( *z=='+' ){
2094120970
z+=incr;
2094220971
}
2094320972
/* copy digits to exponent */
2094420973
while( z<zEnd && sqlite3Isdigit(*z) ){
20945
- e = e*10 + (*z - '0');
20974
+ e = e<10000 ? (e*10 + (*z - '0')) : 10000;
2094620975
z+=incr;
2094720976
eValid = 1;
2094820977
}
2094920978
}
2095020979
@@ -20991,10 +21020,16 @@
2099121020
result /= 1.0e+308;
2099221021
}else{
2099321022
result = s * scale;
2099421023
result *= 1.0e+308;
2099521024
}
21025
+ }else if( e>=342 ){
21026
+ if( esign<0 ){
21027
+ result = 0.0*s;
21028
+ }else{
21029
+ result = 1e308*1e308*s; /* Infinity */
21030
+ }
2099621031
}else{
2099721032
/* 1.0e+22 is the largest power of 10 than can be
2099821033
** represented exactly. */
2099921034
while( e%22 ) { scale *= 1.0e+1; e -= 1; }
2100021035
while( e>0 ) { scale *= 1.0e+22; e -= 22; }
@@ -25102,11 +25137,11 @@
2510225137
return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
2510325138
}
2510425139
#endif
2510525140
2510625141
25107
-#ifdef SQLITE_DEBUG
25142
+#if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
2510825143
/*
2510925144
** Helper function for printing out trace information from debugging
2511025145
** binaries. This returns the string represetation of the supplied
2511125146
** integer lock-type.
2511225147
*/
@@ -25937,18 +25972,18 @@
2593725972
** locking a random byte from a range, concurrent SHARED locks may exist
2593825973
** even if the locking primitive used is always a write-lock.
2593925974
*/
2594025975
int rc = SQLITE_OK;
2594125976
unixFile *pFile = (unixFile*)id;
25942
- unixInodeInfo *pInode = pFile->pInode;
25977
+ unixInodeInfo *pInode;
2594325978
struct flock lock;
2594425979
int tErrno = 0;
2594525980
2594625981
assert( pFile );
2594725982
OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
2594825983
azFileLock(eFileLock), azFileLock(pFile->eFileLock),
25949
- azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
25984
+ azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
2595025985
2595125986
/* If there is already a lock of this type or more restrictive on the
2595225987
** unixFile, do nothing. Don't use the end_lock: exit path, as
2595325988
** unixEnterMutex() hasn't been called yet.
2595425989
*/
@@ -26148,11 +26183,10 @@
2614826183
static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
2614926184
unixFile *pFile = (unixFile*)id;
2615026185
unixInodeInfo *pInode;
2615126186
struct flock lock;
2615226187
int rc = SQLITE_OK;
26153
- int h;
2615426188
2615526189
assert( pFile );
2615626190
OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
2615726191
pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
2615826192
getpid()));
@@ -26160,18 +26194,14 @@
2616026194
assert( eFileLock<=SHARED_LOCK );
2616126195
if( pFile->eFileLock<=eFileLock ){
2616226196
return SQLITE_OK;
2616326197
}
2616426198
unixEnterMutex();
26165
- h = pFile->h;
2616626199
pInode = pFile->pInode;
2616726200
assert( pInode->nShared!=0 );
2616826201
if( pFile->eFileLock>SHARED_LOCK ){
2616926202
assert( pInode->eFileLock==pFile->eFileLock );
26170
- SimulateIOErrorBenign(1);
26171
- SimulateIOError( h=(-1) )
26172
- SimulateIOErrorBenign(0);
2617326203
2617426204
#ifndef NDEBUG
2617526205
/* When reducing a lock such that other processes can start
2617626206
** reading the database file again, make sure that the
2617726207
** transaction counter was updated if any part of the database
@@ -26178,15 +26208,10 @@
2617826208
** file changed. If the transaction counter is not updated,
2617926209
** other connections to the same file might not realize that
2618026210
** the file has changed and hence might not know to flush their
2618126211
** cache. The use of a stale cache can lead to database corruption.
2618226212
*/
26183
-#if 0
26184
- assert( pFile->inNormalWrite==0
26185
- || pFile->dbUpdate==0
26186
- || pFile->transCntrChng==1 );
26187
-#endif
2618826213
pFile->inNormalWrite = 0;
2618926214
#endif
2619026215
2619126216
/* downgrading to a shared lock on NFS involves clearing the write lock
2619226217
** before establishing the readlock - to avoid a race condition we downgrade
@@ -26284,13 +26309,10 @@
2628426309
pInode->nShared--;
2628526310
if( pInode->nShared==0 ){
2628626311
lock.l_type = F_UNLCK;
2628726312
lock.l_whence = SEEK_SET;
2628826313
lock.l_start = lock.l_len = 0L;
26289
- SimulateIOErrorBenign(1);
26290
- SimulateIOError( h=(-1) )
26291
- SimulateIOErrorBenign(0);
2629226314
if( unixFileLock(pFile, &lock)==0 ){
2629326315
pInode->eFileLock = NO_LOCK;
2629426316
}else{
2629526317
rc = SQLITE_IOERR_UNLOCK;
2629626318
pFile->lastErrno = errno;
@@ -28428,20 +28450,19 @@
2842828450
rc = SQLITE_NOMEM;
2842928451
goto shm_open_err;
2843028452
}
2843128453
2843228454
if( pInode->bProcessLock==0 ){
28433
- pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT,
28434
- (sStat.st_mode & 0777));
28455
+ const char *zRO;
28456
+ int openFlags = O_RDWR | O_CREAT;
28457
+ zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
28458
+ if( zRO && sqlite3GetBoolean(zRO) ){
28459
+ openFlags = O_RDONLY;
28460
+ pShmNode->isReadonly = 1;
28461
+ }
28462
+ pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
2843528463
if( pShmNode->h<0 ){
28436
- const char *zRO;
28437
- zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
28438
- if( zRO && sqlite3GetBoolean(zRO) ){
28439
- pShmNode->h = robust_open(zShmFilename, O_RDONLY,
28440
- (sStat.st_mode & 0777));
28441
- pShmNode->isReadonly = 1;
28442
- }
2844328464
if( pShmNode->h<0 ){
2844428465
rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
2844528466
goto shm_open_err;
2844628467
}
2844728468
}
@@ -29122,10 +29143,13 @@
2912229143
assert( zFilename==0 || zFilename[0]=='/'
2912329144
|| pVfs->pAppData==(void*)&autolockIoFinder );
2912429145
#else
2912529146
assert( zFilename==0 || zFilename[0]=='/' );
2912629147
#endif
29148
+
29149
+ /* No locking occurs in temporary files */
29150
+ assert( zFilename!=0 || noLock );
2912729151
2912829152
OSTRACE(("OPEN %-3d %s\n", h, zFilename));
2912929153
pNew->h = h;
2913029154
pNew->zPath = zFilename;
2913129155
if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
@@ -29224,10 +29248,11 @@
2922429248
/* Dotfile locking uses the file path so it needs to be included in
2922529249
** the dotlockLockingContext
2922629250
*/
2922729251
char *zLockFile;
2922829252
int nFilename;
29253
+ assert( zFilename!=0 );
2922929254
nFilename = (int)strlen(zFilename) + 6;
2923029255
zLockFile = (char *)sqlite3_malloc(nFilename);
2923129256
if( zLockFile==0 ){
2923229257
rc = SQLITE_NOMEM;
2923329258
}else{
@@ -29462,12 +29487,20 @@
2946229487
**
2946329488
** where NN is a 4 digit decimal number. The NN naming schemes are
2946429489
** used by the test_multiplex.c module.
2946529490
*/
2946629491
nDb = sqlite3Strlen30(zPath) - 1;
29467
- while( nDb>0 && zPath[nDb]!='-' ) nDb--;
29468
- if( nDb==0 ) return SQLITE_OK;
29492
+#ifdef SQLITE_ENABLE_8_3_NAMES
29493
+ while( nDb>0 && zPath[nDb]!='-' && zPath[nDb]!='/' ) nDb--;
29494
+ if( nDb==0 || zPath[nDb]=='/' ) return SQLITE_OK;
29495
+#else
29496
+ while( zPath[nDb]!='-' ){
29497
+ assert( nDb>0 );
29498
+ assert( zPath[nDb]!='\n' );
29499
+ nDb--;
29500
+ }
29501
+#endif
2946929502
memcpy(zDb, zPath, nDb);
2947029503
zDb[nDb] = '\0';
2947129504
2947229505
if( 0==osStat(zDb, &sStat) ){
2947329506
*pMode = sStat.st_mode & 0777;
@@ -29995,14 +30028,16 @@
2999530028
** the current time and date as a Julian Day number times 86_400_000. In
2999630029
** other words, write into *piNow the number of milliseconds since the Julian
2999730030
** epoch of noon in Greenwich on November 24, 4714 B.C according to the
2999830031
** proleptic Gregorian calendar.
2999930032
**
30000
-** On success, return 0. Return 1 if the time and date cannot be found.
30033
+** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
30034
+** cannot be found.
3000130035
*/
3000230036
static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
3000330037
static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
30038
+ int rc = SQLITE_OK;
3000430039
#if defined(NO_GETTOD)
3000530040
time_t t;
3000630041
time(&t);
3000730042
*piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
3000830043
#elif OS_VXWORKS
@@ -30009,34 +30044,38 @@
3000930044
struct timespec sNow;
3001030045
clock_gettime(CLOCK_REALTIME, &sNow);
3001130046
*piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
3001230047
#else
3001330048
struct timeval sNow;
30014
- gettimeofday(&sNow, 0);
30015
- *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
30049
+ if( gettimeofday(&sNow, 0)==0 ){
30050
+ *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
30051
+ }else{
30052
+ rc = SQLITE_ERROR;
30053
+ }
3001630054
#endif
3001730055
3001830056
#ifdef SQLITE_TEST
3001930057
if( sqlite3_current_time ){
3002030058
*piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
3002130059
}
3002230060
#endif
3002330061
UNUSED_PARAMETER(NotUsed);
30024
- return 0;
30062
+ return rc;
3002530063
}
3002630064
3002730065
/*
3002830066
** Find the current time (in Universal Coordinated Time). Write the
3002930067
** current time and date as a Julian Day number into *prNow and
3003030068
** return 0. Return 1 if the time and date cannot be found.
3003130069
*/
3003230070
static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
30033
- sqlite3_int64 i;
30071
+ sqlite3_int64 i = 0;
30072
+ int rc;
3003430073
UNUSED_PARAMETER(NotUsed);
30035
- unixCurrentTimeInt64(0, &i);
30074
+ rc = unixCurrentTimeInt64(0, &i);
3003630075
*prNow = i/86400000.0;
30037
- return 0;
30076
+ return rc;
3003830077
}
3003930078
3004030079
/*
3004130080
** We added the xGetLastError() method with the intention of providing
3004230081
** better low-level error messages when operating-system problems come up
@@ -34169,11 +34208,11 @@
3416934208
3417034209
if( h==INVALID_HANDLE_VALUE ){
3417134210
pFile->lastErrno = GetLastError();
3417234211
winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
3417334212
free(zConverted);
34174
- if( isReadWrite ){
34213
+ if( isReadWrite && !isExclusive ){
3417534214
return winOpen(pVfs, zName, id,
3417634215
((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
3417734216
}else{
3417834217
return SQLITE_CANTOPEN_BKPT;
3417934218
}
@@ -34535,11 +34574,11 @@
3453534574
}
3453634575
static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
3453734576
UNUSED_PARAMETER(pVfs);
3453834577
getLastErrorMsg(nBuf, zBufOut);
3453934578
}
34540
-void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
34579
+static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
3454134580
UNUSED_PARAMETER(pVfs);
3454234581
#if SQLITE_OS_WINCE
3454334582
/* The GetProcAddressA() routine is only available on wince. */
3454434583
return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
3454534584
#else
@@ -34546,11 +34585,11 @@
3454634585
/* All other windows platforms expect GetProcAddress() to take
3454734586
** an Ansi string regardless of the _UNICODE setting */
3454834587
return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
3454934588
#endif
3455034589
}
34551
-void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
34590
+static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
3455234591
UNUSED_PARAMETER(pVfs);
3455334592
FreeLibrary((HANDLE)pHandle);
3455434593
}
3455534594
#else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
3455634595
#define winDlOpen 0
@@ -34620,11 +34659,12 @@
3462034659
** the current time and date as a Julian Day number times 86_400_000. In
3462134660
** other words, write into *piNow the number of milliseconds since the Julian
3462234661
** epoch of noon in Greenwich on November 24, 4714 B.C according to the
3462334662
** proleptic Gregorian calendar.
3462434663
**
34625
-** On success, return 0. Return 1 if the time and date cannot be found.
34664
+** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
34665
+** cannot be found.
3462634666
*/
3462734667
static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
3462834668
/* FILETIME structure is a 64-bit value representing the number of
3462934669
100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
3463034670
*/
@@ -34640,11 +34680,11 @@
3464034680
#if SQLITE_OS_WINCE
3464134681
SYSTEMTIME time;
3464234682
GetSystemTime(&time);
3464334683
/* if SystemTimeToFileTime() fails, it returns zero. */
3464434684
if (!SystemTimeToFileTime(&time,&ft)){
34645
- return 1;
34685
+ return SQLITE_ERROR;
3464634686
}
3464734687
#else
3464834688
GetSystemTimeAsFileTime( &ft );
3464934689
#endif
3465034690
@@ -34656,19 +34696,19 @@
3465634696
if( sqlite3_current_time ){
3465734697
*piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
3465834698
}
3465934699
#endif
3466034700
UNUSED_PARAMETER(pVfs);
34661
- return 0;
34701
+ return SQLITE_OK;
3466234702
}
3466334703
3466434704
/*
3466534705
** Find the current time (in Universal Coordinated Time). Write the
3466634706
** current time and date as a Julian Day number into *prNow and
3466734707
** return 0. Return 1 if the time and date cannot be found.
3466834708
*/
34669
-int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
34709
+static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
3467034710
int rc;
3467134711
sqlite3_int64 i;
3467234712
rc = winCurrentTimeInt64(pVfs, &i);
3467334713
if( !rc ){
3467434714
*prNow = i/86400000.0;
@@ -35789,12 +35829,10 @@
3578935829
typedef struct PCache1 PCache1;
3579035830
typedef struct PgHdr1 PgHdr1;
3579135831
typedef struct PgFreeslot PgFreeslot;
3579235832
typedef struct PGroup PGroup;
3579335833
35794
-typedef struct PGroupBlock PGroupBlock;
35795
-typedef struct PGroupBlockList PGroupBlockList;
3579635834
3579735835
/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
3579835836
** of one or more PCaches that are able to recycle each others unpinned
3579935837
** pages when they are under memory pressure. A PGroup is an instance of
3580035838
** the following object.
@@ -35821,69 +35859,11 @@
3582135859
int nMaxPage; /* Sum of nMax for purgeable caches */
3582235860
int nMinPage; /* Sum of nMin for purgeable caches */
3582335861
int mxPinned; /* nMaxpage + 10 - nMinPage */
3582435862
int nCurrentPage; /* Number of purgeable pages allocated */
3582535863
PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
35826
-#ifdef SQLITE_PAGECACHE_BLOCKALLOC
35827
- int isBusy; /* Do not run ReleaseMemory() if true */
35828
- PGroupBlockList *pBlockList; /* List of block-lists for this group */
35829
-#endif
35830
-};
35831
-
35832
-/*
35833
-** If SQLITE_PAGECACHE_BLOCKALLOC is defined when the library is built,
35834
-** each PGroup structure has a linked list of the the following starting
35835
-** at PGroup.pBlockList. There is one entry for each distinct page-size
35836
-** currently used by members of the PGroup (i.e. 1024 bytes, 4096 bytes
35837
-** etc.). Variable PGroupBlockList.nByte is set to the actual allocation
35838
-** size requested by each pcache, which is the database page-size plus
35839
-** the various header structures used by the pcache, pager and btree layers.
35840
-** Usually around (pgsz+200) bytes.
35841
-**
35842
-** This size (pgsz+200) bytes is not allocated efficiently by some
35843
-** implementations of malloc. In particular, some implementations are only
35844
-** able to allocate blocks of memory chunks of 2^N bytes, where N is some
35845
-** integer value. Since the page-size is a power of 2, this means we
35846
-** end up wasting (pgsz-200) bytes in each allocation.
35847
-**
35848
-** If SQLITE_PAGECACHE_BLOCKALLOC is defined, the (pgsz+200) byte blocks
35849
-** are not allocated directly. Instead, blocks of roughly M*(pgsz+200) bytes
35850
-** are requested from malloc allocator. After a block is returned,
35851
-** sqlite3MallocSize() is used to determine how many (pgsz+200) byte
35852
-** allocations can fit in the space returned by malloc(). This value may
35853
-** be more than M.
35854
-**
35855
-** The blocks are stored in a doubly-linked list. Variable PGroupBlock.nEntry
35856
-** contains the number of allocations that will fit in the aData[] space.
35857
-** nEntry is limited to the number of bits in bitmask mUsed. If a slot
35858
-** within aData is in use, the corresponding bit in mUsed is set. Thus
35859
-** when (mUsed+1==(1 << nEntry)) the block is completely full.
35860
-**
35861
-** Each time a slot within a block is freed, the block is moved to the start
35862
-** of the linked-list. And if a block becomes completely full, then it is
35863
-** moved to the end of the list. As a result, when searching for a free
35864
-** slot, only the first block in the list need be examined. If it is full,
35865
-** then it is guaranteed that all blocks are full.
35866
-*/
35867
-struct PGroupBlockList {
35868
- int nByte; /* Size of each allocation in bytes */
35869
- PGroupBlock *pFirst; /* First PGroupBlock in list */
35870
- PGroupBlock *pLast; /* Last PGroupBlock in list */
35871
- PGroupBlockList *pNext; /* Next block-list attached to group */
35872
-};
35873
-
35874
-struct PGroupBlock {
35875
- Bitmask mUsed; /* Mask of used slots */
35876
- int nEntry; /* Maximum number of allocations in aData[] */
35877
- u8 *aData; /* Pointer to data block */
35878
- PGroupBlock *pNext; /* Next PGroupBlock in list */
35879
- PGroupBlock *pPrev; /* Previous PGroupBlock in list */
35880
- PGroupBlockList *pList; /* Owner list */
35881
-};
35882
-
35883
-/* Minimum value for PGroupBlock.nEntry */
35884
-#define PAGECACHE_BLOCKALLOC_MINENTRY 15
35864
+};
3588535865
3588635866
/* Each page cache is an instance of the following object. Every
3588735867
** open database file (including each in-memory database and each
3588835868
** temporary or transient database) has a single page cache which
3588935869
** is an instance of this object.
@@ -35983,21 +35963,10 @@
3598335963
**
3598435964
** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
3598535965
*/
3598635966
#define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
3598735967
#define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
35988
-
35989
-/*
35990
-** Blocks used by the SQLITE_PAGECACHE_BLOCKALLOC blocks to store/retrieve
35991
-** a PGroupBlock pointer based on a pointer to a page buffer.
35992
-*/
35993
-#define PAGE_SET_BLOCKPTR(pCache, pPg, pBlock) \
35994
- ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) = pBlock )
35995
-
35996
-#define PAGE_GET_BLOCKPTR(pCache, pPg) \
35997
- ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) )
35998
-
3599935968
3600035969
/*
3600135970
** Macros to enter and leave the PCache LRU mutex.
3600235971
*/
3600335972
#define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
@@ -36120,159 +36089,32 @@
3612036089
return iSize;
3612136090
}
3612236091
}
3612336092
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
3612436093
36125
-#ifdef SQLITE_PAGECACHE_BLOCKALLOC
36126
-/*
36127
-** The block pBlock belongs to list pList but is not currently linked in.
36128
-** Insert it into the start of the list.
36129
-*/
36130
-static void addBlockToList(PGroupBlockList *pList, PGroupBlock *pBlock){
36131
- pBlock->pPrev = 0;
36132
- pBlock->pNext = pList->pFirst;
36133
- pList->pFirst = pBlock;
36134
- if( pBlock->pNext ){
36135
- pBlock->pNext->pPrev = pBlock;
36136
- }else{
36137
- assert( pList->pLast==0 );
36138
- pList->pLast = pBlock;
36139
- }
36140
-}
36141
-
36142
-/*
36143
-** If there are no blocks in the list headed by pList, remove pList
36144
-** from the pGroup->pBlockList list and free it with sqlite3_free().
36145
-*/
36146
-static void freeListIfEmpty(PGroup *pGroup, PGroupBlockList *pList){
36147
- assert( sqlite3_mutex_held(pGroup->mutex) );
36148
- if( pList->pFirst==0 ){
36149
- PGroupBlockList **pp;
36150
- for(pp=&pGroup->pBlockList; *pp!=pList; pp=&(*pp)->pNext);
36151
- *pp = (*pp)->pNext;
36152
- sqlite3_free(pList);
36153
- }
36154
-}
36155
-#endif /* SQLITE_PAGECACHE_BLOCKALLOC */
36156
-
3615736094
/*
3615836095
** Allocate a new page object initially associated with cache pCache.
3615936096
*/
3616036097
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
3616136098
int nByte = sizeof(PgHdr1) + pCache->szPage;
36162
- void *pPg = 0;
36163
- PgHdr1 *p;
36164
-
36165
-#ifdef SQLITE_PAGECACHE_BLOCKALLOC
36166
- PGroup *pGroup = pCache->pGroup;
36167
- PGroupBlockList *pList;
36168
- PGroupBlock *pBlock;
36169
- int i;
36170
-
36171
- nByte += sizeof(PGroupBlockList *);
36172
- nByte = ROUND8(nByte);
36173
-
36174
- for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
36175
- if( pList->nByte==nByte ) break;
36176
- }
36177
- if( pList==0 ){
36178
- PGroupBlockList *pNew;
36179
- assert( pGroup->isBusy==0 );
36180
- assert( sqlite3_mutex_held(pGroup->mutex) );
36181
- pGroup->isBusy = 1; /* Disable sqlite3PcacheReleaseMemory() */
36182
- pNew = (PGroupBlockList *)sqlite3MallocZero(sizeof(PGroupBlockList));
36183
- pGroup->isBusy = 0; /* Reenable sqlite3PcacheReleaseMemory() */
36184
- if( pNew==0 ){
36185
- /* malloc() failure. Return early. */
36186
- return 0;
36187
- }
36188
-#ifdef SQLITE_DEBUG
36189
- for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
36190
- assert( pList->nByte!=nByte );
36191
- }
36192
-#endif
36193
- pNew->nByte = nByte;
36194
- pNew->pNext = pGroup->pBlockList;
36195
- pGroup->pBlockList = pNew;
36196
- pList = pNew;
36197
- }
36198
-
36199
- pBlock = pList->pFirst;
36200
- if( pBlock==0 || pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) ){
36201
- int sz;
36202
-
36203
- /* Allocate a new block. Try to allocate enough space for the PGroupBlock
36204
- ** structure and MINENTRY allocations of nByte bytes each. If the
36205
- ** allocator returns more memory than requested, then more than MINENTRY
36206
- ** allocations may fit in it. */
36207
- assert( sqlite3_mutex_held(pGroup->mutex) );
36208
- pcache1LeaveMutex(pCache->pGroup);
36209
- sz = sizeof(PGroupBlock) + PAGECACHE_BLOCKALLOC_MINENTRY * nByte;
36210
- pBlock = (PGroupBlock *)sqlite3Malloc(sz);
36211
- pcache1EnterMutex(pCache->pGroup);
36212
-
36213
- if( !pBlock ){
36214
- freeListIfEmpty(pGroup, pList);
36215
- return 0;
36216
- }
36217
- pBlock->nEntry = (sqlite3MallocSize(pBlock) - sizeof(PGroupBlock)) / nByte;
36218
- if( pBlock->nEntry>=BMS ){
36219
- pBlock->nEntry = BMS-1;
36220
- }
36221
- pBlock->pList = pList;
36222
- pBlock->mUsed = 0;
36223
- pBlock->aData = (u8 *)&pBlock[1];
36224
- addBlockToList(pList, pBlock);
36225
-
36226
- sz = sqlite3MallocSize(pBlock);
36227
- sqlite3_mutex_enter(pcache1.mutex);
36228
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
36229
- sqlite3_mutex_leave(pcache1.mutex);
36230
- }
36231
-
36232
- for(i=0; pPg==0 && ALWAYS(i<pBlock->nEntry); i++){
36233
- if( 0==(pBlock->mUsed & ((Bitmask)1<<i)) ){
36234
- pBlock->mUsed |= ((Bitmask)1<<i);
36235
- pPg = (void *)&pBlock->aData[pList->nByte * i];
36236
- }
36237
- }
36238
- assert( pPg );
36239
- PAGE_SET_BLOCKPTR(pCache, pPg, pBlock);
36240
-
36241
- /* If the block is now full, shift it to the end of the list */
36242
- if( pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) && pList->pLast!=pBlock ){
36243
- assert( pList->pFirst==pBlock );
36244
- assert( pBlock->pPrev==0 );
36245
- assert( pList->pLast->pNext==0 );
36246
- pList->pFirst = pBlock->pNext;
36247
- pList->pFirst->pPrev = 0;
36248
- pBlock->pPrev = pList->pLast;
36249
- pBlock->pNext = 0;
36250
- pList->pLast->pNext = pBlock;
36251
- pList->pLast = pBlock;
36252
- }
36253
- p = PAGE_TO_PGHDR1(pCache, pPg);
36254
- if( pCache->bPurgeable ){
36255
- pCache->pGroup->nCurrentPage++;
36256
- }
36257
-#else
36099
+ PgHdr1 *p = 0;
36100
+ void *pPg;
36101
+
3625836102
/* The group mutex must be released before pcache1Alloc() is called. This
3625936103
** is because it may call sqlite3_release_memory(), which assumes that
3626036104
** this mutex is not held. */
3626136105
assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
3626236106
pcache1LeaveMutex(pCache->pGroup);
3626336107
pPg = pcache1Alloc(nByte);
3626436108
pcache1EnterMutex(pCache->pGroup);
36109
+
3626536110
if( pPg ){
3626636111
p = PAGE_TO_PGHDR1(pCache, pPg);
3626736112
if( pCache->bPurgeable ){
3626836113
pCache->pGroup->nCurrentPage++;
3626936114
}
36270
- }else{
36271
- p = 0;
3627236115
}
36273
-#endif
3627436116
return p;
3627536117
}
3627636118
3627736119
/*
3627836120
** Free a page object allocated by pcache1AllocPage().
@@ -36282,53 +36124,12 @@
3628236124
** with a NULL pointer, so we mark the NULL test with ALWAYS().
3628336125
*/
3628436126
static void pcache1FreePage(PgHdr1 *p){
3628536127
if( ALWAYS(p) ){
3628636128
PCache1 *pCache = p->pCache;
36287
- void *pPg = PGHDR1_TO_PAGE(p);
36288
-
36289
-#ifdef SQLITE_PAGECACHE_BLOCKALLOC
36290
- PGroupBlock *pBlock = PAGE_GET_BLOCKPTR(pCache, pPg);
36291
- PGroupBlockList *pList = pBlock->pList;
36292
- int i = ((u8 *)pPg - pBlock->aData) / pList->nByte;
36293
-
36294
- assert( pPg==(void *)&pBlock->aData[i*pList->nByte] );
36295
- assert( pBlock->mUsed & ((Bitmask)1<<i) );
36296
- pBlock->mUsed &= ~((Bitmask)1<<i);
36297
-
36298
- /* Remove the block from the list. If it is completely empty, free it.
36299
- ** Or if it is not completely empty, re-insert it at the start of the
36300
- ** list. */
36301
- if( pList->pFirst==pBlock ){
36302
- pList->pFirst = pBlock->pNext;
36303
- if( pList->pFirst ) pList->pFirst->pPrev = 0;
36304
- }else{
36305
- pBlock->pPrev->pNext = pBlock->pNext;
36306
- }
36307
- if( pList->pLast==pBlock ){
36308
- pList->pLast = pBlock->pPrev;
36309
- if( pList->pLast ) pList->pLast->pNext = 0;
36310
- }else{
36311
- pBlock->pNext->pPrev = pBlock->pPrev;
36312
- }
36313
-
36314
- if( pBlock->mUsed==0 ){
36315
- PGroup *pGroup = p->pCache->pGroup;
36316
-
36317
- int sz = sqlite3MallocSize(pBlock);
36318
- sqlite3_mutex_enter(pcache1.mutex);
36319
- sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -sz);
36320
- sqlite3_mutex_leave(pcache1.mutex);
36321
- freeListIfEmpty(pGroup, pList);
36322
- sqlite3_free(pBlock);
36323
- }else{
36324
- addBlockToList(pList, pBlock);
36325
- }
36326
-#else
3632736129
assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
36328
- pcache1Free(pPg);
36329
-#endif
36130
+ pcache1Free(PGHDR1_TO_PAGE(p));
3633036131
if( pCache->bPurgeable ){
3633136132
pCache->pGroup->nCurrentPage--;
3633236133
}
3633336134
}
3633436135
}
@@ -36935,13 +36736,10 @@
3693536736
** been released, the function returns. The return value is the total number
3693636737
** of bytes of memory released.
3693736738
*/
3693836739
SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
3693936740
int nFree = 0;
36940
-#ifdef SQLITE_PAGECACHE_BLOCKALLOC
36941
- if( pcache1.grp.isBusy ) return 0;
36942
-#endif
3694336741
assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
3694436742
assert( sqlite3_mutex_notheld(pcache1.mutex) );
3694536743
if( pcache1.pStart==0 ){
3694636744
PgHdr1 *p;
3694736745
pcache1EnterMutex(&pcache1.grp);
@@ -38200,12 +37998,12 @@
3820037998
i64 journalSizeLimit; /* Size limit for persistent journal files */
3820137999
char *zFilename; /* Name of the database file */
3820238000
char *zJournal; /* Name of the journal file */
3820338001
int (*xBusyHandler)(void*); /* Function to call when busy */
3820438002
void *pBusyHandlerArg; /* Context argument for xBusyHandler */
38003
+ int nHit, nMiss; /* Total cache hits and misses */
3820538004
#ifdef SQLITE_TEST
38206
- int nHit, nMiss; /* Cache hits and missing */
3820738005
int nRead, nWrite; /* Database pages read/written */
3820838006
#endif
3820938007
void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
3821038008
#ifdef SQLITE_HAS_CODEC
3821138009
void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
@@ -40233,11 +40031,10 @@
4023340031
needPagerReset = 0;
4023440032
}
4023540033
rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
4023640034
if( rc!=SQLITE_OK ){
4023740035
if( rc==SQLITE_DONE ){
40238
- rc = SQLITE_OK;
4023940036
pPager->journalOff = szJ;
4024040037
break;
4024140038
}else if( rc==SQLITE_IOERR_SHORT_READ ){
4024240039
/* If the journal has been truncated, simply stop reading and
4024340040
** processing the journal. This might happen if the journal was
@@ -40495,10 +40292,11 @@
4049540292
#if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
4049640293
PgHdr *p; /* For looping over pages */
4049740294
#endif
4049840295
4049940296
assert( pPager->pWal );
40297
+ assert( pList );
4050040298
#ifdef SQLITE_DEBUG
4050140299
/* Verify that the page list is in accending order */
4050240300
for(p=pList; p && p->pDirty; p=p->pDirty){
4050340301
assert( p->pgno < p->pDirty->pgno );
4050440302
}
@@ -41699,11 +41497,11 @@
4169941497
** The doNotSpill flag inhibits all cache spilling regardless of whether
4170041498
** or not a sync is required. This is set during a rollback.
4170141499
**
4170241500
** Spilling is also prohibited when in an error state since that could
4170341501
** lead to database corruption. In the current implementaton it
41704
- ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1
41502
+ ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1
4170541503
** while in the error state, hence it is impossible for this routine to
4170641504
** be called in the error state. Nevertheless, we include a NEVER()
4170741505
** test for the error state as a safeguard against future changes.
4170841506
*/
4170941507
if( NEVER(pPager->errCode) ) return SQLITE_OK;
@@ -42535,18 +42333,17 @@
4253542333
4253642334
if( (*ppPage)->pPager && !noContent ){
4253742335
/* In this case the pcache already contains an initialized copy of
4253842336
** the page. Return without further ado. */
4253942337
assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
42540
- PAGER_INCR(pPager->nHit);
42338
+ pPager->nHit++;
4254142339
return SQLITE_OK;
4254242340
4254342341
}else{
4254442342
/* The pager cache has created a new page. Its content needs to
4254542343
** be initialized. */
4254642344
42547
- PAGER_INCR(pPager->nMiss);
4254842345
pPg = *ppPage;
4254942346
pPg->pPager = pPager;
4255042347
4255142348
/* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
4255242349
** number greater than this, or the unused locking-page, is requested. */
@@ -42578,10 +42375,11 @@
4257842375
}
4257942376
memset(pPg->pData, 0, pPager->pageSize);
4258042377
IOTRACE(("ZERO %p %d\n", pPager, pgno));
4258142378
}else{
4258242379
assert( pPg->pPager==pPager );
42380
+ pPager->nMiss++;
4258342381
rc = readDbPage(pPg);
4258442382
if( rc!=SQLITE_OK ){
4258542383
goto pager_acquire_err;
4258642384
}
4258742385
}
@@ -43611,10 +43409,35 @@
4361143409
a[9] = pPager->nRead;
4361243410
a[10] = pPager->nWrite;
4361343411
return a;
4361443412
}
4361543413
#endif
43414
+
43415
+/*
43416
+** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
43417
+** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
43418
+** current cache hit or miss count, according to the value of eStat. If the
43419
+** reset parameter is non-zero, the cache hit or miss count is zeroed before
43420
+** returning.
43421
+*/
43422
+SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
43423
+ int *piStat;
43424
+
43425
+ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
43426
+ || eStat==SQLITE_DBSTATUS_CACHE_MISS
43427
+ );
43428
+ if( eStat==SQLITE_DBSTATUS_CACHE_HIT ){
43429
+ piStat = &pPager->nHit;
43430
+ }else{
43431
+ piStat = &pPager->nMiss;
43432
+ }
43433
+
43434
+ *pnVal += *piStat;
43435
+ if( reset ){
43436
+ *piStat = 0;
43437
+ }
43438
+}
4361643439
4361743440
/*
4361843441
** Return true if this is an in-memory pager.
4361943442
*/
4362043443
SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
@@ -46706,11 +46529,11 @@
4670646529
*/
4670746530
if( iRead ){
4670846531
int sz;
4670946532
i64 iOffset;
4671046533
sz = pWal->hdr.szPage;
46711
- sz = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
46534
+ sz = (sz&0xfe00) + ((sz&0x0001)<<16);
4671246535
testcase( sz<=32768 );
4671346536
testcase( sz>=65536 );
4671446537
iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
4671546538
*pInWal = 1;
4671646539
/* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
@@ -50019,21 +49842,23 @@
5001949842
*/
5002049843
if( isMemdb==0 && isTempDb==0 ){
5002149844
if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
5002249845
int nFullPathname = pVfs->mxPathname+1;
5002349846
char *zFullPathname = sqlite3Malloc(nFullPathname);
50024
- sqlite3_mutex *mutexShared;
49847
+ MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
5002549848
p->sharable = 1;
5002649849
if( !zFullPathname ){
5002749850
sqlite3_free(p);
5002849851
return SQLITE_NOMEM;
5002949852
}
5003049853
sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
49854
+#if SQLITE_THREADSAFE
5003149855
mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
5003249856
sqlite3_mutex_enter(mutexOpen);
5003349857
mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
5003449858
sqlite3_mutex_enter(mutexShared);
49859
+#endif
5003549860
for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
5003649861
assert( pBt->nRef>0 );
5003749862
if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
5003849863
&& sqlite3PagerVfs(pBt->pPager)==pVfs ){
5003949864
int iDb;
@@ -50135,13 +49960,13 @@
5013549960
5013649961
#if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
5013749962
/* Add the new BtShared object to the linked list sharable BtShareds.
5013849963
*/
5013949964
if( p->sharable ){
50140
- sqlite3_mutex *mutexShared;
49965
+ MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
5014149966
pBt->nRef = 1;
50142
- mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
49967
+ MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
5014349968
if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
5014449969
pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
5014549970
if( pBt->mutex==0 ){
5014649971
rc = SQLITE_NOMEM;
5014749972
db->mallocFailed = 0;
@@ -50219,16 +50044,16 @@
5021950044
** true if the BtShared.nRef counter reaches zero and return
5022050045
** false if it is still positive.
5022150046
*/
5022250047
static int removeFromSharingList(BtShared *pBt){
5022350048
#ifndef SQLITE_OMIT_SHARED_CACHE
50224
- sqlite3_mutex *pMaster;
50049
+ MUTEX_LOGIC( sqlite3_mutex *pMaster; )
5022550050
BtShared *pList;
5022650051
int removed = 0;
5022750052
5022850053
assert( sqlite3_mutex_notheld(pBt->mutex) );
50229
- pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
50054
+ MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
5023050055
sqlite3_mutex_enter(pMaster);
5023150056
pBt->nRef--;
5023250057
if( pBt->nRef<=0 ){
5023350058
if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
5023450059
GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
@@ -52191,25 +52016,59 @@
5219152016
offset -= ovflSize;
5219252017
}else{
5219352018
/* Need to read this page properly. It contains some of the
5219452019
** range of data that is being read (eOp==0) or written (eOp!=0).
5219552020
*/
52196
- DbPage *pDbPage;
52021
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
52022
+ sqlite3_file *fd;
52023
+#endif
5219752024
int a = amt;
52198
- rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
52199
- if( rc==SQLITE_OK ){
52200
- aPayload = sqlite3PagerGetData(pDbPage);
52201
- nextPage = get4byte(aPayload);
52202
- if( a + offset > ovflSize ){
52203
- a = ovflSize - offset;
52204
- }
52205
- rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
52206
- sqlite3PagerUnref(pDbPage);
52207
- offset = 0;
52208
- amt -= a;
52209
- pBuf += a;
52210
- }
52025
+ if( a + offset > ovflSize ){
52026
+ a = ovflSize - offset;
52027
+ }
52028
+
52029
+#ifdef SQLITE_DIRECT_OVERFLOW_READ
52030
+ /* If all the following are true:
52031
+ **
52032
+ ** 1) this is a read operation, and
52033
+ ** 2) data is required from the start of this overflow page, and
52034
+ ** 3) the database is file-backed, and
52035
+ ** 4) there is no open write-transaction, and
52036
+ ** 5) the database is not a WAL database,
52037
+ **
52038
+ ** then data can be read directly from the database file into the
52039
+ ** output buffer, bypassing the page-cache altogether. This speeds
52040
+ ** up loading large records that span many overflow pages.
52041
+ */
52042
+ if( eOp==0 /* (1) */
52043
+ && offset==0 /* (2) */
52044
+ && pBt->inTransaction==TRANS_READ /* (4) */
52045
+ && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
52046
+ && pBt->pPage1->aData[19]==0x01 /* (5) */
52047
+ ){
52048
+ u8 aSave[4];
52049
+ u8 *aWrite = &pBuf[-4];
52050
+ memcpy(aSave, aWrite, 4);
52051
+ rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1));
52052
+ nextPage = get4byte(aWrite);
52053
+ memcpy(aWrite, aSave, 4);
52054
+ }else
52055
+#endif
52056
+
52057
+ {
52058
+ DbPage *pDbPage;
52059
+ rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
52060
+ if( rc==SQLITE_OK ){
52061
+ aPayload = sqlite3PagerGetData(pDbPage);
52062
+ nextPage = get4byte(aPayload);
52063
+ rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
52064
+ sqlite3PagerUnref(pDbPage);
52065
+ offset = 0;
52066
+ }
52067
+ }
52068
+ amt -= a;
52069
+ pBuf += a;
5221152070
}
5221252071
}
5221352072
}
5221452073
5221552074
if( rc==SQLITE_OK && amt>0 ){
@@ -52804,11 +52663,10 @@
5280452663
}
5280552664
}
5280652665
if( c==0 ){
5280752666
if( pPage->intKey && !pPage->leaf ){
5280852667
lwr = idx;
52809
- upr = lwr - 1;
5281052668
break;
5281152669
}else{
5281252670
*pRes = 0;
5281352671
rc = SQLITE_OK;
5281452672
goto moveto_finish;
@@ -52822,11 +52680,11 @@
5282252680
if( lwr>upr ){
5282352681
break;
5282452682
}
5282552683
pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
5282652684
}
52827
- assert( lwr==upr+1 );
52685
+ assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
5282852686
assert( pPage->isInit );
5282952687
if( pPage->leaf ){
5283052688
chldPg = 0;
5283152689
}else if( lwr>=pPage->nCell ){
5283252690
chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
@@ -53087,10 +52945,12 @@
5308752945
}
5308852946
if( rc ){
5308952947
pTrunk = 0;
5309052948
goto end_allocate_page;
5309152949
}
52950
+ assert( pTrunk!=0 );
52951
+ assert( pTrunk->aData!=0 );
5309252952
5309352953
k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
5309452954
if( k==0 && !searchList ){
5309552955
/* The trunk has no leaves and the list is not being searched.
5309652956
** So extract the trunk page itself and use it as the newly
@@ -54214,17 +54074,19 @@
5421454074
** This is safe because dropping a cell only overwrites the first
5421554075
** four bytes of it, and this function does not need the first
5421654076
** four bytes of the divider cell. So the pointer is safe to use
5421754077
** later on.
5421854078
**
54219
- ** Unless SQLite is compiled in secure-delete mode. In this case,
54079
+ ** But not if we are in secure-delete mode. In secure-delete mode,
5422054080
** the dropCell() routine will overwrite the entire cell with zeroes.
5422154081
** In this case, temporarily copy the cell into the aOvflSpace[]
5422254082
** buffer. It will be copied out again as soon as the aSpace[] buffer
5422354083
** is allocated. */
5422454084
if( pBt->secureDelete ){
54225
- int iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
54085
+ int iOff;
54086
+
54087
+ iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
5422654088
if( (iOff+szNew[i])>(int)pBt->usableSize ){
5422754089
rc = SQLITE_CORRUPT_BKPT;
5422854090
memset(apOld, 0, (i+1)*sizeof(MemPage*));
5422954091
goto balance_cleanup;
5423054092
}else{
@@ -54640,10 +54502,11 @@
5464054502
int isDivider = 0;
5464154503
while( i==iNextOld ){
5464254504
/* Cell i is the cell immediately following the last cell on old
5464354505
** sibling page j. If the siblings are not leaf pages of an
5464454506
** intkey b-tree, then cell i was a divider cell. */
54507
+ assert( j+1 < ArraySize(apCopy) );
5464554508
pOld = apCopy[++j];
5464654509
iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
5464754510
if( pOld->nOverflow ){
5464854511
nOverflow = pOld->nOverflow;
5464954512
iOverflow = i + !leafData + pOld->aOvfl[0].idx;
@@ -56982,18 +56845,18 @@
5698256845
/*
5698356846
** Release all resources associated with an sqlite3_backup* handle.
5698456847
*/
5698556848
SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
5698656849
sqlite3_backup **pp; /* Ptr to head of pagers backup list */
56987
- sqlite3_mutex *mutex; /* Mutex to protect source database */
56850
+ MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
5698856851
int rc; /* Value to return */
5698956852
5699056853
/* Enter the mutexes */
5699156854
if( p==0 ) return SQLITE_OK;
5699256855
sqlite3_mutex_enter(p->pSrcDb->mutex);
5699356856
sqlite3BtreeEnter(p->pSrc);
56994
- mutex = p->pSrcDb->mutex;
56857
+ MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
5699556858
if( p->pDestDb ){
5699656859
sqlite3_mutex_enter(p->pDestDb->mutex);
5699756860
}
5699856861
5699956862
/* Detach this backup from the source pager. */
@@ -57108,13 +56971,21 @@
5710856971
** goes wrong, the transaction on pTo is rolled back. If successful, the
5710956972
** transaction is committed before returning.
5711056973
*/
5711156974
SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
5711256975
int rc;
56976
+ sqlite3_file *pFd; /* File descriptor for database pTo */
5711356977
sqlite3_backup b;
5711456978
sqlite3BtreeEnter(pTo);
5711556979
sqlite3BtreeEnter(pFrom);
56980
+
56981
+ assert( sqlite3BtreeIsInTrans(pTo) );
56982
+ pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
56983
+ if( pFd->pMethods ){
56984
+ i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
56985
+ sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
56986
+ }
5711656987
5711756988
/* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
5711856989
** to 0. This is used by the implementations of sqlite3_backup_step()
5711956990
** and sqlite3_backup_finish() to detect that they are being called
5712056991
** from this function, not directly by the user.
@@ -57137,10 +57008,11 @@
5713757008
rc = sqlite3_backup_finish(&b);
5713857009
if( rc==SQLITE_OK ){
5713957010
pTo->pBt->pageSizeFixed = 0;
5714057011
}
5714157012
57013
+ assert( sqlite3BtreeIsInTrans(pTo)==0 );
5714257014
sqlite3BtreeLeave(pFrom);
5714357015
sqlite3BtreeLeave(pTo);
5714457016
return rc;
5714557017
}
5714657018
#endif /* SQLITE_OMIT_VACUUM */
@@ -58171,15 +58043,15 @@
5817158043
*ppVal = 0;
5817258044
return SQLITE_OK;
5817358045
}
5817458046
op = pExpr->op;
5817558047
58176
- /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2.
58048
+ /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3.
5817758049
** The ifdef here is to enable us to achieve 100% branch test coverage even
58178
- ** when SQLITE_ENABLE_STAT2 is omitted.
58050
+ ** when SQLITE_ENABLE_STAT3 is omitted.
5817958051
*/
58180
-#ifdef SQLITE_ENABLE_STAT2
58052
+#ifdef SQLITE_ENABLE_STAT3
5818158053
if( op==TK_REGISTER ) op = pExpr->op2;
5818258054
#else
5818358055
if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
5818458056
#endif
5818558057
@@ -58874,12 +58746,12 @@
5887458746
/*
5887558747
** Change the P2 operand of instruction addr so that it points to
5887658748
** the address of the next instruction to be coded.
5887758749
*/
5887858750
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
58879
- assert( addr>=0 );
58880
- sqlite3VdbeChangeP2(p, addr, p->nOp);
58751
+ assert( addr>=0 || p->db->mallocFailed );
58752
+ if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
5888158753
}
5888258754
5888358755
5888458756
/*
5888558757
** If the input FuncDef structure is ephemeral, then free it. If
@@ -59080,34 +58952,33 @@
5908058952
** Change the comment on the the most recently coded instruction. Or
5908158953
** insert a No-op and add the comment to that new instruction. This
5908258954
** makes the code easier to read during debugging. None of this happens
5908358955
** in a production build.
5908458956
*/
59085
-SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
59086
- va_list ap;
59087
- if( !p ) return;
58957
+static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
5908858958
assert( p->nOp>0 || p->aOp==0 );
5908958959
assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
5909058960
if( p->nOp ){
59091
- char **pz = &p->aOp[p->nOp-1].zComment;
58961
+ assert( p->aOp );
58962
+ sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
58963
+ p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
58964
+ }
58965
+}
58966
+SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
58967
+ va_list ap;
58968
+ if( p ){
5909258969
va_start(ap, zFormat);
59093
- sqlite3DbFree(p->db, *pz);
59094
- *pz = sqlite3VMPrintf(p->db, zFormat, ap);
58970
+ vdbeVComment(p, zFormat, ap);
5909558971
va_end(ap);
5909658972
}
5909758973
}
5909858974
SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
5909958975
va_list ap;
59100
- if( !p ) return;
59101
- sqlite3VdbeAddOp0(p, OP_Noop);
59102
- assert( p->nOp>0 || p->aOp==0 );
59103
- assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
59104
- if( p->nOp ){
59105
- char **pz = &p->aOp[p->nOp-1].zComment;
58976
+ if( p ){
58977
+ sqlite3VdbeAddOp0(p, OP_Noop);
5910658978
va_start(ap, zFormat);
59107
- sqlite3DbFree(p->db, *pz);
59108
- *pz = sqlite3VMPrintf(p->db, zFormat, ap);
58979
+ vdbeVComment(p, zFormat, ap);
5910958980
va_end(ap);
5911058981
}
5911158982
}
5911258983
#endif /* NDEBUG */
5911358984
@@ -59441,11 +59312,11 @@
5944159312
SubProgram **apSub = 0; /* Array of sub-vdbes */
5944259313
Mem *pSub = 0; /* Memory cell hold array of subprogs */
5944359314
sqlite3 *db = p->db; /* The database connection */
5944459315
int i; /* Loop counter */
5944559316
int rc = SQLITE_OK; /* Return code */
59446
- Mem *pMem = p->pResultSet = &p->aMem[1]; /* First Mem of result set */
59317
+ Mem *pMem = &p->aMem[1]; /* First Mem of result set */
5944759318
5944859319
assert( p->explain );
5944959320
assert( p->magic==VDBE_MAGIC_RUN );
5945059321
assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
5945159322
@@ -59452,10 +59323,11 @@
5945259323
/* Even though this opcode does not use dynamic strings for
5945359324
** the result, result columns may become dynamic if the user calls
5945459325
** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
5945559326
*/
5945659327
releaseMemArray(pMem, 8);
59328
+ p->pResultSet = 0;
5945759329
5945859330
if( p->rc==SQLITE_NOMEM ){
5945959331
/* This happens if a malloc() inside a call to sqlite3_column_text() or
5946059332
** sqlite3_column_text16() failed. */
5946159333
db->mallocFailed = 1;
@@ -59606,10 +59478,11 @@
5960659478
pMem->type = SQLITE_NULL;
5960759479
}
5960859480
}
5960959481
5961059482
p->nResColumn = 8 - 4*(p->explain-1);
59483
+ p->pResultSet = &p->aMem[1];
5961159484
p->rc = SQLITE_OK;
5961259485
rc = SQLITE_ROW;
5961359486
}
5961459487
return rc;
5961559488
}
@@ -61361,11 +61234,11 @@
6136161234
** than 2GiB are support - anything large must be database corruption.
6136261235
** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
6136361236
** this code can safely assume that nCellKey is 32-bits
6136461237
*/
6136561238
assert( sqlite3BtreeCursorIsValid(pCur) );
61366
- rc = sqlite3BtreeKeySize(pCur, &nCellKey);
61239
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
6136761240
assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
6136861241
assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
6136961242
6137061243
/* Read in the complete content of the index entry */
6137161244
memset(&m, 0, sizeof(m));
@@ -61436,11 +61309,11 @@
6143661309
int rc;
6143761310
BtCursor *pCur = pC->pCursor;
6143861311
Mem m;
6143961312
6144061313
assert( sqlite3BtreeCursorIsValid(pCur) );
61441
- rc = sqlite3BtreeKeySize(pCur, &nCellKey);
61314
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
6144261315
assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
6144361316
/* nCellKey will always be between 0 and 0xffffffff because of the say
6144461317
** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
6144561318
if( nCellKey<=0 || nCellKey>0x7fffffff ){
6144661319
*res = 0;
@@ -65712,20 +65585,20 @@
6571265585
}else if( u.am.pC->cacheStatus==p->cacheCtr ){
6571365586
u.am.payloadSize = u.am.pC->payloadSize;
6571465587
u.am.zRec = (char*)u.am.pC->aRow;
6571565588
}else if( u.am.pC->isIndex ){
6571665589
assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
65717
- rc = sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64);
65590
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64);
6571865591
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
6571965592
/* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
6572065593
** payload size, so it is impossible for u.am.payloadSize64 to be
6572165594
** larger than 32 bits. */
6572265595
assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 );
6572365596
u.am.payloadSize = (u32)u.am.payloadSize64;
6572465597
}else{
6572565598
assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
65726
- rc = sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
65599
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
6572765600
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
6572865601
}
6572965602
}else if( ALWAYS(u.am.pC->pseudoTableReg>0) ){
6573065603
u.am.pReg = &aMem[u.am.pC->pseudoTableReg];
6573165604
assert( u.am.pReg->flags & MEM_Blob );
@@ -67773,18 +67646,18 @@
6777367646
rc = sqlite3VdbeCursorMoveto(u.bk.pC);
6777467647
if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
6777567648
6777667649
if( u.bk.pC->isIndex ){
6777767650
assert( !u.bk.pC->isTable );
67778
- rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64);
67651
+ VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64);
6777967652
assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
6778067653
if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
6778167654
goto too_big;
6778267655
}
6778367656
u.bk.n = (u32)u.bk.n64;
6778467657
}else{
67785
- rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
67658
+ VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
6778667659
assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
6778767660
if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
6778867661
goto too_big;
6778967662
}
6779067663
}
@@ -69095,11 +68968,11 @@
6909568968
6909668969
/* Do not allow a transition to journal_mode=WAL for a database
6909768970
** in temporary storage or if the VFS does not support shared memory
6909868971
*/
6909968972
if( u.ch.eNew==PAGER_JOURNALMODE_WAL
69100
- && (u.ch.zFilename[0]==0 /* Temp file */
68973
+ && (sqlite3Strlen30(u.ch.zFilename)==0 /* Temp file */
6910168974
|| !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */
6910268975
){
6910368976
u.ch.eNew = u.ch.eOld;
6910468977
}
6910568978
@@ -69530,14 +69403,19 @@
6953069403
u.co.pName = &aMem[pOp->p1];
6953169404
assert( u.co.pVtab->pModule->xRename );
6953269405
assert( memIsValid(u.co.pName) );
6953369406
REGISTER_TRACE(pOp->p1, u.co.pName);
6953469407
assert( u.co.pName->flags & MEM_Str );
69535
- rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z);
69536
- importVtabErrMsg(p, u.co.pVtab);
69537
- p->expired = 0;
69538
-
69408
+ testcase( u.co.pName->enc==SQLITE_UTF8 );
69409
+ testcase( u.co.pName->enc==SQLITE_UTF16BE );
69410
+ testcase( u.co.pName->enc==SQLITE_UTF16LE );
69411
+ rc = sqlite3VdbeChangeEncoding(u.co.pName, SQLITE_UTF8);
69412
+ if( rc==SQLITE_OK ){
69413
+ rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z);
69414
+ importVtabErrMsg(p, u.co.pVtab);
69415
+ p->expired = 0;
69416
+ }
6953969417
break;
6954069418
}
6954169419
#endif
6954269420
6954369421
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -71891,10 +71769,28 @@
7189171769
ExprSetProperty(pExpr, EP_Static);
7189271770
sqlite3ExprDelete(db, pExpr);
7189371771
memcpy(pExpr, pDup, sizeof(*pExpr));
7189471772
sqlite3DbFree(db, pDup);
7189571773
}
71774
+
71775
+
71776
+/*
71777
+** Return TRUE if the name zCol occurs anywhere in the USING clause.
71778
+**
71779
+** Return FALSE if the USING clause is NULL or if it does not contain
71780
+** zCol.
71781
+*/
71782
+static int nameInUsingClause(IdList *pUsing, const char *zCol){
71783
+ if( pUsing ){
71784
+ int k;
71785
+ for(k=0; k<pUsing->nId; k++){
71786
+ if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
71787
+ }
71788
+ }
71789
+ return 0;
71790
+}
71791
+
7189671792
7189771793
/*
7189871794
** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
7189971795
** that name in the set of source tables in pSrcList and make the pExpr
7190071796
** expression node refer back to that source column. The following changes
@@ -71983,38 +71879,25 @@
7198371879
pSchema = pTab->pSchema;
7198471880
pMatch = pItem;
7198571881
}
7198671882
for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
7198771883
if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
71988
- IdList *pUsing;
71884
+ /* If there has been exactly one prior match and this match
71885
+ ** is for the right-hand table of a NATURAL JOIN or is in a
71886
+ ** USING clause, then skip this match.
71887
+ */
71888
+ if( cnt==1 ){
71889
+ if( pItem->jointype & JT_NATURAL ) continue;
71890
+ if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
71891
+ }
7198971892
cnt++;
7199071893
pExpr->iTable = pItem->iCursor;
7199171894
pExpr->pTab = pTab;
7199271895
pMatch = pItem;
7199371896
pSchema = pTab->pSchema;
7199471897
/* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
7199571898
pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
71996
- if( i<pSrcList->nSrc-1 ){
71997
- if( pItem[1].jointype & JT_NATURAL ){
71998
- /* If this match occurred in the left table of a natural join,
71999
- ** then skip the right table to avoid a duplicate match */
72000
- pItem++;
72001
- i++;
72002
- }else if( (pUsing = pItem[1].pUsing)!=0 ){
72003
- /* If this match occurs on a column that is in the USING clause
72004
- ** of a join, skip the search of the right table of the join
72005
- ** to avoid a duplicate match there. */
72006
- int k;
72007
- for(k=0; k<pUsing->nId; k++){
72008
- if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
72009
- pItem++;
72010
- i++;
72011
- break;
72012
- }
72013
- }
72014
- }
72015
- }
7201671899
break;
7201771900
}
7201871901
}
7201971902
}
7202071903
}
@@ -73417,11 +73300,12 @@
7341773300
pNew->flags |= EP_IntValue;
7341873301
pNew->u.iValue = iValue;
7341973302
}else{
7342073303
int c;
7342173304
pNew->u.zToken = (char*)&pNew[1];
73422
- memcpy(pNew->u.zToken, pToken->z, pToken->n);
73305
+ assert( pToken->z!=0 || pToken->n==0 );
73306
+ if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
7342373307
pNew->u.zToken[pToken->n] = 0;
7342473308
if( dequote && nExtra>=3
7342573309
&& ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
7342673310
sqlite3Dequote(pNew->u.zToken);
7342773311
if( c=='"' ) pNew->flags |= EP_DblQuoted;
@@ -74456,15 +74340,23 @@
7445674340
** ephemeral table.
7445774341
*/
7445874342
p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
7445974343
if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
7446074344
sqlite3 *db = pParse->db; /* Database connection */
74461
- Expr *pExpr = p->pEList->a[0].pExpr; /* Expression <column> */
74462
- int iCol = pExpr->iColumn; /* Index of column <column> */
7446374345
Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
74464
- Table *pTab = p->pSrc->a[0].pTab; /* Table <table>. */
74346
+ Table *pTab; /* Table <table>. */
74347
+ Expr *pExpr; /* Expression <column> */
74348
+ int iCol; /* Index of column <column> */
7446574349
int iDb; /* Database idx for pTab */
74350
+
74351
+ assert( p ); /* Because of isCandidateForInOpt(p) */
74352
+ assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
74353
+ assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
74354
+ assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
74355
+ pTab = p->pSrc->a[0].pTab;
74356
+ pExpr = p->pEList->a[0].pExpr;
74357
+ iCol = pExpr->iColumn;
7446674358
7446774359
/* Code an OP_VerifyCookie and OP_TableLock for <table>. */
7446874360
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
7446974361
sqlite3CodeVerifySchema(pParse, iDb);
7447074362
sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -76467,11 +76359,11 @@
7646776359
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
7646876360
return 2;
7646976361
}
7647076362
}else if( pA->op!=TK_COLUMN && pA->u.zToken ){
7647176363
if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
76472
- if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
76364
+ if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
7647376365
return 2;
7647476366
}
7647576367
}
7647676368
if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
7647776369
if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
@@ -77610,10 +77502,112 @@
7761077502
** May you find forgiveness for yourself and forgive others.
7761177503
** May you share freely, never taking more than you give.
7761277504
**
7761377505
*************************************************************************
7761477506
** This file contains code associated with the ANALYZE command.
77507
+**
77508
+** The ANALYZE command gather statistics about the content of tables
77509
+** and indices. These statistics are made available to the query planner
77510
+** to help it make better decisions about how to perform queries.
77511
+**
77512
+** The following system tables are or have been supported:
77513
+**
77514
+** CREATE TABLE sqlite_stat1(tbl, idx, stat);
77515
+** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
77516
+** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
77517
+**
77518
+** Additional tables might be added in future releases of SQLite.
77519
+** The sqlite_stat2 table is not created or used unless the SQLite version
77520
+** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
77521
+** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
77522
+** The sqlite_stat2 table is superceded by sqlite_stat3, which is only
77523
+** created and used by SQLite versions 3.7.9 and later and with
77524
+** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3
77525
+** is a superset of sqlite_stat2.
77526
+**
77527
+** Format of sqlite_stat1:
77528
+**
77529
+** There is normally one row per index, with the index identified by the
77530
+** name in the idx column. The tbl column is the name of the table to
77531
+** which the index belongs. In each such row, the stat column will be
77532
+** a string consisting of a list of integers. The first integer in this
77533
+** list is the number of rows in the index and in the table. The second
77534
+** integer is the average number of rows in the index that have the same
77535
+** value in the first column of the index. The third integer is the average
77536
+** number of rows in the index that have the same value for the first two
77537
+** columns. The N-th integer (for N>1) is the average number of rows in
77538
+** the index which have the same value for the first N-1 columns. For
77539
+** a K-column index, there will be K+1 integers in the stat column. If
77540
+** the index is unique, then the last integer will be 1.
77541
+**
77542
+** The list of integers in the stat column can optionally be followed
77543
+** by the keyword "unordered". The "unordered" keyword, if it is present,
77544
+** must be separated from the last integer by a single space. If the
77545
+** "unordered" keyword is present, then the query planner assumes that
77546
+** the index is unordered and will not use the index for a range query.
77547
+**
77548
+** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
77549
+** column contains a single integer which is the (estimated) number of
77550
+** rows in the table identified by sqlite_stat1.tbl.
77551
+**
77552
+** Format of sqlite_stat2:
77553
+**
77554
+** The sqlite_stat2 is only created and is only used if SQLite is compiled
77555
+** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between
77556
+** 3.6.18 and 3.7.8. The "stat2" table contains additional information
77557
+** about the distribution of keys within an index. The index is identified by
77558
+** the "idx" column and the "tbl" column is the name of the table to which
77559
+** the index belongs. There are usually 10 rows in the sqlite_stat2
77560
+** table for each index.
77561
+**
77562
+** The sqlite_stat2 entries for an index that have sampleno between 0 and 9
77563
+** inclusive are samples of the left-most key value in the index taken at
77564
+** evenly spaced points along the index. Let the number of samples be S
77565
+** (10 in the standard build) and let C be the number of rows in the index.
77566
+** Then the sampled rows are given by:
77567
+**
77568
+** rownumber = (i*C*2 + C)/(S*2)
77569
+**
77570
+** For i between 0 and S-1. Conceptually, the index space is divided into
77571
+** S uniform buckets and the samples are the middle row from each bucket.
77572
+**
77573
+** The format for sqlite_stat2 is recorded here for legacy reference. This
77574
+** version of SQLite does not support sqlite_stat2. It neither reads nor
77575
+** writes the sqlite_stat2 table. This version of SQLite only supports
77576
+** sqlite_stat3.
77577
+**
77578
+** Format for sqlite_stat3:
77579
+**
77580
+** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is
77581
+** used to avoid compatibility problems.
77582
+**
77583
+** The format of the sqlite_stat3 table is similar to the format of
77584
+** the sqlite_stat2 table. There are multiple entries for each index.
77585
+** The idx column names the index and the tbl column is the table of the
77586
+** index. If the idx and tbl columns are the same, then the sample is
77587
+** of the INTEGER PRIMARY KEY. The sample column is a value taken from
77588
+** the left-most column of the index. The nEq column is the approximate
77589
+** number of entires in the index whose left-most column exactly matches
77590
+** the sample. nLt is the approximate number of entires whose left-most
77591
+** column is less than the sample. The nDLt column is the approximate
77592
+** number of distinct left-most entries in the index that are less than
77593
+** the sample.
77594
+**
77595
+** Future versions of SQLite might change to store a string containing
77596
+** multiple integers values in the nDLt column of sqlite_stat3. The first
77597
+** integer will be the number of prior index entires that are distinct in
77598
+** the left-most column. The second integer will be the number of prior index
77599
+** entries that are distinct in the first two columns. The third integer
77600
+** will be the number of prior index entries that are distinct in the first
77601
+** three columns. And so forth. With that extension, the nDLt field is
77602
+** similar in function to the sqlite_stat1.stat field.
77603
+**
77604
+** There can be an arbitrary number of sqlite_stat3 entries per index.
77605
+** The ANALYZE command will typically generate sqlite_stat3 tables
77606
+** that contain between 10 and 40 samples which are distributed across
77607
+** the key space, though not uniformly, and which include samples with
77608
+** largest possible nEq values.
7761577609
*/
7761677610
#ifndef SQLITE_OMIT_ANALYZE
7761777611
7761877612
/*
7761977613
** This routine generates code that opens the sqlite_stat1 table for
@@ -77641,12 +77635,12 @@
7764177635
static const struct {
7764277636
const char *zName;
7764377637
const char *zCols;
7764477638
} aTable[] = {
7764577639
{ "sqlite_stat1", "tbl,idx,stat" },
77646
-#ifdef SQLITE_ENABLE_STAT2
77647
- { "sqlite_stat2", "tbl,idx,sampleno,sample" },
77640
+#ifdef SQLITE_ENABLE_STAT3
77641
+ { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
7764877642
#endif
7764977643
};
7765077644
7765177645
int aRoot[] = {0, 0};
7765277646
u8 aCreateTbl[] = {0, 0};
@@ -77658,10 +77652,13 @@
7765877652
if( v==0 ) return;
7765977653
assert( sqlite3BtreeHoldsAllMutexes(db) );
7766077654
assert( sqlite3VdbeDb(v)==db );
7766177655
pDb = &db->aDb[iDb];
7766277656
77657
+ /* Create new statistic tables if they do not exist, or clear them
77658
+ ** if they do already exist.
77659
+ */
7766377660
for(i=0; i<ArraySize(aTable); i++){
7766477661
const char *zTab = aTable[i].zName;
7766577662
Table *pStat;
7766677663
if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
7766777664
/* The sqlite_stat[12] table does not exist. Create it. Note that a
@@ -77688,17 +77685,237 @@
7768877685
sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
7768977686
}
7769077687
}
7769177688
}
7769277689
77693
- /* Open the sqlite_stat[12] tables for writing. */
77690
+ /* Open the sqlite_stat[13] tables for writing. */
7769477691
for(i=0; i<ArraySize(aTable); i++){
7769577692
sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
7769677693
sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
7769777694
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
7769877695
}
7769977696
}
77697
+
77698
+/*
77699
+** Recommended number of samples for sqlite_stat3
77700
+*/
77701
+#ifndef SQLITE_STAT3_SAMPLES
77702
+# define SQLITE_STAT3_SAMPLES 24
77703
+#endif
77704
+
77705
+/*
77706
+** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
77707
+** share an instance of the following structure to hold their state
77708
+** information.
77709
+*/
77710
+typedef struct Stat3Accum Stat3Accum;
77711
+struct Stat3Accum {
77712
+ tRowcnt nRow; /* Number of rows in the entire table */
77713
+ tRowcnt nPSample; /* How often to do a periodic sample */
77714
+ int iMin; /* Index of entry with minimum nEq and hash */
77715
+ int mxSample; /* Maximum number of samples to accumulate */
77716
+ int nSample; /* Current number of samples */
77717
+ u32 iPrn; /* Pseudo-random number used for sampling */
77718
+ struct Stat3Sample {
77719
+ i64 iRowid; /* Rowid in main table of the key */
77720
+ tRowcnt nEq; /* sqlite_stat3.nEq */
77721
+ tRowcnt nLt; /* sqlite_stat3.nLt */
77722
+ tRowcnt nDLt; /* sqlite_stat3.nDLt */
77723
+ u8 isPSample; /* True if a periodic sample */
77724
+ u32 iHash; /* Tiebreaker hash */
77725
+ } *a; /* An array of samples */
77726
+};
77727
+
77728
+#ifdef SQLITE_ENABLE_STAT3
77729
+/*
77730
+** Implementation of the stat3_init(C,S) SQL function. The two parameters
77731
+** are the number of rows in the table or index (C) and the number of samples
77732
+** to accumulate (S).
77733
+**
77734
+** This routine allocates the Stat3Accum object.
77735
+**
77736
+** The return value is the Stat3Accum object (P).
77737
+*/
77738
+static void stat3Init(
77739
+ sqlite3_context *context,
77740
+ int argc,
77741
+ sqlite3_value **argv
77742
+){
77743
+ Stat3Accum *p;
77744
+ tRowcnt nRow;
77745
+ int mxSample;
77746
+ int n;
77747
+
77748
+ UNUSED_PARAMETER(argc);
77749
+ nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
77750
+ mxSample = sqlite3_value_int(argv[1]);
77751
+ n = sizeof(*p) + sizeof(p->a[0])*mxSample;
77752
+ p = sqlite3_malloc( n );
77753
+ if( p==0 ){
77754
+ sqlite3_result_error_nomem(context);
77755
+ return;
77756
+ }
77757
+ memset(p, 0, n);
77758
+ p->a = (struct Stat3Sample*)&p[1];
77759
+ p->nRow = nRow;
77760
+ p->mxSample = mxSample;
77761
+ p->nPSample = p->nRow/(mxSample/3+1) + 1;
77762
+ sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
77763
+ sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
77764
+}
77765
+static const FuncDef stat3InitFuncdef = {
77766
+ 2, /* nArg */
77767
+ SQLITE_UTF8, /* iPrefEnc */
77768
+ 0, /* flags */
77769
+ 0, /* pUserData */
77770
+ 0, /* pNext */
77771
+ stat3Init, /* xFunc */
77772
+ 0, /* xStep */
77773
+ 0, /* xFinalize */
77774
+ "stat3_init", /* zName */
77775
+ 0, /* pHash */
77776
+ 0 /* pDestructor */
77777
+};
77778
+
77779
+
77780
+/*
77781
+** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The
77782
+** arguments describe a single key instance. This routine makes the
77783
+** decision about whether or not to retain this key for the sqlite_stat3
77784
+** table.
77785
+**
77786
+** The return value is NULL.
77787
+*/
77788
+static void stat3Push(
77789
+ sqlite3_context *context,
77790
+ int argc,
77791
+ sqlite3_value **argv
77792
+){
77793
+ Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]);
77794
+ tRowcnt nEq = sqlite3_value_int64(argv[0]);
77795
+ tRowcnt nLt = sqlite3_value_int64(argv[1]);
77796
+ tRowcnt nDLt = sqlite3_value_int64(argv[2]);
77797
+ i64 rowid = sqlite3_value_int64(argv[3]);
77798
+ u8 isPSample = 0;
77799
+ u8 doInsert = 0;
77800
+ int iMin = p->iMin;
77801
+ struct Stat3Sample *pSample;
77802
+ int i;
77803
+ u32 h;
77804
+
77805
+ UNUSED_PARAMETER(context);
77806
+ UNUSED_PARAMETER(argc);
77807
+ if( nEq==0 ) return;
77808
+ h = p->iPrn = p->iPrn*1103515245 + 12345;
77809
+ if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){
77810
+ doInsert = isPSample = 1;
77811
+ }else if( p->nSample<p->mxSample ){
77812
+ doInsert = 1;
77813
+ }else{
77814
+ if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
77815
+ doInsert = 1;
77816
+ }
77817
+ }
77818
+ if( !doInsert ) return;
77819
+ if( p->nSample==p->mxSample ){
77820
+ assert( p->nSample - iMin - 1 >= 0 );
77821
+ memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
77822
+ pSample = &p->a[p->nSample-1];
77823
+ }else{
77824
+ pSample = &p->a[p->nSample++];
77825
+ }
77826
+ pSample->iRowid = rowid;
77827
+ pSample->nEq = nEq;
77828
+ pSample->nLt = nLt;
77829
+ pSample->nDLt = nDLt;
77830
+ pSample->iHash = h;
77831
+ pSample->isPSample = isPSample;
77832
+
77833
+ /* Find the new minimum */
77834
+ if( p->nSample==p->mxSample ){
77835
+ pSample = p->a;
77836
+ i = 0;
77837
+ while( pSample->isPSample ){
77838
+ i++;
77839
+ pSample++;
77840
+ assert( i<p->nSample );
77841
+ }
77842
+ nEq = pSample->nEq;
77843
+ h = pSample->iHash;
77844
+ iMin = i;
77845
+ for(i++, pSample++; i<p->nSample; i++, pSample++){
77846
+ if( pSample->isPSample ) continue;
77847
+ if( pSample->nEq<nEq
77848
+ || (pSample->nEq==nEq && pSample->iHash<h)
77849
+ ){
77850
+ iMin = i;
77851
+ nEq = pSample->nEq;
77852
+ h = pSample->iHash;
77853
+ }
77854
+ }
77855
+ p->iMin = iMin;
77856
+ }
77857
+}
77858
+static const FuncDef stat3PushFuncdef = {
77859
+ 5, /* nArg */
77860
+ SQLITE_UTF8, /* iPrefEnc */
77861
+ 0, /* flags */
77862
+ 0, /* pUserData */
77863
+ 0, /* pNext */
77864
+ stat3Push, /* xFunc */
77865
+ 0, /* xStep */
77866
+ 0, /* xFinalize */
77867
+ "stat3_push", /* zName */
77868
+ 0, /* pHash */
77869
+ 0 /* pDestructor */
77870
+};
77871
+
77872
+/*
77873
+** Implementation of the stat3_get(P,N,...) SQL function. This routine is
77874
+** used to query the results. Content is returned for the Nth sqlite_stat3
77875
+** row where N is between 0 and S-1 and S is the number of samples. The
77876
+** value returned depends on the number of arguments.
77877
+**
77878
+** argc==2 result: rowid
77879
+** argc==3 result: nEq
77880
+** argc==4 result: nLt
77881
+** argc==5 result: nDLt
77882
+*/
77883
+static void stat3Get(
77884
+ sqlite3_context *context,
77885
+ int argc,
77886
+ sqlite3_value **argv
77887
+){
77888
+ int n = sqlite3_value_int(argv[1]);
77889
+ Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]);
77890
+
77891
+ assert( p!=0 );
77892
+ if( p->nSample<=n ) return;
77893
+ switch( argc ){
77894
+ case 2: sqlite3_result_int64(context, p->a[n].iRowid); break;
77895
+ case 3: sqlite3_result_int64(context, p->a[n].nEq); break;
77896
+ case 4: sqlite3_result_int64(context, p->a[n].nLt); break;
77897
+ default: sqlite3_result_int64(context, p->a[n].nDLt); break;
77898
+ }
77899
+}
77900
+static const FuncDef stat3GetFuncdef = {
77901
+ -1, /* nArg */
77902
+ SQLITE_UTF8, /* iPrefEnc */
77903
+ 0, /* flags */
77904
+ 0, /* pUserData */
77905
+ 0, /* pNext */
77906
+ stat3Get, /* xFunc */
77907
+ 0, /* xStep */
77908
+ 0, /* xFinalize */
77909
+ "stat3_get", /* zName */
77910
+ 0, /* pHash */
77911
+ 0 /* pDestructor */
77912
+};
77913
+#endif /* SQLITE_ENABLE_STAT3 */
77914
+
77915
+
77916
+
7770077917
7770177918
/*
7770277919
** Generate code to do an analysis of all indices associated with
7770377920
** a single table.
7770477921
*/
@@ -77718,24 +77935,31 @@
7771877935
int endOfLoop; /* The end of the loop */
7771977936
int jZeroRows = -1; /* Jump from here if number of rows is zero */
7772077937
int iDb; /* Index of database containing pTab */
7772177938
int regTabname = iMem++; /* Register containing table name */
7772277939
int regIdxname = iMem++; /* Register containing index name */
77723
- int regSampleno = iMem++; /* Register containing next sample number */
77724
- int regCol = iMem++; /* Content of a column analyzed table */
77940
+ int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
77941
+#ifdef SQLITE_ENABLE_STAT3
77942
+ int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
77943
+ int regNumLt = iMem++; /* Number of keys less than regSample */
77944
+ int regNumDLt = iMem++; /* Number of distinct keys less than regSample */
77945
+ int regSample = iMem++; /* The next sample value */
77946
+ int regRowid = regSample; /* Rowid of a sample */
77947
+ int regAccum = iMem++; /* Register to hold Stat3Accum object */
77948
+ int regLoop = iMem++; /* Loop counter */
77949
+ int regCount = iMem++; /* Number of rows in the table or index */
77950
+ int regTemp1 = iMem++; /* Intermediate register */
77951
+ int regTemp2 = iMem++; /* Intermediate register */
77952
+ int once = 1; /* One-time initialization */
77953
+ int shortJump = 0; /* Instruction address */
77954
+ int iTabCur = pParse->nTab++; /* Table cursor */
77955
+#endif
77956
+ int regCol = iMem++; /* Content of a column in analyzed table */
7772577957
int regRec = iMem++; /* Register holding completed record */
7772677958
int regTemp = iMem++; /* Temporary use register */
77727
- int regRowid = iMem++; /* Rowid for the inserted record */
77728
-
77729
-#ifdef SQLITE_ENABLE_STAT2
77730
- int addr = 0; /* Instruction address */
77731
- int regTemp2 = iMem++; /* Temporary use register */
77732
- int regSamplerecno = iMem++; /* Index of next sample to record */
77733
- int regRecno = iMem++; /* Current sample index */
77734
- int regLast = iMem++; /* Index of last sample to record */
77735
- int regFirst = iMem++; /* Index of first sample to record */
77736
-#endif
77959
+ int regNewRowid = iMem++; /* Rowid for the inserted record */
77960
+
7773777961
7773877962
v = sqlite3GetVdbe(pParse);
7773977963
if( v==0 || NEVER(pTab==0) ){
7774077964
return;
7774177965
}
@@ -77764,13 +77988,18 @@
7776477988
iIdxCur = pParse->nTab++;
7776577989
sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
7776677990
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
7776777991
int nCol;
7776877992
KeyInfo *pKey;
77993
+ int addrIfNot = 0; /* address of OP_IfNot */
77994
+ int *aChngAddr; /* Array of jump instruction addresses */
7776977995
7777077996
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
77997
+ VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
7777177998
nCol = pIdx->nColumn;
77999
+ aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
78000
+ if( aChngAddr==0 ) continue;
7777278001
pKey = sqlite3IndexKeyinfo(pParse, pIdx);
7777378002
if( iMem+1+(nCol*2)>pParse->nMem ){
7777478003
pParse->nMem = iMem+1+(nCol*2);
7777578004
}
7777678005
@@ -77781,35 +78010,24 @@
7778178010
VdbeComment((v, "%s", pIdx->zName));
7778278011
7778378012
/* Populate the register containing the index name. */
7778478013
sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
7778578014
77786
-#ifdef SQLITE_ENABLE_STAT2
77787
-
77788
- /* If this iteration of the loop is generating code to analyze the
77789
- ** first index in the pTab->pIndex list, then register regLast has
77790
- ** not been populated. In this case populate it now. */
77791
- if( pTab->pIndex==pIdx ){
77792
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno);
77793
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp);
77794
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2);
77795
-
77796
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast);
77797
- sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst);
77798
- addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast);
77799
- sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst);
77800
- sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast);
77801
- sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2);
77802
- sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regLast);
77803
- sqlite3VdbeJumpHere(v, addr);
77804
- }
77805
-
77806
- /* Zero the regSampleno and regRecno registers. */
77807
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
77808
- sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno);
77809
- sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno);
77810
-#endif
78015
+#ifdef SQLITE_ENABLE_STAT3
78016
+ if( once ){
78017
+ once = 0;
78018
+ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
78019
+ }
78020
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
78021
+ sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
78022
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq);
78023
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt);
78024
+ sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
78025
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
78026
+ (char*)&stat3InitFuncdef, P4_FUNCDEF);
78027
+ sqlite3VdbeChangeP5(v, 2);
78028
+#endif /* SQLITE_ENABLE_STAT3 */
7781178029
7781278030
/* The block of memory cells initialized here is used as follows.
7781378031
**
7781478032
** iMem:
7781578033
** The total number of rows in the table.
@@ -77835,79 +78053,87 @@
7783578053
/* Start the analysis loop. This loop runs through all the entries in
7783678054
** the index b-tree. */
7783778055
endOfLoop = sqlite3VdbeMakeLabel(v);
7783878056
sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
7783978057
topOfLoop = sqlite3VdbeCurrentAddr(v);
77840
- sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);
78058
+ sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */
7784178059
7784278060
for(i=0; i<nCol; i++){
7784378061
CollSeq *pColl;
7784478062
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
7784578063
if( i==0 ){
77846
-#ifdef SQLITE_ENABLE_STAT2
77847
- /* Check if the record that cursor iIdxCur points to contains a
77848
- ** value that should be stored in the sqlite_stat2 table. If so,
77849
- ** store it. */
77850
- int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno);
77851
- assert( regTabname+1==regIdxname
77852
- && regTabname+2==regSampleno
77853
- && regTabname+3==regCol
77854
- );
77855
- sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
77856
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0);
77857
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
77858
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);
77859
-
77860
- /* Calculate new values for regSamplerecno and regSampleno.
77861
- **
77862
- ** sampleno = sampleno + 1
77863
- ** samplerecno = samplerecno+(remaining records)/(remaining samples)
77864
- */
77865
- sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
77866
- sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regLast, regTemp);
77867
- sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
77868
- sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2);
77869
- sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2);
77870
- sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp);
77871
- sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno);
77872
-
77873
- sqlite3VdbeJumpHere(v, ne);
77874
- sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
77875
-#endif
77876
-
7787778064
/* Always record the very first row */
77878
- sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
78065
+ addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
7787978066
}
7788078067
assert( pIdx->azColl!=0 );
7788178068
assert( pIdx->azColl[i]!=0 );
7788278069
pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
77883
- sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
77884
- (char*)pColl, P4_COLLSEQ);
78070
+ aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
78071
+ (char*)pColl, P4_COLLSEQ);
7788578072
sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
77886
- }
77887
- if( db->mallocFailed ){
77888
- /* If a malloc failure has occurred, then the result of the expression
77889
- ** passed as the second argument to the call to sqlite3VdbeJumpHere()
77890
- ** below may be negative. Which causes an assert() to fail (or an
77891
- ** out-of-bounds write if SQLITE_DEBUG is not defined). */
77892
- return;
78073
+ VdbeComment((v, "jump if column %d changed", i));
78074
+#ifdef SQLITE_ENABLE_STAT3
78075
+ if( i==0 ){
78076
+ sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1);
78077
+ VdbeComment((v, "incr repeat count"));
78078
+ }
78079
+#endif
7789378080
}
7789478081
sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
7789578082
for(i=0; i<nCol; i++){
77896
- int addr2 = sqlite3VdbeCurrentAddr(v) - (nCol*2);
78083
+ sqlite3VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */
7789778084
if( i==0 ){
77898
- sqlite3VdbeJumpHere(v, addr2-1); /* Set jump dest for the OP_IfNot */
78085
+ sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */
78086
+#ifdef SQLITE_ENABLE_STAT3
78087
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
78088
+ (char*)&stat3PushFuncdef, P4_FUNCDEF);
78089
+ sqlite3VdbeChangeP5(v, 5);
78090
+ sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid);
78091
+ sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt);
78092
+ sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1);
78093
+ sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq);
78094
+#endif
7789978095
}
77900
- sqlite3VdbeJumpHere(v, addr2); /* Set jump dest for the OP_Ne */
7790178096
sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
7790278097
sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
7790378098
}
78099
+ sqlite3DbFree(db, aChngAddr);
7790478100
77905
- /* End of the analysis loop. */
78101
+ /* Always jump here after updating the iMem+1...iMem+1+nCol counters */
7790678102
sqlite3VdbeResolveLabel(v, endOfLoop);
78103
+
7790778104
sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
7790878105
sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
78106
+#ifdef SQLITE_ENABLE_STAT3
78107
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
78108
+ (char*)&stat3PushFuncdef, P4_FUNCDEF);
78109
+ sqlite3VdbeChangeP5(v, 5);
78110
+ sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop);
78111
+ shortJump =
78112
+ sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1);
78113
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1,
78114
+ (char*)&stat3GetFuncdef, P4_FUNCDEF);
78115
+ sqlite3VdbeChangeP5(v, 2);
78116
+ sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1);
78117
+ sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);
78118
+ sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample);
78119
+ sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample);
78120
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq,
78121
+ (char*)&stat3GetFuncdef, P4_FUNCDEF);
78122
+ sqlite3VdbeChangeP5(v, 3);
78123
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt,
78124
+ (char*)&stat3GetFuncdef, P4_FUNCDEF);
78125
+ sqlite3VdbeChangeP5(v, 4);
78126
+ sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt,
78127
+ (char*)&stat3GetFuncdef, P4_FUNCDEF);
78128
+ sqlite3VdbeChangeP5(v, 5);
78129
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0);
78130
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
78131
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid);
78132
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump);
78133
+ sqlite3VdbeJumpHere(v, shortJump+2);
78134
+#endif
7790978135
7791078136
/* Store the results in sqlite_stat1.
7791178137
**
7791278138
** The result is a single row of the sqlite_stat1 table. The first
7791378139
** two columns are the names of the table and index. The third column
@@ -77923,50 +78149,51 @@
7792378149
**
7792478150
** If K==0 then no entry is made into the sqlite_stat1 table.
7792578151
** If K>0 then it is always the case the D>0 so division by zero
7792678152
** is never possible.
7792778153
*/
77928
- sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
78154
+ sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
7792978155
if( jZeroRows<0 ){
7793078156
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
7793178157
}
7793278158
for(i=0; i<nCol; i++){
7793378159
sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
77934
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
78160
+ sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
7793578161
sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
7793678162
sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
7793778163
sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
7793878164
sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
77939
- sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
78165
+ sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
7794078166
}
7794178167
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
77942
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
77943
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
78168
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
78169
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
7794478170
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
7794578171
}
7794678172
7794778173
/* If the table has no indices, create a single sqlite_stat1 entry
7794878174
** containing NULL as the index name and the row count as the content.
7794978175
*/
7795078176
if( pTab->pIndex==0 ){
7795178177
sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
7795278178
VdbeComment((v, "%s", pTab->zName));
77953
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno);
78179
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
7795478180
sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
77955
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regSampleno);
78181
+ jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
7795678182
}else{
7795778183
sqlite3VdbeJumpHere(v, jZeroRows);
7795878184
jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
7795978185
}
7796078186
sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
7796178187
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
77962
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
77963
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
78188
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
78189
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
7796478190
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
7796578191
if( pParse->nMem<regRec ) pParse->nMem = regRec;
7796678192
sqlite3VdbeJumpHere(v, jZeroRows);
7796778193
}
78194
+
7796878195
7796978196
/*
7797078197
** Generate code that will cause the most recent index analysis to
7797178198
** be loaded into internal hash tables where is can be used.
7797278199
*/
@@ -77987,11 +78214,11 @@
7798778214
int iStatCur;
7798878215
int iMem;
7798978216
7799078217
sqlite3BeginWriteOperation(pParse, 0, iDb);
7799178218
iStatCur = pParse->nTab;
77992
- pParse->nTab += 2;
78219
+ pParse->nTab += 3;
7799378220
openStatTable(pParse, iDb, iStatCur, 0, 0);
7799478221
iMem = pParse->nMem+1;
7799578222
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
7799678223
for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
7799778224
Table *pTab = (Table*)sqliteHashData(k);
@@ -78012,11 +78239,11 @@
7801278239
assert( pTab!=0 );
7801378240
assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
7801478241
iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
7801578242
sqlite3BeginWriteOperation(pParse, 0, iDb);
7801678243
iStatCur = pParse->nTab;
78017
- pParse->nTab += 2;
78244
+ pParse->nTab += 3;
7801878245
if( pOnlyIdx ){
7801978246
openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
7802078247
}else{
7802178248
openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
7802278249
}
@@ -78117,11 +78344,11 @@
7811778344
static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
7811878345
analysisInfo *pInfo = (analysisInfo*)pData;
7811978346
Index *pIndex;
7812078347
Table *pTable;
7812178348
int i, c, n;
78122
- unsigned int v;
78349
+ tRowcnt v;
7812378350
const char *z;
7812478351
7812578352
assert( argc==3 );
7812678353
UNUSED_PARAMETER2(NotUsed, argc);
7812778354
@@ -78160,40 +78387,172 @@
7816078387
/*
7816178388
** If the Index.aSample variable is not NULL, delete the aSample[] array
7816278389
** and its contents.
7816378390
*/
7816478391
SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
78165
-#ifdef SQLITE_ENABLE_STAT2
78392
+#ifdef SQLITE_ENABLE_STAT3
7816678393
if( pIdx->aSample ){
7816778394
int j;
78168
- for(j=0; j<SQLITE_INDEX_SAMPLES; j++){
78395
+ for(j=0; j<pIdx->nSample; j++){
7816978396
IndexSample *p = &pIdx->aSample[j];
7817078397
if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
7817178398
sqlite3DbFree(db, p->u.z);
7817278399
}
7817378400
}
7817478401
sqlite3DbFree(db, pIdx->aSample);
78402
+ }
78403
+ if( db && db->pnBytesFreed==0 ){
78404
+ pIdx->nSample = 0;
78405
+ pIdx->aSample = 0;
7817578406
}
7817678407
#else
7817778408
UNUSED_PARAMETER(db);
7817878409
UNUSED_PARAMETER(pIdx);
7817978410
#endif
7818078411
}
7818178412
78413
+#ifdef SQLITE_ENABLE_STAT3
7818278414
/*
78183
-** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
78415
+** Load content from the sqlite_stat3 table into the Index.aSample[]
78416
+** arrays of all indices.
78417
+*/
78418
+static int loadStat3(sqlite3 *db, const char *zDb){
78419
+ int rc; /* Result codes from subroutines */
78420
+ sqlite3_stmt *pStmt = 0; /* An SQL statement being run */
78421
+ char *zSql; /* Text of the SQL statement */
78422
+ Index *pPrevIdx = 0; /* Previous index in the loop */
78423
+ int idx = 0; /* slot in pIdx->aSample[] for next sample */
78424
+ int eType; /* Datatype of a sample */
78425
+ IndexSample *pSample; /* A slot in pIdx->aSample[] */
78426
+
78427
+ if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
78428
+ return SQLITE_OK;
78429
+ }
78430
+
78431
+ zSql = sqlite3MPrintf(db,
78432
+ "SELECT idx,count(*) FROM %Q.sqlite_stat3"
78433
+ " GROUP BY idx", zDb);
78434
+ if( !zSql ){
78435
+ return SQLITE_NOMEM;
78436
+ }
78437
+ rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
78438
+ sqlite3DbFree(db, zSql);
78439
+ if( rc ) return rc;
78440
+
78441
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
78442
+ char *zIndex; /* Index name */
78443
+ Index *pIdx; /* Pointer to the index object */
78444
+ int nSample; /* Number of samples */
78445
+
78446
+ zIndex = (char *)sqlite3_column_text(pStmt, 0);
78447
+ if( zIndex==0 ) continue;
78448
+ nSample = sqlite3_column_int(pStmt, 1);
78449
+ pIdx = sqlite3FindIndex(db, zIndex, zDb);
78450
+ if( pIdx==0 ) continue;
78451
+ assert( pIdx->nSample==0 );
78452
+ pIdx->nSample = nSample;
78453
+ pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) );
78454
+ pIdx->avgEq = pIdx->aiRowEst[1];
78455
+ if( pIdx->aSample==0 ){
78456
+ db->mallocFailed = 1;
78457
+ sqlite3_finalize(pStmt);
78458
+ return SQLITE_NOMEM;
78459
+ }
78460
+ }
78461
+ rc = sqlite3_finalize(pStmt);
78462
+ if( rc ) return rc;
78463
+
78464
+ zSql = sqlite3MPrintf(db,
78465
+ "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
78466
+ if( !zSql ){
78467
+ return SQLITE_NOMEM;
78468
+ }
78469
+ rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
78470
+ sqlite3DbFree(db, zSql);
78471
+ if( rc ) return rc;
78472
+
78473
+ while( sqlite3_step(pStmt)==SQLITE_ROW ){
78474
+ char *zIndex; /* Index name */
78475
+ Index *pIdx; /* Pointer to the index object */
78476
+ int i; /* Loop counter */
78477
+ tRowcnt sumEq; /* Sum of the nEq values */
78478
+
78479
+ zIndex = (char *)sqlite3_column_text(pStmt, 0);
78480
+ if( zIndex==0 ) continue;
78481
+ pIdx = sqlite3FindIndex(db, zIndex, zDb);
78482
+ if( pIdx==0 ) continue;
78483
+ if( pIdx==pPrevIdx ){
78484
+ idx++;
78485
+ }else{
78486
+ pPrevIdx = pIdx;
78487
+ idx = 0;
78488
+ }
78489
+ assert( idx<pIdx->nSample );
78490
+ pSample = &pIdx->aSample[idx];
78491
+ pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1);
78492
+ pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2);
78493
+ pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3);
78494
+ if( idx==pIdx->nSample-1 ){
78495
+ if( pSample->nDLt>0 ){
78496
+ for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq;
78497
+ pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt;
78498
+ }
78499
+ if( pIdx->avgEq<=0 ) pIdx->avgEq = 1;
78500
+ }
78501
+ eType = sqlite3_column_type(pStmt, 4);
78502
+ pSample->eType = (u8)eType;
78503
+ switch( eType ){
78504
+ case SQLITE_INTEGER: {
78505
+ pSample->u.i = sqlite3_column_int64(pStmt, 4);
78506
+ break;
78507
+ }
78508
+ case SQLITE_FLOAT: {
78509
+ pSample->u.r = sqlite3_column_double(pStmt, 4);
78510
+ break;
78511
+ }
78512
+ case SQLITE_NULL: {
78513
+ break;
78514
+ }
78515
+ default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); {
78516
+ const char *z = (const char *)(
78517
+ (eType==SQLITE_BLOB) ?
78518
+ sqlite3_column_blob(pStmt, 4):
78519
+ sqlite3_column_text(pStmt, 4)
78520
+ );
78521
+ int n = z ? sqlite3_column_bytes(pStmt, 4) : 0;
78522
+ pSample->nByte = n;
78523
+ if( n < 1){
78524
+ pSample->u.z = 0;
78525
+ }else{
78526
+ pSample->u.z = sqlite3Malloc(n);
78527
+ if( pSample->u.z==0 ){
78528
+ db->mallocFailed = 1;
78529
+ sqlite3_finalize(pStmt);
78530
+ return SQLITE_NOMEM;
78531
+ }
78532
+ memcpy(pSample->u.z, z, n);
78533
+ }
78534
+ }
78535
+ }
78536
+ }
78537
+ return sqlite3_finalize(pStmt);
78538
+}
78539
+#endif /* SQLITE_ENABLE_STAT3 */
78540
+
78541
+/*
78542
+** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
7818478543
** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
78185
-** arrays. The contents of sqlite_stat2 are used to populate the
78544
+** arrays. The contents of sqlite_stat3 are used to populate the
7818678545
** Index.aSample[] arrays.
7818778546
**
7818878547
** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
78189
-** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined
78190
-** during compilation and the sqlite_stat2 table is present, no data is
78548
+** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined
78549
+** during compilation and the sqlite_stat3 table is present, no data is
7819178550
** read from it.
7819278551
**
78193
-** If SQLITE_ENABLE_STAT2 was defined during compilation and the
78194
-** sqlite_stat2 table is not present in the database, SQLITE_ERROR is
78552
+** If SQLITE_ENABLE_STAT3 was defined during compilation and the
78553
+** sqlite_stat3 table is not present in the database, SQLITE_ERROR is
7819578554
** returned. However, in this case, data is read from the sqlite_stat1
7819678555
** table (if it is present) before returning.
7819778556
**
7819878557
** If an OOM error occurs, this function always sets db->mallocFailed.
7819978558
** This means if the caller does not care about other errors, the return
@@ -78211,12 +78570,14 @@
7821178570
/* Clear any prior statistics */
7821278571
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
7821378572
for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
7821478573
Index *pIdx = sqliteHashData(i);
7821578574
sqlite3DefaultRowEst(pIdx);
78575
+#ifdef SQLITE_ENABLE_STAT3
7821678576
sqlite3DeleteIndexSamples(db, pIdx);
7821778577
pIdx->aSample = 0;
78578
+#endif
7821878579
}
7821978580
7822078581
/* Check to make sure the sqlite_stat1 table exists */
7822178582
sInfo.db = db;
7822278583
sInfo.zDatabase = db->aDb[iDb].zName;
@@ -78224,91 +78585,23 @@
7822478585
return SQLITE_ERROR;
7822578586
}
7822678587
7822778588
/* Load new statistics out of the sqlite_stat1 table */
7822878589
zSql = sqlite3MPrintf(db,
78229
- "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
78590
+ "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
7823078591
if( zSql==0 ){
7823178592
rc = SQLITE_NOMEM;
7823278593
}else{
7823378594
rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
7823478595
sqlite3DbFree(db, zSql);
7823578596
}
7823678597
7823778598
78238
- /* Load the statistics from the sqlite_stat2 table. */
78239
-#ifdef SQLITE_ENABLE_STAT2
78240
- if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){
78241
- rc = SQLITE_ERROR;
78242
- }
78243
- if( rc==SQLITE_OK ){
78244
- sqlite3_stmt *pStmt = 0;
78245
-
78246
- zSql = sqlite3MPrintf(db,
78247
- "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase);
78248
- if( !zSql ){
78249
- rc = SQLITE_NOMEM;
78250
- }else{
78251
- rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
78252
- sqlite3DbFree(db, zSql);
78253
- }
78254
-
78255
- if( rc==SQLITE_OK ){
78256
- while( sqlite3_step(pStmt)==SQLITE_ROW ){
78257
- char *zIndex; /* Index name */
78258
- Index *pIdx; /* Pointer to the index object */
78259
-
78260
- zIndex = (char *)sqlite3_column_text(pStmt, 0);
78261
- pIdx = zIndex ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : 0;
78262
- if( pIdx ){
78263
- int iSample = sqlite3_column_int(pStmt, 1);
78264
- if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
78265
- int eType = sqlite3_column_type(pStmt, 2);
78266
-
78267
- if( pIdx->aSample==0 ){
78268
- static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
78269
- pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz);
78270
- if( pIdx->aSample==0 ){
78271
- db->mallocFailed = 1;
78272
- break;
78273
- }
78274
- memset(pIdx->aSample, 0, sz);
78275
- }
78276
-
78277
- assert( pIdx->aSample );
78278
- {
78279
- IndexSample *pSample = &pIdx->aSample[iSample];
78280
- pSample->eType = (u8)eType;
78281
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
78282
- pSample->u.r = sqlite3_column_double(pStmt, 2);
78283
- }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
78284
- const char *z = (const char *)(
78285
- (eType==SQLITE_BLOB) ?
78286
- sqlite3_column_blob(pStmt, 2):
78287
- sqlite3_column_text(pStmt, 2)
78288
- );
78289
- int n = sqlite3_column_bytes(pStmt, 2);
78290
- if( n>24 ){
78291
- n = 24;
78292
- }
78293
- pSample->nByte = (u8)n;
78294
- if( n < 1){
78295
- pSample->u.z = 0;
78296
- }else{
78297
- pSample->u.z = sqlite3DbStrNDup(0, z, n);
78298
- if( pSample->u.z==0 ){
78299
- db->mallocFailed = 1;
78300
- break;
78301
- }
78302
- }
78303
- }
78304
- }
78305
- }
78306
- }
78307
- }
78308
- rc = sqlite3_finalize(pStmt);
78309
- }
78599
+ /* Load the statistics from the sqlite_stat3 table. */
78600
+#ifdef SQLITE_ENABLE_STAT3
78601
+ if( rc==SQLITE_OK ){
78602
+ rc = loadStat3(db, sInfo.zDatabase);
7831078603
}
7831178604
#endif
7831278605
7831378606
if( rc==SQLITE_NOMEM ){
7831478607
db->mallocFailed = 1;
@@ -81120,11 +81413,15 @@
8112081413
Parse *pParse, /* The parsing context */
8112181414
int iDb, /* The database number */
8112281415
const char *zType, /* "idx" or "tbl" */
8112381416
const char *zName /* Name of index or table */
8112481417
){
81125
- static const char *azStatTab[] = { "sqlite_stat1", "sqlite_stat2" };
81418
+ static const char *azStatTab[] = {
81419
+ "sqlite_stat1",
81420
+ "sqlite_stat2",
81421
+ "sqlite_stat3",
81422
+ };
8112681423
int i;
8112781424
const char *zDbName = pParse->db->aDb[iDb].zName;
8112881425
for(i=0; i<ArraySize(azStatTab); i++){
8112981426
if( sqlite3FindTable(pParse->db, azStatTab[i], zDbName) ){
8113081427
sqlite3NestedParse(pParse,
@@ -81132,10 +81429,80 @@
8113281429
zDbName, azStatTab[i], zType, zName
8113381430
);
8113481431
}
8113581432
}
8113681433
}
81434
+
81435
+/*
81436
+** Generate code to drop a table.
81437
+*/
81438
+SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
81439
+ Vdbe *v;
81440
+ sqlite3 *db = pParse->db;
81441
+ Trigger *pTrigger;
81442
+ Db *pDb = &db->aDb[iDb];
81443
+
81444
+ v = sqlite3GetVdbe(pParse);
81445
+ assert( v!=0 );
81446
+ sqlite3BeginWriteOperation(pParse, 1, iDb);
81447
+
81448
+#ifndef SQLITE_OMIT_VIRTUALTABLE
81449
+ if( IsVirtual(pTab) ){
81450
+ sqlite3VdbeAddOp0(v, OP_VBegin);
81451
+ }
81452
+#endif
81453
+
81454
+ /* Drop all triggers associated with the table being dropped. Code
81455
+ ** is generated to remove entries from sqlite_master and/or
81456
+ ** sqlite_temp_master if required.
81457
+ */
81458
+ pTrigger = sqlite3TriggerList(pParse, pTab);
81459
+ while( pTrigger ){
81460
+ assert( pTrigger->pSchema==pTab->pSchema ||
81461
+ pTrigger->pSchema==db->aDb[1].pSchema );
81462
+ sqlite3DropTriggerPtr(pParse, pTrigger);
81463
+ pTrigger = pTrigger->pNext;
81464
+ }
81465
+
81466
+#ifndef SQLITE_OMIT_AUTOINCREMENT
81467
+ /* Remove any entries of the sqlite_sequence table associated with
81468
+ ** the table being dropped. This is done before the table is dropped
81469
+ ** at the btree level, in case the sqlite_sequence table needs to
81470
+ ** move as a result of the drop (can happen in auto-vacuum mode).
81471
+ */
81472
+ if( pTab->tabFlags & TF_Autoincrement ){
81473
+ sqlite3NestedParse(pParse,
81474
+ "DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
81475
+ pDb->zName, pTab->zName
81476
+ );
81477
+ }
81478
+#endif
81479
+
81480
+ /* Drop all SQLITE_MASTER table and index entries that refer to the
81481
+ ** table. The program name loops through the master table and deletes
81482
+ ** every row that refers to a table of the same name as the one being
81483
+ ** dropped. Triggers are handled seperately because a trigger can be
81484
+ ** created in the temp database that refers to a table in another
81485
+ ** database.
81486
+ */
81487
+ sqlite3NestedParse(pParse,
81488
+ "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
81489
+ pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
81490
+ if( !isView && !IsVirtual(pTab) ){
81491
+ destroyTable(pParse, pTab);
81492
+ }
81493
+
81494
+ /* Remove the table entry from SQLite's internal schema and modify
81495
+ ** the schema cookie.
81496
+ */
81497
+ if( IsVirtual(pTab) ){
81498
+ sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
81499
+ }
81500
+ sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
81501
+ sqlite3ChangeCookie(pParse, iDb);
81502
+ sqliteViewResetAll(db, iDb);
81503
+}
8113781504
8113881505
/*
8113981506
** This routine is called to do the work of a DROP TABLE statement.
8114081507
** pName is the name of the table to be dropped.
8114181508
*/
@@ -81201,11 +81568,12 @@
8120181568
if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
8120281569
goto exit_drop_table;
8120381570
}
8120481571
}
8120581572
#endif
81206
- if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
81573
+ if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
81574
+ && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
8120781575
sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
8120881576
goto exit_drop_table;
8120981577
}
8121081578
8121181579
#ifndef SQLITE_OMIT_VIEW
@@ -81225,72 +81593,15 @@
8122581593
/* Generate code to remove the table from the master table
8122681594
** on disk.
8122781595
*/
8122881596
v = sqlite3GetVdbe(pParse);
8122981597
if( v ){
81230
- Trigger *pTrigger;
81231
- Db *pDb = &db->aDb[iDb];
8123281598
sqlite3BeginWriteOperation(pParse, 1, iDb);
81233
-
81234
-#ifndef SQLITE_OMIT_VIRTUALTABLE
81235
- if( IsVirtual(pTab) ){
81236
- sqlite3VdbeAddOp0(v, OP_VBegin);
81237
- }
81238
-#endif
81599
+ sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
8123981600
sqlite3FkDropTable(pParse, pName, pTab);
81240
-
81241
- /* Drop all triggers associated with the table being dropped. Code
81242
- ** is generated to remove entries from sqlite_master and/or
81243
- ** sqlite_temp_master if required.
81244
- */
81245
- pTrigger = sqlite3TriggerList(pParse, pTab);
81246
- while( pTrigger ){
81247
- assert( pTrigger->pSchema==pTab->pSchema ||
81248
- pTrigger->pSchema==db->aDb[1].pSchema );
81249
- sqlite3DropTriggerPtr(pParse, pTrigger);
81250
- pTrigger = pTrigger->pNext;
81251
- }
81252
-
81253
-#ifndef SQLITE_OMIT_AUTOINCREMENT
81254
- /* Remove any entries of the sqlite_sequence table associated with
81255
- ** the table being dropped. This is done before the table is dropped
81256
- ** at the btree level, in case the sqlite_sequence table needs to
81257
- ** move as a result of the drop (can happen in auto-vacuum mode).
81258
- */
81259
- if( pTab->tabFlags & TF_Autoincrement ){
81260
- sqlite3NestedParse(pParse,
81261
- "DELETE FROM %s.sqlite_sequence WHERE name=%Q",
81262
- pDb->zName, pTab->zName
81263
- );
81264
- }
81265
-#endif
81266
-
81267
- /* Drop all SQLITE_MASTER table and index entries that refer to the
81268
- ** table. The program name loops through the master table and deletes
81269
- ** every row that refers to a table of the same name as the one being
81270
- ** dropped. Triggers are handled seperately because a trigger can be
81271
- ** created in the temp database that refers to a table in another
81272
- ** database.
81273
- */
81274
- sqlite3NestedParse(pParse,
81275
- "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
81276
- pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
81277
- sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
81278
- if( !isView && !IsVirtual(pTab) ){
81279
- destroyTable(pParse, pTab);
81280
- }
81281
-
81282
- /* Remove the table entry from SQLite's internal schema and modify
81283
- ** the schema cookie.
81284
- */
81285
- if( IsVirtual(pTab) ){
81286
- sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
81287
- }
81288
- sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
81289
- sqlite3ChangeCookie(pParse, iDb);
81290
- }
81291
- sqliteViewResetAll(db, iDb);
81601
+ sqlite3CodeDropTable(pParse, pTab, iDb, isView);
81602
+ }
8129281603
8129381604
exit_drop_table:
8129481605
sqlite3SrcListDelete(db, pName);
8129581606
}
8129681607
@@ -81454,17 +81765,19 @@
8145481765
*/
8145581766
static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
8145681767
Table *pTab = pIndex->pTable; /* The table that is indexed */
8145781768
int iTab = pParse->nTab++; /* Btree cursor used for pTab */
8145881769
int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
81459
- int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */
81770
+ int iSorter; /* Cursor opened by OpenSorter (if in use) */
8146081771
int addr1; /* Address of top of loop */
8146181772
int addr2; /* Address to jump to for next iteration */
8146281773
int tnum; /* Root page of index */
8146381774
Vdbe *v; /* Generate code into this virtual machine */
8146481775
KeyInfo *pKey; /* KeyInfo for index */
81776
+#ifdef SQLITE_OMIT_MERGE_SORT
8146581777
int regIdxKey; /* Registers containing the index key */
81778
+#endif
8146681779
int regRecord; /* Register holding assemblied index record */
8146781780
sqlite3 *db = pParse->db; /* The database connection */
8146881781
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
8146981782
8147081783
#ifndef SQLITE_OMIT_AUTHORIZATION
@@ -81494,21 +81807,22 @@
8149481807
8149581808
#ifndef SQLITE_OMIT_MERGE_SORT
8149681809
/* Open the sorter cursor if we are to use one. */
8149781810
iSorter = pParse->nTab++;
8149881811
sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
81812
+#else
81813
+ iSorter = iTab;
8149981814
#endif
8150081815
8150181816
/* Open the table. Loop through all rows of the table, inserting index
8150281817
** records into the sorter. */
8150381818
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
8150481819
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
81505
- addr2 = addr1 + 1;
8150681820
regRecord = sqlite3GetTempReg(pParse);
81507
- regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
8150881821
8150981822
#ifndef SQLITE_OMIT_MERGE_SORT
81823
+ sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
8151081824
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
8151181825
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
8151281826
sqlite3VdbeJumpHere(v, addr1);
8151381827
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
8151481828
if( pIndex->onError!=OE_None ){
@@ -81524,10 +81838,12 @@
8152481838
}
8152581839
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
8152681840
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
8152781841
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
8152881842
#else
81843
+ regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
81844
+ addr2 = addr1 + 1;
8152981845
if( pIndex->onError!=OE_None ){
8153081846
const int regRowid = regIdxKey + pIndex->nColumn;
8153181847
const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
8153281848
void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
8153381849
@@ -81621,10 +81937,11 @@
8162181937
** before looking up the table.
8162281938
*/
8162381939
assert( pName1 && pName2 );
8162481940
iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
8162581941
if( iDb<0 ) goto exit_create_index;
81942
+ assert( pName && pName->z );
8162681943
8162781944
#ifndef SQLITE_OMIT_TEMPDB
8162881945
/* If the index name was unqualified, check if the the table
8162981946
** is a temp table. If so, set the database to 1. Do not do this
8163081947
** if initialising a database schema.
@@ -81648,10 +81965,11 @@
8164881965
pTblName->a[0].zDatabase);
8164981966
if( !pTab || db->mallocFailed ) goto exit_create_index;
8165081967
assert( db->aDb[iDb].pSchema==pTab->pSchema );
8165181968
}else{
8165281969
assert( pName==0 );
81970
+ assert( pStart==0 );
8165381971
pTab = pParse->pNewTable;
8165481972
if( !pTab ) goto exit_create_index;
8165581973
iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
8165681974
}
8165781975
pDb = &db->aDb[iDb];
@@ -81690,10 +82008,11 @@
8169082008
** own name.
8169182009
*/
8169282010
if( pName ){
8169382011
zName = sqlite3NameFromToken(db, pName);
8169482012
if( zName==0 ) goto exit_create_index;
82013
+ assert( pName->z!=0 );
8169582014
if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
8169682015
goto exit_create_index;
8169782016
}
8169882017
if( !db->init.busy ){
8169982018
if( sqlite3FindTable(db, zName, 0)!=0 ){
@@ -81769,24 +82088,24 @@
8176982088
*/
8177082089
nName = sqlite3Strlen30(zName);
8177182090
nCol = pList->nExpr;
8177282091
pIndex = sqlite3DbMallocZero(db,
8177382092
sizeof(Index) + /* Index structure */
82093
+ sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
8177482094
sizeof(int)*nCol + /* Index.aiColumn */
81775
- sizeof(int)*(nCol+1) + /* Index.aiRowEst */
8177682095
sizeof(char *)*nCol + /* Index.azColl */
8177782096
sizeof(u8)*nCol + /* Index.aSortOrder */
8177882097
nName + 1 + /* Index.zName */
8177982098
nExtra /* Collation sequence names */
8178082099
);
8178182100
if( db->mallocFailed ){
8178282101
goto exit_create_index;
8178382102
}
81784
- pIndex->azColl = (char**)(&pIndex[1]);
82103
+ pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]);
82104
+ pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]);
8178582105
pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
81786
- pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]);
81787
- pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]);
82106
+ pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
8178882107
pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
8178982108
zExtra = (char *)(&pIndex->zName[nName+1]);
8179082109
memcpy(pIndex->zName, zName, nName+1);
8179182110
pIndex->pTable = pTab;
8179282111
pIndex->nColumn = pList->nExpr;
@@ -82059,13 +82378,13 @@
8205982378
** Apart from that, we have little to go on besides intuition as to
8206082379
** how aiRowEst[] should be initialized. The numbers generated here
8206182380
** are based on typical values found in actual indices.
8206282381
*/
8206382382
SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
82064
- unsigned *a = pIdx->aiRowEst;
82383
+ tRowcnt *a = pIdx->aiRowEst;
8206582384
int i;
82066
- unsigned n;
82385
+ tRowcnt n;
8206782386
assert( a!=0 );
8206882387
a[0] = pIdx->pTable->nRowEst;
8206982388
if( a[0]<10 ) a[0] = 10;
8207082389
n = 10;
8207182390
for(i=1; i<=pIdx->nColumn; i++){
@@ -82545,17 +82864,14 @@
8254582864
8254682865
/*
8254782866
** Commit a transaction
8254882867
*/
8254982868
SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
82550
- sqlite3 *db;
8255182869
Vdbe *v;
8255282870
8255382871
assert( pParse!=0 );
82554
- db = pParse->db;
82555
- assert( db!=0 );
82556
-/* if( db->aDb[0].pBt==0 ) return; */
82872
+ assert( pParse->db!=0 );
8255782873
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
8255882874
return;
8255982875
}
8256082876
v = sqlite3GetVdbe(pParse);
8256182877
if( v ){
@@ -82565,17 +82881,14 @@
8256582881
8256682882
/*
8256782883
** Rollback a transaction
8256882884
*/
8256982885
SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
82570
- sqlite3 *db;
8257182886
Vdbe *v;
8257282887
8257382888
assert( pParse!=0 );
82574
- db = pParse->db;
82575
- assert( db!=0 );
82576
-/* if( db->aDb[0].pBt==0 ) return; */
82889
+ assert( pParse->db!=0 );
8257782890
if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
8257882891
return;
8257982892
}
8258082893
v = sqlite3GetVdbe(pParse);
8258182894
if( v ){
@@ -84377,20 +84690,19 @@
8437784690
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
8437884691
assert( z2==(char*)sqlite3_value_text(argv[0]) );
8437984692
if( z2 ){
8438084693
z1 = contextMalloc(context, ((i64)n)+1);
8438184694
if( z1 ){
84382
- memcpy(z1, z2, n+1);
84383
- for(i=0; z1[i]; i++){
84384
- z1[i] = (char)sqlite3Toupper(z1[i]);
84695
+ for(i=0; i<n; i++){
84696
+ z1[i] = (char)sqlite3Toupper(z2[i]);
8438584697
}
84386
- sqlite3_result_text(context, z1, -1, sqlite3_free);
84698
+ sqlite3_result_text(context, z1, n, sqlite3_free);
8438784699
}
8438884700
}
8438984701
}
8439084702
static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
84391
- u8 *z1;
84703
+ char *z1;
8439284704
const char *z2;
8439384705
int i, n;
8439484706
UNUSED_PARAMETER(argc);
8439584707
z2 = (char*)sqlite3_value_text(argv[0]);
8439684708
n = sqlite3_value_bytes(argv[0]);
@@ -84397,15 +84709,14 @@
8439784709
/* Verify that the call to _bytes() does not invalidate the _text() pointer */
8439884710
assert( z2==(char*)sqlite3_value_text(argv[0]) );
8439984711
if( z2 ){
8440084712
z1 = contextMalloc(context, ((i64)n)+1);
8440184713
if( z1 ){
84402
- memcpy(z1, z2, n+1);
84403
- for(i=0; z1[i]; i++){
84404
- z1[i] = sqlite3Tolower(z1[i]);
84714
+ for(i=0; i<n; i++){
84715
+ z1[i] = sqlite3Tolower(z2[i]);
8440584716
}
84406
- sqlite3_result_text(context, (char *)z1, -1, sqlite3_free);
84717
+ sqlite3_result_text(context, z1, n, sqlite3_free);
8440784718
}
8440884719
}
8440984720
}
8441084721
8441184722
@@ -86778,10 +87089,11 @@
8677887089
sqlite3SelectDelete(db, pSelect);
8677987090
if( db->mallocFailed==1 ){
8678087091
fkTriggerDelete(db, pTrigger);
8678187092
return 0;
8678287093
}
87094
+ assert( pStep!=0 );
8678387095
8678487096
switch( action ){
8678587097
case OE_Restrict:
8678687098
pStep->op = TK_SELECT;
8678787099
break;
@@ -88621,10 +88933,13 @@
8862188933
*/
8862288934
if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
8862388935
return 0;
8862488936
}
8862588937
#endif
88938
+ if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
88939
+ return 0;
88940
+ }
8862688941
8862788942
/* If we get this far, it means either:
8862888943
**
8862988944
** * We can always do the transfer if the table contains an
8863088945
** an integer primary key
@@ -89698,11 +90013,11 @@
8969890013
sqlite3_vfs *pVfs = db->pVfs;
8969990014
void *handle;
8970090015
int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
8970190016
char *zErrmsg = 0;
8970290017
void **aHandle;
89703
- const int nMsg = 300;
90018
+ int nMsg = 300 + sqlite3Strlen30(zFile);
8970490019
8970590020
if( pzErrMsg ) *pzErrMsg = 0;
8970690021
8970790022
/* Ticket #1863. To avoid a creating security problems for older
8970890023
** applications that relink against newer versions of SQLite, the
@@ -89735,10 +90050,11 @@
8973590050
}
8973690051
xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
8973790052
sqlite3OsDlSym(pVfs, handle, zProc);
8973890053
if( xInit==0 ){
8973990054
if( pzErrMsg ){
90055
+ nMsg += sqlite3Strlen30(zProc);
8974090056
*pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
8974190057
if( zErrmsg ){
8974290058
sqlite3_snprintf(nMsg, zErrmsg,
8974390059
"no entry point [%s] in shared library [%s]", zProc,zFile);
8974490060
sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
@@ -90420,11 +90736,11 @@
9042090736
){
9042190737
int iReg;
9042290738
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
9042390739
sqlite3CodeVerifySchema(pParse, iDb);
9042490740
iReg = ++pParse->nMem;
90425
- if( zLeft[0]=='p' ){
90741
+ if( sqlite3Tolower(zLeft[0])=='p' ){
9042690742
sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
9042790743
}else{
9042890744
sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
9042990745
}
9043090746
sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
@@ -90486,12 +90802,14 @@
9048690802
*/
9048790803
if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
9048890804
int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
9048990805
int ii; /* Loop counter */
9049090806
90491
- /* Force the schema to be loaded on all databases. This cases all
90492
- ** database files to be opened and the journal_modes set. */
90807
+ /* Force the schema to be loaded on all databases. This causes all
90808
+ ** database files to be opened and the journal_modes set. This is
90809
+ ** necessary because subsequent processing must know if the databases
90810
+ ** are in WAL mode. */
9049390811
if( sqlite3ReadSchema(pParse) ){
9049490812
goto pragma_out;
9049590813
}
9049690814
9049790815
sqlite3VdbeSetNumCols(v, 1);
@@ -91031,11 +91349,11 @@
9103191349
{ OP_IfNeg, 1, 0, 0}, /* 1 */
9103291350
{ OP_String8, 0, 3, 0}, /* 2 */
9103391351
{ OP_ResultRow, 3, 1, 0},
9103491352
};
9103591353
91036
- int isQuick = (zLeft[0]=='q');
91354
+ int isQuick = (sqlite3Tolower(zLeft[0])=='q');
9103791355
9103891356
/* Initialize the VDBE program */
9103991357
if( sqlite3ReadSchema(pParse) ) goto pragma_out;
9104091358
pParse->nMem = 6;
9104191359
sqlite3VdbeSetNumCols(v, 1);
@@ -92406,10 +92724,11 @@
9240692724
Select standin;
9240792725
sqlite3 *db = pParse->db;
9240892726
pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
9240992727
assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
9241092728
if( pNew==0 ){
92729
+ assert( db->mallocFailed );
9241192730
pNew = &standin;
9241292731
memset(pNew, 0, sizeof(*pNew));
9241392732
}
9241492733
if( pEList==0 ){
9241592734
pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
@@ -92433,10 +92752,11 @@
9243392752
if( pNew!=&standin ) sqlite3DbFree(db, pNew);
9243492753
pNew = 0;
9243592754
}else{
9243692755
assert( pNew->pSrc!=0 || pParse->nErr>0 );
9243792756
}
92757
+ assert( pNew!=&standin );
9243892758
return pNew;
9243992759
}
9244092760
9244192761
/*
9244292762
** Delete the given Select structure and all of its substructures.
@@ -93611,11 +93931,14 @@
9361193931
/* If the column contains an "AS <name>" phrase, use <name> as the name */
9361293932
zName = sqlite3DbStrDup(db, zName);
9361393933
}else{
9361493934
Expr *pColExpr = p; /* The expression that is the result column name */
9361593935
Table *pTab; /* Table associated with this expression */
93616
- while( pColExpr->op==TK_DOT ) pColExpr = pColExpr->pRight;
93936
+ while( pColExpr->op==TK_DOT ){
93937
+ pColExpr = pColExpr->pRight;
93938
+ assert( pColExpr!=0 );
93939
+ }
9361793940
if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
9361893941
/* For columns use the column name name */
9361993942
int iCol = pColExpr->iColumn;
9362093943
pTab = pColExpr->pTab;
9362193944
if( iCol<0 ) iCol = pTab->iPKey;
@@ -98609,10 +98932,11 @@
9860998932
break;
9861098933
}
9861198934
}
9861298935
}
9861398936
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
98937
+ assert( aRegIdx );
9861498938
if( openAll || aRegIdx[i]>0 ){
9861598939
KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
9861698940
sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
9861798941
(char*)pKey, P4_KEYINFO_HANDOFF);
9861898942
assert( pParse->nTab>iCur+i+1 );
@@ -98782,10 +99106,11 @@
9878299106
sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
9878399107
sqlite3VdbeJumpHere(v, addr);
9878499108
9878599109
/* Close all tables */
9878699110
for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
99111
+ assert( aRegIdx );
9878799112
if( openAll || aRegIdx[i]>0 ){
9878899113
sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
9878999114
}
9879099115
}
9879199116
sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
@@ -98969,11 +99294,11 @@
9896999294
if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
9897099295
sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
9897199296
return sqlite3_errcode(db);
9897299297
}
9897399298
VVA_ONLY( rc = ) sqlite3_step(pStmt);
98974
- assert( rc!=SQLITE_ROW );
99299
+ assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) );
9897599300
return vacuumFinalize(db, pStmt, pzErrMsg);
9897699301
}
9897799302
9897899303
/*
9897999304
** Execute zSql on database db. The statement returns exactly
@@ -99187,17 +99512,15 @@
9918799512
" WHERE type='view' OR type='trigger'"
9918899513
" OR (type='table' AND rootpage=0)"
9918999514
);
9919099515
if( rc ) goto end_of_vacuum;
9919199516
99192
- /* At this point, unless the main db was completely empty, there is now a
99193
- ** transaction open on the vacuum database, but not on the main database.
99194
- ** Open a btree level transaction on the main database. This allows a
99195
- ** call to sqlite3BtreeCopyFile(). The main database btree level
99196
- ** transaction is then committed, so the SQL level never knows it was
99197
- ** opened for writing. This way, the SQL transaction used to create the
99198
- ** temporary database never needs to be committed.
99517
+ /* At this point, there is a write transaction open on both the
99518
+ ** vacuum database and the main database. Assuming no error occurs,
99519
+ ** both transactions are closed by this block - the main database
99520
+ ** transaction by sqlite3BtreeCopyFile() and the other by an explicit
99521
+ ** call to sqlite3BtreeCommit().
9919999522
*/
9920099523
{
9920199524
u32 meta;
9920299525
int i;
9920399526
@@ -100457,25 +100780,35 @@
100457100780
#define TERM_CODED 0x04 /* This term is already coded */
100458100781
#define TERM_COPIED 0x08 /* Has a child */
100459100782
#define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
100460100783
#define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
100461100784
#define TERM_OR_OK 0x40 /* Used during OR-clause processing */
100462
-#ifdef SQLITE_ENABLE_STAT2
100785
+#ifdef SQLITE_ENABLE_STAT3
100463100786
# define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
100464100787
#else
100465
-# define TERM_VNULL 0x00 /* Disabled if not using stat2 */
100788
+# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
100466100789
#endif
100467100790
100468100791
/*
100469100792
** An instance of the following structure holds all information about a
100470100793
** WHERE clause. Mostly this is a container for one or more WhereTerms.
100794
+**
100795
+** Explanation of pOuter: For a WHERE clause of the form
100796
+**
100797
+** a AND ((b AND c) OR (d AND e)) AND f
100798
+**
100799
+** There are separate WhereClause objects for the whole clause and for
100800
+** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the
100801
+** subclauses points to the WhereClause object for the whole clause.
100471100802
*/
100472100803
struct WhereClause {
100473100804
Parse *pParse; /* The parser context */
100474100805
WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
100475100806
Bitmask vmask; /* Bitmask identifying virtual table cursors */
100807
+ WhereClause *pOuter; /* Outer conjunction */
100476100808
u8 op; /* Split operator. TK_AND or TK_OR */
100809
+ u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
100477100810
int nTerm; /* Number of terms */
100478100811
int nSlot; /* Number of entries in a[] */
100479100812
WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
100480100813
#if defined(SQLITE_SMALL_STACK)
100481100814
WhereTerm aStatic[1]; /* Initial static space for a[] */
@@ -100600,18 +100933,21 @@
100600100933
** Initialize a preallocated WhereClause structure.
100601100934
*/
100602100935
static void whereClauseInit(
100603100936
WhereClause *pWC, /* The WhereClause to be initialized */
100604100937
Parse *pParse, /* The parsing context */
100605
- WhereMaskSet *pMaskSet /* Mapping from table cursor numbers to bitmasks */
100938
+ WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmasks */
100939
+ u16 wctrlFlags /* Might include WHERE_AND_ONLY */
100606100940
){
100607100941
pWC->pParse = pParse;
100608100942
pWC->pMaskSet = pMaskSet;
100943
+ pWC->pOuter = 0;
100609100944
pWC->nTerm = 0;
100610100945
pWC->nSlot = ArraySize(pWC->aStatic);
100611100946
pWC->a = pWC->aStatic;
100612100947
pWC->vmask = 0;
100948
+ pWC->wctrlFlags = wctrlFlags;
100613100949
}
100614100950
100615100951
/* Forward reference */
100616100952
static void whereClauseClear(WhereClause*);
100617100953
@@ -100923,40 +101259,42 @@
100923101259
){
100924101260
WhereTerm *pTerm;
100925101261
int k;
100926101262
assert( iCur>=0 );
100927101263
op &= WO_ALL;
100928
- for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
100929
- if( pTerm->leftCursor==iCur
100930
- && (pTerm->prereqRight & notReady)==0
100931
- && pTerm->u.leftColumn==iColumn
100932
- && (pTerm->eOperator & op)!=0
100933
- ){
100934
- if( pIdx && pTerm->eOperator!=WO_ISNULL ){
100935
- Expr *pX = pTerm->pExpr;
100936
- CollSeq *pColl;
100937
- char idxaff;
100938
- int j;
100939
- Parse *pParse = pWC->pParse;
100940
-
100941
- idxaff = pIdx->pTable->aCol[iColumn].affinity;
100942
- if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
100943
-
100944
- /* Figure out the collation sequence required from an index for
100945
- ** it to be useful for optimising expression pX. Store this
100946
- ** value in variable pColl.
100947
- */
100948
- assert(pX->pLeft);
100949
- pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
100950
- assert(pColl || pParse->nErr);
100951
-
100952
- for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
100953
- if( NEVER(j>=pIdx->nColumn) ) return 0;
100954
- }
100955
- if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
100956
- }
100957
- return pTerm;
101264
+ for(; pWC; pWC=pWC->pOuter){
101265
+ for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
101266
+ if( pTerm->leftCursor==iCur
101267
+ && (pTerm->prereqRight & notReady)==0
101268
+ && pTerm->u.leftColumn==iColumn
101269
+ && (pTerm->eOperator & op)!=0
101270
+ ){
101271
+ if( pIdx && pTerm->eOperator!=WO_ISNULL ){
101272
+ Expr *pX = pTerm->pExpr;
101273
+ CollSeq *pColl;
101274
+ char idxaff;
101275
+ int j;
101276
+ Parse *pParse = pWC->pParse;
101277
+
101278
+ idxaff = pIdx->pTable->aCol[iColumn].affinity;
101279
+ if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
101280
+
101281
+ /* Figure out the collation sequence required from an index for
101282
+ ** it to be useful for optimising expression pX. Store this
101283
+ ** value in variable pColl.
101284
+ */
101285
+ assert(pX->pLeft);
101286
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
101287
+ assert(pColl || pParse->nErr);
101288
+
101289
+ for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
101290
+ if( NEVER(j>=pIdx->nColumn) ) return 0;
101291
+ }
101292
+ if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
101293
+ }
101294
+ return pTerm;
101295
+ }
100958101296
}
100959101297
}
100960101298
return 0;
100961101299
}
100962101300
@@ -101029,11 +101367,11 @@
101029101367
int iCol = pRight->iColumn;
101030101368
pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
101031101369
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
101032101370
z = (char *)sqlite3_value_text(pVal);
101033101371
}
101034
- sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-23257-02778 */
101372
+ sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-31526-56213 */
101035101373
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
101036101374
}else if( op==TK_STRING ){
101037101375
z = pRight->u.zToken;
101038101376
}
101039101377
if( z ){
@@ -101047,11 +101385,11 @@
101047101385
pPrefix = sqlite3Expr(db, TK_STRING, z);
101048101386
if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
101049101387
*ppPrefix = pPrefix;
101050101388
if( op==TK_VARIABLE ){
101051101389
Vdbe *v = pParse->pVdbe;
101052
- sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-23257-02778 */
101390
+ sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-31526-56213 */
101053101391
if( *pisComplete && pRight->u.zToken[1] ){
101054101392
/* If the rhs of the LIKE expression is a variable, and the current
101055101393
** value of the variable means there is no need to invoke the LIKE
101056101394
** function, then no OP_Variable will be added to the program.
101057101395
** This causes problems for the sqlite3_bind_parameter_name()
@@ -101216,11 +101554,11 @@
101216101554
assert( pExpr->op==TK_OR );
101217101555
pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo));
101218101556
if( pOrInfo==0 ) return;
101219101557
pTerm->wtFlags |= TERM_ORINFO;
101220101558
pOrWc = &pOrInfo->wc;
101221
- whereClauseInit(pOrWc, pWC->pParse, pMaskSet);
101559
+ whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
101222101560
whereSplit(pOrWc, pExpr, TK_OR);
101223101561
exprAnalyzeAll(pSrc, pOrWc);
101224101562
if( db->mallocFailed ) return;
101225101563
assert( pOrWc->nTerm>=2 );
101226101564
@@ -101243,13 +101581,14 @@
101243101581
Bitmask b = 0;
101244101582
pOrTerm->u.pAndInfo = pAndInfo;
101245101583
pOrTerm->wtFlags |= TERM_ANDINFO;
101246101584
pOrTerm->eOperator = WO_AND;
101247101585
pAndWC = &pAndInfo->wc;
101248
- whereClauseInit(pAndWC, pWC->pParse, pMaskSet);
101586
+ whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
101249101587
whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
101250101588
exprAnalyzeAll(pSrc, pAndWC);
101589
+ pAndWC->pOuter = pWC;
101251101590
testcase( db->mallocFailed );
101252101591
if( !db->mallocFailed ){
101253101592
for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
101254101593
assert( pAndTerm->pExpr );
101255101594
if( allowedOp(pAndTerm->pExpr->op) ){
@@ -101679,12 +102018,12 @@
101679102018
pNewTerm->prereqAll = pTerm->prereqAll;
101680102019
}
101681102020
}
101682102021
#endif /* SQLITE_OMIT_VIRTUALTABLE */
101683102022
101684
-#ifdef SQLITE_ENABLE_STAT2
101685
- /* When sqlite_stat2 histogram data is available an operator of the
102023
+#ifdef SQLITE_ENABLE_STAT3
102024
+ /* When sqlite_stat3 histogram data is available an operator of the
101686102025
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
101687102026
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
101688102027
** virtual term of that form.
101689102028
**
101690102029
** Note that the virtual term must be tagged with TERM_VNULL. This
@@ -101718,11 +102057,11 @@
101718102057
pTerm->nChild = 1;
101719102058
pTerm->wtFlags |= TERM_COPIED;
101720102059
pNewTerm->prereqAll = pTerm->prereqAll;
101721102060
}
101722102061
}
101723
-#endif /* SQLITE_ENABLE_STAT2 */
102062
+#endif /* SQLITE_ENABLE_STAT */
101724102063
101725102064
/* Prevent ON clause terms of a LEFT JOIN from being used to drive
101726102065
** an index for tables to the left of the join.
101727102066
*/
101728102067
pTerm->prereqRight |= extraRight;
@@ -102140,14 +102479,17 @@
102140102479
const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
102141102480
const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
102142102481
WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
102143102482
WhereTerm *pTerm; /* A single term of the WHERE clause */
102144102483
102145
- /* No OR-clause optimization allowed if the INDEXED BY or NOT INDEXED clauses
102146
- ** are used */
102484
+ /* The OR-clause optimization is disallowed if the INDEXED BY or
102485
+ ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
102147102486
if( pSrc->notIndexed || pSrc->pIndex!=0 ){
102148102487
return;
102488
+ }
102489
+ if( pWC->wctrlFlags & WHERE_AND_ONLY ){
102490
+ return;
102149102491
}
102150102492
102151102493
/* Search the WHERE clause terms for a usable WO_OR term. */
102152102494
for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
102153102495
if( pTerm->eOperator==WO_OR
@@ -102172,12 +102514,14 @@
102172102514
bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
102173102515
}else if( pOrTerm->leftCursor==iCur ){
102174102516
WhereClause tempWC;
102175102517
tempWC.pParse = pWC->pParse;
102176102518
tempWC.pMaskSet = pWC->pMaskSet;
102519
+ tempWC.pOuter = pWC;
102177102520
tempWC.op = TK_AND;
102178102521
tempWC.a = pOrTerm;
102522
+ tempWC.wctrlFlags = 0;
102179102523
tempWC.nTerm = 1;
102180102524
bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
102181102525
}else{
102182102526
continue;
102183102527
}
@@ -102766,71 +103110,89 @@
102766103110
*/
102767103111
bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
102768103112
}
102769103113
#endif /* SQLITE_OMIT_VIRTUALTABLE */
102770103114
103115
+#ifdef SQLITE_ENABLE_STAT3
102771103116
/*
102772
-** Argument pIdx is a pointer to an index structure that has an array of
102773
-** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column
102774
-** stored in Index.aSample. These samples divide the domain of values stored
102775
-** the index into (SQLITE_INDEX_SAMPLES+1) regions.
102776
-** Region 0 contains all values less than the first sample value. Region
102777
-** 1 contains values between the first and second samples. Region 2 contains
102778
-** values between samples 2 and 3. And so on. Region SQLITE_INDEX_SAMPLES
102779
-** contains values larger than the last sample.
102780
-**
102781
-** If the index contains many duplicates of a single value, then it is
102782
-** possible that two or more adjacent samples can hold the same value.
102783
-** When that is the case, the smallest possible region code is returned
102784
-** when roundUp is false and the largest possible region code is returned
102785
-** when roundUp is true.
102786
-**
102787
-** If successful, this function determines which of the regions value
102788
-** pVal lies in, sets *piRegion to the region index (a value between 0
102789
-** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK.
102790
-** Or, if an OOM occurs while converting text values between encodings,
102791
-** SQLITE_NOMEM is returned and *piRegion is undefined.
102792
-*/
102793
-#ifdef SQLITE_ENABLE_STAT2
102794
-static int whereRangeRegion(
103117
+** Estimate the location of a particular key among all keys in an
103118
+** index. Store the results in aStat as follows:
103119
+**
103120
+** aStat[0] Est. number of rows less than pVal
103121
+** aStat[1] Est. number of rows equal to pVal
103122
+**
103123
+** Return SQLITE_OK on success.
103124
+*/
103125
+static int whereKeyStats(
102795103126
Parse *pParse, /* Database connection */
102796103127
Index *pIdx, /* Index to consider domain of */
102797103128
sqlite3_value *pVal, /* Value to consider */
102798
- int roundUp, /* Return largest valid region if true */
102799
- int *piRegion /* OUT: Region of domain in which value lies */
103129
+ int roundUp, /* Round up if true. Round down if false */
103130
+ tRowcnt *aStat /* OUT: stats written here */
102800103131
){
103132
+ tRowcnt n;
103133
+ IndexSample *aSample;
103134
+ int i, eType;
103135
+ int isEq = 0;
103136
+ i64 v;
103137
+ double r, rS;
103138
+
102801103139
assert( roundUp==0 || roundUp==1 );
102802
- if( ALWAYS(pVal) ){
102803
- IndexSample *aSample = pIdx->aSample;
102804
- int i = 0;
102805
- int eType = sqlite3_value_type(pVal);
102806
-
102807
- if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
102808
- double r = sqlite3_value_double(pVal);
102809
- for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
102810
- if( aSample[i].eType==SQLITE_NULL ) continue;
102811
- if( aSample[i].eType>=SQLITE_TEXT ) break;
102812
- if( roundUp ){
102813
- if( aSample[i].u.r>r ) break;
102814
- }else{
102815
- if( aSample[i].u.r>=r ) break;
102816
- }
102817
- }
102818
- }else if( eType==SQLITE_NULL ){
102819
- i = 0;
102820
- if( roundUp ){
102821
- while( i<SQLITE_INDEX_SAMPLES && aSample[i].eType==SQLITE_NULL ) i++;
102822
- }
102823
- }else{
103140
+ assert( pIdx->nSample>0 );
103141
+ if( pVal==0 ) return SQLITE_ERROR;
103142
+ n = pIdx->aiRowEst[0];
103143
+ aSample = pIdx->aSample;
103144
+ eType = sqlite3_value_type(pVal);
103145
+
103146
+ if( eType==SQLITE_INTEGER ){
103147
+ v = sqlite3_value_int64(pVal);
103148
+ r = (i64)v;
103149
+ for(i=0; i<pIdx->nSample; i++){
103150
+ if( aSample[i].eType==SQLITE_NULL ) continue;
103151
+ if( aSample[i].eType>=SQLITE_TEXT ) break;
103152
+ if( aSample[i].eType==SQLITE_INTEGER ){
103153
+ if( aSample[i].u.i>=v ){
103154
+ isEq = aSample[i].u.i==v;
103155
+ break;
103156
+ }
103157
+ }else{
103158
+ assert( aSample[i].eType==SQLITE_FLOAT );
103159
+ if( aSample[i].u.r>=r ){
103160
+ isEq = aSample[i].u.r==r;
103161
+ break;
103162
+ }
103163
+ }
103164
+ }
103165
+ }else if( eType==SQLITE_FLOAT ){
103166
+ r = sqlite3_value_double(pVal);
103167
+ for(i=0; i<pIdx->nSample; i++){
103168
+ if( aSample[i].eType==SQLITE_NULL ) continue;
103169
+ if( aSample[i].eType>=SQLITE_TEXT ) break;
103170
+ if( aSample[i].eType==SQLITE_FLOAT ){
103171
+ rS = aSample[i].u.r;
103172
+ }else{
103173
+ rS = aSample[i].u.i;
103174
+ }
103175
+ if( rS>=r ){
103176
+ isEq = rS==r;
103177
+ break;
103178
+ }
103179
+ }
103180
+ }else if( eType==SQLITE_NULL ){
103181
+ i = 0;
103182
+ if( aSample[0].eType==SQLITE_NULL ) isEq = 1;
103183
+ }else{
103184
+ assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
103185
+ for(i=0; i<pIdx->nSample; i++){
103186
+ if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){
103187
+ break;
103188
+ }
103189
+ }
103190
+ if( i<pIdx->nSample ){
102824103191
sqlite3 *db = pParse->db;
102825103192
CollSeq *pColl;
102826103193
const u8 *z;
102827
- int n;
102828
-
102829
- /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */
102830
- assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
102831
-
102832103194
if( eType==SQLITE_BLOB ){
102833103195
z = (const u8 *)sqlite3_value_blob(pVal);
102834103196
pColl = db->pDfltColl;
102835103197
assert( pColl->enc==SQLITE_UTF8 );
102836103198
}else{
@@ -102845,16 +103207,16 @@
102845103207
return SQLITE_NOMEM;
102846103208
}
102847103209
assert( z && pColl && pColl->xCmp );
102848103210
}
102849103211
n = sqlite3ValueBytes(pVal, pColl->enc);
102850
-
102851
- for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
103212
+
103213
+ for(; i<pIdx->nSample; i++){
102852103214
int c;
102853103215
int eSampletype = aSample[i].eType;
102854
- if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue;
102855
- if( (eSampletype!=eType) ) break;
103216
+ if( eSampletype<eType ) continue;
103217
+ if( eSampletype!=eType ) break;
102856103218
#ifndef SQLITE_OMIT_UTF16
102857103219
if( pColl->enc!=SQLITE_UTF8 ){
102858103220
int nSample;
102859103221
char *zSample = sqlite3Utf8to16(
102860103222
db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
@@ -102868,20 +103230,51 @@
102868103230
}else
102869103231
#endif
102870103232
{
102871103233
c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
102872103234
}
102873
- if( c-roundUp>=0 ) break;
103235
+ if( c>=0 ){
103236
+ if( c==0 ) isEq = 1;
103237
+ break;
103238
+ }
102874103239
}
102875103240
}
103241
+ }
102876103242
102877
- assert( i>=0 && i<=SQLITE_INDEX_SAMPLES );
102878
- *piRegion = i;
103243
+ /* At this point, aSample[i] is the first sample that is greater than
103244
+ ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less
103245
+ ** than pVal. If aSample[i]==pVal, then isEq==1.
103246
+ */
103247
+ if( isEq ){
103248
+ assert( i<pIdx->nSample );
103249
+ aStat[0] = aSample[i].nLt;
103250
+ aStat[1] = aSample[i].nEq;
103251
+ }else{
103252
+ tRowcnt iLower, iUpper, iGap;
103253
+ if( i==0 ){
103254
+ iLower = 0;
103255
+ iUpper = aSample[0].nLt;
103256
+ }else{
103257
+ iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
103258
+ iLower = aSample[i-1].nEq + aSample[i-1].nLt;
103259
+ }
103260
+ aStat[1] = pIdx->avgEq;
103261
+ if( iLower>=iUpper ){
103262
+ iGap = 0;
103263
+ }else{
103264
+ iGap = iUpper - iLower;
103265
+ }
103266
+ if( roundUp ){
103267
+ iGap = (iGap*2)/3;
103268
+ }else{
103269
+ iGap = iGap/3;
103270
+ }
103271
+ aStat[0] = iLower + iGap;
102879103272
}
102880103273
return SQLITE_OK;
102881103274
}
102882
-#endif /* #ifdef SQLITE_ENABLE_STAT2 */
103275
+#endif /* SQLITE_ENABLE_STAT3 */
102883103276
102884103277
/*
102885103278
** If expression pExpr represents a literal value, set *pp to point to
102886103279
** an sqlite3_value structure containing the same value, with affinity
102887103280
** aff applied to it, before returning. It is the responsibility of the
@@ -102895,11 +103288,11 @@
102895103288
**
102896103289
** If neither of the above apply, set *pp to NULL.
102897103290
**
102898103291
** If an error occurs, return an error code. Otherwise, SQLITE_OK.
102899103292
*/
102900
-#ifdef SQLITE_ENABLE_STAT2
103293
+#ifdef SQLITE_ENABLE_STAT3
102901103294
static int valueFromExpr(
102902103295
Parse *pParse,
102903103296
Expr *pExpr,
102904103297
u8 aff,
102905103298
sqlite3_value **pp
@@ -102906,11 +103299,11 @@
102906103299
){
102907103300
if( pExpr->op==TK_VARIABLE
102908103301
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
102909103302
){
102910103303
int iVar = pExpr->iColumn;
102911
- sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */
103304
+ sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-31526-56213 */
102912103305
*pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
102913103306
return SQLITE_OK;
102914103307
}
102915103308
return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
102916103309
}
@@ -102943,106 +103336,92 @@
102943103336
**
102944103337
** ... FROM t1 WHERE a > ? AND a < ? ...
102945103338
**
102946103339
** then nEq should be passed 0.
102947103340
**
102948
-** The returned value is an integer between 1 and 100, inclusive. A return
102949
-** value of 1 indicates that the proposed range scan is expected to visit
102950
-** approximately 1/100th (1%) of the rows selected by the nEq equality
102951
-** constraints (if any). A return value of 100 indicates that it is expected
102952
-** that the range scan will visit every row (100%) selected by the equality
102953
-** constraints.
103341
+** The returned value is an integer divisor to reduce the estimated
103342
+** search space. A return value of 1 means that range constraints are
103343
+** no help at all. A return value of 2 means range constraints are
103344
+** expected to reduce the search space by half. And so forth...
102954103345
**
102955
-** In the absence of sqlite_stat2 ANALYZE data, each range inequality
102956
-** reduces the search space by 3/4ths. Hence a single constraint (x>?)
102957
-** results in a return of 25 and a range constraint (x>? AND x<?) results
102958
-** in a return of 6.
103346
+** In the absence of sqlite_stat3 ANALYZE data, each range inequality
103347
+** reduces the search space by a factor of 4. Hence a single constraint (x>?)
103348
+** results in a return of 4 and a range constraint (x>? AND x<?) results
103349
+** in a return of 16.
102959103350
*/
102960103351
static int whereRangeScanEst(
102961103352
Parse *pParse, /* Parsing & code generating context */
102962103353
Index *p, /* The index containing the range-compared column; "x" */
102963103354
int nEq, /* index into p->aCol[] of the range-compared column */
102964103355
WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
102965103356
WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
102966
- int *piEst /* OUT: Return value */
103357
+ double *pRangeDiv /* OUT: Reduce search space by this divisor */
102967103358
){
102968103359
int rc = SQLITE_OK;
102969103360
102970
-#ifdef SQLITE_ENABLE_STAT2
102971
-
102972
- if( nEq==0 && p->aSample ){
102973
- sqlite3_value *pLowerVal = 0;
102974
- sqlite3_value *pUpperVal = 0;
102975
- int iEst;
102976
- int iLower = 0;
102977
- int iUpper = SQLITE_INDEX_SAMPLES;
102978
- int roundUpUpper = 0;
102979
- int roundUpLower = 0;
103361
+#ifdef SQLITE_ENABLE_STAT3
103362
+
103363
+ if( nEq==0 && p->nSample ){
103364
+ sqlite3_value *pRangeVal;
103365
+ tRowcnt iLower = 0;
103366
+ tRowcnt iUpper = p->aiRowEst[0];
103367
+ tRowcnt a[2];
102980103368
u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
102981103369
102982103370
if( pLower ){
102983103371
Expr *pExpr = pLower->pExpr->pRight;
102984
- rc = valueFromExpr(pParse, pExpr, aff, &pLowerVal);
103372
+ rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
102985103373
assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE );
102986
- roundUpLower = (pLower->eOperator==WO_GT) ?1:0;
103374
+ if( rc==SQLITE_OK
103375
+ && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK
103376
+ ){
103377
+ iLower = a[0];
103378
+ if( pLower->eOperator==WO_GT ) iLower += a[1];
103379
+ }
103380
+ sqlite3ValueFree(pRangeVal);
102987103381
}
102988103382
if( rc==SQLITE_OK && pUpper ){
102989103383
Expr *pExpr = pUpper->pExpr->pRight;
102990
- rc = valueFromExpr(pParse, pExpr, aff, &pUpperVal);
103384
+ rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
102991103385
assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE );
102992
- roundUpUpper = (pUpper->eOperator==WO_LE) ?1:0;
102993
- }
102994
-
102995
- if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){
102996
- sqlite3ValueFree(pLowerVal);
102997
- sqlite3ValueFree(pUpperVal);
102998
- goto range_est_fallback;
102999
- }else if( pLowerVal==0 ){
103000
- rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper);
103001
- if( pLower ) iLower = iUpper/2;
103002
- }else if( pUpperVal==0 ){
103003
- rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower);
103004
- if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2;
103005
- }else{
103006
- rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper);
103007
- if( rc==SQLITE_OK ){
103008
- rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower);
103009
- }
103010
- }
103011
- WHERETRACE(("range scan regions: %d..%d\n", iLower, iUpper));
103012
-
103013
- iEst = iUpper - iLower;
103014
- testcase( iEst==SQLITE_INDEX_SAMPLES );
103015
- assert( iEst<=SQLITE_INDEX_SAMPLES );
103016
- if( iEst<1 ){
103017
- *piEst = 50/SQLITE_INDEX_SAMPLES;
103018
- }else{
103019
- *piEst = (iEst*100)/SQLITE_INDEX_SAMPLES;
103020
- }
103021
- sqlite3ValueFree(pLowerVal);
103022
- sqlite3ValueFree(pUpperVal);
103023
- return rc;
103024
- }
103025
-range_est_fallback:
103386
+ if( rc==SQLITE_OK
103387
+ && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK
103388
+ ){
103389
+ iUpper = a[0];
103390
+ if( pUpper->eOperator==WO_LE ) iUpper += a[1];
103391
+ }
103392
+ sqlite3ValueFree(pRangeVal);
103393
+ }
103394
+ if( rc==SQLITE_OK ){
103395
+ if( iUpper<=iLower ){
103396
+ *pRangeDiv = (double)p->aiRowEst[0];
103397
+ }else{
103398
+ *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
103399
+ }
103400
+ WHERETRACE(("range scan regions: %u..%u div=%g\n",
103401
+ (u32)iLower, (u32)iUpper, *pRangeDiv));
103402
+ return SQLITE_OK;
103403
+ }
103404
+ }
103026103405
#else
103027103406
UNUSED_PARAMETER(pParse);
103028103407
UNUSED_PARAMETER(p);
103029103408
UNUSED_PARAMETER(nEq);
103030103409
#endif
103031103410
assert( pLower || pUpper );
103032
- *piEst = 100;
103033
- if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *piEst /= 4;
103034
- if( pUpper ) *piEst /= 4;
103411
+ *pRangeDiv = (double)1;
103412
+ if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
103413
+ if( pUpper ) *pRangeDiv *= (double)4;
103035103414
return rc;
103036103415
}
103037103416
103038
-#ifdef SQLITE_ENABLE_STAT2
103417
+#ifdef SQLITE_ENABLE_STAT3
103039103418
/*
103040103419
** Estimate the number of rows that will be returned based on
103041103420
** an equality constraint x=VALUE and where that VALUE occurs in
103042103421
** the histogram data. This only works when x is the left-most
103043
-** column of an index and sqlite_stat2 histogram data is available
103422
+** column of an index and sqlite_stat3 histogram data is available
103044103423
** for that index. When pExpr==NULL that means the constraint is
103045103424
** "x IS NULL" instead of "x=VALUE".
103046103425
**
103047103426
** Write the estimated row count into *pnRow and return SQLITE_OK.
103048103427
** If unable to make an estimate, leave *pnRow unchanged and return
@@ -103058,44 +103437,36 @@
103058103437
Index *p, /* The index whose left-most column is pTerm */
103059103438
Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
103060103439
double *pnRow /* Write the revised row estimate here */
103061103440
){
103062103441
sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
103063
- int iLower, iUpper; /* Range of histogram regions containing pRhs */
103064103442
u8 aff; /* Column affinity */
103065103443
int rc; /* Subfunction return code */
103066
- double nRowEst; /* New estimate of the number of rows */
103444
+ tRowcnt a[2]; /* Statistics */
103067103445
103068103446
assert( p->aSample!=0 );
103447
+ assert( p->nSample>0 );
103069103448
aff = p->pTable->aCol[p->aiColumn[0]].affinity;
103070103449
if( pExpr ){
103071103450
rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
103072103451
if( rc ) goto whereEqualScanEst_cancel;
103073103452
}else{
103074103453
pRhs = sqlite3ValueNew(pParse->db);
103075103454
}
103076103455
if( pRhs==0 ) return SQLITE_NOTFOUND;
103077
- rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower);
103078
- if( rc ) goto whereEqualScanEst_cancel;
103079
- rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper);
103080
- if( rc ) goto whereEqualScanEst_cancel;
103081
- WHERETRACE(("equality scan regions: %d..%d\n", iLower, iUpper));
103082
- if( iLower>=iUpper ){
103083
- nRowEst = p->aiRowEst[0]/(SQLITE_INDEX_SAMPLES*2);
103084
- if( nRowEst<*pnRow ) *pnRow = nRowEst;
103085
- }else{
103086
- nRowEst = (iUpper-iLower)*p->aiRowEst[0]/SQLITE_INDEX_SAMPLES;
103087
- *pnRow = nRowEst;
103088
- }
103089
-
103456
+ rc = whereKeyStats(pParse, p, pRhs, 0, a);
103457
+ if( rc==SQLITE_OK ){
103458
+ WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
103459
+ *pnRow = a[1];
103460
+ }
103090103461
whereEqualScanEst_cancel:
103091103462
sqlite3ValueFree(pRhs);
103092103463
return rc;
103093103464
}
103094
-#endif /* defined(SQLITE_ENABLE_STAT2) */
103465
+#endif /* defined(SQLITE_ENABLE_STAT3) */
103095103466
103096
-#ifdef SQLITE_ENABLE_STAT2
103467
+#ifdef SQLITE_ENABLE_STAT3
103097103468
/*
103098103469
** Estimate the number of rows that will be returned based on
103099103470
** an IN constraint where the right-hand side of the IN operator
103100103471
** is a list of values. Example:
103101103472
**
@@ -103114,64 +103485,29 @@
103114103485
Parse *pParse, /* Parsing & code generating context */
103115103486
Index *p, /* The index whose left-most column is pTerm */
103116103487
ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
103117103488
double *pnRow /* Write the revised row estimate here */
103118103489
){
103119
- sqlite3_value *pVal = 0; /* One value from list */
103120
- int iLower, iUpper; /* Range of histogram regions containing pRhs */
103121
- u8 aff; /* Column affinity */
103122
- int rc = SQLITE_OK; /* Subfunction return code */
103123
- double nRowEst; /* New estimate of the number of rows */
103124
- int nSpan = 0; /* Number of histogram regions spanned */
103125
- int nSingle = 0; /* Histogram regions hit by a single value */
103126
- int nNotFound = 0; /* Count of values that are not constants */
103127
- int i; /* Loop counter */
103128
- u8 aSpan[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */
103129
- u8 aSingle[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions hit once */
103490
+ int rc = SQLITE_OK; /* Subfunction return code */
103491
+ double nEst; /* Number of rows for a single term */
103492
+ double nRowEst = (double)0; /* New estimate of the number of rows */
103493
+ int i; /* Loop counter */
103130103494
103131103495
assert( p->aSample!=0 );
103132
- aff = p->pTable->aCol[p->aiColumn[0]].affinity;
103133
- memset(aSpan, 0, sizeof(aSpan));
103134
- memset(aSingle, 0, sizeof(aSingle));
103135
- for(i=0; i<pList->nExpr; i++){
103136
- sqlite3ValueFree(pVal);
103137
- rc = valueFromExpr(pParse, pList->a[i].pExpr, aff, &pVal);
103138
- if( rc ) break;
103139
- if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
103140
- nNotFound++;
103141
- continue;
103142
- }
103143
- rc = whereRangeRegion(pParse, p, pVal, 0, &iLower);
103144
- if( rc ) break;
103145
- rc = whereRangeRegion(pParse, p, pVal, 1, &iUpper);
103146
- if( rc ) break;
103147
- if( iLower>=iUpper ){
103148
- aSingle[iLower] = 1;
103149
- }else{
103150
- assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES );
103151
- while( iLower<iUpper ) aSpan[iLower++] = 1;
103152
- }
103496
+ for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
103497
+ nEst = p->aiRowEst[0];
103498
+ rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
103499
+ nRowEst += nEst;
103153103500
}
103154103501
if( rc==SQLITE_OK ){
103155
- for(i=nSpan=0; i<=SQLITE_INDEX_SAMPLES; i++){
103156
- if( aSpan[i] ){
103157
- nSpan++;
103158
- }else if( aSingle[i] ){
103159
- nSingle++;
103160
- }
103161
- }
103162
- nRowEst = (nSpan*2+nSingle)*p->aiRowEst[0]/(2*SQLITE_INDEX_SAMPLES)
103163
- + nNotFound*p->aiRowEst[1];
103164103502
if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
103165103503
*pnRow = nRowEst;
103166
- WHERETRACE(("IN row estimate: nSpan=%d, nSingle=%d, nNotFound=%d, est=%g\n",
103167
- nSpan, nSingle, nNotFound, nRowEst));
103504
+ WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
103168103505
}
103169
- sqlite3ValueFree(pVal);
103170103506
return rc;
103171103507
}
103172
-#endif /* defined(SQLITE_ENABLE_STAT2) */
103508
+#endif /* defined(SQLITE_ENABLE_STAT3) */
103173103509
103174103510
103175103511
/*
103176103512
** Find the best query plan for accessing a particular table. Write the
103177103513
** best query plan and its cost into the WhereCost object supplied as the
@@ -103214,11 +103550,11 @@
103214103550
Index *pProbe; /* An index we are evaluating */
103215103551
Index *pIdx; /* Copy of pProbe, or zero for IPK index */
103216103552
int eqTermMask; /* Current mask of valid equality operators */
103217103553
int idxEqTermMask; /* Index mask of valid equality operators */
103218103554
Index sPk; /* A fake index object for the primary key */
103219
- unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
103555
+ tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
103220103556
int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
103221103557
int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */
103222103558
103223103559
/* Initialize the cost to a worst-case value */
103224103560
memset(pCost, 0, sizeof(*pCost));
@@ -103269,14 +103605,14 @@
103269103605
}
103270103606
103271103607
/* Loop over all indices looking for the best one to use
103272103608
*/
103273103609
for(; pProbe; pIdx=pProbe=pProbe->pNext){
103274
- const unsigned int * const aiRowEst = pProbe->aiRowEst;
103610
+ const tRowcnt * const aiRowEst = pProbe->aiRowEst;
103275103611
double cost; /* Cost of using pProbe */
103276103612
double nRow; /* Estimated number of rows in result set */
103277
- double log10N; /* base-10 logarithm of nRow (inexact) */
103613
+ double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */
103278103614
int rev; /* True to scan in reverse order */
103279103615
int wsFlags = 0;
103280103616
Bitmask used = 0;
103281103617
103282103618
/* The following variables are populated based on the properties of
@@ -103312,18 +103648,16 @@
103312103648
** Set to true if there was at least one "x IN (SELECT ...)" term used
103313103649
** in determining the value of nInMul. Note that the RHS of the
103314103650
** IN operator must be a SELECT, not a value list, for this variable
103315103651
** to be true.
103316103652
**
103317
- ** estBound:
103318
- ** An estimate on the amount of the table that must be searched. A
103319
- ** value of 100 means the entire table is searched. Range constraints
103320
- ** might reduce this to a value less than 100 to indicate that only
103321
- ** a fraction of the table needs searching. In the absence of
103322
- ** sqlite_stat2 ANALYZE data, a single inequality reduces the search
103323
- ** space to 1/4rd its original size. So an x>? constraint reduces
103324
- ** estBound to 25. Two constraints (x>? AND x<?) reduce estBound to 6.
103653
+ ** rangeDiv:
103654
+ ** An estimate of a divisor by which to reduce the search space due
103655
+ ** to inequality constraints. In the absence of sqlite_stat3 ANALYZE
103656
+ ** data, a single inequality reduces the search space to 1/4rd its
103657
+ ** original size (rangeDiv==4). Two inequalities reduce the search
103658
+ ** space to 1/16th of its original size (rangeDiv==16).
103325103659
**
103326103660
** bSort:
103327103661
** Boolean. True if there is an ORDER BY clause that will require an
103328103662
** external sort (i.e. scanning the index being evaluated will not
103329103663
** correctly order records).
@@ -103344,26 +103678,27 @@
103344103678
** SELECT a, b, c FROM tbl WHERE a = 1;
103345103679
*/
103346103680
int nEq; /* Number of == or IN terms matching index */
103347103681
int bInEst = 0; /* True if "x IN (SELECT...)" seen */
103348103682
int nInMul = 1; /* Number of distinct equalities to lookup */
103349
- int estBound = 100; /* Estimated reduction in search space */
103683
+ double rangeDiv = (double)1; /* Estimated reduction in search space */
103350103684
int nBound = 0; /* Number of range constraints seen */
103351103685
int bSort = !!pOrderBy; /* True if external sort required */
103352103686
int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */
103353103687
int bLookup = 0; /* True if not a covering index */
103354103688
WhereTerm *pTerm; /* A single term of the WHERE clause */
103355
-#ifdef SQLITE_ENABLE_STAT2
103689
+#ifdef SQLITE_ENABLE_STAT3
103356103690
WhereTerm *pFirstTerm = 0; /* First term matching the index */
103357103691
#endif
103358103692
103359103693
/* Determine the values of nEq and nInMul */
103360103694
for(nEq=0; nEq<pProbe->nColumn; nEq++){
103361103695
int j = pProbe->aiColumn[nEq];
103362103696
pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
103363103697
if( pTerm==0 ) break;
103364103698
wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
103699
+ testcase( pTerm->pWC!=pWC );
103365103700
if( pTerm->eOperator & WO_IN ){
103366103701
Expr *pExpr = pTerm->pExpr;
103367103702
wsFlags |= WHERE_COLUMN_IN;
103368103703
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
103369103704
/* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */
@@ -103374,32 +103709,34 @@
103374103709
nInMul *= pExpr->x.pList->nExpr;
103375103710
}
103376103711
}else if( pTerm->eOperator & WO_ISNULL ){
103377103712
wsFlags |= WHERE_COLUMN_NULL;
103378103713
}
103379
-#ifdef SQLITE_ENABLE_STAT2
103714
+#ifdef SQLITE_ENABLE_STAT3
103380103715
if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
103381103716
#endif
103382103717
used |= pTerm->prereqRight;
103383103718
}
103384103719
103385
- /* Determine the value of estBound. */
103720
+ /* Determine the value of rangeDiv */
103386103721
if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
103387103722
int j = pProbe->aiColumn[nEq];
103388103723
if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
103389103724
WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
103390103725
WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
103391
- whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
103726
+ whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
103392103727
if( pTop ){
103393103728
nBound = 1;
103394103729
wsFlags |= WHERE_TOP_LIMIT;
103395103730
used |= pTop->prereqRight;
103731
+ testcase( pTop->pWC!=pWC );
103396103732
}
103397103733
if( pBtm ){
103398103734
nBound++;
103399103735
wsFlags |= WHERE_BTM_LIMIT;
103400103736
used |= pBtm->prereqRight;
103737
+ testcase( pBtm->pWC!=pWC );
103401103738
}
103402103739
wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
103403103740
}
103404103741
}else if( pProbe->onError!=OE_None ){
103405103742
testcase( wsFlags & WHERE_COLUMN_IN );
@@ -103458,32 +103795,34 @@
103458103795
if( bInEst && nRow*2>aiRowEst[0] ){
103459103796
nRow = aiRowEst[0]/2;
103460103797
nInMul = (int)(nRow / aiRowEst[nEq]);
103461103798
}
103462103799
103463
-#ifdef SQLITE_ENABLE_STAT2
103800
+#ifdef SQLITE_ENABLE_STAT3
103464103801
/* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
103465103802
** and we do not think that values of x are unique and if histogram
103466103803
** data is available for column x, then it might be possible
103467103804
** to get a better estimate on the number of rows based on
103468103805
** VALUE and how common that value is according to the histogram.
103469103806
*/
103470103807
if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
103808
+ assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
103471103809
if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
103472103810
testcase( pFirstTerm->eOperator==WO_EQ );
103473103811
testcase( pFirstTerm->eOperator==WO_ISNULL );
103474103812
whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
103475
- }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){
103813
+ }else if( bInEst==0 ){
103814
+ assert( pFirstTerm->eOperator==WO_IN );
103476103815
whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
103477103816
}
103478103817
}
103479
-#endif /* SQLITE_ENABLE_STAT2 */
103818
+#endif /* SQLITE_ENABLE_STAT3 */
103480103819
103481103820
/* Adjust the number of output rows and downward to reflect rows
103482103821
** that are excluded by range constraints.
103483103822
*/
103484
- nRow = (nRow * (double)estBound) / (double)100;
103823
+ nRow = nRow/rangeDiv;
103485103824
if( nRow<1 ) nRow = 1;
103486103825
103487103826
/* Experiments run on real SQLite databases show that the time needed
103488103827
** to do a binary search to locate a row in a table or index is roughly
103489103828
** log10(N) times the time to move from one row to the next row within
@@ -103608,14 +103947,14 @@
103608103947
if( nRow<2 ) nRow = 2;
103609103948
}
103610103949
103611103950
103612103951
WHERETRACE((
103613
- "%s(%s): nEq=%d nInMul=%d estBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
103952
+ "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
103614103953
" notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
103615103954
pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"),
103616
- nEq, nInMul, estBound, bSort, bLookup, wsFlags,
103955
+ nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
103617103956
notReady, log10N, nRow, cost, used
103618103957
));
103619103958
103620103959
/* If this index is the best we have seen so far, then record this
103621103960
** index and its cost in the pCost structure.
@@ -104115,11 +104454,12 @@
104115104454
*/
104116104455
static Bitmask codeOneLoopStart(
104117104456
WhereInfo *pWInfo, /* Complete information about the WHERE clause */
104118104457
int iLevel, /* Which level of pWInfo->a[] should be coded */
104119104458
u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
104120
- Bitmask notReady /* Which tables are currently available */
104459
+ Bitmask notReady, /* Which tables are currently available */
104460
+ Expr *pWhere /* Complete WHERE clause */
104121104461
){
104122104462
int j, k; /* Loop counters */
104123104463
int iCur; /* The VDBE cursor for the table */
104124104464
int addrNxt; /* Where to jump to continue with the next IN case */
104125104465
int omitTable; /* True if we use the index only */
@@ -104597,11 +104937,12 @@
104597104937
int regRowset = 0; /* Register for RowSet object */
104598104938
int regRowid = 0; /* Register holding rowid */
104599104939
int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
104600104940
int iRetInit; /* Address of regReturn init */
104601104941
int untestedTerms = 0; /* Some terms not completely tested */
104602
- int ii;
104942
+ int ii; /* Loop counter */
104943
+ Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
104603104944
104604104945
pTerm = pLevel->plan.u.pTerm;
104605104946
assert( pTerm!=0 );
104606104947
assert( pTerm->eOperator==WO_OR );
104607104948
assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -104646,18 +104987,33 @@
104646104987
regRowset = ++pParse->nMem;
104647104988
regRowid = ++pParse->nMem;
104648104989
sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
104649104990
}
104650104991
iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
104992
+
104993
+ /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
104994
+ ** Then for every term xN, evaluate as the subexpression: xN AND z
104995
+ ** That way, terms in y that are factored into the disjunction will
104996
+ ** be picked up by the recursive calls to sqlite3WhereBegin() below.
104997
+ */
104998
+ if( pWC->nTerm>1 ){
104999
+ pAndExpr = sqlite3ExprAlloc(pParse->db, TK_AND, 0, 0);
105000
+ pAndExpr->pRight = pWhere;
105001
+ }
104651105002
104652105003
for(ii=0; ii<pOrWc->nTerm; ii++){
104653105004
WhereTerm *pOrTerm = &pOrWc->a[ii];
104654105005
if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
104655105006
WhereInfo *pSubWInfo; /* Info for single OR-term scan */
105007
+ Expr *pOrExpr = pOrTerm->pExpr;
105008
+ if( pAndExpr ){
105009
+ pAndExpr->pLeft = pOrExpr;
105010
+ pOrExpr = pAndExpr;
105011
+ }
104656105012
/* Loop through table entries that match term pOrTerm. */
104657
- pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrTerm->pExpr, 0, 0,
104658
- WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE |
105013
+ pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
105014
+ WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
104659105015
WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY);
104660105016
if( pSubWInfo ){
104661105017
explainOneScan(
104662105018
pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
104663105019
);
@@ -104681,10 +105037,11 @@
104681105037
/* Finish the loop through table entries that match term pOrTerm. */
104682105038
sqlite3WhereEnd(pSubWInfo);
104683105039
}
104684105040
}
104685105041
}
105042
+ sqlite3DbFree(pParse->db, pAndExpr);
104686105043
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
104687105044
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
104688105045
sqlite3VdbeResolveLabel(v, iLoopBody);
104689105046
104690105047
if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
@@ -104962,11 +105319,11 @@
104962105319
104963105320
/* Split the WHERE clause into separate subexpressions where each
104964105321
** subexpression is separated by an AND operator.
104965105322
*/
104966105323
initMaskSet(pMaskSet);
104967
- whereClauseInit(pWC, pParse, pMaskSet);
105324
+ whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags);
104968105325
sqlite3ExprCodeConstants(pParse, pWhere);
104969105326
whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
104970105327
104971105328
/* Special case: a WHERE clause that is constant. Evaluate the
104972105329
** expression and either jump over all of the code or fall thru.
@@ -105201,11 +105558,12 @@
105201105558
assert( bestJ>=0 );
105202105559
assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
105203105560
WHERETRACE(("*** Optimizer selects table %d for loop %d"
105204105561
" with cost=%g and nRow=%g\n",
105205105562
bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
105206
- if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
105563
+ /* The ALWAYS() that follows was added to hush up clang scan-build */
105564
+ if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
105207105565
*ppOrderBy = 0;
105208105566
}
105209105567
if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
105210105568
assert( pWInfo->eDistinct==0 );
105211105569
pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -105290,11 +105648,11 @@
105290105648
int iCur = pTabItem->iCursor;
105291105649
sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
105292105650
}else
105293105651
#endif
105294105652
if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
105295
- && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){
105653
+ && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
105296105654
int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
105297105655
sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
105298105656
testcase( pTab->nCol==BMS-1 );
105299105657
testcase( pTab->nCol==BMS );
105300105658
if( !pWInfo->okOnePass && pTab->nCol<BMS ){
@@ -105335,11 +105693,11 @@
105335105693
*/
105336105694
notReady = ~(Bitmask)0;
105337105695
for(i=0; i<nTabList; i++){
105338105696
pLevel = &pWInfo->a[i];
105339105697
explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
105340
- notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
105698
+ notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere);
105341105699
pWInfo->iContinue = pLevel->addrCont;
105342105700
}
105343105701
105344105702
#ifdef SQLITE_TEST /* For testing and debugging use only */
105345105703
/* Record in the query plan information about the current table
@@ -105470,11 +105828,11 @@
105470105828
struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
105471105829
Table *pTab = pTabItem->pTab;
105472105830
assert( pTab!=0 );
105473105831
if( (pTab->tabFlags & TF_Ephemeral)==0
105474105832
&& pTab->pSelect==0
105475
- && (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0
105833
+ && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
105476105834
){
105477105835
int ws = pLevel->plan.wsFlags;
105478105836
if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
105479105837
sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
105480105838
}
@@ -108817,11 +109175,13 @@
108817109175
sqlite3ParserTOKENTYPE yyminor /* The value for the token */
108818109176
sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
108819109177
){
108820109178
YYMINORTYPE yyminorunion;
108821109179
int yyact; /* The parser action. */
109180
+#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
108822109181
int yyendofinput; /* True if we are at the end of input */
109182
+#endif
108823109183
#ifdef YYERRORSYMBOL
108824109184
int yyerrorhit = 0; /* True if yymajor has invoked an error */
108825109185
#endif
108826109186
yyParser *yypParser; /* The parser */
108827109187
@@ -108840,11 +109200,13 @@
108840109200
yypParser->yyerrcnt = -1;
108841109201
yypParser->yystack[0].stateno = 0;
108842109202
yypParser->yystack[0].major = 0;
108843109203
}
108844109204
yyminorunion.yy0 = yyminor;
109205
+#if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
108845109206
yyendofinput = (yymajor==0);
109207
+#endif
108846109208
sqlite3ParserARG_STORE;
108847109209
108848109210
#ifndef NDEBUG
108849109211
if( yyTraceFILE ){
108850109212
fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
@@ -108852,11 +109214,10 @@
108852109214
#endif
108853109215
108854109216
do{
108855109217
yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
108856109218
if( yyact<YYNSTATE ){
108857
- assert( !yyendofinput ); /* Impossible to shift the $ token */
108858109219
yy_shift(yypParser,yyact,yymajor,&yyminorunion);
108859109220
yypParser->yyerrcnt--;
108860109221
yymajor = YYNOCODE;
108861109222
}else if( yyact < YYNSTATE + YYNRULE ){
108862109223
yy_reduce(yypParser,yyact-YYNSTATE);
@@ -110244,11 +110605,11 @@
110244110605
**
110245110606
** * Recursive calls to this routine from thread X return immediately
110246110607
** without blocking.
110247110608
*/
110248110609
SQLITE_API int sqlite3_initialize(void){
110249
- sqlite3_mutex *pMaster; /* The main static mutex */
110610
+ MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
110250110611
int rc; /* Result code */
110251110612
110252110613
#ifdef SQLITE_OMIT_WSD
110253110614
rc = sqlite3_wsd_init(4096, 24);
110254110615
if( rc!=SQLITE_OK ){
@@ -110278,11 +110639,11 @@
110278110639
** This operation is protected by the STATIC_MASTER mutex. Note that
110279110640
** MutexAlloc() is called for a static mutex prior to initializing the
110280110641
** malloc subsystem - this implies that the allocation of a static
110281110642
** mutex must not require support from the malloc subsystem.
110282110643
*/
110283
- pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
110644
+ MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
110284110645
sqlite3_mutex_enter(pMaster);
110285110646
sqlite3GlobalConfig.isMutexInit = 1;
110286110647
if( !sqlite3GlobalConfig.isMallocInit ){
110287110648
rc = sqlite3MallocInit();
110288110649
}
@@ -111352,17 +111713,17 @@
111352111713
sqlite3 *db,
111353111714
const char *zName,
111354111715
int nArg
111355111716
){
111356111717
int nName = sqlite3Strlen30(zName);
111357
- int rc;
111718
+ int rc = SQLITE_OK;
111358111719
sqlite3_mutex_enter(db->mutex);
111359111720
if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
111360
- sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
111361
- 0, sqlite3InvalidFunction, 0, 0, 0);
111721
+ rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
111722
+ 0, sqlite3InvalidFunction, 0, 0, 0);
111362111723
}
111363
- rc = sqlite3ApiExit(db, SQLITE_OK);
111724
+ rc = sqlite3ApiExit(db, rc);
111364111725
sqlite3_mutex_leave(db->mutex);
111365111726
return rc;
111366111727
}
111367111728
111368111729
#ifndef SQLITE_OMIT_TRACE
@@ -112420,10 +112781,11 @@
112420112781
if( db ){
112421112782
assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
112422112783
sqlite3_mutex_leave(db->mutex);
112423112784
}
112424112785
rc = sqlite3_errcode(db);
112786
+ assert( db!=0 || rc==SQLITE_NOMEM );
112425112787
if( rc==SQLITE_NOMEM ){
112426112788
sqlite3_close(db);
112427112789
db = 0;
112428112790
}else if( rc!=SQLITE_OK ){
112429112791
db->magic = SQLITE_MAGIC_SICK;
@@ -114148,10 +114510,17 @@
114148114510
#else
114149114511
# define TESTONLY(X)
114150114512
#endif
114151114513
114152114514
#endif /* SQLITE_AMALGAMATION */
114515
+
114516
+#ifdef SQLITE_DEBUG
114517
+SQLITE_PRIVATE int sqlite3Fts3Corrupt(void);
114518
+# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt()
114519
+#else
114520
+# define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB
114521
+#endif
114153114522
114154114523
typedef struct Fts3Table Fts3Table;
114155114524
typedef struct Fts3Cursor Fts3Cursor;
114156114525
typedef struct Fts3Expr Fts3Expr;
114157114526
typedef struct Fts3Phrase Fts3Phrase;
@@ -114176,10 +114545,11 @@
114176114545
const char *zDb; /* logical database name */
114177114546
const char *zName; /* virtual table name */
114178114547
int nColumn; /* number of named columns in virtual table */
114179114548
char **azColumn; /* column names. malloced */
114180114549
sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */
114550
+ char *zContentTbl; /* content=xxx option, or NULL */
114181114551
114182114552
/* Precompiled statements used by the implementation. Each of these
114183114553
** statements is run and reset within a single virtual table API call.
114184114554
*/
114185114555
sqlite3_stmt *aStmt[27];
@@ -114216,11 +114586,11 @@
114216114586
} *aIndex;
114217114587
int nMaxPendingData; /* Max pending data before flush to disk */
114218114588
int nPendingData; /* Current bytes of pending data */
114219114589
sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
114220114590
114221
-#if defined(SQLITE_DEBUG)
114591
+#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
114222114592
/* State variables used for validating that the transaction control
114223114593
** methods of the virtual table are called at appropriate times. These
114224114594
** values do not contribution to the FTS computation; they are used for
114225114595
** verifying the SQLite core.
114226114596
*/
@@ -114301,10 +114671,11 @@
114301114671
*/
114302114672
struct Fts3PhraseToken {
114303114673
char *z; /* Text of the token */
114304114674
int n; /* Number of bytes in buffer z */
114305114675
int isPrefix; /* True if token ends with a "*" character */
114676
+ int bFirst; /* True if token must appear at position 0 */
114306114677
114307114678
/* Variables above this point are populated when the expression is
114308114679
** parsed (by code in fts3_expr.c). Below this point the variables are
114309114680
** used when evaluating the expression. */
114310114681
Fts3DeferredToken *pDeferred; /* Deferred token object for this token */
@@ -114419,10 +114790,11 @@
114419114790
#define FTS3_SEGMENT_REQUIRE_POS 0x00000001
114420114791
#define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002
114421114792
#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
114422114793
#define FTS3_SEGMENT_PREFIX 0x00000008
114423114794
#define FTS3_SEGMENT_SCAN 0x00000010
114795
+#define FTS3_SEGMENT_FIRST 0x00000020
114424114796
114425114797
/* Type passed as 4th argument to SegmentReaderIterate() */
114426114798
struct Fts3SegFilter {
114427114799
const char *zTerm;
114428114800
int nTerm;
@@ -114458,12 +114830,12 @@
114458114830
SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
114459114831
SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
114460114832
SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
114461114833
SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
114462114834
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
114463
-
114464114835
SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
114836
+SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
114465114837
114466114838
/* fts3_tokenizer.c */
114467114839
SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
114468114840
SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
114469114841
SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -114478,11 +114850,11 @@
114478114850
);
114479114851
SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
114480114852
114481114853
/* fts3_expr.c */
114482114854
SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *,
114483
- char **, int, int, const char *, int, Fts3Expr **
114855
+ char **, int, int, int, const char *, int, Fts3Expr **
114484114856
);
114485114857
SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
114486114858
#ifdef SQLITE_TEST
114487114859
SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
114488114860
SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
@@ -114649,11 +115021,11 @@
114649115021
char **pp,
114650115022
char *pStart,
114651115023
sqlite3_int64 *pVal
114652115024
){
114653115025
sqlite3_int64 iVal;
114654
- char *p = *pp;
115026
+ char *p;
114655115027
114656115028
/* Pointer p now points at the first byte past the varint we are
114657115029
** interested in. So, unless the doclist is corrupt, the 0x80 bit is
114658115030
** clear on character p[-1]. */
114659115031
for(p = (*pp)-2; p>=pStart && *p&0x80; p--);
@@ -114679,10 +115051,11 @@
114679115051
sqlite3_finalize(p->aStmt[i]);
114680115052
}
114681115053
sqlite3_free(p->zSegmentsTbl);
114682115054
sqlite3_free(p->zReadExprlist);
114683115055
sqlite3_free(p->zWriteExprlist);
115056
+ sqlite3_free(p->zContentTbl);
114684115057
114685115058
/* Invoke the tokenizer destructor to free the tokenizer. */
114686115059
p->pTokenizer->pModule->xDestroy(p->pTokenizer);
114687115060
114688115061
sqlite3_free(p);
@@ -114718,20 +115091,23 @@
114718115091
114719115092
/*
114720115093
** The xDestroy() virtual table method.
114721115094
*/
114722115095
static int fts3DestroyMethod(sqlite3_vtab *pVtab){
114723
- int rc = SQLITE_OK; /* Return code */
114724115096
Fts3Table *p = (Fts3Table *)pVtab;
114725
- sqlite3 *db = p->db;
115097
+ int rc = SQLITE_OK; /* Return code */
115098
+ const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */
115099
+ sqlite3 *db = p->db; /* Database handle */
114726115100
114727115101
/* Drop the shadow tables */
114728
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", p->zDb, p->zName);
114729
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", p->zDb,p->zName);
114730
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", p->zDb, p->zName);
114731
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", p->zDb, p->zName);
114732
- fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", p->zDb, p->zName);
115102
+ if( p->zContentTbl==0 ){
115103
+ fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
115104
+ }
115105
+ fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
115106
+ fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
115107
+ fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
115108
+ fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
114733115109
114734115110
/* If everything has worked, invoke fts3DisconnectMethod() to free the
114735115111
** memory associated with the Fts3Table structure and return SQLITE_OK.
114736115112
** Otherwise, return an SQLite error code.
114737115113
*/
@@ -114789,27 +115165,31 @@
114789115165
** %_stat tables required by FTS4.
114790115166
*/
114791115167
static int fts3CreateTables(Fts3Table *p){
114792115168
int rc = SQLITE_OK; /* Return code */
114793115169
int i; /* Iterator variable */
114794
- char *zContentCols; /* Columns of %_content table */
114795115170
sqlite3 *db = p->db; /* The database connection */
114796115171
114797
- /* Create a list of user columns for the content table */
114798
- zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
114799
- for(i=0; zContentCols && i<p->nColumn; i++){
114800
- char *z = p->azColumn[i];
114801
- zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
114802
- }
114803
- if( zContentCols==0 ) rc = SQLITE_NOMEM;
114804
-
114805
- /* Create the content table */
114806
- fts3DbExec(&rc, db,
114807
- "CREATE TABLE %Q.'%q_content'(%s)",
114808
- p->zDb, p->zName, zContentCols
114809
- );
114810
- sqlite3_free(zContentCols);
115172
+ if( p->zContentTbl==0 ){
115173
+ char *zContentCols; /* Columns of %_content table */
115174
+
115175
+ /* Create a list of user columns for the content table */
115176
+ zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
115177
+ for(i=0; zContentCols && i<p->nColumn; i++){
115178
+ char *z = p->azColumn[i];
115179
+ zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
115180
+ }
115181
+ if( zContentCols==0 ) rc = SQLITE_NOMEM;
115182
+
115183
+ /* Create the content table */
115184
+ fts3DbExec(&rc, db,
115185
+ "CREATE TABLE %Q.'%q_content'(%s)",
115186
+ p->zDb, p->zName, zContentCols
115187
+ );
115188
+ sqlite3_free(zContentCols);
115189
+ }
115190
+
114811115191
/* Create other tables */
114812115192
fts3DbExec(&rc, db,
114813115193
"CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
114814115194
p->zDb, p->zName
114815115195
);
@@ -114956,12 +115336,12 @@
114956115336
}
114957115337
return zRet;
114958115338
}
114959115339
114960115340
/*
114961
-** Return a list of comma separated SQL expressions that could be used
114962
-** in a SELECT statement such as the following:
115341
+** Return a list of comma separated SQL expressions and a FROM clause that
115342
+** could be used in a SELECT statement such as the following:
114963115343
**
114964115344
** SELECT <list of expressions> FROM %_content AS x ...
114965115345
**
114966115346
** to return the docid, followed by each column of text data in order
114967115347
** from left to write. If parameter zFunc is not NULL, then instead of
@@ -114968,11 +115348,11 @@
114968115348
** being returned directly each column of text data is passed to an SQL
114969115349
** function named zFunc first. For example, if zFunc is "unzip" and the
114970115350
** table has the three user-defined columns "a", "b", and "c", the following
114971115351
** string is returned:
114972115352
**
114973
-** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c')"
115353
+** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x"
114974115354
**
114975115355
** The pointer returned points to a buffer allocated by sqlite3_malloc(). It
114976115356
** is the responsibility of the caller to eventually free it.
114977115357
**
114978115358
** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and
@@ -114984,20 +115364,32 @@
114984115364
char *zRet = 0;
114985115365
char *zFree = 0;
114986115366
char *zFunction;
114987115367
int i;
114988115368
114989
- if( !zFunc ){
114990
- zFunction = "";
115369
+ if( p->zContentTbl==0 ){
115370
+ if( !zFunc ){
115371
+ zFunction = "";
115372
+ }else{
115373
+ zFree = zFunction = fts3QuoteId(zFunc);
115374
+ }
115375
+ fts3Appendf(pRc, &zRet, "docid");
115376
+ for(i=0; i<p->nColumn; i++){
115377
+ fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
115378
+ }
115379
+ sqlite3_free(zFree);
114991115380
}else{
114992
- zFree = zFunction = fts3QuoteId(zFunc);
115381
+ fts3Appendf(pRc, &zRet, "rowid");
115382
+ for(i=0; i<p->nColumn; i++){
115383
+ fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]);
115384
+ }
114993115385
}
114994
- fts3Appendf(pRc, &zRet, "docid");
114995
- for(i=0; i<p->nColumn; i++){
114996
- fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
114997
- }
114998
- sqlite3_free(zFree);
115386
+ fts3Appendf(pRc, &zRet, "FROM '%q'.'%q%s' AS x",
115387
+ p->zDb,
115388
+ (p->zContentTbl ? p->zContentTbl : p->zName),
115389
+ (p->zContentTbl ? "" : "_content")
115390
+ );
114999115391
return zRet;
115000115392
}
115001115393
115002115394
/*
115003115395
** Return a list of N comma separated question marks, where N is the number
@@ -115050,11 +115442,11 @@
115050115442
** the output value undefined. Otherwise SQLITE_OK is returned.
115051115443
**
115052115444
** This function is used when parsing the "prefix=" FTS4 parameter.
115053115445
*/
115054115446
static int fts3GobbleInt(const char **pp, int *pnOut){
115055
- const char *p = *pp; /* Iterator pointer */
115447
+ const char *p; /* Iterator pointer */
115056115448
int nInt = 0; /* Output value */
115057115449
115058115450
for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
115059115451
nInt = nInt * 10 + (p[0] - '0');
115060115452
}
@@ -115116,10 +115508,95 @@
115116115508
}
115117115509
}
115118115510
115119115511
return SQLITE_OK;
115120115512
}
115513
+
115514
+/*
115515
+** This function is called when initializing an FTS4 table that uses the
115516
+** content=xxx option. It determines the number of and names of the columns
115517
+** of the new FTS4 table.
115518
+**
115519
+** The third argument passed to this function is the value passed to the
115520
+** config=xxx option (i.e. "xxx"). This function queries the database for
115521
+** a table of that name. If found, the output variables are populated
115522
+** as follows:
115523
+**
115524
+** *pnCol: Set to the number of columns table xxx has,
115525
+**
115526
+** *pnStr: Set to the total amount of space required to store a copy
115527
+** of each columns name, including the nul-terminator.
115528
+**
115529
+** *pazCol: Set to point to an array of *pnCol strings. Each string is
115530
+** the name of the corresponding column in table xxx. The array
115531
+** and its contents are allocated using a single allocation. It
115532
+** is the responsibility of the caller to free this allocation
115533
+** by eventually passing the *pazCol value to sqlite3_free().
115534
+**
115535
+** If the table cannot be found, an error code is returned and the output
115536
+** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is
115537
+** returned (and the output variables are undefined).
115538
+*/
115539
+static int fts3ContentColumns(
115540
+ sqlite3 *db, /* Database handle */
115541
+ const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */
115542
+ const char *zTbl, /* Name of content table */
115543
+ const char ***pazCol, /* OUT: Malloc'd array of column names */
115544
+ int *pnCol, /* OUT: Size of array *pazCol */
115545
+ int *pnStr /* OUT: Bytes of string content */
115546
+){
115547
+ int rc = SQLITE_OK; /* Return code */
115548
+ char *zSql; /* "SELECT *" statement on zTbl */
115549
+ sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */
115550
+
115551
+ zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
115552
+ if( !zSql ){
115553
+ rc = SQLITE_NOMEM;
115554
+ }else{
115555
+ rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
115556
+ }
115557
+ sqlite3_free(zSql);
115558
+
115559
+ if( rc==SQLITE_OK ){
115560
+ const char **azCol; /* Output array */
115561
+ int nStr = 0; /* Size of all column names (incl. 0x00) */
115562
+ int nCol; /* Number of table columns */
115563
+ int i; /* Used to iterate through columns */
115564
+
115565
+ /* Loop through the returned columns. Set nStr to the number of bytes of
115566
+ ** space required to store a copy of each column name, including the
115567
+ ** nul-terminator byte. */
115568
+ nCol = sqlite3_column_count(pStmt);
115569
+ for(i=0; i<nCol; i++){
115570
+ const char *zCol = sqlite3_column_name(pStmt, i);
115571
+ nStr += strlen(zCol) + 1;
115572
+ }
115573
+
115574
+ /* Allocate and populate the array to return. */
115575
+ azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
115576
+ if( azCol==0 ){
115577
+ rc = SQLITE_NOMEM;
115578
+ }else{
115579
+ char *p = (char *)&azCol[nCol];
115580
+ for(i=0; i<nCol; i++){
115581
+ const char *zCol = sqlite3_column_name(pStmt, i);
115582
+ int n = strlen(zCol)+1;
115583
+ memcpy(p, zCol, n);
115584
+ azCol[i] = p;
115585
+ p += n;
115586
+ }
115587
+ }
115588
+ sqlite3_finalize(pStmt);
115589
+
115590
+ /* Set the output variables. */
115591
+ *pnCol = nCol;
115592
+ *pnStr = nStr;
115593
+ *pazCol = azCol;
115594
+ }
115595
+
115596
+ return rc;
115597
+}
115121115598
115122115599
/*
115123115600
** This function is the implementation of both the xConnect and xCreate
115124115601
** methods of the FTS3 virtual table.
115125115602
**
@@ -115161,10 +115638,11 @@
115161115638
int bNoDocsize = 0; /* True to omit %_docsize table */
115162115639
int bDescIdx = 0; /* True to store descending indexes */
115163115640
char *zPrefix = 0; /* Prefix parameter value (or NULL) */
115164115641
char *zCompress = 0; /* compress=? parameter (or NULL) */
115165115642
char *zUncompress = 0; /* uncompress=? parameter (or NULL) */
115643
+ char *zContent = 0; /* content=? parameter (or NULL) */
115166115644
115167115645
assert( strlen(argv[0])==4 );
115168115646
assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
115169115647
|| (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4)
115170115648
);
@@ -115204,17 +115682,17 @@
115204115682
/* Check if it is an FTS4 special argument. */
115205115683
else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){
115206115684
struct Fts4Option {
115207115685
const char *zOpt;
115208115686
int nOpt;
115209
- char **pzVar;
115210115687
} aFts4Opt[] = {
115211
- { "matchinfo", 9, 0 }, /* 0 -> MATCHINFO */
115212
- { "prefix", 6, 0 }, /* 1 -> PREFIX */
115213
- { "compress", 8, 0 }, /* 2 -> COMPRESS */
115214
- { "uncompress", 10, 0 }, /* 3 -> UNCOMPRESS */
115215
- { "order", 5, 0 } /* 4 -> ORDER */
115688
+ { "matchinfo", 9 }, /* 0 -> MATCHINFO */
115689
+ { "prefix", 6 }, /* 1 -> PREFIX */
115690
+ { "compress", 8 }, /* 2 -> COMPRESS */
115691
+ { "uncompress", 10 }, /* 3 -> UNCOMPRESS */
115692
+ { "order", 5 }, /* 4 -> ORDER */
115693
+ { "content", 7 } /* 5 -> CONTENT */
115216115694
};
115217115695
115218115696
int iOpt;
115219115697
if( !zVal ){
115220115698
rc = SQLITE_NOMEM;
@@ -115256,17 +115734,24 @@
115256115734
zVal = 0;
115257115735
break;
115258115736
115259115737
case 4: /* ORDER */
115260115738
if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
115261
- && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 3))
115739
+ && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
115262115740
){
115263115741
*pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
115264115742
rc = SQLITE_ERROR;
115265115743
}
115266115744
bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
115267115745
break;
115746
+
115747
+ default: /* CONTENT */
115748
+ assert( iOpt==5 );
115749
+ sqlite3_free(zUncompress);
115750
+ zContent = zVal;
115751
+ zVal = 0;
115752
+ break;
115268115753
}
115269115754
}
115270115755
sqlite3_free(zVal);
115271115756
}
115272115757
}
@@ -115275,10 +115760,30 @@
115275115760
else {
115276115761
nString += (int)(strlen(z) + 1);
115277115762
aCol[nCol++] = z;
115278115763
}
115279115764
}
115765
+
115766
+ /* If a content=xxx option was specified, the following:
115767
+ **
115768
+ ** 1. Ignore any compress= and uncompress= options.
115769
+ **
115770
+ ** 2. If no column names were specified as part of the CREATE VIRTUAL
115771
+ ** TABLE statement, use all columns from the content table.
115772
+ */
115773
+ if( rc==SQLITE_OK && zContent ){
115774
+ sqlite3_free(zCompress);
115775
+ sqlite3_free(zUncompress);
115776
+ zCompress = 0;
115777
+ zUncompress = 0;
115778
+ if( nCol==0 ){
115779
+ sqlite3_free((void*)aCol);
115780
+ aCol = 0;
115781
+ rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
115782
+ }
115783
+ assert( rc!=SQLITE_OK || nCol>0 );
115784
+ }
115280115785
if( rc!=SQLITE_OK ) goto fts3_init_out;
115281115786
115282115787
if( nCol==0 ){
115283115788
assert( nString==0 );
115284115789
aCol[0] = "content";
@@ -115319,10 +115824,12 @@
115319115824
p->pTokenizer = pTokenizer;
115320115825
p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
115321115826
p->bHasDocsize = (isFts4 && bNoDocsize==0);
115322115827
p->bHasStat = isFts4;
115323115828
p->bDescIdx = bDescIdx;
115829
+ p->zContentTbl = zContent;
115830
+ zContent = 0;
115324115831
TESTONLY( p->inTransaction = -1 );
115325115832
TESTONLY( p->mxSavepoint = -1 );
115326115833
115327115834
p->aIndex = (struct Fts3Index *)&p->azColumn[nCol];
115328115835
memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex);
@@ -115380,10 +115887,11 @@
115380115887
fts3_init_out:
115381115888
sqlite3_free(zPrefix);
115382115889
sqlite3_free(aIndex);
115383115890
sqlite3_free(zCompress);
115384115891
sqlite3_free(zUncompress);
115892
+ sqlite3_free(zContent);
115385115893
sqlite3_free((void *)aCol);
115386115894
if( rc!=SQLITE_OK ){
115387115895
if( p ){
115388115896
fts3DisconnectMethod((sqlite3_vtab *)p);
115389115897
}else if( pTokenizer ){
@@ -115530,40 +116038,69 @@
115530116038
sqlite3_free(pCsr->aMatchinfo);
115531116039
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
115532116040
sqlite3_free(pCsr);
115533116041
return SQLITE_OK;
115534116042
}
116043
+
116044
+/*
116045
+** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then
116046
+** compose and prepare an SQL statement of the form:
116047
+**
116048
+** "SELECT <columns> FROM %_content WHERE rowid = ?"
116049
+**
116050
+** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
116051
+** it. If an error occurs, return an SQLite error code.
116052
+**
116053
+** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
116054
+*/
116055
+static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
116056
+ int rc = SQLITE_OK;
116057
+ if( pCsr->pStmt==0 ){
116058
+ Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
116059
+ char *zSql;
116060
+ zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
116061
+ if( !zSql ) return SQLITE_NOMEM;
116062
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
116063
+ sqlite3_free(zSql);
116064
+ }
116065
+ *ppStmt = pCsr->pStmt;
116066
+ return rc;
116067
+}
115535116068
115536116069
/*
115537116070
** Position the pCsr->pStmt statement so that it is on the row
115538116071
** of the %_content table that contains the last match. Return
115539116072
** SQLITE_OK on success.
115540116073
*/
115541116074
static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
116075
+ int rc = SQLITE_OK;
115542116076
if( pCsr->isRequireSeek ){
115543
- sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
115544
- pCsr->isRequireSeek = 0;
115545
- if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
115546
- return SQLITE_OK;
115547
- }else{
115548
- int rc = sqlite3_reset(pCsr->pStmt);
115549
- if( rc==SQLITE_OK ){
115550
- /* If no row was found and no error has occured, then the %_content
115551
- ** table is missing a row that is present in the full-text index.
115552
- ** The data structures are corrupt.
115553
- */
115554
- rc = SQLITE_CORRUPT_VTAB;
115555
- }
115556
- pCsr->isEof = 1;
115557
- if( pContext ){
115558
- sqlite3_result_error_code(pContext, rc);
115559
- }
115560
- return rc;
115561
- }
115562
- }else{
115563
- return SQLITE_OK;
115564
- }
116077
+ sqlite3_stmt *pStmt = 0;
116078
+
116079
+ rc = fts3CursorSeekStmt(pCsr, &pStmt);
116080
+ if( rc==SQLITE_OK ){
116081
+ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
116082
+ pCsr->isRequireSeek = 0;
116083
+ if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
116084
+ return SQLITE_OK;
116085
+ }else{
116086
+ rc = sqlite3_reset(pCsr->pStmt);
116087
+ if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
116088
+ /* If no row was found and no error has occured, then the %_content
116089
+ ** table is missing a row that is present in the full-text index.
116090
+ ** The data structures are corrupt. */
116091
+ rc = FTS_CORRUPT_VTAB;
116092
+ pCsr->isEof = 1;
116093
+ }
116094
+ }
116095
+ }
116096
+ }
116097
+
116098
+ if( rc!=SQLITE_OK && pContext ){
116099
+ sqlite3_result_error_code(pContext, rc);
116100
+ }
116101
+ return rc;
115565116102
}
115566116103
115567116104
/*
115568116105
** This function is used to process a single interior node when searching
115569116106
** a b-tree for a term or term prefix. The node data is passed to this
@@ -115609,11 +116146,11 @@
115609116146
** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
115610116147
*/
115611116148
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
115612116149
zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
115613116150
if( zCsr>zEnd ){
115614
- return SQLITE_CORRUPT_VTAB;
116151
+ return FTS_CORRUPT_VTAB;
115615116152
}
115616116153
115617116154
while( zCsr<zEnd && (piFirst || piLast) ){
115618116155
int cmp; /* memcmp() result */
115619116156
int nSuffix; /* Size of term suffix */
@@ -115627,11 +116164,11 @@
115627116164
}
115628116165
isFirstTerm = 0;
115629116166
zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
115630116167
115631116168
if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
115632
- rc = SQLITE_CORRUPT_VTAB;
116169
+ rc = FTS_CORRUPT_VTAB;
115633116170
goto finish_scan;
115634116171
}
115635116172
if( nPrefix+nSuffix>nAlloc ){
115636116173
char *zNew;
115637116174
nAlloc = (nPrefix+nSuffix) * 2;
@@ -115640,10 +116177,11 @@
115640116177
rc = SQLITE_NOMEM;
115641116178
goto finish_scan;
115642116179
}
115643116180
zBuffer = zNew;
115644116181
}
116182
+ assert( zBuffer );
115645116183
memcpy(&zBuffer[nPrefix], zCsr, nSuffix);
115646116184
nBuffer = nPrefix + nSuffix;
115647116185
zCsr += nSuffix;
115648116186
115649116187
/* Compare the term we are searching for with the term just loaded from
@@ -115998,20 +116536,20 @@
115998116536
int isSaveLeft, /* Save the left position */
115999116537
int isExact, /* If *pp1 is exactly nTokens before *pp2 */
116000116538
char **pp1, /* IN/OUT: Left input list */
116001116539
char **pp2 /* IN/OUT: Right input list */
116002116540
){
116003
- char *p = (pp ? *pp : 0);
116541
+ char *p = *pp;
116004116542
char *p1 = *pp1;
116005116543
char *p2 = *pp2;
116006116544
int iCol1 = 0;
116007116545
int iCol2 = 0;
116008116546
116009116547
/* Never set both isSaveLeft and isExact for the same invocation. */
116010116548
assert( isSaveLeft==0 || isExact==0 );
116011116549
116012
- assert( *p1!=0 && *p2!=0 );
116550
+ assert( p!=0 && *p1!=0 && *p2!=0 );
116013116551
if( *p1==POS_COLUMN ){
116014116552
p1++;
116015116553
p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
116016116554
}
116017116555
if( *p2==POS_COLUMN ){
@@ -116024,11 +116562,11 @@
116024116562
char *pSave = p;
116025116563
sqlite3_int64 iPrev = 0;
116026116564
sqlite3_int64 iPos1 = 0;
116027116565
sqlite3_int64 iPos2 = 0;
116028116566
116029
- if( pp && iCol1 ){
116567
+ if( iCol1 ){
116030116568
*p++ = POS_COLUMN;
116031116569
p += sqlite3Fts3PutVarint(p, iCol1);
116032116570
}
116033116571
116034116572
assert( *p1!=POS_END && *p1!=POS_COLUMN );
@@ -116039,20 +116577,14 @@
116039116577
while( 1 ){
116040116578
if( iPos2==iPos1+nToken
116041116579
|| (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken)
116042116580
){
116043116581
sqlite3_int64 iSave;
116044
- if( !pp ){
116045
- fts3PoslistCopy(0, &p2);
116046
- fts3PoslistCopy(0, &p1);
116047
- *pp1 = p1;
116048
- *pp2 = p2;
116049
- return 1;
116050
- }
116051116582
iSave = isSaveLeft ? iPos1 : iPos2;
116052116583
fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2;
116053116584
pSave = 0;
116585
+ assert( p );
116054116586
}
116055116587
if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){
116056116588
if( (*p2&0xFE)==0 ) break;
116057116589
fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
116058116590
}else{
@@ -116097,11 +116629,11 @@
116097116629
116098116630
fts3PoslistCopy(0, &p2);
116099116631
fts3PoslistCopy(0, &p1);
116100116632
*pp1 = p1;
116101116633
*pp2 = p2;
116102
- if( !pp || *pp==p ){
116634
+ if( *pp==p ){
116103116635
return 0;
116104116636
}
116105116637
*p++ = 0x00;
116106116638
*pp = p;
116107116639
return 1;
@@ -116399,10 +116931,60 @@
116399116931
}
116400116932
}
116401116933
116402116934
*pnRight = p - aOut;
116403116935
}
116936
+
116937
+/*
116938
+** Argument pList points to a position list nList bytes in size. This
116939
+** function checks to see if the position list contains any entries for
116940
+** a token in position 0 (of any column). If so, it writes argument iDelta
116941
+** to the output buffer pOut, followed by a position list consisting only
116942
+** of the entries from pList at position 0, and terminated by an 0x00 byte.
116943
+** The value returned is the number of bytes written to pOut (if any).
116944
+*/
116945
+SQLITE_PRIVATE int sqlite3Fts3FirstFilter(
116946
+ sqlite3_int64 iDelta, /* Varint that may be written to pOut */
116947
+ char *pList, /* Position list (no 0x00 term) */
116948
+ int nList, /* Size of pList in bytes */
116949
+ char *pOut /* Write output here */
116950
+){
116951
+ int nOut = 0;
116952
+ int bWritten = 0; /* True once iDelta has been written */
116953
+ char *p = pList;
116954
+ char *pEnd = &pList[nList];
116955
+
116956
+ if( *p!=0x01 ){
116957
+ if( *p==0x02 ){
116958
+ nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
116959
+ pOut[nOut++] = 0x02;
116960
+ bWritten = 1;
116961
+ }
116962
+ fts3ColumnlistCopy(0, &p);
116963
+ }
116964
+
116965
+ while( p<pEnd && *p==0x01 ){
116966
+ sqlite3_int64 iCol;
116967
+ p++;
116968
+ p += sqlite3Fts3GetVarint(p, &iCol);
116969
+ if( *p==0x02 ){
116970
+ if( bWritten==0 ){
116971
+ nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
116972
+ bWritten = 1;
116973
+ }
116974
+ pOut[nOut++] = 0x01;
116975
+ nOut += sqlite3Fts3PutVarint(&pOut[nOut], iCol);
116976
+ pOut[nOut++] = 0x02;
116977
+ }
116978
+ fts3ColumnlistCopy(0, &p);
116979
+ }
116980
+ if( bWritten ){
116981
+ pOut[nOut++] = 0x00;
116982
+ }
116983
+
116984
+ return nOut;
116985
+}
116404116986
116405116987
116406116988
/*
116407116989
** Merge all doclists in the TermSelect.aaOutput[] array into a single
116408116990
** doclist stored in TermSelect.aaOutput[0]. If successful, delete all
@@ -116756,10 +117338,11 @@
116756117338
pSegcsr = pTok->pSegcsr;
116757117339
memset(&tsc, 0, sizeof(TermSelect));
116758117340
116759117341
filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS
116760117342
| (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0)
117343
+ | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0)
116761117344
| (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0);
116762117345
filter.iCol = iColumn;
116763117346
filter.zTerm = pTok->z;
116764117347
filter.nTerm = pTok->n;
116765117348
@@ -116896,12 +117479,12 @@
116896117479
116897117480
if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
116898117481
return SQLITE_NOMEM;
116899117482
}
116900117483
116901
- rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->nColumn,
116902
- iCol, zQuery, -1, &pCsr->pExpr
117484
+ rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->bHasStat,
117485
+ p->nColumn, iCol, zQuery, -1, &pCsr->pExpr
116903117486
);
116904117487
if( rc!=SQLITE_OK ){
116905117488
if( rc==SQLITE_ERROR ){
116906117489
static const char *zErr = "malformed MATCH expression: [%s]";
116907117490
p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery);
@@ -116924,26 +117507,27 @@
116924117507
** statement loops through all rows of the %_content table. For a
116925117508
** full-text query or docid lookup, the statement retrieves a single
116926117509
** row by docid.
116927117510
*/
116928117511
if( idxNum==FTS3_FULLSCAN_SEARCH ){
116929
- const char *zSort = (pCsr->bDesc ? "DESC" : "ASC");
116930
- const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x ORDER BY docid %s";
116931
- zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName, zSort);
116932
- }else{
116933
- const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x WHERE docid = ?";
116934
- zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName);
116935
- }
116936
- if( !zSql ) return SQLITE_NOMEM;
116937
- rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
116938
- sqlite3_free(zSql);
116939
- if( rc!=SQLITE_OK ) return rc;
116940
-
116941
- if( idxNum==FTS3_DOCID_SEARCH ){
116942
- rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
116943
- if( rc!=SQLITE_OK ) return rc;
116944
- }
117512
+ zSql = sqlite3_mprintf(
117513
+ "SELECT %s ORDER BY rowid %s",
117514
+ p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
117515
+ );
117516
+ if( zSql ){
117517
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
117518
+ sqlite3_free(zSql);
117519
+ }else{
117520
+ rc = SQLITE_NOMEM;
117521
+ }
117522
+ }else if( idxNum==FTS3_DOCID_SEARCH ){
117523
+ rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
117524
+ if( rc==SQLITE_OK ){
117525
+ rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
117526
+ }
117527
+ }
117528
+ if( rc!=SQLITE_OK ) return rc;
116945117529
116946117530
return fts3NextMethod(pCursor);
116947117531
}
116948117532
116949117533
/*
@@ -116992,11 +117576,11 @@
116992117576
** Return a blob which is a pointer to the cursor.
116993117577
*/
116994117578
sqlite3_result_blob(pContext, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
116995117579
}else{
116996117580
rc = fts3CursorSeek(0, pCsr);
116997
- if( rc==SQLITE_OK ){
117581
+ if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
116998117582
sqlite3_result_value(pContext, sqlite3_column_value(pCsr->pStmt, iCol+1));
116999117583
}
117000117584
}
117001117585
117002117586
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
@@ -117076,11 +117660,11 @@
117076117660
** moves *ppPoslist so that it instead points to the first byte of the
117077117661
** same position list.
117078117662
*/
117079117663
static void fts3ReversePoslist(char *pStart, char **ppPoslist){
117080117664
char *p = &(*ppPoslist)[-2];
117081
- char c;
117665
+ char c = 0;
117082117666
117083117667
while( p>pStart && (c=*p--)==0 );
117084117668
while( p>pStart && (*p & 0x80) | c ){
117085117669
c = *p--;
117086117670
}
@@ -117285,19 +117869,26 @@
117285117869
){
117286117870
Fts3Table *p = (Fts3Table *)pVtab;
117287117871
sqlite3 *db = p->db; /* Database connection */
117288117872
int rc; /* Return Code */
117289117873
117874
+ /* As it happens, the pending terms table is always empty here. This is
117875
+ ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction
117876
+ ** always opens a savepoint transaction. And the xSavepoint() method
117877
+ ** flushes the pending terms table. But leave the (no-op) call to
117878
+ ** PendingTermsFlush() in in case that changes.
117879
+ */
117880
+ assert( p->nPendingData==0 );
117290117881
rc = sqlite3Fts3PendingTermsFlush(p);
117291
- if( rc!=SQLITE_OK ){
117292
- return rc;
117882
+
117883
+ if( p->zContentTbl==0 ){
117884
+ fts3DbExec(&rc, db,
117885
+ "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';",
117886
+ p->zDb, p->zName, zName
117887
+ );
117293117888
}
117294117889
117295
- fts3DbExec(&rc, db,
117296
- "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';",
117297
- p->zDb, p->zName, zName
117298
- );
117299117890
if( p->bHasDocsize ){
117300117891
fts3DbExec(&rc, db,
117301117892
"ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';",
117302117893
p->zDb, p->zName, zName
117303117894
);
@@ -117652,25 +118243,24 @@
117652118243
**
117653118244
** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
117654118245
*/
117655118246
static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
117656118247
int iToken; /* Used to iterate through phrase tokens */
117657
- int rc = SQLITE_OK; /* Return code */
117658118248
char *aPoslist = 0; /* Position list for deferred tokens */
117659118249
int nPoslist = 0; /* Number of bytes in aPoslist */
117660118250
int iPrev = -1; /* Token number of previous deferred token */
117661118251
117662118252
assert( pPhrase->doclist.bFreeList==0 );
117663118253
117664
- for(iToken=0; rc==SQLITE_OK && iToken<pPhrase->nToken; iToken++){
118254
+ for(iToken=0; iToken<pPhrase->nToken; iToken++){
117665118255
Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
117666118256
Fts3DeferredToken *pDeferred = pToken->pDeferred;
117667118257
117668118258
if( pDeferred ){
117669118259
char *pList;
117670118260
int nList;
117671
- rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
118261
+ int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
117672118262
if( rc!=SQLITE_OK ) return rc;
117673118263
117674118264
if( pList==0 ){
117675118265
sqlite3_free(aPoslist);
117676118266
pPhrase->doclist.pList = 0;
@@ -117767,10 +118357,11 @@
117767118357
if( pCsr->bDesc==pTab->bDescIdx
117768118358
&& bOptOk==1
117769118359
&& p->nToken==1
117770118360
&& pFirst->pSegcsr
117771118361
&& pFirst->pSegcsr->bLookup
118362
+ && pFirst->bFirst==0
117772118363
){
117773118364
/* Use the incremental approach. */
117774118365
int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
117775118366
rc = sqlite3Fts3MsrIncrStart(
117776118367
pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
@@ -117996,11 +118587,11 @@
117996118587
Fts3Expr *pExpr, /* Expression to consider */
117997118588
Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */
117998118589
Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */
117999118590
int *pRc /* IN/OUT: Error code */
118000118591
){
118001
- if( *pRc==SQLITE_OK && pExpr ){
118592
+ if( *pRc==SQLITE_OK ){
118002118593
if( pExpr->eType==FTSQUERY_PHRASE ){
118003118594
Fts3Phrase *pPhrase = pExpr->pPhrase;
118004118595
int i;
118005118596
for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
118006118597
Fts3TokenAndCost *pTC = (*ppTC)++;
@@ -118010,10 +118601,15 @@
118010118601
pTC->pToken = &pPhrase->aToken[i];
118011118602
pTC->iCol = pPhrase->iColumn;
118012118603
*pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl);
118013118604
}
118014118605
}else if( pExpr->eType!=FTSQUERY_NOT ){
118606
+ assert( pExpr->eType==FTSQUERY_OR
118607
+ || pExpr->eType==FTSQUERY_AND
118608
+ || pExpr->eType==FTSQUERY_NEAR
118609
+ );
118610
+ assert( pExpr->pLeft && pExpr->pRight );
118015118611
if( pExpr->eType==FTSQUERY_OR ){
118016118612
pRoot = pExpr->pLeft;
118017118613
**ppOr = pRoot;
118018118614
(*ppOr)++;
118019118615
}
@@ -118070,11 +118666,11 @@
118070118666
while( a<pEnd ){
118071118667
a += sqlite3Fts3GetVarint(a, &nByte);
118072118668
}
118073118669
if( nDoc==0 || nByte==0 ){
118074118670
sqlite3_reset(pStmt);
118075
- return SQLITE_CORRUPT_VTAB;
118671
+ return FTS_CORRUPT_VTAB;
118076118672
}
118077118673
118078118674
pCsr->nDoc = nDoc;
118079118675
pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
118080118676
assert( pCsr->nRowAvg>0 );
@@ -118113,10 +118709,19 @@
118113118709
int nOvfl = 0; /* Total overflow pages used by doclists */
118114118710
int nToken = 0; /* Total number of tokens in cluster */
118115118711
118116118712
int nMinEst = 0; /* The minimum count for any phrase so far. */
118117118713
int nLoad4 = 1; /* (Phrases that will be loaded)^4. */
118714
+
118715
+ /* Tokens are never deferred for FTS tables created using the content=xxx
118716
+ ** option. The reason being that it is not guaranteed that the content
118717
+ ** table actually contains the same data as the index. To prevent this from
118718
+ ** causing any problems, the deferred token optimization is completely
118719
+ ** disabled for content=xxx tables. */
118720
+ if( pTab->zContentTbl ){
118721
+ return SQLITE_OK;
118722
+ }
118118118723
118119118724
/* Count the tokens in this AND/NEAR cluster. If none of the doclists
118120118725
** associated with the tokens spill onto overflow pages, or if there is
118121118726
** only 1 token, exit early. No tokens to defer in this case. */
118122118727
for(ii=0; ii<nTC; ii++){
@@ -118176,11 +118781,15 @@
118176118781
Fts3PhraseToken *pToken = pTC->pToken;
118177118782
rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
118178118783
fts3SegReaderCursorFree(pToken->pSegcsr);
118179118784
pToken->pSegcsr = 0;
118180118785
}else{
118181
- nLoad4 = nLoad4*4;
118786
+ /* Set nLoad4 to the value of (4^nOther) for the next iteration of the
118787
+ ** for-loop. Except, limit the value to 2^24 to prevent it from
118788
+ ** overflowing the 32-bit integer it is stored in. */
118789
+ if( ii<12 ) nLoad4 = nLoad4*4;
118790
+
118182118791
if( ii==0 || pTC->pPhrase->nToken>1 ){
118183118792
/* Either this is the cheapest token in the entire query, or it is
118184118793
** part of a multi-token phrase. Either way, the entire doclist will
118185118794
** (eventually) be loaded into memory. It may as well be now. */
118186118795
Fts3PhraseToken *pToken = pTC->pToken;
@@ -118546,12 +119155,15 @@
118546119155
}
118547119156
118548119157
aPoslist = pExpr->pRight->pPhrase->doclist.pList;
118549119158
nToken = pExpr->pRight->pPhrase->nToken;
118550119159
for(p=pExpr->pLeft; p && res; p=p->pLeft){
118551
- int nNear = p->pParent->nNear;
118552
- Fts3Phrase *pPhrase = (
119160
+ int nNear;
119161
+ Fts3Phrase *pPhrase;
119162
+ assert( p->pParent && p->pParent->pLeft==p );
119163
+ nNear = p->pParent->nNear;
119164
+ pPhrase = (
118553119165
p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
118554119166
);
118555119167
res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
118556119168
}
118557119169
}
@@ -119037,10 +119649,19 @@
119037119649
pPhrase->aToken[i].pSegcsr = 0;
119038119650
}
119039119651
}
119040119652
}
119041119653
119654
+/*
119655
+** Return SQLITE_CORRUPT_VTAB.
119656
+*/
119657
+#ifdef SQLITE_DEBUG
119658
+SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
119659
+ return SQLITE_CORRUPT_VTAB;
119660
+}
119661
+#endif
119662
+
119042119663
#if !SQLITE_CORE
119043119664
/*
119044119665
** Initialize API pointer table, if required.
119045119666
*/
119046119667
SQLITE_API int sqlite3_extension_init(
@@ -119625,10 +120246,11 @@
119625120246
*/
119626120247
typedef struct ParseContext ParseContext;
119627120248
struct ParseContext {
119628120249
sqlite3_tokenizer *pTokenizer; /* Tokenizer module */
119629120250
const char **azCol; /* Array of column names for fts3 table */
120251
+ int bFts4; /* True to allow FTS4-only syntax */
119630120252
int nCol; /* Number of entries in azCol[] */
119631120253
int iDefaultCol; /* Default column to query */
119632120254
int isNot; /* True if getNextNode() sees a unary - */
119633120255
sqlite3_context *pCtx; /* Write error message here */
119634120256
int nNest; /* Number of nested brackets */
@@ -119712,13 +120334,25 @@
119712120334
119713120335
if( iEnd<n && z[iEnd]=='*' ){
119714120336
pRet->pPhrase->aToken[0].isPrefix = 1;
119715120337
iEnd++;
119716120338
}
119717
- if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){
119718
- pParse->isNot = 1;
120339
+
120340
+ while( 1 ){
120341
+ if( !sqlite3_fts3_enable_parentheses
120342
+ && iStart>0 && z[iStart-1]=='-'
120343
+ ){
120344
+ pParse->isNot = 1;
120345
+ iStart--;
120346
+ }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){
120347
+ pRet->pPhrase->aToken[0].bFirst = 1;
120348
+ iStart--;
120349
+ }else{
120350
+ break;
120351
+ }
119719120352
}
120353
+
119720120354
}
119721120355
nConsumed = iEnd;
119722120356
}
119723120357
119724120358
pModule->xClose(pCursor);
@@ -119813,10 +120447,11 @@
119813120447
memcpy(&zTemp[nTemp], zByte, nByte);
119814120448
nTemp += nByte;
119815120449
119816120450
pToken->n = nByte;
119817120451
pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
120452
+ pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
119818120453
nToken = ii+1;
119819120454
}
119820120455
}
119821120456
119822120457
pModule->xClose(pCursor);
@@ -119834,12 +120469,16 @@
119834120469
p->pPhrase = (Fts3Phrase *)&p[1];
119835120470
p->pPhrase->iColumn = pParse->iDefaultCol;
119836120471
p->pPhrase->nToken = nToken;
119837120472
119838120473
zBuf = (char *)&p->pPhrase->aToken[nToken];
119839
- memcpy(zBuf, zTemp, nTemp);
119840
- sqlite3_free(zTemp);
120474
+ if( zTemp ){
120475
+ memcpy(zBuf, zTemp, nTemp);
120476
+ sqlite3_free(zTemp);
120477
+ }else{
120478
+ assert( nTemp==0 );
120479
+ }
119841120480
119842120481
for(jj=0; jj<p->pPhrase->nToken; jj++){
119843120482
p->pPhrase->aToken[jj].z = zBuf;
119844120483
zBuf += p->pPhrase->aToken[jj].n;
119845120484
}
@@ -120260,10 +120899,11 @@
120260120899
** match any table column.
120261120900
*/
120262120901
SQLITE_PRIVATE int sqlite3Fts3ExprParse(
120263120902
sqlite3_tokenizer *pTokenizer, /* Tokenizer module */
120264120903
char **azCol, /* Array of column names for fts3 table */
120904
+ int bFts4, /* True to allow FTS4-only syntax */
120265120905
int nCol, /* Number of entries in azCol[] */
120266120906
int iDefaultCol, /* Default column to query */
120267120907
const char *z, int n, /* Text of MATCH query */
120268120908
Fts3Expr **ppExpr /* OUT: Parsed query structure */
120269120909
){
@@ -120273,10 +120913,11 @@
120273120913
sParse.pTokenizer = pTokenizer;
120274120914
sParse.azCol = (const char **)azCol;
120275120915
sParse.nCol = nCol;
120276120916
sParse.iDefaultCol = iDefaultCol;
120277120917
sParse.nNest = 0;
120918
+ sParse.bFts4 = bFts4;
120278120919
if( z==0 ){
120279120920
*ppExpr = 0;
120280120921
return SQLITE_OK;
120281120922
}
120282120923
if( n<0 ){
@@ -120462,11 +121103,11 @@
120462121103
for(ii=0; ii<nCol; ii++){
120463121104
azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
120464121105
}
120465121106
120466121107
rc = sqlite3Fts3ExprParse(
120467
- pTokenizer, azCol, nCol, nCol, zExpr, nExpr, &pExpr
121108
+ pTokenizer, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
120468121109
);
120469121110
if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
120470121111
sqlite3_result_error(context, "Error parsing expression", -1);
120471121112
}else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
120472121113
sqlite3_result_error_nomem(context);
@@ -122509,11 +123150,11 @@
122509123150
/* 2 */ "DELETE FROM %Q.'%q_content'",
122510123151
/* 3 */ "DELETE FROM %Q.'%q_segments'",
122511123152
/* 4 */ "DELETE FROM %Q.'%q_segdir'",
122512123153
/* 5 */ "DELETE FROM %Q.'%q_docsize'",
122513123154
/* 6 */ "DELETE FROM %Q.'%q_stat'",
122514
-/* 7 */ "SELECT %s FROM %Q.'%q_content' AS x WHERE rowid=?",
123155
+/* 7 */ "SELECT %s WHERE rowid=?",
122515123156
/* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1",
122516123157
/* 9 */ "INSERT INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)",
122517123158
/* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)",
122518123159
/* 11 */ "INSERT INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)",
122519123160
@@ -122551,11 +123192,11 @@
122551123192
if( !pStmt ){
122552123193
char *zSql;
122553123194
if( eStmt==SQL_CONTENT_INSERT ){
122554123195
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
122555123196
}else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
122556
- zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist, p->zDb, p->zName);
123197
+ zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
122557123198
}else{
122558123199
zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
122559123200
}
122560123201
if( !zSql ){
122561123202
rc = SQLITE_NOMEM;
@@ -122594,11 +123235,11 @@
122594123235
sqlite3_bind_int64(pStmt, 1, iDocid);
122595123236
}
122596123237
rc = sqlite3_step(pStmt);
122597123238
if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
122598123239
rc = sqlite3_reset(pStmt);
122599
- if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT_VTAB;
123240
+ if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
122600123241
pStmt = 0;
122601123242
}else{
122602123243
rc = SQLITE_OK;
122603123244
}
122604123245
}
@@ -122662,21 +123303,28 @@
122662123303
** We try to avoid this because if FTS3 returns any error when committing
122663123304
** a transaction, the whole transaction will be rolled back. And this is
122664123305
** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
122665123306
** still happen if the user reads data directly from the %_segments or
122666123307
** %_segdir tables instead of going through FTS3 though.
123308
+**
123309
+** This reasoning does not apply to a content=xxx table.
122667123310
*/
122668123311
SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
122669123312
int rc; /* Return code */
122670123313
sqlite3_stmt *pStmt; /* Statement used to obtain lock */
122671123314
122672
- rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
122673
- if( rc==SQLITE_OK ){
122674
- sqlite3_bind_null(pStmt, 1);
122675
- sqlite3_step(pStmt);
122676
- rc = sqlite3_reset(pStmt);
123315
+ if( p->zContentTbl==0 ){
123316
+ rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
123317
+ if( rc==SQLITE_OK ){
123318
+ sqlite3_bind_null(pStmt, 1);
123319
+ sqlite3_step(pStmt);
123320
+ rc = sqlite3_reset(pStmt);
123321
+ }
123322
+ }else{
123323
+ rc = SQLITE_OK;
122677123324
}
123325
+
122678123326
return rc;
122679123327
}
122680123328
122681123329
/*
122682123330
** Set *ppStmt to a statement handle that may be used to iterate through
@@ -123032,10 +123680,22 @@
123032123680
sqlite3_value **apVal, /* Array of values to insert */
123033123681
sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */
123034123682
){
123035123683
int rc; /* Return code */
123036123684
sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */
123685
+
123686
+ if( p->zContentTbl ){
123687
+ sqlite3_value *pRowid = apVal[p->nColumn+3];
123688
+ if( sqlite3_value_type(pRowid)==SQLITE_NULL ){
123689
+ pRowid = apVal[1];
123690
+ }
123691
+ if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){
123692
+ return SQLITE_CONSTRAINT;
123693
+ }
123694
+ *piDocid = sqlite3_value_int64(pRowid);
123695
+ return SQLITE_OK;
123696
+ }
123037123697
123038123698
/* Locate the statement handle used to insert data into the %_content
123039123699
** table. The SQL for this statement is:
123040123700
**
123041123701
** INSERT INTO %_content VALUES(?, ?, ?, ...)
@@ -123083,18 +123743,20 @@
123083123743
123084123744
/*
123085123745
** Remove all data from the FTS3 table. Clear the hash table containing
123086123746
** pending terms.
123087123747
*/
123088
-static int fts3DeleteAll(Fts3Table *p){
123748
+static int fts3DeleteAll(Fts3Table *p, int bContent){
123089123749
int rc = SQLITE_OK; /* Return code */
123090123750
123091123751
/* Discard the contents of the pending-terms hash table. */
123092123752
sqlite3Fts3PendingTermsClear(p);
123093123753
123094
- /* Delete everything from the %_content, %_segments and %_segdir tables. */
123095
- fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
123754
+ /* Delete everything from the shadow tables. Except, leave %_content as
123755
+ ** is if bContent is false. */
123756
+ assert( p->zContentTbl==0 || bContent==0 );
123757
+ if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
123096123758
fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0);
123097123759
fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
123098123760
if( p->bHasDocsize ){
123099123761
fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
123100123762
}
@@ -123398,11 +124060,11 @@
123398124060
pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
123399124061
pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
123400124062
if( nPrefix<0 || nSuffix<=0
123401124063
|| &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
123402124064
){
123403
- return SQLITE_CORRUPT_VTAB;
124065
+ return FTS_CORRUPT_VTAB;
123404124066
}
123405124067
123406124068
if( nPrefix+nSuffix>pReader->nTermAlloc ){
123407124069
int nNew = (nPrefix+nSuffix)*2;
123408124070
char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
@@ -123428,11 +124090,11 @@
123428124090
** of these statements is untrue, then the data structure is corrupt.
123429124091
*/
123430124092
if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
123431124093
|| (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
123432124094
){
123433
- return SQLITE_CORRUPT_VTAB;
124095
+ return FTS_CORRUPT_VTAB;
123434124096
}
123435124097
return SQLITE_OK;
123436124098
}
123437124099
123438124100
/*
@@ -124378,16 +125040,22 @@
124378125040
** error occurs, an SQLite error code is returned.
124379125041
*/
124380125042
static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){
124381125043
sqlite3_stmt *pStmt;
124382125044
int rc;
124383
- rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
124384
- if( rc==SQLITE_OK ){
124385
- if( SQLITE_ROW==sqlite3_step(pStmt) ){
124386
- *pisEmpty = sqlite3_column_int(pStmt, 0);
125045
+ if( p->zContentTbl ){
125046
+ /* If using the content=xxx option, assume the table is never empty */
125047
+ *pisEmpty = 0;
125048
+ rc = SQLITE_OK;
125049
+ }else{
125050
+ rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
125051
+ if( rc==SQLITE_OK ){
125052
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
125053
+ *pisEmpty = sqlite3_column_int(pStmt, 0);
125054
+ }
125055
+ rc = sqlite3_reset(pStmt);
124387125056
}
124388
- rc = sqlite3_reset(pStmt);
124389125057
}
124390125058
return rc;
124391125059
}
124392125060
124393125061
/*
@@ -124735,10 +125403,11 @@
124735125403
int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY);
124736125404
int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS);
124737125405
int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER);
124738125406
int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX);
124739125407
int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN);
125408
+ int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST);
124740125409
124741125410
Fts3SegReader **apSegment = pCsr->apSegment;
124742125411
int nSegment = pCsr->nSegment;
124743125412
Fts3SegFilter *pFilter = pCsr->pFilter;
124744125413
int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
@@ -124794,10 +125463,11 @@
124794125463
}
124795125464
124796125465
assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
124797125466
if( nMerge==1
124798125467
&& !isIgnoreEmpty
125468
+ && !isFirst
124799125469
&& (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
124800125470
){
124801125471
pCsr->nDoclist = apSegment[0]->nDoclist;
124802125472
if( fts3SegReaderIsPending(apSegment[0]) ){
124803125473
rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
@@ -124859,16 +125529,28 @@
124859125529
if( !aNew ){
124860125530
return SQLITE_NOMEM;
124861125531
}
124862125532
pCsr->aBuffer = aNew;
124863125533
}
124864
- nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
124865
- iPrev = iDocid;
124866
- if( isRequirePos ){
124867
- memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
124868
- nDoclist += nList;
124869
- pCsr->aBuffer[nDoclist++] = '\0';
125534
+
125535
+ if( isFirst ){
125536
+ char *a = &pCsr->aBuffer[nDoclist];
125537
+ int nWrite;
125538
+
125539
+ nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
125540
+ if( nWrite ){
125541
+ iPrev = iDocid;
125542
+ nDoclist += nWrite;
125543
+ }
125544
+ }else{
125545
+ nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
125546
+ iPrev = iDocid;
125547
+ if( isRequirePos ){
125548
+ memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
125549
+ nDoclist += nList;
125550
+ pCsr->aBuffer[nDoclist++] = '\0';
125551
+ }
124870125552
}
124871125553
}
124872125554
124873125555
fts3SegReaderSort(apSegment, nMerge, j, xCmp);
124874125556
}
@@ -125040,13 +125722,13 @@
125040125722
** Insert the sizes (in tokens) for each column of the document
125041125723
** with docid equal to p->iPrevDocid. The sizes are encoded as
125042125724
** a blob of varints.
125043125725
*/
125044125726
static void fts3InsertDocsize(
125045
- int *pRC, /* Result code */
125046
- Fts3Table *p, /* Table into which to insert */
125047
- u32 *aSz /* Sizes of each column */
125727
+ int *pRC, /* Result code */
125728
+ Fts3Table *p, /* Table into which to insert */
125729
+ u32 *aSz /* Sizes of each column, in tokens */
125048125730
){
125049125731
char *pBlob; /* The BLOB encoding of the document size */
125050125732
int nBlob; /* Number of bytes in the BLOB */
125051125733
sqlite3_stmt *pStmt; /* Statement used to insert the encoding */
125052125734
int rc; /* Result code from subfunctions */
@@ -125163,10 +125845,90 @@
125163125845
sqlite3Fts3SegmentsClose(p);
125164125846
sqlite3Fts3PendingTermsClear(p);
125165125847
125166125848
return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
125167125849
}
125850
+
125851
+/*
125852
+** This function is called when the user executes the following statement:
125853
+**
125854
+** INSERT INTO <tbl>(<tbl>) VALUES('rebuild');
125855
+**
125856
+** The entire FTS index is discarded and rebuilt. If the table is one
125857
+** created using the content=xxx option, then the new index is based on
125858
+** the current contents of the xxx table. Otherwise, it is rebuilt based
125859
+** on the contents of the %_content table.
125860
+*/
125861
+static int fts3DoRebuild(Fts3Table *p){
125862
+ int rc; /* Return Code */
125863
+
125864
+ rc = fts3DeleteAll(p, 0);
125865
+ if( rc==SQLITE_OK ){
125866
+ u32 *aSz = 0;
125867
+ u32 *aSzIns = 0;
125868
+ u32 *aSzDel = 0;
125869
+ sqlite3_stmt *pStmt = 0;
125870
+ int nEntry = 0;
125871
+
125872
+ /* Compose and prepare an SQL statement to loop through the content table */
125873
+ char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
125874
+ if( !zSql ){
125875
+ rc = SQLITE_NOMEM;
125876
+ }else{
125877
+ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
125878
+ sqlite3_free(zSql);
125879
+ }
125880
+
125881
+ if( rc==SQLITE_OK ){
125882
+ int nByte = sizeof(u32) * (p->nColumn+1)*3;
125883
+ aSz = (u32 *)sqlite3_malloc(nByte);
125884
+ if( aSz==0 ){
125885
+ rc = SQLITE_NOMEM;
125886
+ }else{
125887
+ memset(aSz, 0, nByte);
125888
+ aSzIns = &aSz[p->nColumn+1];
125889
+ aSzDel = &aSzIns[p->nColumn+1];
125890
+ }
125891
+ }
125892
+
125893
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
125894
+ int iCol;
125895
+ rc = fts3PendingTermsDocid(p, sqlite3_column_int64(pStmt, 0));
125896
+ aSz[p->nColumn] = 0;
125897
+ for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
125898
+ const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
125899
+ rc = fts3PendingTermsAdd(p, z, iCol, &aSz[iCol]);
125900
+ aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
125901
+ }
125902
+ if( p->bHasDocsize ){
125903
+ fts3InsertDocsize(&rc, p, aSz);
125904
+ }
125905
+ if( rc!=SQLITE_OK ){
125906
+ sqlite3_finalize(pStmt);
125907
+ pStmt = 0;
125908
+ }else{
125909
+ nEntry++;
125910
+ for(iCol=0; iCol<=p->nColumn; iCol++){
125911
+ aSzIns[iCol] += aSz[iCol];
125912
+ }
125913
+ }
125914
+ }
125915
+ if( p->bHasStat ){
125916
+ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry);
125917
+ }
125918
+ sqlite3_free(aSz);
125919
+
125920
+ if( pStmt ){
125921
+ int rc2 = sqlite3_finalize(pStmt);
125922
+ if( rc==SQLITE_OK ){
125923
+ rc = rc2;
125924
+ }
125925
+ }
125926
+ }
125927
+
125928
+ return rc;
125929
+}
125168125930
125169125931
/*
125170125932
** Handle a 'special' INSERT of the form:
125171125933
**
125172125934
** "INSERT INTO tbl(tbl) VALUES(<expr>)"
@@ -125181,10 +125943,12 @@
125181125943
125182125944
if( !zVal ){
125183125945
return SQLITE_NOMEM;
125184125946
}else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
125185125947
rc = fts3DoOptimize(p, 0);
125948
+ }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){
125949
+ rc = fts3DoRebuild(p);
125186125950
#ifdef SQLITE_TEST
125187125951
}else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
125188125952
p->nNodeSize = atoi(&zVal[9]);
125189125953
rc = SQLITE_OK;
125190125954
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
@@ -125261,10 +126025,11 @@
125261126025
pTC->pTokenizer = pT;
125262126026
rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
125263126027
for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
125264126028
Fts3PhraseToken *pPT = pDef->pToken;
125265126029
if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
126030
+ && (pPT->bFirst==0 || iPos==0)
125266126031
&& (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
125267126032
&& (0==memcmp(zToken, pPT->z, pPT->n))
125268126033
){
125269126034
fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
125270126035
}
@@ -125352,18 +126117,22 @@
125352126117
if( rc==SQLITE_OK ){
125353126118
if( isEmpty ){
125354126119
/* Deleting this row means the whole table is empty. In this case
125355126120
** delete the contents of all three tables and throw away any
125356126121
** data in the pendingTerms hash table. */
125357
- rc = fts3DeleteAll(p);
126122
+ rc = fts3DeleteAll(p, 1);
125358126123
*pnDoc = *pnDoc - 1;
125359126124
}else{
125360126125
sqlite3_int64 iRemove = sqlite3_value_int64(pRowid);
125361126126
rc = fts3PendingTermsDocid(p, iRemove);
125362126127
fts3DeleteTerms(&rc, p, pRowid, aSzDel);
125363
- fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
125364
- if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
126128
+ if( p->zContentTbl==0 ){
126129
+ fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
126130
+ if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
126131
+ }else{
126132
+ *pnDoc = *pnDoc - 1;
126133
+ }
125365126134
if( p->bHasDocsize ){
125366126135
fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
125367126136
}
125368126137
}
125369126138
}
@@ -125382,11 +126151,10 @@
125382126151
sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
125383126152
){
125384126153
Fts3Table *p = (Fts3Table *)pVtab;
125385126154
int rc = SQLITE_OK; /* Return Code */
125386126155
int isRemove = 0; /* True for an UPDATE or DELETE */
125387
- sqlite3_int64 iRemove = 0; /* Rowid removed by UPDATE or DELETE */
125388126156
u32 *aSzIns = 0; /* Sizes of inserted documents */
125389126157
u32 *aSzDel; /* Sizes of deleted documents */
125390126158
int nChng = 0; /* Net change in number of documents */
125391126159
int bInsertDone = 0;
125392126160
@@ -125420,11 +126188,11 @@
125420126188
** should be deleted from the database before inserting the new row. Or,
125421126189
** if the on-conflict mode is other than REPLACE, then this method must
125422126190
** detect the conflict and return SQLITE_CONSTRAINT before beginning to
125423126191
** modify the database file.
125424126192
*/
125425
- if( nArg>1 ){
126193
+ if( nArg>1 && p->zContentTbl==0 ){
125426126194
/* Find the value object that holds the new rowid value. */
125427126195
sqlite3_value *pNewRowid = apVal[3+p->nColumn];
125428126196
if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){
125429126197
pNewRowid = apVal[1];
125430126198
}
@@ -125465,23 +126233,25 @@
125465126233
/* If this is a DELETE or UPDATE operation, remove the old record. */
125466126234
if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
125467126235
assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
125468126236
rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
125469126237
isRemove = 1;
125470
- iRemove = sqlite3_value_int64(apVal[0]);
125471126238
}
125472126239
125473126240
/* If this is an INSERT or UPDATE operation, insert the new record. */
125474126241
if( nArg>1 && rc==SQLITE_OK ){
125475126242
if( bInsertDone==0 ){
125476126243
rc = fts3InsertData(p, apVal, pRowid);
125477
- if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT_VTAB;
126244
+ if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
126245
+ rc = FTS_CORRUPT_VTAB;
126246
+ }
125478126247
}
125479
- if( rc==SQLITE_OK && (!isRemove || *pRowid!=iRemove) ){
126248
+ if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
125480126249
rc = fts3PendingTermsDocid(p, *pRowid);
125481126250
}
125482126251
if( rc==SQLITE_OK ){
126252
+ assert( p->iPrevDocid==*pRowid );
125483126253
rc = fts3InsertTerms(p, apVal, aSzIns);
125484126254
}
125485126255
if( p->bHasDocsize ){
125486126256
fts3InsertDocsize(&rc, p, aSzIns);
125487126257
}
@@ -125891,10 +126661,11 @@
125891126661
pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol);
125892126662
if( pCsr ){
125893126663
int iFirst = 0;
125894126664
pPhrase->pList = pCsr;
125895126665
fts3GetDeltaPosition(&pCsr, &iFirst);
126666
+ assert( iFirst>=0 );
125896126667
pPhrase->pHead = pCsr;
125897126668
pPhrase->pTail = pCsr;
125898126669
pPhrase->iHead = iFirst;
125899126670
pPhrase->iTail = iFirst;
125900126671
}else{
@@ -126371,11 +127142,11 @@
126371127142
pStmt = *ppStmt;
126372127143
assert( sqlite3_data_count(pStmt)==1 );
126373127144
126374127145
a = sqlite3_column_blob(pStmt, 0);
126375127146
a += sqlite3Fts3GetVarint(a, &nDoc);
126376
- if( nDoc==0 ) return SQLITE_CORRUPT_VTAB;
127147
+ if( nDoc==0 ) return FTS_CORRUPT_VTAB;
126377127148
*pnDoc = (u32)nDoc;
126378127149
126379127150
if( paLen ) *paLen = a;
126380127151
return SQLITE_OK;
126381127152
}
@@ -126932,11 +127703,11 @@
126932127703
}
126933127704
}
126934127705
126935127706
if( !pTerm ){
126936127707
/* All offsets for this column have been gathered. */
126937
- break;
127708
+ rc = SQLITE_DONE;
126938127709
}else{
126939127710
assert( iCurrent<=iMinPos );
126940127711
if( 0==(0xFE&*pTerm->pList) ){
126941127712
pTerm->pList = 0;
126942127713
}else{
@@ -126949,12 +127720,12 @@
126949127720
char aBuffer[64];
126950127721
sqlite3_snprintf(sizeof(aBuffer), aBuffer,
126951127722
"%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
126952127723
);
126953127724
rc = fts3StringAppend(&res, aBuffer, -1);
126954
- }else if( rc==SQLITE_DONE ){
126955
- rc = SQLITE_CORRUPT_VTAB;
127725
+ }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){
127726
+ rc = FTS_CORRUPT_VTAB;
126956127727
}
126957127728
}
126958127729
}
126959127730
if( rc==SQLITE_DONE ){
126960127731
rc = SQLITE_OK;
@@ -128291,11 +129062,12 @@
128291129062
pCsr->nConstraint = argc;
128292129063
if( !pCsr->aConstraint ){
128293129064
rc = SQLITE_NOMEM;
128294129065
}else{
128295129066
memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
128296
- assert( (idxStr==0 && argc==0) || (int)strlen(idxStr)==argc*2 );
129067
+ assert( (idxStr==0 && argc==0)
129068
+ || (idxStr && (int)strlen(idxStr)==argc*2) );
128297129069
for(ii=0; ii<argc; ii++){
128298129070
RtreeConstraint *p = &pCsr->aConstraint[ii];
128299129071
p->op = idxStr[ii*2];
128300129072
p->iCoord = idxStr[ii*2+1]-'a';
128301129073
if( p->op==RTREE_MATCH ){
@@ -128592,11 +129364,14 @@
128592129364
int iCell;
128593129365
sqlite3_int64 iBest = 0;
128594129366
128595129367
float fMinGrowth = 0.0;
128596129368
float fMinArea = 0.0;
129369
+#if VARIANT_RSTARTREE_CHOOSESUBTREE
128597129370
float fMinOverlap = 0.0;
129371
+ float overlap;
129372
+#endif
128598129373
128599129374
int nCell = NCELL(pNode);
128600129375
RtreeCell cell;
128601129376
RtreeNode *pChild;
128602129377
@@ -128624,33 +129399,34 @@
128624129399
*/
128625129400
for(iCell=0; iCell<nCell; iCell++){
128626129401
int bBest = 0;
128627129402
float growth;
128628129403
float area;
128629
- float overlap = 0.0;
128630129404
nodeGetCell(pRtree, pNode, iCell, &cell);
128631129405
growth = cellGrowth(pRtree, &cell, pCell);
128632129406
area = cellArea(pRtree, &cell);
128633129407
128634129408
#if VARIANT_RSTARTREE_CHOOSESUBTREE
128635129409
if( ii==(pRtree->iDepth-1) ){
128636129410
overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
129411
+ }else{
129412
+ overlap = 0.0;
128637129413
}
128638129414
if( (iCell==0)
128639129415
|| (overlap<fMinOverlap)
128640129416
|| (overlap==fMinOverlap && growth<fMinGrowth)
128641129417
|| (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
128642129418
){
128643129419
bBest = 1;
129420
+ fMinOverlap = overlap;
128644129421
}
128645129422
#else
128646129423
if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
128647129424
bBest = 1;
128648129425
}
128649129426
#endif
128650129427
if( bBest ){
128651
- fMinOverlap = overlap;
128652129428
fMinGrowth = growth;
128653129429
fMinArea = area;
128654129430
iBest = cell.iRowid;
128655129431
}
128656129432
}
128657129433
--- 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.7.8. 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.
@@ -394,11 +394,11 @@
394 ** assert() macro is enabled, each call into the Win32 native heap subsystem
395 ** will cause HeapValidate to be called. If heap validation should fail, an
396 ** assertion will be triggered.
397 **
398 ** (Historical note: There used to be several other options, but we've
399 ** pared it down to just these two.)
400 **
401 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
402 ** the default.
403 */
404 #if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
@@ -654,13 +654,13 @@
654 **
655 ** See also: [sqlite3_libversion()],
656 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
657 ** [sqlite_version()] and [sqlite_source_id()].
658 */
659 #define SQLITE_VERSION "3.7.8"
660 #define SQLITE_VERSION_NUMBER 3007008
661 #define SQLITE_SOURCE_ID "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177"
662
663 /*
664 ** CAPI3REF: Run-Time Library Version Numbers
665 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
666 **
@@ -1318,11 +1318,15 @@
1318 ** in order for the database to be readable. The fourth parameter to
1319 ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
1320 ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
1321 ** WAL mode. If the integer is -1, then it is overwritten with the current
1322 ** WAL persistence setting.
1323 **
 
 
 
 
1324 */
1325 #define SQLITE_FCNTL_LOCKSTATE 1
1326 #define SQLITE_GET_LOCKPROXYFILE 2
1327 #define SQLITE_SET_LOCKPROXYFILE 3
1328 #define SQLITE_LAST_ERRNO 4
@@ -1330,10 +1334,11 @@
1330 #define SQLITE_FCNTL_CHUNK_SIZE 6
1331 #define SQLITE_FCNTL_FILE_POINTER 7
1332 #define SQLITE_FCNTL_SYNC_OMITTED 8
1333 #define SQLITE_FCNTL_WIN32_AV_RETRY 9
1334 #define SQLITE_FCNTL_PERSIST_WAL 10
 
1335
1336 /*
1337 ** CAPI3REF: Mutex Handle
1338 **
1339 ** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1946,12 +1951,12 @@
1946 ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
1947 ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
1948 ** allocator is engaged to handle all of SQLites memory allocation needs.
1949 ** The first pointer (the memory pointer) must be aligned to an 8-byte
1950 ** boundary or subsequent behavior of SQLite will be undefined.
1951 ** The minimum allocation size is capped at 2^12. Reasonable values
1952 ** for the minimum allocation size are 2^5 through 2^8.</dd>
1953 **
1954 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
1955 ** <dd> ^(This option takes a single argument which is a pointer to an
1956 ** instance of the [sqlite3_mutex_methods] structure. The argument specifies
1957 ** alternative low-level mutex routines to be used in place
@@ -3346,11 +3351,12 @@
3346 ** zSql string ends at either the first '\000' or '\u0000' character or
3347 ** the nByte-th byte, whichever comes first. If the caller knows
3348 ** that the supplied string is nul-terminated, then there is a small
3349 ** performance advantage to be gained by passing an nByte parameter that
3350 ** is equal to the number of bytes in the input string <i>including</i>
3351 ** the nul-terminator bytes.
 
3352 **
3353 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
3354 ** past the end of the first SQL statement in zSql. These routines only
3355 ** compile the first statement in zSql, so *pzTail is left pointing to
3356 ** what remains uncompiled.
@@ -3397,11 +3403,11 @@
3397 ** a schema change, on the first [sqlite3_step()] call following any change
3398 ** to the [sqlite3_bind_text | bindings] of that [parameter].
3399 ** ^The specific value of WHERE-clause [parameter] might influence the
3400 ** choice of query plan if the parameter is the left-hand side of a [LIKE]
3401 ** or [GLOB] operator or if the parameter is compared to an indexed column
3402 ** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
3403 ** the
3404 ** </li>
3405 ** </ol>
3406 */
3407 SQLITE_API int sqlite3_prepare(
@@ -3567,10 +3573,17 @@
3567 ** ^(In those routines that have a fourth argument, its value is the
3568 ** number of bytes in the parameter. To be clear: the value is the
3569 ** number of <u>bytes</u> in the value, not the number of characters.)^
3570 ** ^If the fourth parameter is negative, the length of the string is
3571 ** the number of bytes up to the first zero terminator.
 
 
 
 
 
 
 
3572 **
3573 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3574 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3575 ** string after SQLite has finished with it. ^The destructor is called
3576 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
@@ -3900,10 +3913,16 @@
3900 ** current row of the result set of [prepared statement] P.
3901 ** ^If prepared statement P does not have results ready to return
3902 ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
3903 ** interfaces) then sqlite3_data_count(P) returns 0.
3904 ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
 
 
 
 
 
 
3905 **
3906 ** See also: [sqlite3_column_count()]
3907 */
3908 SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
3909
@@ -4579,11 +4598,16 @@
4579 ** is negative, then SQLite takes result text from the 2nd parameter
4580 ** through the first zero character.
4581 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
4582 ** is non-negative, then as many bytes (not characters) of the text
4583 ** pointed to by the 2nd parameter are taken as the application-defined
4584 ** function result.
 
 
 
 
 
4585 ** ^If the 4th parameter to the sqlite3_result_text* interfaces
4586 ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
4587 ** function as the destructor on the text or BLOB result when it has
4588 ** finished using that result.
4589 ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
@@ -6362,20 +6386,34 @@
6362 ** <dd>This parameter returns the approximate number of of bytes of heap
6363 ** and lookaside memory used by all prepared statements associated with
6364 ** the database connection.)^
6365 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
6366 ** </dd>
 
 
 
 
 
 
 
 
 
 
 
 
6367 ** </dl>
6368 */
6369 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
6370 #define SQLITE_DBSTATUS_CACHE_USED 1
6371 #define SQLITE_DBSTATUS_SCHEMA_USED 2
6372 #define SQLITE_DBSTATUS_STMT_USED 3
6373 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
6374 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
6375 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6376 #define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */
 
 
6377
6378
6379 /*
6380 ** CAPI3REF: Prepared Statement Status
6381 **
@@ -6425,11 +6463,10 @@
6425 ** <dd>^This is the number of rows inserted into transient indices that
6426 ** were created automatically in order to help joins run faster.
6427 ** A non-zero value in this counter may indicate an opportunity to
6428 ** improvement performance by adding permanent indices that do not
6429 ** need to be reinitialized each time the statement is run.</dd>
6430 **
6431 ** </dl>
6432 */
6433 #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
6434 #define SQLITE_STMTSTATUS_SORT 2
6435 #define SQLITE_STMTSTATUS_AUTOINDEX 3
@@ -7711,10 +7748,22 @@
7711 ** is 0x00000000ffffffff. But because of quirks of some compilers, we
7712 ** have to specify the value in the less intuitive manner shown:
7713 */
7714 #define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
7715
 
 
 
 
 
 
 
 
 
 
 
 
7716 /*
7717 ** Macros to determine whether the machine is big or little endian,
7718 ** evaluated at runtime.
7719 */
7720 #ifdef SQLITE_AMALGAMATION
@@ -8742,10 +8791,11 @@
8742 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
8743 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
8744 SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
8745 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
8746 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
 
8747
8748 /* Functions used to truncate the database file. */
8749 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
8750
8751 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
@@ -9278,18 +9328,21 @@
9278 /*
9279 ** If this is a no-op implementation, implement everything as macros.
9280 */
9281 #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
9282 #define sqlite3_mutex_free(X)
9283 #define sqlite3_mutex_enter(X)
9284 #define sqlite3_mutex_try(X) SQLITE_OK
9285 #define sqlite3_mutex_leave(X)
9286 #define sqlite3_mutex_held(X) ((void)(X),1)
9287 #define sqlite3_mutex_notheld(X) ((void)(X),1)
9288 #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8)
9289 #define sqlite3MutexInit() SQLITE_OK
9290 #define sqlite3MutexEnd()
 
 
 
9291 #endif /* defined(SQLITE_MUTEX_OMIT) */
9292
9293 /************** End of mutex.h ***********************************************/
9294 /************** Continuing where we left off in sqliteInt.h ******************/
9295
@@ -9918,11 +9971,11 @@
9918 int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
9919 int nCol; /* Number of columns in this table */
9920 Column *aCol; /* Information about each column */
9921 Index *pIndex; /* List of SQL indexes on this table. */
9922 int tnum; /* Root BTree node for this table (see note above) */
9923 unsigned nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
9924 Select *pSelect; /* NULL for tables. Points to definition if a view. */
9925 u16 nRef; /* Number of pointers to this Table */
9926 u8 tabFlags; /* Mask of TF_* values */
9927 u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
9928 FKey *pFKey; /* Linked list of all foreign keys in this table */
@@ -10117,11 +10170,11 @@
10117 */
10118 struct Index {
10119 char *zName; /* Name of this index */
10120 int nColumn; /* Number of columns in the table used by this index */
10121 int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10122 unsigned *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10123 Table *pTable; /* The SQL table being indexed */
10124 int tnum; /* Page containing root of this index in database file */
10125 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10126 u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
10127 u8 bUnordered; /* Use this index for == or IN queries only */
@@ -10128,24 +10181,32 @@
10128 char *zColAff; /* String defining the affinity of each column */
10129 Index *pNext; /* The next index associated with the same table */
10130 Schema *pSchema; /* Schema containing this index */
10131 u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
10132 char **azColl; /* Array of collation sequence names for index */
10133 IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */
 
 
 
 
10134 };
10135
10136 /*
10137 ** Each sample stored in the sqlite_stat2 table is represented in memory
10138 ** using a structure of this type.
10139 */
10140 struct IndexSample {
10141 union {
10142 char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
10143 double r; /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */
 
10144 } u;
10145 u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
10146 u8 nByte; /* Size in byte of text or blob. */
 
 
 
10147 };
10148
10149 /*
10150 ** Each token coming out of the lexer is an instance of
10151 ** this structure. Tokens are also used as part of an expression.
@@ -10593,14 +10654,14 @@
10593 #define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
10594 #define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
10595 #define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */
10596 #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
10597 #define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
10598 #define WHERE_OMIT_OPEN 0x0010 /* Table cursors are already open */
10599 #define WHERE_OMIT_CLOSE 0x0020 /* Omit close of table & index cursors */
10600 #define WHERE_FORCE_TABLE 0x0040 /* Do not use an index-only search */
10601 #define WHERE_ONETABLE_ONLY 0x0080 /* Only code the 1st table in pTabList */
10602
10603 /*
10604 ** The WHERE clause processing routine has two halves. The
10605 ** first part does the start of the WHERE loop and the second
10606 ** half does the tail of the WHERE loop. An instance of
@@ -11350,10 +11411,11 @@
11350 #else
11351 # define sqlite3ViewGetColumnNames(A,B) 0
11352 #endif
11353
11354 SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
 
11355 SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
11356 #ifndef SQLITE_OMIT_AUTOINCREMENT
11357 SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
11358 SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
11359 #else
@@ -11606,11 +11668,11 @@
11606 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
11607 void(*)(void*));
11608 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
11609 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
11610 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
11611 #ifdef SQLITE_ENABLE_STAT2
11612 SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
11613 #endif
11614 SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
11615 SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
11616 #ifndef SQLITE_AMALGAMATION
@@ -11708,19 +11770,21 @@
11708 # define sqlite3VtabInSync(db) 0
11709 # define sqlite3VtabLock(X)
11710 # define sqlite3VtabUnlock(X)
11711 # define sqlite3VtabUnlockList(X)
11712 # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
 
11713 #else
11714 SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*);
11715 SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
11716 SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
11717 SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
11718 SQLITE_PRIVATE void sqlite3VtabLock(VTable *);
11719 SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *);
11720 SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
11721 SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
 
11722 # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
11723 #endif
11724 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
11725 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
11726 SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
@@ -11736,11 +11800,10 @@
11736 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
11737 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
11738 SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
11739 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
11740 SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
11741 SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
11742 SQLITE_PRIVATE const char *sqlite3JournalModename(int);
11743 SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
11744 SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
11745
11746 /* Declarations for functions in fkey.c. All of these are replaced by
@@ -12232,10 +12295,13 @@
12232 #ifdef SQLITE_ENABLE_RTREE
12233 "ENABLE_RTREE",
12234 #endif
12235 #ifdef SQLITE_ENABLE_STAT2
12236 "ENABLE_STAT2",
 
 
 
12237 #endif
12238 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
12239 "ENABLE_UNLOCK_NOTIFY",
12240 #endif
12241 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -12445,13 +12511,10 @@
12445 "OMIT_WSD",
12446 #endif
12447 #ifdef SQLITE_OMIT_XFER_OPT
12448 "OMIT_XFER_OPT",
12449 #endif
12450 #ifdef SQLITE_PAGECACHE_BLOCKALLOC
12451 "PAGECACHE_BLOCKALLOC",
12452 #endif
12453 #ifdef SQLITE_PERFORMANCE_TRACE
12454 "PERFORMANCE_TRACE",
12455 #endif
12456 #ifdef SQLITE_PROXY_DEBUG
12457 "PROXY_DEBUG",
@@ -13189,10 +13252,32 @@
13189 *pHighwater = 0;
13190 *pCurrent = nByte;
13191
13192 break;
13193 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13194
13195 default: {
13196 rc = SQLITE_ERROR;
13197 }
13198 }
@@ -13490,16 +13575,22 @@
13490 }
13491 return 0;
13492 }
13493
13494 /*
13495 ** Set the time to the current time reported by the VFS
 
 
13496 */
13497 static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
13498 sqlite3 *db = sqlite3_context_db_handle(context);
13499 sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD);
13500 p->validJD = 1;
 
 
 
 
13501 }
13502
13503 /*
13504 ** Attempt to parse the given string into a Julian Day Number. Return
13505 ** the number of errors.
@@ -13525,12 +13616,11 @@
13525 if( parseYyyyMmDd(zDate,p)==0 ){
13526 return 0;
13527 }else if( parseHhMmSs(zDate, p)==0 ){
13528 return 0;
13529 }else if( sqlite3StrICmp(zDate,"now")==0){
13530 setDateTimeToCurrent(context, p);
13531 return 0;
13532 }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
13533 p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
13534 p->validJD = 1;
13535 return 0;
13536 }
@@ -13953,12 +14043,13 @@
13953 int i;
13954 const unsigned char *z;
13955 int eType;
13956 memset(p, 0, sizeof(*p));
13957 if( argc==0 ){
13958 setDateTimeToCurrent(context, p);
13959 }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
 
13960 || eType==SQLITE_INTEGER ){
13961 p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
13962 p->validJD = 1;
13963 }else{
13964 z = sqlite3_value_text(argv[0]);
@@ -14266,35 +14357,32 @@
14266 ){
14267 time_t t;
14268 char *zFormat = (char *)sqlite3_user_data(context);
14269 sqlite3 *db;
14270 sqlite3_int64 iT;
 
 
14271 char zBuf[20];
14272
14273 UNUSED_PARAMETER(argc);
14274 UNUSED_PARAMETER(argv);
14275
14276 db = sqlite3_context_db_handle(context);
14277 sqlite3OsCurrentTimeInt64(db->pVfs, &iT);
14278 t = iT/1000 - 10000*(sqlite3_int64)21086676;
14279 #ifdef HAVE_GMTIME_R
14280 {
14281 struct tm sNow;
14282 gmtime_r(&t, &sNow);
 
 
 
 
 
14283 strftime(zBuf, 20, zFormat, &sNow);
14284 }
14285 #else
14286 {
14287 struct tm *pTm;
14288 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14289 pTm = gmtime(&t);
14290 strftime(zBuf, 20, zFormat, pTm);
14291 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14292 }
14293 #endif
14294
14295 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
14296 }
14297 #endif
14298
14299 /*
14300 ** This function registered all of the above C functions as SQL
@@ -14625,16 +14713,16 @@
14625 ** Register a VFS with the system. It is harmless to register the same
14626 ** VFS multiple times. The new VFS becomes the default if makeDflt is
14627 ** true.
14628 */
14629 SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
14630 sqlite3_mutex *mutex = 0;
14631 #ifndef SQLITE_OMIT_AUTOINIT
14632 int rc = sqlite3_initialize();
14633 if( rc ) return rc;
14634 #endif
14635 mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
14636 sqlite3_mutex_enter(mutex);
14637 vfsUnlink(pVfs);
14638 if( makeDflt || vfsList==0 ){
14639 pVfs->pNext = vfsList;
14640 vfsList = pVfs;
@@ -18878,52 +18966,14 @@
18878 ** an historical reference. Most of the "enhancements" have been backed
18879 ** out so that the functionality is now the same as standard printf().
18880 **
18881 **************************************************************************
18882 **
18883 ** The following modules is an enhanced replacement for the "printf" subroutines
18884 ** found in the standard C library. The following enhancements are
18885 ** supported:
18886 **
18887 ** + Additional functions. The standard set of "printf" functions
18888 ** includes printf, fprintf, sprintf, vprintf, vfprintf, and
18889 ** vsprintf. This module adds the following:
18890 **
18891 ** * snprintf -- Works like sprintf, but has an extra argument
18892 ** which is the size of the buffer written to.
18893 **
18894 ** * mprintf -- Similar to sprintf. Writes output to memory
18895 ** obtained from malloc.
18896 **
18897 ** * xprintf -- Calls a function to dispose of output.
18898 **
18899 ** * nprintf -- No output, but returns the number of characters
18900 ** that would have been output by printf.
18901 **
18902 ** * A v- version (ex: vsnprintf) of every function is also
18903 ** supplied.
18904 **
18905 ** + A few extensions to the formatting notation are supported:
18906 **
18907 ** * The "=" flag (similar to "-") causes the output to be
18908 ** be centered in the appropriately sized field.
18909 **
18910 ** * The %b field outputs an integer in binary notation.
18911 **
18912 ** * The %c field now accepts a precision. The character output
18913 ** is repeated by the number of times the precision specifies.
18914 **
18915 ** * The %' field works like %c, but takes as its character the
18916 ** next character of the format string, instead of the next
18917 ** argument. For example, printf("%.78'-") prints 78 minus
18918 ** signs, the same as printf("%.78c",'-').
18919 **
18920 ** + When compiled using GCC on a SPARC, this version of printf is
18921 ** faster than the library printf for SUN OS 4.1.
18922 **
18923 ** + All functions are fully reentrant.
18924 **
18925 */
18926
18927 /*
18928 ** Conversion types fall into various categories as defined by the
18929 ** following enumeration.
@@ -19057,47 +19107,19 @@
19057 }
19058 }
19059
19060 /*
19061 ** On machines with a small stack size, you can redefine the
19062 ** SQLITE_PRINT_BUF_SIZE to be less than 350.
19063 */
19064 #ifndef SQLITE_PRINT_BUF_SIZE
19065 # if defined(SQLITE_SMALL_STACK)
19066 # define SQLITE_PRINT_BUF_SIZE 50
19067 # else
19068 # define SQLITE_PRINT_BUF_SIZE 350
19069 # endif
19070 #endif
19071 #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
19072
19073 /*
19074 ** The root program. All variations call this core.
19075 **
19076 ** INPUTS:
19077 ** func This is a pointer to a function taking three arguments
19078 ** 1. A pointer to anything. Same as the "arg" parameter.
19079 ** 2. A pointer to the list of characters to be output
19080 ** (Note, this list is NOT null terminated.)
19081 ** 3. An integer number of characters to be output.
19082 ** (Note: This number might be zero.)
19083 **
19084 ** arg This is the pointer to anything which will be passed as the
19085 ** first argument to "func". Use it for whatever you like.
19086 **
19087 ** fmt This is the format string, as in the usual print.
19088 **
19089 ** ap This is a pointer to a list of arguments. Same as in
19090 ** vfprint.
19091 **
19092 ** OUTPUTS:
19093 ** The return value is the total number of characters sent to
19094 ** the function "func". Returns -1 on a error.
19095 **
19096 ** Note that the order in which automatic variables are declared below
19097 ** seems to make a big difference in determining how fast this beast
19098 ** will run.
19099 */
19100 SQLITE_PRIVATE void sqlite3VXPrintf(
19101 StrAccum *pAccum, /* Accumulate results here */
19102 int useExtended, /* Allow extended %-conversions */
19103 const char *fmt, /* Format string */
@@ -19116,27 +19138,27 @@
19116 etByte flag_altform2; /* True if "!" flag is present */
19117 etByte flag_zeropad; /* True if field width constant starts with zero */
19118 etByte flag_long; /* True if "l" flag is present */
19119 etByte flag_longlong; /* True if the "ll" flag is present */
19120 etByte done; /* Loop termination flag */
 
 
19121 sqlite_uint64 longvalue; /* Value for integer types */
19122 LONGDOUBLE_TYPE realvalue; /* Value for real types */
19123 const et_info *infop; /* Pointer to the appropriate info structure */
19124 char buf[etBUFSIZE]; /* Conversion buffer */
19125 char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
19126 etByte xtype = 0; /* Conversion paradigm */
19127 char *zExtra; /* Extra memory used for etTCLESCAPE conversions */
19128 #ifndef SQLITE_OMIT_FLOATING_POINT
19129 int exp, e2; /* exponent of real numbers */
 
19130 double rounder; /* Used for rounding floating point values */
19131 etByte flag_dp; /* True if decimal point should be shown */
19132 etByte flag_rtz; /* True if trailing zeros should be removed */
19133 etByte flag_exp; /* True to force display of the exponent */
19134 int nsd; /* Number of significant digits returned */
19135 #endif
 
19136
19137 length = 0;
19138 bufpt = 0;
19139 for(; (c=(*fmt))!=0; ++fmt){
19140 if( c!='%' ){
19141 int amt;
19142 bufpt = (char *)fmt;
@@ -19177,13 +19199,10 @@
19177 while( c>='0' && c<='9' ){
19178 width = width*10 + c - '0';
19179 c = *++fmt;
19180 }
19181 }
19182 if( width > etBUFSIZE-10 ){
19183 width = etBUFSIZE-10;
19184 }
19185 /* Get the precision */
19186 if( c=='.' ){
19187 precision = 0;
19188 c = *++fmt;
19189 if( c=='*' ){
@@ -19226,16 +19245,10 @@
19226 break;
19227 }
19228 }
19229 zExtra = 0;
19230
19231
19232 /* Limit the precision to prevent overflowing buf[] during conversion */
19233 if( precision>etBUFSIZE-40 && (infop->flags & FLAG_STRING)==0 ){
19234 precision = etBUFSIZE-40;
19235 }
19236
19237 /*
19238 ** At this point, variables are initialized as follows:
19239 **
19240 ** flag_alternateform TRUE if a '#' is present.
19241 ** flag_altform2 TRUE if a '!' is present.
@@ -19296,20 +19309,30 @@
19296 }
19297 if( longvalue==0 ) flag_alternateform = 0;
19298 if( flag_zeropad && precision<width-(prefix!=0) ){
19299 precision = width-(prefix!=0);
19300 }
19301 bufpt = &buf[etBUFSIZE-1];
 
 
 
 
 
 
 
 
 
 
 
19302 if( xtype==etORDINAL ){
19303 static const char zOrd[] = "thstndrd";
19304 int x = (int)(longvalue % 10);
19305 if( x>=4 || (longvalue/10)%10==1 ){
19306 x = 0;
19307 }
19308 buf[etBUFSIZE-3] = zOrd[x*2];
19309 buf[etBUFSIZE-2] = zOrd[x*2+1];
19310 bufpt -= 2;
19311 }
19312 {
19313 register const char *cset; /* Use registers for speed */
19314 register int base;
19315 cset = &aDigits[infop->charset];
@@ -19317,11 +19340,11 @@
19317 do{ /* Convert to ascii */
19318 *(--bufpt) = cset[longvalue%base];
19319 longvalue = longvalue/base;
19320 }while( longvalue>0 );
19321 }
19322 length = (int)(&buf[etBUFSIZE-1]-bufpt);
19323 for(idx=precision-length; idx>0; idx--){
19324 *(--bufpt) = '0'; /* Zero pad */
19325 }
19326 if( prefix ) *(--bufpt) = prefix; /* Add sign */
19327 if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
@@ -19328,21 +19351,20 @@
19328 const char *pre;
19329 char x;
19330 pre = &aPrefix[infop->prefix];
19331 for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
19332 }
19333 length = (int)(&buf[etBUFSIZE-1]-bufpt);
19334 break;
19335 case etFLOAT:
19336 case etEXP:
19337 case etGENERIC:
19338 realvalue = va_arg(ap,double);
19339 #ifdef SQLITE_OMIT_FLOATING_POINT
19340 length = 0;
19341 #else
19342 if( precision<0 ) precision = 6; /* Set default precision */
19343 if( precision>etBUFSIZE/2-10 ) precision = etBUFSIZE/2-10;
19344 if( realvalue<0.0 ){
19345 realvalue = -realvalue;
19346 prefix = '-';
19347 }else{
19348 if( flag_plussign ) prefix = '+';
@@ -19386,11 +19408,10 @@
19386 bufpt = buf;
19387 /*
19388 ** If the field type is etGENERIC, then convert to either etEXP
19389 ** or etFLOAT, as appropriate.
19390 */
19391 flag_exp = xtype==etEXP;
19392 if( xtype!=etFLOAT ){
19393 realvalue += rounder;
19394 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
19395 }
19396 if( xtype==etGENERIC ){
@@ -19407,10 +19428,18 @@
19407 if( xtype==etEXP ){
19408 e2 = 0;
19409 }else{
19410 e2 = exp;
19411 }
 
 
 
 
 
 
 
 
19412 nsd = 0;
19413 flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
19414 /* The sign in front of the number */
19415 if( prefix ){
19416 *(bufpt++) = prefix;
@@ -19438,21 +19467,21 @@
19438 *(bufpt++) = et_getdigit(&realvalue,&nsd);
19439 }
19440 /* Remove trailing zeros and the "." if no digits follow the "." */
19441 if( flag_rtz && flag_dp ){
19442 while( bufpt[-1]=='0' ) *(--bufpt) = 0;
19443 assert( bufpt>buf );
19444 if( bufpt[-1]=='.' ){
19445 if( flag_altform2 ){
19446 *(bufpt++) = '0';
19447 }else{
19448 *(--bufpt) = 0;
19449 }
19450 }
19451 }
19452 /* Add the "eNNN" suffix */
19453 if( flag_exp || xtype==etEXP ){
19454 *(bufpt++) = aDigits[infop->charset];
19455 if( exp<0 ){
19456 *(bufpt++) = '-'; exp = -exp;
19457 }else{
19458 *(bufpt++) = '+';
@@ -19467,12 +19496,12 @@
19467 *bufpt = 0;
19468
19469 /* The converted number is in buf[] and zero terminated. Output it.
19470 ** Note that the number is in the usual order, not reversed as with
19471 ** integer conversions. */
19472 length = (int)(bufpt-buf);
19473 bufpt = buf;
19474
19475 /* Special case: Add leading zeros if the flag_zeropad flag is
19476 ** set and we are not left justified */
19477 if( flag_zeropad && !flag_leftjustify && length < width){
19478 int i;
@@ -19606,13 +19635,11 @@
19606 nspace = width-length;
19607 if( nspace>0 ){
19608 appendSpace(pAccum, nspace);
19609 }
19610 }
19611 if( zExtra ){
19612 sqlite3_free(zExtra);
19613 }
19614 }/* End for loop over the format string */
19615 } /* End of function */
19616
19617 /*
19618 ** Append N bytes of text from z to the StrAccum object.
@@ -19622,10 +19649,11 @@
19622 if( p->tooBig | p->mallocFailed ){
19623 testcase(p->tooBig);
19624 testcase(p->mallocFailed);
19625 return;
19626 }
 
19627 if( N<0 ){
19628 N = sqlite3Strlen30(z);
19629 }
19630 if( N==0 || NEVER(z==0) ){
19631 return;
@@ -19653,19 +19681,20 @@
19653 zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
19654 }else{
19655 zNew = sqlite3_realloc(zOld, p->nAlloc);
19656 }
19657 if( zNew ){
19658 if( zOld==0 ) memcpy(zNew, p->zText, p->nChar);
19659 p->zText = zNew;
19660 }else{
19661 p->mallocFailed = 1;
19662 sqlite3StrAccumReset(p);
19663 return;
19664 }
19665 }
19666 }
 
19667 memcpy(&p->zText[p->nChar], z, N);
19668 p->nChar += N;
19669 }
19670
19671 /*
@@ -20511,11 +20540,11 @@
20511 ** no longer required.
20512 **
20513 ** If a malloc failure occurs, NULL is returned and the db.mallocFailed
20514 ** flag set.
20515 */
20516 #ifdef SQLITE_ENABLE_STAT2
20517 SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
20518 Mem m;
20519 memset(&m, 0, sizeof(m));
20520 m.db = db;
20521 sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
@@ -20940,11 +20969,11 @@
20940 }else if( *z=='+' ){
20941 z+=incr;
20942 }
20943 /* copy digits to exponent */
20944 while( z<zEnd && sqlite3Isdigit(*z) ){
20945 e = e*10 + (*z - '0');
20946 z+=incr;
20947 eValid = 1;
20948 }
20949 }
20950
@@ -20991,10 +21020,16 @@
20991 result /= 1.0e+308;
20992 }else{
20993 result = s * scale;
20994 result *= 1.0e+308;
20995 }
 
 
 
 
 
 
20996 }else{
20997 /* 1.0e+22 is the largest power of 10 than can be
20998 ** represented exactly. */
20999 while( e%22 ) { scale *= 1.0e+1; e -= 1; }
21000 while( e>0 ) { scale *= 1.0e+22; e -= 22; }
@@ -25102,11 +25137,11 @@
25102 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
25103 }
25104 #endif
25105
25106
25107 #ifdef SQLITE_DEBUG
25108 /*
25109 ** Helper function for printing out trace information from debugging
25110 ** binaries. This returns the string represetation of the supplied
25111 ** integer lock-type.
25112 */
@@ -25937,18 +25972,18 @@
25937 ** locking a random byte from a range, concurrent SHARED locks may exist
25938 ** even if the locking primitive used is always a write-lock.
25939 */
25940 int rc = SQLITE_OK;
25941 unixFile *pFile = (unixFile*)id;
25942 unixInodeInfo *pInode = pFile->pInode;
25943 struct flock lock;
25944 int tErrno = 0;
25945
25946 assert( pFile );
25947 OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
25948 azFileLock(eFileLock), azFileLock(pFile->eFileLock),
25949 azFileLock(pInode->eFileLock), pInode->nShared , getpid()));
25950
25951 /* If there is already a lock of this type or more restrictive on the
25952 ** unixFile, do nothing. Don't use the end_lock: exit path, as
25953 ** unixEnterMutex() hasn't been called yet.
25954 */
@@ -26148,11 +26183,10 @@
26148 static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
26149 unixFile *pFile = (unixFile*)id;
26150 unixInodeInfo *pInode;
26151 struct flock lock;
26152 int rc = SQLITE_OK;
26153 int h;
26154
26155 assert( pFile );
26156 OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
26157 pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
26158 getpid()));
@@ -26160,18 +26194,14 @@
26160 assert( eFileLock<=SHARED_LOCK );
26161 if( pFile->eFileLock<=eFileLock ){
26162 return SQLITE_OK;
26163 }
26164 unixEnterMutex();
26165 h = pFile->h;
26166 pInode = pFile->pInode;
26167 assert( pInode->nShared!=0 );
26168 if( pFile->eFileLock>SHARED_LOCK ){
26169 assert( pInode->eFileLock==pFile->eFileLock );
26170 SimulateIOErrorBenign(1);
26171 SimulateIOError( h=(-1) )
26172 SimulateIOErrorBenign(0);
26173
26174 #ifndef NDEBUG
26175 /* When reducing a lock such that other processes can start
26176 ** reading the database file again, make sure that the
26177 ** transaction counter was updated if any part of the database
@@ -26178,15 +26208,10 @@
26178 ** file changed. If the transaction counter is not updated,
26179 ** other connections to the same file might not realize that
26180 ** the file has changed and hence might not know to flush their
26181 ** cache. The use of a stale cache can lead to database corruption.
26182 */
26183 #if 0
26184 assert( pFile->inNormalWrite==0
26185 || pFile->dbUpdate==0
26186 || pFile->transCntrChng==1 );
26187 #endif
26188 pFile->inNormalWrite = 0;
26189 #endif
26190
26191 /* downgrading to a shared lock on NFS involves clearing the write lock
26192 ** before establishing the readlock - to avoid a race condition we downgrade
@@ -26284,13 +26309,10 @@
26284 pInode->nShared--;
26285 if( pInode->nShared==0 ){
26286 lock.l_type = F_UNLCK;
26287 lock.l_whence = SEEK_SET;
26288 lock.l_start = lock.l_len = 0L;
26289 SimulateIOErrorBenign(1);
26290 SimulateIOError( h=(-1) )
26291 SimulateIOErrorBenign(0);
26292 if( unixFileLock(pFile, &lock)==0 ){
26293 pInode->eFileLock = NO_LOCK;
26294 }else{
26295 rc = SQLITE_IOERR_UNLOCK;
26296 pFile->lastErrno = errno;
@@ -28428,20 +28450,19 @@
28428 rc = SQLITE_NOMEM;
28429 goto shm_open_err;
28430 }
28431
28432 if( pInode->bProcessLock==0 ){
28433 pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT,
28434 (sStat.st_mode & 0777));
 
 
 
 
 
 
28435 if( pShmNode->h<0 ){
28436 const char *zRO;
28437 zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
28438 if( zRO && sqlite3GetBoolean(zRO) ){
28439 pShmNode->h = robust_open(zShmFilename, O_RDONLY,
28440 (sStat.st_mode & 0777));
28441 pShmNode->isReadonly = 1;
28442 }
28443 if( pShmNode->h<0 ){
28444 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
28445 goto shm_open_err;
28446 }
28447 }
@@ -29122,10 +29143,13 @@
29122 assert( zFilename==0 || zFilename[0]=='/'
29123 || pVfs->pAppData==(void*)&autolockIoFinder );
29124 #else
29125 assert( zFilename==0 || zFilename[0]=='/' );
29126 #endif
 
 
 
29127
29128 OSTRACE(("OPEN %-3d %s\n", h, zFilename));
29129 pNew->h = h;
29130 pNew->zPath = zFilename;
29131 if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
@@ -29224,10 +29248,11 @@
29224 /* Dotfile locking uses the file path so it needs to be included in
29225 ** the dotlockLockingContext
29226 */
29227 char *zLockFile;
29228 int nFilename;
 
29229 nFilename = (int)strlen(zFilename) + 6;
29230 zLockFile = (char *)sqlite3_malloc(nFilename);
29231 if( zLockFile==0 ){
29232 rc = SQLITE_NOMEM;
29233 }else{
@@ -29462,12 +29487,20 @@
29462 **
29463 ** where NN is a 4 digit decimal number. The NN naming schemes are
29464 ** used by the test_multiplex.c module.
29465 */
29466 nDb = sqlite3Strlen30(zPath) - 1;
29467 while( nDb>0 && zPath[nDb]!='-' ) nDb--;
29468 if( nDb==0 ) return SQLITE_OK;
 
 
 
 
 
 
 
 
29469 memcpy(zDb, zPath, nDb);
29470 zDb[nDb] = '\0';
29471
29472 if( 0==osStat(zDb, &sStat) ){
29473 *pMode = sStat.st_mode & 0777;
@@ -29995,14 +30028,16 @@
29995 ** the current time and date as a Julian Day number times 86_400_000. In
29996 ** other words, write into *piNow the number of milliseconds since the Julian
29997 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
29998 ** proleptic Gregorian calendar.
29999 **
30000 ** On success, return 0. Return 1 if the time and date cannot be found.
 
30001 */
30002 static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
30003 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
 
30004 #if defined(NO_GETTOD)
30005 time_t t;
30006 time(&t);
30007 *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
30008 #elif OS_VXWORKS
@@ -30009,34 +30044,38 @@
30009 struct timespec sNow;
30010 clock_gettime(CLOCK_REALTIME, &sNow);
30011 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
30012 #else
30013 struct timeval sNow;
30014 gettimeofday(&sNow, 0);
30015 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
 
 
 
30016 #endif
30017
30018 #ifdef SQLITE_TEST
30019 if( sqlite3_current_time ){
30020 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
30021 }
30022 #endif
30023 UNUSED_PARAMETER(NotUsed);
30024 return 0;
30025 }
30026
30027 /*
30028 ** Find the current time (in Universal Coordinated Time). Write the
30029 ** current time and date as a Julian Day number into *prNow and
30030 ** return 0. Return 1 if the time and date cannot be found.
30031 */
30032 static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
30033 sqlite3_int64 i;
 
30034 UNUSED_PARAMETER(NotUsed);
30035 unixCurrentTimeInt64(0, &i);
30036 *prNow = i/86400000.0;
30037 return 0;
30038 }
30039
30040 /*
30041 ** We added the xGetLastError() method with the intention of providing
30042 ** better low-level error messages when operating-system problems come up
@@ -34169,11 +34208,11 @@
34169
34170 if( h==INVALID_HANDLE_VALUE ){
34171 pFile->lastErrno = GetLastError();
34172 winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
34173 free(zConverted);
34174 if( isReadWrite ){
34175 return winOpen(pVfs, zName, id,
34176 ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
34177 }else{
34178 return SQLITE_CANTOPEN_BKPT;
34179 }
@@ -34535,11 +34574,11 @@
34535 }
34536 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
34537 UNUSED_PARAMETER(pVfs);
34538 getLastErrorMsg(nBuf, zBufOut);
34539 }
34540 void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
34541 UNUSED_PARAMETER(pVfs);
34542 #if SQLITE_OS_WINCE
34543 /* The GetProcAddressA() routine is only available on wince. */
34544 return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
34545 #else
@@ -34546,11 +34585,11 @@
34546 /* All other windows platforms expect GetProcAddress() to take
34547 ** an Ansi string regardless of the _UNICODE setting */
34548 return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
34549 #endif
34550 }
34551 void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
34552 UNUSED_PARAMETER(pVfs);
34553 FreeLibrary((HANDLE)pHandle);
34554 }
34555 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
34556 #define winDlOpen 0
@@ -34620,11 +34659,12 @@
34620 ** the current time and date as a Julian Day number times 86_400_000. In
34621 ** other words, write into *piNow the number of milliseconds since the Julian
34622 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
34623 ** proleptic Gregorian calendar.
34624 **
34625 ** On success, return 0. Return 1 if the time and date cannot be found.
 
34626 */
34627 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
34628 /* FILETIME structure is a 64-bit value representing the number of
34629 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
34630 */
@@ -34640,11 +34680,11 @@
34640 #if SQLITE_OS_WINCE
34641 SYSTEMTIME time;
34642 GetSystemTime(&time);
34643 /* if SystemTimeToFileTime() fails, it returns zero. */
34644 if (!SystemTimeToFileTime(&time,&ft)){
34645 return 1;
34646 }
34647 #else
34648 GetSystemTimeAsFileTime( &ft );
34649 #endif
34650
@@ -34656,19 +34696,19 @@
34656 if( sqlite3_current_time ){
34657 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
34658 }
34659 #endif
34660 UNUSED_PARAMETER(pVfs);
34661 return 0;
34662 }
34663
34664 /*
34665 ** Find the current time (in Universal Coordinated Time). Write the
34666 ** current time and date as a Julian Day number into *prNow and
34667 ** return 0. Return 1 if the time and date cannot be found.
34668 */
34669 int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
34670 int rc;
34671 sqlite3_int64 i;
34672 rc = winCurrentTimeInt64(pVfs, &i);
34673 if( !rc ){
34674 *prNow = i/86400000.0;
@@ -35789,12 +35829,10 @@
35789 typedef struct PCache1 PCache1;
35790 typedef struct PgHdr1 PgHdr1;
35791 typedef struct PgFreeslot PgFreeslot;
35792 typedef struct PGroup PGroup;
35793
35794 typedef struct PGroupBlock PGroupBlock;
35795 typedef struct PGroupBlockList PGroupBlockList;
35796
35797 /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
35798 ** of one or more PCaches that are able to recycle each others unpinned
35799 ** pages when they are under memory pressure. A PGroup is an instance of
35800 ** the following object.
@@ -35821,69 +35859,11 @@
35821 int nMaxPage; /* Sum of nMax for purgeable caches */
35822 int nMinPage; /* Sum of nMin for purgeable caches */
35823 int mxPinned; /* nMaxpage + 10 - nMinPage */
35824 int nCurrentPage; /* Number of purgeable pages allocated */
35825 PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
35826 #ifdef SQLITE_PAGECACHE_BLOCKALLOC
35827 int isBusy; /* Do not run ReleaseMemory() if true */
35828 PGroupBlockList *pBlockList; /* List of block-lists for this group */
35829 #endif
35830 };
35831
35832 /*
35833 ** If SQLITE_PAGECACHE_BLOCKALLOC is defined when the library is built,
35834 ** each PGroup structure has a linked list of the the following starting
35835 ** at PGroup.pBlockList. There is one entry for each distinct page-size
35836 ** currently used by members of the PGroup (i.e. 1024 bytes, 4096 bytes
35837 ** etc.). Variable PGroupBlockList.nByte is set to the actual allocation
35838 ** size requested by each pcache, which is the database page-size plus
35839 ** the various header structures used by the pcache, pager and btree layers.
35840 ** Usually around (pgsz+200) bytes.
35841 **
35842 ** This size (pgsz+200) bytes is not allocated efficiently by some
35843 ** implementations of malloc. In particular, some implementations are only
35844 ** able to allocate blocks of memory chunks of 2^N bytes, where N is some
35845 ** integer value. Since the page-size is a power of 2, this means we
35846 ** end up wasting (pgsz-200) bytes in each allocation.
35847 **
35848 ** If SQLITE_PAGECACHE_BLOCKALLOC is defined, the (pgsz+200) byte blocks
35849 ** are not allocated directly. Instead, blocks of roughly M*(pgsz+200) bytes
35850 ** are requested from malloc allocator. After a block is returned,
35851 ** sqlite3MallocSize() is used to determine how many (pgsz+200) byte
35852 ** allocations can fit in the space returned by malloc(). This value may
35853 ** be more than M.
35854 **
35855 ** The blocks are stored in a doubly-linked list. Variable PGroupBlock.nEntry
35856 ** contains the number of allocations that will fit in the aData[] space.
35857 ** nEntry is limited to the number of bits in bitmask mUsed. If a slot
35858 ** within aData is in use, the corresponding bit in mUsed is set. Thus
35859 ** when (mUsed+1==(1 << nEntry)) the block is completely full.
35860 **
35861 ** Each time a slot within a block is freed, the block is moved to the start
35862 ** of the linked-list. And if a block becomes completely full, then it is
35863 ** moved to the end of the list. As a result, when searching for a free
35864 ** slot, only the first block in the list need be examined. If it is full,
35865 ** then it is guaranteed that all blocks are full.
35866 */
35867 struct PGroupBlockList {
35868 int nByte; /* Size of each allocation in bytes */
35869 PGroupBlock *pFirst; /* First PGroupBlock in list */
35870 PGroupBlock *pLast; /* Last PGroupBlock in list */
35871 PGroupBlockList *pNext; /* Next block-list attached to group */
35872 };
35873
35874 struct PGroupBlock {
35875 Bitmask mUsed; /* Mask of used slots */
35876 int nEntry; /* Maximum number of allocations in aData[] */
35877 u8 *aData; /* Pointer to data block */
35878 PGroupBlock *pNext; /* Next PGroupBlock in list */
35879 PGroupBlock *pPrev; /* Previous PGroupBlock in list */
35880 PGroupBlockList *pList; /* Owner list */
35881 };
35882
35883 /* Minimum value for PGroupBlock.nEntry */
35884 #define PAGECACHE_BLOCKALLOC_MINENTRY 15
35885
35886 /* Each page cache is an instance of the following object. Every
35887 ** open database file (including each in-memory database and each
35888 ** temporary or transient database) has a single page cache which
35889 ** is an instance of this object.
@@ -35983,21 +35963,10 @@
35983 **
35984 ** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
35985 */
35986 #define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
35987 #define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
35988
35989 /*
35990 ** Blocks used by the SQLITE_PAGECACHE_BLOCKALLOC blocks to store/retrieve
35991 ** a PGroupBlock pointer based on a pointer to a page buffer.
35992 */
35993 #define PAGE_SET_BLOCKPTR(pCache, pPg, pBlock) \
35994 ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) = pBlock )
35995
35996 #define PAGE_GET_BLOCKPTR(pCache, pPg) \
35997 ( *(PGroupBlock **)&(((u8*)pPg)[sizeof(PgHdr1) + pCache->szPage]) )
35998
35999
36000 /*
36001 ** Macros to enter and leave the PCache LRU mutex.
36002 */
36003 #define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
@@ -36120,159 +36089,32 @@
36120 return iSize;
36121 }
36122 }
36123 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
36124
36125 #ifdef SQLITE_PAGECACHE_BLOCKALLOC
36126 /*
36127 ** The block pBlock belongs to list pList but is not currently linked in.
36128 ** Insert it into the start of the list.
36129 */
36130 static void addBlockToList(PGroupBlockList *pList, PGroupBlock *pBlock){
36131 pBlock->pPrev = 0;
36132 pBlock->pNext = pList->pFirst;
36133 pList->pFirst = pBlock;
36134 if( pBlock->pNext ){
36135 pBlock->pNext->pPrev = pBlock;
36136 }else{
36137 assert( pList->pLast==0 );
36138 pList->pLast = pBlock;
36139 }
36140 }
36141
36142 /*
36143 ** If there are no blocks in the list headed by pList, remove pList
36144 ** from the pGroup->pBlockList list and free it with sqlite3_free().
36145 */
36146 static void freeListIfEmpty(PGroup *pGroup, PGroupBlockList *pList){
36147 assert( sqlite3_mutex_held(pGroup->mutex) );
36148 if( pList->pFirst==0 ){
36149 PGroupBlockList **pp;
36150 for(pp=&pGroup->pBlockList; *pp!=pList; pp=&(*pp)->pNext);
36151 *pp = (*pp)->pNext;
36152 sqlite3_free(pList);
36153 }
36154 }
36155 #endif /* SQLITE_PAGECACHE_BLOCKALLOC */
36156
36157 /*
36158 ** Allocate a new page object initially associated with cache pCache.
36159 */
36160 static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
36161 int nByte = sizeof(PgHdr1) + pCache->szPage;
36162 void *pPg = 0;
36163 PgHdr1 *p;
36164
36165 #ifdef SQLITE_PAGECACHE_BLOCKALLOC
36166 PGroup *pGroup = pCache->pGroup;
36167 PGroupBlockList *pList;
36168 PGroupBlock *pBlock;
36169 int i;
36170
36171 nByte += sizeof(PGroupBlockList *);
36172 nByte = ROUND8(nByte);
36173
36174 for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
36175 if( pList->nByte==nByte ) break;
36176 }
36177 if( pList==0 ){
36178 PGroupBlockList *pNew;
36179 assert( pGroup->isBusy==0 );
36180 assert( sqlite3_mutex_held(pGroup->mutex) );
36181 pGroup->isBusy = 1; /* Disable sqlite3PcacheReleaseMemory() */
36182 pNew = (PGroupBlockList *)sqlite3MallocZero(sizeof(PGroupBlockList));
36183 pGroup->isBusy = 0; /* Reenable sqlite3PcacheReleaseMemory() */
36184 if( pNew==0 ){
36185 /* malloc() failure. Return early. */
36186 return 0;
36187 }
36188 #ifdef SQLITE_DEBUG
36189 for(pList=pGroup->pBlockList; pList; pList=pList->pNext){
36190 assert( pList->nByte!=nByte );
36191 }
36192 #endif
36193 pNew->nByte = nByte;
36194 pNew->pNext = pGroup->pBlockList;
36195 pGroup->pBlockList = pNew;
36196 pList = pNew;
36197 }
36198
36199 pBlock = pList->pFirst;
36200 if( pBlock==0 || pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) ){
36201 int sz;
36202
36203 /* Allocate a new block. Try to allocate enough space for the PGroupBlock
36204 ** structure and MINENTRY allocations of nByte bytes each. If the
36205 ** allocator returns more memory than requested, then more than MINENTRY
36206 ** allocations may fit in it. */
36207 assert( sqlite3_mutex_held(pGroup->mutex) );
36208 pcache1LeaveMutex(pCache->pGroup);
36209 sz = sizeof(PGroupBlock) + PAGECACHE_BLOCKALLOC_MINENTRY * nByte;
36210 pBlock = (PGroupBlock *)sqlite3Malloc(sz);
36211 pcache1EnterMutex(pCache->pGroup);
36212
36213 if( !pBlock ){
36214 freeListIfEmpty(pGroup, pList);
36215 return 0;
36216 }
36217 pBlock->nEntry = (sqlite3MallocSize(pBlock) - sizeof(PGroupBlock)) / nByte;
36218 if( pBlock->nEntry>=BMS ){
36219 pBlock->nEntry = BMS-1;
36220 }
36221 pBlock->pList = pList;
36222 pBlock->mUsed = 0;
36223 pBlock->aData = (u8 *)&pBlock[1];
36224 addBlockToList(pList, pBlock);
36225
36226 sz = sqlite3MallocSize(pBlock);
36227 sqlite3_mutex_enter(pcache1.mutex);
36228 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz);
36229 sqlite3_mutex_leave(pcache1.mutex);
36230 }
36231
36232 for(i=0; pPg==0 && ALWAYS(i<pBlock->nEntry); i++){
36233 if( 0==(pBlock->mUsed & ((Bitmask)1<<i)) ){
36234 pBlock->mUsed |= ((Bitmask)1<<i);
36235 pPg = (void *)&pBlock->aData[pList->nByte * i];
36236 }
36237 }
36238 assert( pPg );
36239 PAGE_SET_BLOCKPTR(pCache, pPg, pBlock);
36240
36241 /* If the block is now full, shift it to the end of the list */
36242 if( pBlock->mUsed==(((Bitmask)1<<pBlock->nEntry)-1) && pList->pLast!=pBlock ){
36243 assert( pList->pFirst==pBlock );
36244 assert( pBlock->pPrev==0 );
36245 assert( pList->pLast->pNext==0 );
36246 pList->pFirst = pBlock->pNext;
36247 pList->pFirst->pPrev = 0;
36248 pBlock->pPrev = pList->pLast;
36249 pBlock->pNext = 0;
36250 pList->pLast->pNext = pBlock;
36251 pList->pLast = pBlock;
36252 }
36253 p = PAGE_TO_PGHDR1(pCache, pPg);
36254 if( pCache->bPurgeable ){
36255 pCache->pGroup->nCurrentPage++;
36256 }
36257 #else
36258 /* The group mutex must be released before pcache1Alloc() is called. This
36259 ** is because it may call sqlite3_release_memory(), which assumes that
36260 ** this mutex is not held. */
36261 assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
36262 pcache1LeaveMutex(pCache->pGroup);
36263 pPg = pcache1Alloc(nByte);
36264 pcache1EnterMutex(pCache->pGroup);
 
36265 if( pPg ){
36266 p = PAGE_TO_PGHDR1(pCache, pPg);
36267 if( pCache->bPurgeable ){
36268 pCache->pGroup->nCurrentPage++;
36269 }
36270 }else{
36271 p = 0;
36272 }
36273 #endif
36274 return p;
36275 }
36276
36277 /*
36278 ** Free a page object allocated by pcache1AllocPage().
@@ -36282,53 +36124,12 @@
36282 ** with a NULL pointer, so we mark the NULL test with ALWAYS().
36283 */
36284 static void pcache1FreePage(PgHdr1 *p){
36285 if( ALWAYS(p) ){
36286 PCache1 *pCache = p->pCache;
36287 void *pPg = PGHDR1_TO_PAGE(p);
36288
36289 #ifdef SQLITE_PAGECACHE_BLOCKALLOC
36290 PGroupBlock *pBlock = PAGE_GET_BLOCKPTR(pCache, pPg);
36291 PGroupBlockList *pList = pBlock->pList;
36292 int i = ((u8 *)pPg - pBlock->aData) / pList->nByte;
36293
36294 assert( pPg==(void *)&pBlock->aData[i*pList->nByte] );
36295 assert( pBlock->mUsed & ((Bitmask)1<<i) );
36296 pBlock->mUsed &= ~((Bitmask)1<<i);
36297
36298 /* Remove the block from the list. If it is completely empty, free it.
36299 ** Or if it is not completely empty, re-insert it at the start of the
36300 ** list. */
36301 if( pList->pFirst==pBlock ){
36302 pList->pFirst = pBlock->pNext;
36303 if( pList->pFirst ) pList->pFirst->pPrev = 0;
36304 }else{
36305 pBlock->pPrev->pNext = pBlock->pNext;
36306 }
36307 if( pList->pLast==pBlock ){
36308 pList->pLast = pBlock->pPrev;
36309 if( pList->pLast ) pList->pLast->pNext = 0;
36310 }else{
36311 pBlock->pNext->pPrev = pBlock->pPrev;
36312 }
36313
36314 if( pBlock->mUsed==0 ){
36315 PGroup *pGroup = p->pCache->pGroup;
36316
36317 int sz = sqlite3MallocSize(pBlock);
36318 sqlite3_mutex_enter(pcache1.mutex);
36319 sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -sz);
36320 sqlite3_mutex_leave(pcache1.mutex);
36321 freeListIfEmpty(pGroup, pList);
36322 sqlite3_free(pBlock);
36323 }else{
36324 addBlockToList(pList, pBlock);
36325 }
36326 #else
36327 assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
36328 pcache1Free(pPg);
36329 #endif
36330 if( pCache->bPurgeable ){
36331 pCache->pGroup->nCurrentPage--;
36332 }
36333 }
36334 }
@@ -36935,13 +36736,10 @@
36935 ** been released, the function returns. The return value is the total number
36936 ** of bytes of memory released.
36937 */
36938 SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
36939 int nFree = 0;
36940 #ifdef SQLITE_PAGECACHE_BLOCKALLOC
36941 if( pcache1.grp.isBusy ) return 0;
36942 #endif
36943 assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
36944 assert( sqlite3_mutex_notheld(pcache1.mutex) );
36945 if( pcache1.pStart==0 ){
36946 PgHdr1 *p;
36947 pcache1EnterMutex(&pcache1.grp);
@@ -38200,12 +37998,12 @@
38200 i64 journalSizeLimit; /* Size limit for persistent journal files */
38201 char *zFilename; /* Name of the database file */
38202 char *zJournal; /* Name of the journal file */
38203 int (*xBusyHandler)(void*); /* Function to call when busy */
38204 void *pBusyHandlerArg; /* Context argument for xBusyHandler */
 
38205 #ifdef SQLITE_TEST
38206 int nHit, nMiss; /* Cache hits and missing */
38207 int nRead, nWrite; /* Database pages read/written */
38208 #endif
38209 void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
38210 #ifdef SQLITE_HAS_CODEC
38211 void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
@@ -40233,11 +40031,10 @@
40233 needPagerReset = 0;
40234 }
40235 rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
40236 if( rc!=SQLITE_OK ){
40237 if( rc==SQLITE_DONE ){
40238 rc = SQLITE_OK;
40239 pPager->journalOff = szJ;
40240 break;
40241 }else if( rc==SQLITE_IOERR_SHORT_READ ){
40242 /* If the journal has been truncated, simply stop reading and
40243 ** processing the journal. This might happen if the journal was
@@ -40495,10 +40292,11 @@
40495 #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
40496 PgHdr *p; /* For looping over pages */
40497 #endif
40498
40499 assert( pPager->pWal );
 
40500 #ifdef SQLITE_DEBUG
40501 /* Verify that the page list is in accending order */
40502 for(p=pList; p && p->pDirty; p=p->pDirty){
40503 assert( p->pgno < p->pDirty->pgno );
40504 }
@@ -41699,11 +41497,11 @@
41699 ** The doNotSpill flag inhibits all cache spilling regardless of whether
41700 ** or not a sync is required. This is set during a rollback.
41701 **
41702 ** Spilling is also prohibited when in an error state since that could
41703 ** lead to database corruption. In the current implementaton it
41704 ** is impossible for sqlite3PCacheFetch() to be called with createFlag==1
41705 ** while in the error state, hence it is impossible for this routine to
41706 ** be called in the error state. Nevertheless, we include a NEVER()
41707 ** test for the error state as a safeguard against future changes.
41708 */
41709 if( NEVER(pPager->errCode) ) return SQLITE_OK;
@@ -42535,18 +42333,17 @@
42535
42536 if( (*ppPage)->pPager && !noContent ){
42537 /* In this case the pcache already contains an initialized copy of
42538 ** the page. Return without further ado. */
42539 assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
42540 PAGER_INCR(pPager->nHit);
42541 return SQLITE_OK;
42542
42543 }else{
42544 /* The pager cache has created a new page. Its content needs to
42545 ** be initialized. */
42546
42547 PAGER_INCR(pPager->nMiss);
42548 pPg = *ppPage;
42549 pPg->pPager = pPager;
42550
42551 /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
42552 ** number greater than this, or the unused locking-page, is requested. */
@@ -42578,10 +42375,11 @@
42578 }
42579 memset(pPg->pData, 0, pPager->pageSize);
42580 IOTRACE(("ZERO %p %d\n", pPager, pgno));
42581 }else{
42582 assert( pPg->pPager==pPager );
 
42583 rc = readDbPage(pPg);
42584 if( rc!=SQLITE_OK ){
42585 goto pager_acquire_err;
42586 }
42587 }
@@ -43611,10 +43409,35 @@
43611 a[9] = pPager->nRead;
43612 a[10] = pPager->nWrite;
43613 return a;
43614 }
43615 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43616
43617 /*
43618 ** Return true if this is an in-memory pager.
43619 */
43620 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
@@ -46706,11 +46529,11 @@
46706 */
46707 if( iRead ){
46708 int sz;
46709 i64 iOffset;
46710 sz = pWal->hdr.szPage;
46711 sz = (pWal->hdr.szPage&0xfe00) + ((pWal->hdr.szPage&0x0001)<<16);
46712 testcase( sz<=32768 );
46713 testcase( sz>=65536 );
46714 iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
46715 *pInWal = 1;
46716 /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
@@ -50019,21 +49842,23 @@
50019 */
50020 if( isMemdb==0 && isTempDb==0 ){
50021 if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
50022 int nFullPathname = pVfs->mxPathname+1;
50023 char *zFullPathname = sqlite3Malloc(nFullPathname);
50024 sqlite3_mutex *mutexShared;
50025 p->sharable = 1;
50026 if( !zFullPathname ){
50027 sqlite3_free(p);
50028 return SQLITE_NOMEM;
50029 }
50030 sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
 
50031 mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
50032 sqlite3_mutex_enter(mutexOpen);
50033 mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
50034 sqlite3_mutex_enter(mutexShared);
 
50035 for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
50036 assert( pBt->nRef>0 );
50037 if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
50038 && sqlite3PagerVfs(pBt->pPager)==pVfs ){
50039 int iDb;
@@ -50135,13 +49960,13 @@
50135
50136 #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
50137 /* Add the new BtShared object to the linked list sharable BtShareds.
50138 */
50139 if( p->sharable ){
50140 sqlite3_mutex *mutexShared;
50141 pBt->nRef = 1;
50142 mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
50143 if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
50144 pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
50145 if( pBt->mutex==0 ){
50146 rc = SQLITE_NOMEM;
50147 db->mallocFailed = 0;
@@ -50219,16 +50044,16 @@
50219 ** true if the BtShared.nRef counter reaches zero and return
50220 ** false if it is still positive.
50221 */
50222 static int removeFromSharingList(BtShared *pBt){
50223 #ifndef SQLITE_OMIT_SHARED_CACHE
50224 sqlite3_mutex *pMaster;
50225 BtShared *pList;
50226 int removed = 0;
50227
50228 assert( sqlite3_mutex_notheld(pBt->mutex) );
50229 pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
50230 sqlite3_mutex_enter(pMaster);
50231 pBt->nRef--;
50232 if( pBt->nRef<=0 ){
50233 if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
50234 GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
@@ -52191,25 +52016,59 @@
52191 offset -= ovflSize;
52192 }else{
52193 /* Need to read this page properly. It contains some of the
52194 ** range of data that is being read (eOp==0) or written (eOp!=0).
52195 */
52196 DbPage *pDbPage;
 
 
52197 int a = amt;
52198 rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
52199 if( rc==SQLITE_OK ){
52200 aPayload = sqlite3PagerGetData(pDbPage);
52201 nextPage = get4byte(aPayload);
52202 if( a + offset > ovflSize ){
52203 a = ovflSize - offset;
52204 }
52205 rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
52206 sqlite3PagerUnref(pDbPage);
52207 offset = 0;
52208 amt -= a;
52209 pBuf += a;
52210 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52211 }
52212 }
52213 }
52214
52215 if( rc==SQLITE_OK && amt>0 ){
@@ -52804,11 +52663,10 @@
52804 }
52805 }
52806 if( c==0 ){
52807 if( pPage->intKey && !pPage->leaf ){
52808 lwr = idx;
52809 upr = lwr - 1;
52810 break;
52811 }else{
52812 *pRes = 0;
52813 rc = SQLITE_OK;
52814 goto moveto_finish;
@@ -52822,11 +52680,11 @@
52822 if( lwr>upr ){
52823 break;
52824 }
52825 pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
52826 }
52827 assert( lwr==upr+1 );
52828 assert( pPage->isInit );
52829 if( pPage->leaf ){
52830 chldPg = 0;
52831 }else if( lwr>=pPage->nCell ){
52832 chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
@@ -53087,10 +52945,12 @@
53087 }
53088 if( rc ){
53089 pTrunk = 0;
53090 goto end_allocate_page;
53091 }
 
 
53092
53093 k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
53094 if( k==0 && !searchList ){
53095 /* The trunk has no leaves and the list is not being searched.
53096 ** So extract the trunk page itself and use it as the newly
@@ -54214,17 +54074,19 @@
54214 ** This is safe because dropping a cell only overwrites the first
54215 ** four bytes of it, and this function does not need the first
54216 ** four bytes of the divider cell. So the pointer is safe to use
54217 ** later on.
54218 **
54219 ** Unless SQLite is compiled in secure-delete mode. In this case,
54220 ** the dropCell() routine will overwrite the entire cell with zeroes.
54221 ** In this case, temporarily copy the cell into the aOvflSpace[]
54222 ** buffer. It will be copied out again as soon as the aSpace[] buffer
54223 ** is allocated. */
54224 if( pBt->secureDelete ){
54225 int iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
 
 
54226 if( (iOff+szNew[i])>(int)pBt->usableSize ){
54227 rc = SQLITE_CORRUPT_BKPT;
54228 memset(apOld, 0, (i+1)*sizeof(MemPage*));
54229 goto balance_cleanup;
54230 }else{
@@ -54640,10 +54502,11 @@
54640 int isDivider = 0;
54641 while( i==iNextOld ){
54642 /* Cell i is the cell immediately following the last cell on old
54643 ** sibling page j. If the siblings are not leaf pages of an
54644 ** intkey b-tree, then cell i was a divider cell. */
 
54645 pOld = apCopy[++j];
54646 iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
54647 if( pOld->nOverflow ){
54648 nOverflow = pOld->nOverflow;
54649 iOverflow = i + !leafData + pOld->aOvfl[0].idx;
@@ -56982,18 +56845,18 @@
56982 /*
56983 ** Release all resources associated with an sqlite3_backup* handle.
56984 */
56985 SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
56986 sqlite3_backup **pp; /* Ptr to head of pagers backup list */
56987 sqlite3_mutex *mutex; /* Mutex to protect source database */
56988 int rc; /* Value to return */
56989
56990 /* Enter the mutexes */
56991 if( p==0 ) return SQLITE_OK;
56992 sqlite3_mutex_enter(p->pSrcDb->mutex);
56993 sqlite3BtreeEnter(p->pSrc);
56994 mutex = p->pSrcDb->mutex;
56995 if( p->pDestDb ){
56996 sqlite3_mutex_enter(p->pDestDb->mutex);
56997 }
56998
56999 /* Detach this backup from the source pager. */
@@ -57108,13 +56971,21 @@
57108 ** goes wrong, the transaction on pTo is rolled back. If successful, the
57109 ** transaction is committed before returning.
57110 */
57111 SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
57112 int rc;
 
57113 sqlite3_backup b;
57114 sqlite3BtreeEnter(pTo);
57115 sqlite3BtreeEnter(pFrom);
 
 
 
 
 
 
 
57116
57117 /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
57118 ** to 0. This is used by the implementations of sqlite3_backup_step()
57119 ** and sqlite3_backup_finish() to detect that they are being called
57120 ** from this function, not directly by the user.
@@ -57137,10 +57008,11 @@
57137 rc = sqlite3_backup_finish(&b);
57138 if( rc==SQLITE_OK ){
57139 pTo->pBt->pageSizeFixed = 0;
57140 }
57141
 
57142 sqlite3BtreeLeave(pFrom);
57143 sqlite3BtreeLeave(pTo);
57144 return rc;
57145 }
57146 #endif /* SQLITE_OMIT_VACUUM */
@@ -58171,15 +58043,15 @@
58171 *ppVal = 0;
58172 return SQLITE_OK;
58173 }
58174 op = pExpr->op;
58175
58176 /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT2.
58177 ** The ifdef here is to enable us to achieve 100% branch test coverage even
58178 ** when SQLITE_ENABLE_STAT2 is omitted.
58179 */
58180 #ifdef SQLITE_ENABLE_STAT2
58181 if( op==TK_REGISTER ) op = pExpr->op2;
58182 #else
58183 if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
58184 #endif
58185
@@ -58874,12 +58746,12 @@
58874 /*
58875 ** Change the P2 operand of instruction addr so that it points to
58876 ** the address of the next instruction to be coded.
58877 */
58878 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
58879 assert( addr>=0 );
58880 sqlite3VdbeChangeP2(p, addr, p->nOp);
58881 }
58882
58883
58884 /*
58885 ** If the input FuncDef structure is ephemeral, then free it. If
@@ -59080,34 +58952,33 @@
59080 ** Change the comment on the the most recently coded instruction. Or
59081 ** insert a No-op and add the comment to that new instruction. This
59082 ** makes the code easier to read during debugging. None of this happens
59083 ** in a production build.
59084 */
59085 SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
59086 va_list ap;
59087 if( !p ) return;
59088 assert( p->nOp>0 || p->aOp==0 );
59089 assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
59090 if( p->nOp ){
59091 char **pz = &p->aOp[p->nOp-1].zComment;
 
 
 
 
 
 
 
59092 va_start(ap, zFormat);
59093 sqlite3DbFree(p->db, *pz);
59094 *pz = sqlite3VMPrintf(p->db, zFormat, ap);
59095 va_end(ap);
59096 }
59097 }
59098 SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
59099 va_list ap;
59100 if( !p ) return;
59101 sqlite3VdbeAddOp0(p, OP_Noop);
59102 assert( p->nOp>0 || p->aOp==0 );
59103 assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
59104 if( p->nOp ){
59105 char **pz = &p->aOp[p->nOp-1].zComment;
59106 va_start(ap, zFormat);
59107 sqlite3DbFree(p->db, *pz);
59108 *pz = sqlite3VMPrintf(p->db, zFormat, ap);
59109 va_end(ap);
59110 }
59111 }
59112 #endif /* NDEBUG */
59113
@@ -59441,11 +59312,11 @@
59441 SubProgram **apSub = 0; /* Array of sub-vdbes */
59442 Mem *pSub = 0; /* Memory cell hold array of subprogs */
59443 sqlite3 *db = p->db; /* The database connection */
59444 int i; /* Loop counter */
59445 int rc = SQLITE_OK; /* Return code */
59446 Mem *pMem = p->pResultSet = &p->aMem[1]; /* First Mem of result set */
59447
59448 assert( p->explain );
59449 assert( p->magic==VDBE_MAGIC_RUN );
59450 assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
59451
@@ -59452,10 +59323,11 @@
59452 /* Even though this opcode does not use dynamic strings for
59453 ** the result, result columns may become dynamic if the user calls
59454 ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
59455 */
59456 releaseMemArray(pMem, 8);
 
59457
59458 if( p->rc==SQLITE_NOMEM ){
59459 /* This happens if a malloc() inside a call to sqlite3_column_text() or
59460 ** sqlite3_column_text16() failed. */
59461 db->mallocFailed = 1;
@@ -59606,10 +59478,11 @@
59606 pMem->type = SQLITE_NULL;
59607 }
59608 }
59609
59610 p->nResColumn = 8 - 4*(p->explain-1);
 
59611 p->rc = SQLITE_OK;
59612 rc = SQLITE_ROW;
59613 }
59614 return rc;
59615 }
@@ -61361,11 +61234,11 @@
61361 ** than 2GiB are support - anything large must be database corruption.
61362 ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
61363 ** this code can safely assume that nCellKey is 32-bits
61364 */
61365 assert( sqlite3BtreeCursorIsValid(pCur) );
61366 rc = sqlite3BtreeKeySize(pCur, &nCellKey);
61367 assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
61368 assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
61369
61370 /* Read in the complete content of the index entry */
61371 memset(&m, 0, sizeof(m));
@@ -61436,11 +61309,11 @@
61436 int rc;
61437 BtCursor *pCur = pC->pCursor;
61438 Mem m;
61439
61440 assert( sqlite3BtreeCursorIsValid(pCur) );
61441 rc = sqlite3BtreeKeySize(pCur, &nCellKey);
61442 assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
61443 /* nCellKey will always be between 0 and 0xffffffff because of the say
61444 ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
61445 if( nCellKey<=0 || nCellKey>0x7fffffff ){
61446 *res = 0;
@@ -65712,20 +65585,20 @@
65712 }else if( u.am.pC->cacheStatus==p->cacheCtr ){
65713 u.am.payloadSize = u.am.pC->payloadSize;
65714 u.am.zRec = (char*)u.am.pC->aRow;
65715 }else if( u.am.pC->isIndex ){
65716 assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
65717 rc = sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64);
65718 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
65719 /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
65720 ** payload size, so it is impossible for u.am.payloadSize64 to be
65721 ** larger than 32 bits. */
65722 assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 );
65723 u.am.payloadSize = (u32)u.am.payloadSize64;
65724 }else{
65725 assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
65726 rc = sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
65727 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
65728 }
65729 }else if( ALWAYS(u.am.pC->pseudoTableReg>0) ){
65730 u.am.pReg = &aMem[u.am.pC->pseudoTableReg];
65731 assert( u.am.pReg->flags & MEM_Blob );
@@ -67773,18 +67646,18 @@
67773 rc = sqlite3VdbeCursorMoveto(u.bk.pC);
67774 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
67775
67776 if( u.bk.pC->isIndex ){
67777 assert( !u.bk.pC->isTable );
67778 rc = sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64);
67779 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
67780 if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
67781 goto too_big;
67782 }
67783 u.bk.n = (u32)u.bk.n64;
67784 }else{
67785 rc = sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
67786 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
67787 if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
67788 goto too_big;
67789 }
67790 }
@@ -69095,11 +68968,11 @@
69095
69096 /* Do not allow a transition to journal_mode=WAL for a database
69097 ** in temporary storage or if the VFS does not support shared memory
69098 */
69099 if( u.ch.eNew==PAGER_JOURNALMODE_WAL
69100 && (u.ch.zFilename[0]==0 /* Temp file */
69101 || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */
69102 ){
69103 u.ch.eNew = u.ch.eOld;
69104 }
69105
@@ -69530,14 +69403,19 @@
69530 u.co.pName = &aMem[pOp->p1];
69531 assert( u.co.pVtab->pModule->xRename );
69532 assert( memIsValid(u.co.pName) );
69533 REGISTER_TRACE(pOp->p1, u.co.pName);
69534 assert( u.co.pName->flags & MEM_Str );
69535 rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z);
69536 importVtabErrMsg(p, u.co.pVtab);
69537 p->expired = 0;
69538
 
 
 
 
 
69539 break;
69540 }
69541 #endif
69542
69543 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -71891,10 +71769,28 @@
71891 ExprSetProperty(pExpr, EP_Static);
71892 sqlite3ExprDelete(db, pExpr);
71893 memcpy(pExpr, pDup, sizeof(*pExpr));
71894 sqlite3DbFree(db, pDup);
71895 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71896
71897 /*
71898 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
71899 ** that name in the set of source tables in pSrcList and make the pExpr
71900 ** expression node refer back to that source column. The following changes
@@ -71983,38 +71879,25 @@
71983 pSchema = pTab->pSchema;
71984 pMatch = pItem;
71985 }
71986 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
71987 if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
71988 IdList *pUsing;
 
 
 
 
 
 
 
71989 cnt++;
71990 pExpr->iTable = pItem->iCursor;
71991 pExpr->pTab = pTab;
71992 pMatch = pItem;
71993 pSchema = pTab->pSchema;
71994 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
71995 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
71996 if( i<pSrcList->nSrc-1 ){
71997 if( pItem[1].jointype & JT_NATURAL ){
71998 /* If this match occurred in the left table of a natural join,
71999 ** then skip the right table to avoid a duplicate match */
72000 pItem++;
72001 i++;
72002 }else if( (pUsing = pItem[1].pUsing)!=0 ){
72003 /* If this match occurs on a column that is in the USING clause
72004 ** of a join, skip the search of the right table of the join
72005 ** to avoid a duplicate match there. */
72006 int k;
72007 for(k=0; k<pUsing->nId; k++){
72008 if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ){
72009 pItem++;
72010 i++;
72011 break;
72012 }
72013 }
72014 }
72015 }
72016 break;
72017 }
72018 }
72019 }
72020 }
@@ -73417,11 +73300,12 @@
73417 pNew->flags |= EP_IntValue;
73418 pNew->u.iValue = iValue;
73419 }else{
73420 int c;
73421 pNew->u.zToken = (char*)&pNew[1];
73422 memcpy(pNew->u.zToken, pToken->z, pToken->n);
 
73423 pNew->u.zToken[pToken->n] = 0;
73424 if( dequote && nExtra>=3
73425 && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
73426 sqlite3Dequote(pNew->u.zToken);
73427 if( c=='"' ) pNew->flags |= EP_DblQuoted;
@@ -74456,15 +74340,23 @@
74456 ** ephemeral table.
74457 */
74458 p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
74459 if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
74460 sqlite3 *db = pParse->db; /* Database connection */
74461 Expr *pExpr = p->pEList->a[0].pExpr; /* Expression <column> */
74462 int iCol = pExpr->iColumn; /* Index of column <column> */
74463 Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
74464 Table *pTab = p->pSrc->a[0].pTab; /* Table <table>. */
 
 
74465 int iDb; /* Database idx for pTab */
 
 
 
 
 
 
 
 
74466
74467 /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
74468 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
74469 sqlite3CodeVerifySchema(pParse, iDb);
74470 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -76467,11 +76359,11 @@
76467 if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
76468 return 2;
76469 }
76470 }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
76471 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
76472 if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ){
76473 return 2;
76474 }
76475 }
76476 if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
76477 if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
@@ -77610,10 +77502,112 @@
77610 ** May you find forgiveness for yourself and forgive others.
77611 ** May you share freely, never taking more than you give.
77612 **
77613 *************************************************************************
77614 ** This file contains code associated with the ANALYZE command.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77615 */
77616 #ifndef SQLITE_OMIT_ANALYZE
77617
77618 /*
77619 ** This routine generates code that opens the sqlite_stat1 table for
@@ -77641,12 +77635,12 @@
77641 static const struct {
77642 const char *zName;
77643 const char *zCols;
77644 } aTable[] = {
77645 { "sqlite_stat1", "tbl,idx,stat" },
77646 #ifdef SQLITE_ENABLE_STAT2
77647 { "sqlite_stat2", "tbl,idx,sampleno,sample" },
77648 #endif
77649 };
77650
77651 int aRoot[] = {0, 0};
77652 u8 aCreateTbl[] = {0, 0};
@@ -77658,10 +77652,13 @@
77658 if( v==0 ) return;
77659 assert( sqlite3BtreeHoldsAllMutexes(db) );
77660 assert( sqlite3VdbeDb(v)==db );
77661 pDb = &db->aDb[iDb];
77662
 
 
 
77663 for(i=0; i<ArraySize(aTable); i++){
77664 const char *zTab = aTable[i].zName;
77665 Table *pStat;
77666 if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
77667 /* The sqlite_stat[12] table does not exist. Create it. Note that a
@@ -77688,17 +77685,237 @@
77688 sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
77689 }
77690 }
77691 }
77692
77693 /* Open the sqlite_stat[12] tables for writing. */
77694 for(i=0; i<ArraySize(aTable); i++){
77695 sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
77696 sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
77697 sqlite3VdbeChangeP5(v, aCreateTbl[i]);
77698 }
77699 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77700
77701 /*
77702 ** Generate code to do an analysis of all indices associated with
77703 ** a single table.
77704 */
@@ -77718,24 +77935,31 @@
77718 int endOfLoop; /* The end of the loop */
77719 int jZeroRows = -1; /* Jump from here if number of rows is zero */
77720 int iDb; /* Index of database containing pTab */
77721 int regTabname = iMem++; /* Register containing table name */
77722 int regIdxname = iMem++; /* Register containing index name */
77723 int regSampleno = iMem++; /* Register containing next sample number */
77724 int regCol = iMem++; /* Content of a column analyzed table */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77725 int regRec = iMem++; /* Register holding completed record */
77726 int regTemp = iMem++; /* Temporary use register */
77727 int regRowid = iMem++; /* Rowid for the inserted record */
77728
77729 #ifdef SQLITE_ENABLE_STAT2
77730 int addr = 0; /* Instruction address */
77731 int regTemp2 = iMem++; /* Temporary use register */
77732 int regSamplerecno = iMem++; /* Index of next sample to record */
77733 int regRecno = iMem++; /* Current sample index */
77734 int regLast = iMem++; /* Index of last sample to record */
77735 int regFirst = iMem++; /* Index of first sample to record */
77736 #endif
77737
77738 v = sqlite3GetVdbe(pParse);
77739 if( v==0 || NEVER(pTab==0) ){
77740 return;
77741 }
@@ -77764,13 +77988,18 @@
77764 iIdxCur = pParse->nTab++;
77765 sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
77766 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
77767 int nCol;
77768 KeyInfo *pKey;
 
 
77769
77770 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
 
77771 nCol = pIdx->nColumn;
 
 
77772 pKey = sqlite3IndexKeyinfo(pParse, pIdx);
77773 if( iMem+1+(nCol*2)>pParse->nMem ){
77774 pParse->nMem = iMem+1+(nCol*2);
77775 }
77776
@@ -77781,35 +78010,24 @@
77781 VdbeComment((v, "%s", pIdx->zName));
77782
77783 /* Populate the register containing the index name. */
77784 sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
77785
77786 #ifdef SQLITE_ENABLE_STAT2
77787
77788 /* If this iteration of the loop is generating code to analyze the
77789 ** first index in the pTab->pIndex list, then register regLast has
77790 ** not been populated. In this case populate it now. */
77791 if( pTab->pIndex==pIdx ){
77792 sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno);
77793 sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp);
77794 sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2);
77795
77796 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast);
77797 sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst);
77798 addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast);
77799 sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst);
77800 sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast);
77801 sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2);
77802 sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regLast);
77803 sqlite3VdbeJumpHere(v, addr);
77804 }
77805
77806 /* Zero the regSampleno and regRecno registers. */
77807 sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno);
77808 sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno);
77809 sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno);
77810 #endif
77811
77812 /* The block of memory cells initialized here is used as follows.
77813 **
77814 ** iMem:
77815 ** The total number of rows in the table.
@@ -77835,79 +78053,87 @@
77835 /* Start the analysis loop. This loop runs through all the entries in
77836 ** the index b-tree. */
77837 endOfLoop = sqlite3VdbeMakeLabel(v);
77838 sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
77839 topOfLoop = sqlite3VdbeCurrentAddr(v);
77840 sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1);
77841
77842 for(i=0; i<nCol; i++){
77843 CollSeq *pColl;
77844 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
77845 if( i==0 ){
77846 #ifdef SQLITE_ENABLE_STAT2
77847 /* Check if the record that cursor iIdxCur points to contains a
77848 ** value that should be stored in the sqlite_stat2 table. If so,
77849 ** store it. */
77850 int ne = sqlite3VdbeAddOp3(v, OP_Ne, regRecno, 0, regSamplerecno);
77851 assert( regTabname+1==regIdxname
77852 && regTabname+2==regSampleno
77853 && regTabname+3==regCol
77854 );
77855 sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
77856 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 4, regRec, "aaab", 0);
77857 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regRowid);
77858 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regRowid);
77859
77860 /* Calculate new values for regSamplerecno and regSampleno.
77861 **
77862 ** sampleno = sampleno + 1
77863 ** samplerecno = samplerecno+(remaining records)/(remaining samples)
77864 */
77865 sqlite3VdbeAddOp2(v, OP_AddImm, regSampleno, 1);
77866 sqlite3VdbeAddOp3(v, OP_Subtract, regRecno, regLast, regTemp);
77867 sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
77868 sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regTemp2);
77869 sqlite3VdbeAddOp3(v, OP_Subtract, regSampleno, regTemp2, regTemp2);
77870 sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regTemp, regTemp);
77871 sqlite3VdbeAddOp3(v, OP_Add, regSamplerecno, regTemp, regSamplerecno);
77872
77873 sqlite3VdbeJumpHere(v, ne);
77874 sqlite3VdbeAddOp2(v, OP_AddImm, regRecno, 1);
77875 #endif
77876
77877 /* Always record the very first row */
77878 sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
77879 }
77880 assert( pIdx->azColl!=0 );
77881 assert( pIdx->azColl[i]!=0 );
77882 pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
77883 sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
77884 (char*)pColl, P4_COLLSEQ);
77885 sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
77886 }
77887 if( db->mallocFailed ){
77888 /* If a malloc failure has occurred, then the result of the expression
77889 ** passed as the second argument to the call to sqlite3VdbeJumpHere()
77890 ** below may be negative. Which causes an assert() to fail (or an
77891 ** out-of-bounds write if SQLITE_DEBUG is not defined). */
77892 return;
77893 }
77894 sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
77895 for(i=0; i<nCol; i++){
77896 int addr2 = sqlite3VdbeCurrentAddr(v) - (nCol*2);
77897 if( i==0 ){
77898 sqlite3VdbeJumpHere(v, addr2-1); /* Set jump dest for the OP_IfNot */
 
 
 
 
 
 
 
 
 
77899 }
77900 sqlite3VdbeJumpHere(v, addr2); /* Set jump dest for the OP_Ne */
77901 sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
77902 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
77903 }
 
77904
77905 /* End of the analysis loop. */
77906 sqlite3VdbeResolveLabel(v, endOfLoop);
 
77907 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
77908 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77909
77910 /* Store the results in sqlite_stat1.
77911 **
77912 ** The result is a single row of the sqlite_stat1 table. The first
77913 ** two columns are the names of the table and index. The third column
@@ -77923,50 +78149,51 @@
77923 **
77924 ** If K==0 then no entry is made into the sqlite_stat1 table.
77925 ** If K>0 then it is always the case the D>0 so division by zero
77926 ** is never possible.
77927 */
77928 sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno);
77929 if( jZeroRows<0 ){
77930 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
77931 }
77932 for(i=0; i<nCol; i++){
77933 sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
77934 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
77935 sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
77936 sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
77937 sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
77938 sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
77939 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regSampleno, regSampleno);
77940 }
77941 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
77942 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
77943 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
77944 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
77945 }
77946
77947 /* If the table has no indices, create a single sqlite_stat1 entry
77948 ** containing NULL as the index name and the row count as the content.
77949 */
77950 if( pTab->pIndex==0 ){
77951 sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
77952 VdbeComment((v, "%s", pTab->zName));
77953 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regSampleno);
77954 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
77955 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regSampleno);
77956 }else{
77957 sqlite3VdbeJumpHere(v, jZeroRows);
77958 jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
77959 }
77960 sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
77961 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
77962 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regRowid);
77963 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regRowid);
77964 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
77965 if( pParse->nMem<regRec ) pParse->nMem = regRec;
77966 sqlite3VdbeJumpHere(v, jZeroRows);
77967 }
 
77968
77969 /*
77970 ** Generate code that will cause the most recent index analysis to
77971 ** be loaded into internal hash tables where is can be used.
77972 */
@@ -77987,11 +78214,11 @@
77987 int iStatCur;
77988 int iMem;
77989
77990 sqlite3BeginWriteOperation(pParse, 0, iDb);
77991 iStatCur = pParse->nTab;
77992 pParse->nTab += 2;
77993 openStatTable(pParse, iDb, iStatCur, 0, 0);
77994 iMem = pParse->nMem+1;
77995 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
77996 for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
77997 Table *pTab = (Table*)sqliteHashData(k);
@@ -78012,11 +78239,11 @@
78012 assert( pTab!=0 );
78013 assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
78014 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
78015 sqlite3BeginWriteOperation(pParse, 0, iDb);
78016 iStatCur = pParse->nTab;
78017 pParse->nTab += 2;
78018 if( pOnlyIdx ){
78019 openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
78020 }else{
78021 openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
78022 }
@@ -78117,11 +78344,11 @@
78117 static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
78118 analysisInfo *pInfo = (analysisInfo*)pData;
78119 Index *pIndex;
78120 Table *pTable;
78121 int i, c, n;
78122 unsigned int v;
78123 const char *z;
78124
78125 assert( argc==3 );
78126 UNUSED_PARAMETER2(NotUsed, argc);
78127
@@ -78160,40 +78387,172 @@
78160 /*
78161 ** If the Index.aSample variable is not NULL, delete the aSample[] array
78162 ** and its contents.
78163 */
78164 SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
78165 #ifdef SQLITE_ENABLE_STAT2
78166 if( pIdx->aSample ){
78167 int j;
78168 for(j=0; j<SQLITE_INDEX_SAMPLES; j++){
78169 IndexSample *p = &pIdx->aSample[j];
78170 if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
78171 sqlite3DbFree(db, p->u.z);
78172 }
78173 }
78174 sqlite3DbFree(db, pIdx->aSample);
 
 
 
 
78175 }
78176 #else
78177 UNUSED_PARAMETER(db);
78178 UNUSED_PARAMETER(pIdx);
78179 #endif
78180 }
78181
 
78182 /*
78183 ** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78184 ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
78185 ** arrays. The contents of sqlite_stat2 are used to populate the
78186 ** Index.aSample[] arrays.
78187 **
78188 ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
78189 ** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined
78190 ** during compilation and the sqlite_stat2 table is present, no data is
78191 ** read from it.
78192 **
78193 ** If SQLITE_ENABLE_STAT2 was defined during compilation and the
78194 ** sqlite_stat2 table is not present in the database, SQLITE_ERROR is
78195 ** returned. However, in this case, data is read from the sqlite_stat1
78196 ** table (if it is present) before returning.
78197 **
78198 ** If an OOM error occurs, this function always sets db->mallocFailed.
78199 ** This means if the caller does not care about other errors, the return
@@ -78211,12 +78570,14 @@
78211 /* Clear any prior statistics */
78212 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
78213 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
78214 Index *pIdx = sqliteHashData(i);
78215 sqlite3DefaultRowEst(pIdx);
 
78216 sqlite3DeleteIndexSamples(db, pIdx);
78217 pIdx->aSample = 0;
 
78218 }
78219
78220 /* Check to make sure the sqlite_stat1 table exists */
78221 sInfo.db = db;
78222 sInfo.zDatabase = db->aDb[iDb].zName;
@@ -78224,91 +78585,23 @@
78224 return SQLITE_ERROR;
78225 }
78226
78227 /* Load new statistics out of the sqlite_stat1 table */
78228 zSql = sqlite3MPrintf(db,
78229 "SELECT tbl, idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
78230 if( zSql==0 ){
78231 rc = SQLITE_NOMEM;
78232 }else{
78233 rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
78234 sqlite3DbFree(db, zSql);
78235 }
78236
78237
78238 /* Load the statistics from the sqlite_stat2 table. */
78239 #ifdef SQLITE_ENABLE_STAT2
78240 if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){
78241 rc = SQLITE_ERROR;
78242 }
78243 if( rc==SQLITE_OK ){
78244 sqlite3_stmt *pStmt = 0;
78245
78246 zSql = sqlite3MPrintf(db,
78247 "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase);
78248 if( !zSql ){
78249 rc = SQLITE_NOMEM;
78250 }else{
78251 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
78252 sqlite3DbFree(db, zSql);
78253 }
78254
78255 if( rc==SQLITE_OK ){
78256 while( sqlite3_step(pStmt)==SQLITE_ROW ){
78257 char *zIndex; /* Index name */
78258 Index *pIdx; /* Pointer to the index object */
78259
78260 zIndex = (char *)sqlite3_column_text(pStmt, 0);
78261 pIdx = zIndex ? sqlite3FindIndex(db, zIndex, sInfo.zDatabase) : 0;
78262 if( pIdx ){
78263 int iSample = sqlite3_column_int(pStmt, 1);
78264 if( iSample<SQLITE_INDEX_SAMPLES && iSample>=0 ){
78265 int eType = sqlite3_column_type(pStmt, 2);
78266
78267 if( pIdx->aSample==0 ){
78268 static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES;
78269 pIdx->aSample = (IndexSample *)sqlite3DbMallocRaw(0, sz);
78270 if( pIdx->aSample==0 ){
78271 db->mallocFailed = 1;
78272 break;
78273 }
78274 memset(pIdx->aSample, 0, sz);
78275 }
78276
78277 assert( pIdx->aSample );
78278 {
78279 IndexSample *pSample = &pIdx->aSample[iSample];
78280 pSample->eType = (u8)eType;
78281 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
78282 pSample->u.r = sqlite3_column_double(pStmt, 2);
78283 }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){
78284 const char *z = (const char *)(
78285 (eType==SQLITE_BLOB) ?
78286 sqlite3_column_blob(pStmt, 2):
78287 sqlite3_column_text(pStmt, 2)
78288 );
78289 int n = sqlite3_column_bytes(pStmt, 2);
78290 if( n>24 ){
78291 n = 24;
78292 }
78293 pSample->nByte = (u8)n;
78294 if( n < 1){
78295 pSample->u.z = 0;
78296 }else{
78297 pSample->u.z = sqlite3DbStrNDup(0, z, n);
78298 if( pSample->u.z==0 ){
78299 db->mallocFailed = 1;
78300 break;
78301 }
78302 }
78303 }
78304 }
78305 }
78306 }
78307 }
78308 rc = sqlite3_finalize(pStmt);
78309 }
78310 }
78311 #endif
78312
78313 if( rc==SQLITE_NOMEM ){
78314 db->mallocFailed = 1;
@@ -81120,11 +81413,15 @@
81120 Parse *pParse, /* The parsing context */
81121 int iDb, /* The database number */
81122 const char *zType, /* "idx" or "tbl" */
81123 const char *zName /* Name of index or table */
81124 ){
81125 static const char *azStatTab[] = { "sqlite_stat1", "sqlite_stat2" };
 
 
 
 
81126 int i;
81127 const char *zDbName = pParse->db->aDb[iDb].zName;
81128 for(i=0; i<ArraySize(azStatTab); i++){
81129 if( sqlite3FindTable(pParse->db, azStatTab[i], zDbName) ){
81130 sqlite3NestedParse(pParse,
@@ -81132,10 +81429,80 @@
81132 zDbName, azStatTab[i], zType, zName
81133 );
81134 }
81135 }
81136 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81137
81138 /*
81139 ** This routine is called to do the work of a DROP TABLE statement.
81140 ** pName is the name of the table to be dropped.
81141 */
@@ -81201,11 +81568,12 @@
81201 if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
81202 goto exit_drop_table;
81203 }
81204 }
81205 #endif
81206 if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){
 
81207 sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
81208 goto exit_drop_table;
81209 }
81210
81211 #ifndef SQLITE_OMIT_VIEW
@@ -81225,72 +81593,15 @@
81225 /* Generate code to remove the table from the master table
81226 ** on disk.
81227 */
81228 v = sqlite3GetVdbe(pParse);
81229 if( v ){
81230 Trigger *pTrigger;
81231 Db *pDb = &db->aDb[iDb];
81232 sqlite3BeginWriteOperation(pParse, 1, iDb);
81233
81234 #ifndef SQLITE_OMIT_VIRTUALTABLE
81235 if( IsVirtual(pTab) ){
81236 sqlite3VdbeAddOp0(v, OP_VBegin);
81237 }
81238 #endif
81239 sqlite3FkDropTable(pParse, pName, pTab);
81240
81241 /* Drop all triggers associated with the table being dropped. Code
81242 ** is generated to remove entries from sqlite_master and/or
81243 ** sqlite_temp_master if required.
81244 */
81245 pTrigger = sqlite3TriggerList(pParse, pTab);
81246 while( pTrigger ){
81247 assert( pTrigger->pSchema==pTab->pSchema ||
81248 pTrigger->pSchema==db->aDb[1].pSchema );
81249 sqlite3DropTriggerPtr(pParse, pTrigger);
81250 pTrigger = pTrigger->pNext;
81251 }
81252
81253 #ifndef SQLITE_OMIT_AUTOINCREMENT
81254 /* Remove any entries of the sqlite_sequence table associated with
81255 ** the table being dropped. This is done before the table is dropped
81256 ** at the btree level, in case the sqlite_sequence table needs to
81257 ** move as a result of the drop (can happen in auto-vacuum mode).
81258 */
81259 if( pTab->tabFlags & TF_Autoincrement ){
81260 sqlite3NestedParse(pParse,
81261 "DELETE FROM %s.sqlite_sequence WHERE name=%Q",
81262 pDb->zName, pTab->zName
81263 );
81264 }
81265 #endif
81266
81267 /* Drop all SQLITE_MASTER table and index entries that refer to the
81268 ** table. The program name loops through the master table and deletes
81269 ** every row that refers to a table of the same name as the one being
81270 ** dropped. Triggers are handled seperately because a trigger can be
81271 ** created in the temp database that refers to a table in another
81272 ** database.
81273 */
81274 sqlite3NestedParse(pParse,
81275 "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
81276 pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
81277 sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
81278 if( !isView && !IsVirtual(pTab) ){
81279 destroyTable(pParse, pTab);
81280 }
81281
81282 /* Remove the table entry from SQLite's internal schema and modify
81283 ** the schema cookie.
81284 */
81285 if( IsVirtual(pTab) ){
81286 sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
81287 }
81288 sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
81289 sqlite3ChangeCookie(pParse, iDb);
81290 }
81291 sqliteViewResetAll(db, iDb);
81292
81293 exit_drop_table:
81294 sqlite3SrcListDelete(db, pName);
81295 }
81296
@@ -81454,17 +81765,19 @@
81454 */
81455 static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
81456 Table *pTab = pIndex->pTable; /* The table that is indexed */
81457 int iTab = pParse->nTab++; /* Btree cursor used for pTab */
81458 int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
81459 int iSorter = iTab; /* Cursor opened by OpenSorter (if in use) */
81460 int addr1; /* Address of top of loop */
81461 int addr2; /* Address to jump to for next iteration */
81462 int tnum; /* Root page of index */
81463 Vdbe *v; /* Generate code into this virtual machine */
81464 KeyInfo *pKey; /* KeyInfo for index */
 
81465 int regIdxKey; /* Registers containing the index key */
 
81466 int regRecord; /* Register holding assemblied index record */
81467 sqlite3 *db = pParse->db; /* The database connection */
81468 int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
81469
81470 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -81494,21 +81807,22 @@
81494
81495 #ifndef SQLITE_OMIT_MERGE_SORT
81496 /* Open the sorter cursor if we are to use one. */
81497 iSorter = pParse->nTab++;
81498 sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
 
 
81499 #endif
81500
81501 /* Open the table. Loop through all rows of the table, inserting index
81502 ** records into the sorter. */
81503 sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
81504 addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
81505 addr2 = addr1 + 1;
81506 regRecord = sqlite3GetTempReg(pParse);
81507 regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
81508
81509 #ifndef SQLITE_OMIT_MERGE_SORT
 
81510 sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
81511 sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
81512 sqlite3VdbeJumpHere(v, addr1);
81513 addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
81514 if( pIndex->onError!=OE_None ){
@@ -81524,10 +81838,12 @@
81524 }
81525 sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
81526 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
81527 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
81528 #else
 
 
81529 if( pIndex->onError!=OE_None ){
81530 const int regRowid = regIdxKey + pIndex->nColumn;
81531 const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
81532 void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
81533
@@ -81621,10 +81937,11 @@
81621 ** before looking up the table.
81622 */
81623 assert( pName1 && pName2 );
81624 iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
81625 if( iDb<0 ) goto exit_create_index;
 
81626
81627 #ifndef SQLITE_OMIT_TEMPDB
81628 /* If the index name was unqualified, check if the the table
81629 ** is a temp table. If so, set the database to 1. Do not do this
81630 ** if initialising a database schema.
@@ -81648,10 +81965,11 @@
81648 pTblName->a[0].zDatabase);
81649 if( !pTab || db->mallocFailed ) goto exit_create_index;
81650 assert( db->aDb[iDb].pSchema==pTab->pSchema );
81651 }else{
81652 assert( pName==0 );
 
81653 pTab = pParse->pNewTable;
81654 if( !pTab ) goto exit_create_index;
81655 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
81656 }
81657 pDb = &db->aDb[iDb];
@@ -81690,10 +82008,11 @@
81690 ** own name.
81691 */
81692 if( pName ){
81693 zName = sqlite3NameFromToken(db, pName);
81694 if( zName==0 ) goto exit_create_index;
 
81695 if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
81696 goto exit_create_index;
81697 }
81698 if( !db->init.busy ){
81699 if( sqlite3FindTable(db, zName, 0)!=0 ){
@@ -81769,24 +82088,24 @@
81769 */
81770 nName = sqlite3Strlen30(zName);
81771 nCol = pList->nExpr;
81772 pIndex = sqlite3DbMallocZero(db,
81773 sizeof(Index) + /* Index structure */
 
81774 sizeof(int)*nCol + /* Index.aiColumn */
81775 sizeof(int)*(nCol+1) + /* Index.aiRowEst */
81776 sizeof(char *)*nCol + /* Index.azColl */
81777 sizeof(u8)*nCol + /* Index.aSortOrder */
81778 nName + 1 + /* Index.zName */
81779 nExtra /* Collation sequence names */
81780 );
81781 if( db->mallocFailed ){
81782 goto exit_create_index;
81783 }
81784 pIndex->azColl = (char**)(&pIndex[1]);
 
81785 pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
81786 pIndex->aiRowEst = (unsigned *)(&pIndex->aiColumn[nCol]);
81787 pIndex->aSortOrder = (u8 *)(&pIndex->aiRowEst[nCol+1]);
81788 pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
81789 zExtra = (char *)(&pIndex->zName[nName+1]);
81790 memcpy(pIndex->zName, zName, nName+1);
81791 pIndex->pTable = pTab;
81792 pIndex->nColumn = pList->nExpr;
@@ -82059,13 +82378,13 @@
82059 ** Apart from that, we have little to go on besides intuition as to
82060 ** how aiRowEst[] should be initialized. The numbers generated here
82061 ** are based on typical values found in actual indices.
82062 */
82063 SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
82064 unsigned *a = pIdx->aiRowEst;
82065 int i;
82066 unsigned n;
82067 assert( a!=0 );
82068 a[0] = pIdx->pTable->nRowEst;
82069 if( a[0]<10 ) a[0] = 10;
82070 n = 10;
82071 for(i=1; i<=pIdx->nColumn; i++){
@@ -82545,17 +82864,14 @@
82545
82546 /*
82547 ** Commit a transaction
82548 */
82549 SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
82550 sqlite3 *db;
82551 Vdbe *v;
82552
82553 assert( pParse!=0 );
82554 db = pParse->db;
82555 assert( db!=0 );
82556 /* if( db->aDb[0].pBt==0 ) return; */
82557 if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
82558 return;
82559 }
82560 v = sqlite3GetVdbe(pParse);
82561 if( v ){
@@ -82565,17 +82881,14 @@
82565
82566 /*
82567 ** Rollback a transaction
82568 */
82569 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
82570 sqlite3 *db;
82571 Vdbe *v;
82572
82573 assert( pParse!=0 );
82574 db = pParse->db;
82575 assert( db!=0 );
82576 /* if( db->aDb[0].pBt==0 ) return; */
82577 if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
82578 return;
82579 }
82580 v = sqlite3GetVdbe(pParse);
82581 if( v ){
@@ -84377,20 +84690,19 @@
84377 /* Verify that the call to _bytes() does not invalidate the _text() pointer */
84378 assert( z2==(char*)sqlite3_value_text(argv[0]) );
84379 if( z2 ){
84380 z1 = contextMalloc(context, ((i64)n)+1);
84381 if( z1 ){
84382 memcpy(z1, z2, n+1);
84383 for(i=0; z1[i]; i++){
84384 z1[i] = (char)sqlite3Toupper(z1[i]);
84385 }
84386 sqlite3_result_text(context, z1, -1, sqlite3_free);
84387 }
84388 }
84389 }
84390 static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
84391 u8 *z1;
84392 const char *z2;
84393 int i, n;
84394 UNUSED_PARAMETER(argc);
84395 z2 = (char*)sqlite3_value_text(argv[0]);
84396 n = sqlite3_value_bytes(argv[0]);
@@ -84397,15 +84709,14 @@
84397 /* Verify that the call to _bytes() does not invalidate the _text() pointer */
84398 assert( z2==(char*)sqlite3_value_text(argv[0]) );
84399 if( z2 ){
84400 z1 = contextMalloc(context, ((i64)n)+1);
84401 if( z1 ){
84402 memcpy(z1, z2, n+1);
84403 for(i=0; z1[i]; i++){
84404 z1[i] = sqlite3Tolower(z1[i]);
84405 }
84406 sqlite3_result_text(context, (char *)z1, -1, sqlite3_free);
84407 }
84408 }
84409 }
84410
84411
@@ -86778,10 +87089,11 @@
86778 sqlite3SelectDelete(db, pSelect);
86779 if( db->mallocFailed==1 ){
86780 fkTriggerDelete(db, pTrigger);
86781 return 0;
86782 }
 
86783
86784 switch( action ){
86785 case OE_Restrict:
86786 pStep->op = TK_SELECT;
86787 break;
@@ -88621,10 +88933,13 @@
88621 */
88622 if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
88623 return 0;
88624 }
88625 #endif
 
 
 
88626
88627 /* If we get this far, it means either:
88628 **
88629 ** * We can always do the transfer if the table contains an
88630 ** an integer primary key
@@ -89698,11 +90013,11 @@
89698 sqlite3_vfs *pVfs = db->pVfs;
89699 void *handle;
89700 int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
89701 char *zErrmsg = 0;
89702 void **aHandle;
89703 const int nMsg = 300;
89704
89705 if( pzErrMsg ) *pzErrMsg = 0;
89706
89707 /* Ticket #1863. To avoid a creating security problems for older
89708 ** applications that relink against newer versions of SQLite, the
@@ -89735,10 +90050,11 @@
89735 }
89736 xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
89737 sqlite3OsDlSym(pVfs, handle, zProc);
89738 if( xInit==0 ){
89739 if( pzErrMsg ){
 
89740 *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
89741 if( zErrmsg ){
89742 sqlite3_snprintf(nMsg, zErrmsg,
89743 "no entry point [%s] in shared library [%s]", zProc,zFile);
89744 sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
@@ -90420,11 +90736,11 @@
90420 ){
90421 int iReg;
90422 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
90423 sqlite3CodeVerifySchema(pParse, iDb);
90424 iReg = ++pParse->nMem;
90425 if( zLeft[0]=='p' ){
90426 sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
90427 }else{
90428 sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
90429 }
90430 sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
@@ -90486,12 +90802,14 @@
90486 */
90487 if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
90488 int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
90489 int ii; /* Loop counter */
90490
90491 /* Force the schema to be loaded on all databases. This cases all
90492 ** database files to be opened and the journal_modes set. */
 
 
90493 if( sqlite3ReadSchema(pParse) ){
90494 goto pragma_out;
90495 }
90496
90497 sqlite3VdbeSetNumCols(v, 1);
@@ -91031,11 +91349,11 @@
91031 { OP_IfNeg, 1, 0, 0}, /* 1 */
91032 { OP_String8, 0, 3, 0}, /* 2 */
91033 { OP_ResultRow, 3, 1, 0},
91034 };
91035
91036 int isQuick = (zLeft[0]=='q');
91037
91038 /* Initialize the VDBE program */
91039 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
91040 pParse->nMem = 6;
91041 sqlite3VdbeSetNumCols(v, 1);
@@ -92406,10 +92724,11 @@
92406 Select standin;
92407 sqlite3 *db = pParse->db;
92408 pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
92409 assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
92410 if( pNew==0 ){
 
92411 pNew = &standin;
92412 memset(pNew, 0, sizeof(*pNew));
92413 }
92414 if( pEList==0 ){
92415 pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
@@ -92433,10 +92752,11 @@
92433 if( pNew!=&standin ) sqlite3DbFree(db, pNew);
92434 pNew = 0;
92435 }else{
92436 assert( pNew->pSrc!=0 || pParse->nErr>0 );
92437 }
 
92438 return pNew;
92439 }
92440
92441 /*
92442 ** Delete the given Select structure and all of its substructures.
@@ -93611,11 +93931,14 @@
93611 /* If the column contains an "AS <name>" phrase, use <name> as the name */
93612 zName = sqlite3DbStrDup(db, zName);
93613 }else{
93614 Expr *pColExpr = p; /* The expression that is the result column name */
93615 Table *pTab; /* Table associated with this expression */
93616 while( pColExpr->op==TK_DOT ) pColExpr = pColExpr->pRight;
 
 
 
93617 if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
93618 /* For columns use the column name name */
93619 int iCol = pColExpr->iColumn;
93620 pTab = pColExpr->pTab;
93621 if( iCol<0 ) iCol = pTab->iPKey;
@@ -98609,10 +98932,11 @@
98609 break;
98610 }
98611 }
98612 }
98613 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
 
98614 if( openAll || aRegIdx[i]>0 ){
98615 KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
98616 sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
98617 (char*)pKey, P4_KEYINFO_HANDOFF);
98618 assert( pParse->nTab>iCur+i+1 );
@@ -98782,10 +99106,11 @@
98782 sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
98783 sqlite3VdbeJumpHere(v, addr);
98784
98785 /* Close all tables */
98786 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
 
98787 if( openAll || aRegIdx[i]>0 ){
98788 sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
98789 }
98790 }
98791 sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
@@ -98969,11 +99294,11 @@
98969 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
98970 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
98971 return sqlite3_errcode(db);
98972 }
98973 VVA_ONLY( rc = ) sqlite3_step(pStmt);
98974 assert( rc!=SQLITE_ROW );
98975 return vacuumFinalize(db, pStmt, pzErrMsg);
98976 }
98977
98978 /*
98979 ** Execute zSql on database db. The statement returns exactly
@@ -99187,17 +99512,15 @@
99187 " WHERE type='view' OR type='trigger'"
99188 " OR (type='table' AND rootpage=0)"
99189 );
99190 if( rc ) goto end_of_vacuum;
99191
99192 /* At this point, unless the main db was completely empty, there is now a
99193 ** transaction open on the vacuum database, but not on the main database.
99194 ** Open a btree level transaction on the main database. This allows a
99195 ** call to sqlite3BtreeCopyFile(). The main database btree level
99196 ** transaction is then committed, so the SQL level never knows it was
99197 ** opened for writing. This way, the SQL transaction used to create the
99198 ** temporary database never needs to be committed.
99199 */
99200 {
99201 u32 meta;
99202 int i;
99203
@@ -100457,25 +100780,35 @@
100457 #define TERM_CODED 0x04 /* This term is already coded */
100458 #define TERM_COPIED 0x08 /* Has a child */
100459 #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
100460 #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
100461 #define TERM_OR_OK 0x40 /* Used during OR-clause processing */
100462 #ifdef SQLITE_ENABLE_STAT2
100463 # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
100464 #else
100465 # define TERM_VNULL 0x00 /* Disabled if not using stat2 */
100466 #endif
100467
100468 /*
100469 ** An instance of the following structure holds all information about a
100470 ** WHERE clause. Mostly this is a container for one or more WhereTerms.
 
 
 
 
 
 
 
 
100471 */
100472 struct WhereClause {
100473 Parse *pParse; /* The parser context */
100474 WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
100475 Bitmask vmask; /* Bitmask identifying virtual table cursors */
 
100476 u8 op; /* Split operator. TK_AND or TK_OR */
 
100477 int nTerm; /* Number of terms */
100478 int nSlot; /* Number of entries in a[] */
100479 WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
100480 #if defined(SQLITE_SMALL_STACK)
100481 WhereTerm aStatic[1]; /* Initial static space for a[] */
@@ -100600,18 +100933,21 @@
100600 ** Initialize a preallocated WhereClause structure.
100601 */
100602 static void whereClauseInit(
100603 WhereClause *pWC, /* The WhereClause to be initialized */
100604 Parse *pParse, /* The parsing context */
100605 WhereMaskSet *pMaskSet /* Mapping from table cursor numbers to bitmasks */
 
100606 ){
100607 pWC->pParse = pParse;
100608 pWC->pMaskSet = pMaskSet;
 
100609 pWC->nTerm = 0;
100610 pWC->nSlot = ArraySize(pWC->aStatic);
100611 pWC->a = pWC->aStatic;
100612 pWC->vmask = 0;
 
100613 }
100614
100615 /* Forward reference */
100616 static void whereClauseClear(WhereClause*);
100617
@@ -100923,40 +101259,42 @@
100923 ){
100924 WhereTerm *pTerm;
100925 int k;
100926 assert( iCur>=0 );
100927 op &= WO_ALL;
100928 for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
100929 if( pTerm->leftCursor==iCur
100930 && (pTerm->prereqRight & notReady)==0
100931 && pTerm->u.leftColumn==iColumn
100932 && (pTerm->eOperator & op)!=0
100933 ){
100934 if( pIdx && pTerm->eOperator!=WO_ISNULL ){
100935 Expr *pX = pTerm->pExpr;
100936 CollSeq *pColl;
100937 char idxaff;
100938 int j;
100939 Parse *pParse = pWC->pParse;
100940
100941 idxaff = pIdx->pTable->aCol[iColumn].affinity;
100942 if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
100943
100944 /* Figure out the collation sequence required from an index for
100945 ** it to be useful for optimising expression pX. Store this
100946 ** value in variable pColl.
100947 */
100948 assert(pX->pLeft);
100949 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
100950 assert(pColl || pParse->nErr);
100951
100952 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
100953 if( NEVER(j>=pIdx->nColumn) ) return 0;
100954 }
100955 if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
100956 }
100957 return pTerm;
 
 
100958 }
100959 }
100960 return 0;
100961 }
100962
@@ -101029,11 +101367,11 @@
101029 int iCol = pRight->iColumn;
101030 pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
101031 if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
101032 z = (char *)sqlite3_value_text(pVal);
101033 }
101034 sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-23257-02778 */
101035 assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
101036 }else if( op==TK_STRING ){
101037 z = pRight->u.zToken;
101038 }
101039 if( z ){
@@ -101047,11 +101385,11 @@
101047 pPrefix = sqlite3Expr(db, TK_STRING, z);
101048 if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
101049 *ppPrefix = pPrefix;
101050 if( op==TK_VARIABLE ){
101051 Vdbe *v = pParse->pVdbe;
101052 sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-23257-02778 */
101053 if( *pisComplete && pRight->u.zToken[1] ){
101054 /* If the rhs of the LIKE expression is a variable, and the current
101055 ** value of the variable means there is no need to invoke the LIKE
101056 ** function, then no OP_Variable will be added to the program.
101057 ** This causes problems for the sqlite3_bind_parameter_name()
@@ -101216,11 +101554,11 @@
101216 assert( pExpr->op==TK_OR );
101217 pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo));
101218 if( pOrInfo==0 ) return;
101219 pTerm->wtFlags |= TERM_ORINFO;
101220 pOrWc = &pOrInfo->wc;
101221 whereClauseInit(pOrWc, pWC->pParse, pMaskSet);
101222 whereSplit(pOrWc, pExpr, TK_OR);
101223 exprAnalyzeAll(pSrc, pOrWc);
101224 if( db->mallocFailed ) return;
101225 assert( pOrWc->nTerm>=2 );
101226
@@ -101243,13 +101581,14 @@
101243 Bitmask b = 0;
101244 pOrTerm->u.pAndInfo = pAndInfo;
101245 pOrTerm->wtFlags |= TERM_ANDINFO;
101246 pOrTerm->eOperator = WO_AND;
101247 pAndWC = &pAndInfo->wc;
101248 whereClauseInit(pAndWC, pWC->pParse, pMaskSet);
101249 whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
101250 exprAnalyzeAll(pSrc, pAndWC);
 
101251 testcase( db->mallocFailed );
101252 if( !db->mallocFailed ){
101253 for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
101254 assert( pAndTerm->pExpr );
101255 if( allowedOp(pAndTerm->pExpr->op) ){
@@ -101679,12 +102018,12 @@
101679 pNewTerm->prereqAll = pTerm->prereqAll;
101680 }
101681 }
101682 #endif /* SQLITE_OMIT_VIRTUALTABLE */
101683
101684 #ifdef SQLITE_ENABLE_STAT2
101685 /* When sqlite_stat2 histogram data is available an operator of the
101686 ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
101687 ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
101688 ** virtual term of that form.
101689 **
101690 ** Note that the virtual term must be tagged with TERM_VNULL. This
@@ -101718,11 +102057,11 @@
101718 pTerm->nChild = 1;
101719 pTerm->wtFlags |= TERM_COPIED;
101720 pNewTerm->prereqAll = pTerm->prereqAll;
101721 }
101722 }
101723 #endif /* SQLITE_ENABLE_STAT2 */
101724
101725 /* Prevent ON clause terms of a LEFT JOIN from being used to drive
101726 ** an index for tables to the left of the join.
101727 */
101728 pTerm->prereqRight |= extraRight;
@@ -102140,14 +102479,17 @@
102140 const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
102141 const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
102142 WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
102143 WhereTerm *pTerm; /* A single term of the WHERE clause */
102144
102145 /* No OR-clause optimization allowed if the INDEXED BY or NOT INDEXED clauses
102146 ** are used */
102147 if( pSrc->notIndexed || pSrc->pIndex!=0 ){
102148 return;
 
 
 
102149 }
102150
102151 /* Search the WHERE clause terms for a usable WO_OR term. */
102152 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
102153 if( pTerm->eOperator==WO_OR
@@ -102172,12 +102514,14 @@
102172 bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
102173 }else if( pOrTerm->leftCursor==iCur ){
102174 WhereClause tempWC;
102175 tempWC.pParse = pWC->pParse;
102176 tempWC.pMaskSet = pWC->pMaskSet;
 
102177 tempWC.op = TK_AND;
102178 tempWC.a = pOrTerm;
 
102179 tempWC.nTerm = 1;
102180 bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
102181 }else{
102182 continue;
102183 }
@@ -102766,71 +103110,89 @@
102766 */
102767 bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
102768 }
102769 #endif /* SQLITE_OMIT_VIRTUALTABLE */
102770
 
102771 /*
102772 ** Argument pIdx is a pointer to an index structure that has an array of
102773 ** SQLITE_INDEX_SAMPLES evenly spaced samples of the first indexed column
102774 ** stored in Index.aSample. These samples divide the domain of values stored
102775 ** the index into (SQLITE_INDEX_SAMPLES+1) regions.
102776 ** Region 0 contains all values less than the first sample value. Region
102777 ** 1 contains values between the first and second samples. Region 2 contains
102778 ** values between samples 2 and 3. And so on. Region SQLITE_INDEX_SAMPLES
102779 ** contains values larger than the last sample.
102780 **
102781 ** If the index contains many duplicates of a single value, then it is
102782 ** possible that two or more adjacent samples can hold the same value.
102783 ** When that is the case, the smallest possible region code is returned
102784 ** when roundUp is false and the largest possible region code is returned
102785 ** when roundUp is true.
102786 **
102787 ** If successful, this function determines which of the regions value
102788 ** pVal lies in, sets *piRegion to the region index (a value between 0
102789 ** and SQLITE_INDEX_SAMPLES+1, inclusive) and returns SQLITE_OK.
102790 ** Or, if an OOM occurs while converting text values between encodings,
102791 ** SQLITE_NOMEM is returned and *piRegion is undefined.
102792 */
102793 #ifdef SQLITE_ENABLE_STAT2
102794 static int whereRangeRegion(
102795 Parse *pParse, /* Database connection */
102796 Index *pIdx, /* Index to consider domain of */
102797 sqlite3_value *pVal, /* Value to consider */
102798 int roundUp, /* Return largest valid region if true */
102799 int *piRegion /* OUT: Region of domain in which value lies */
102800 ){
 
 
 
 
 
 
 
102801 assert( roundUp==0 || roundUp==1 );
102802 if( ALWAYS(pVal) ){
102803 IndexSample *aSample = pIdx->aSample;
102804 int i = 0;
102805 int eType = sqlite3_value_type(pVal);
102806
102807 if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){
102808 double r = sqlite3_value_double(pVal);
102809 for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
102810 if( aSample[i].eType==SQLITE_NULL ) continue;
102811 if( aSample[i].eType>=SQLITE_TEXT ) break;
102812 if( roundUp ){
102813 if( aSample[i].u.r>r ) break;
102814 }else{
102815 if( aSample[i].u.r>=r ) break;
102816 }
102817 }
102818 }else if( eType==SQLITE_NULL ){
102819 i = 0;
102820 if( roundUp ){
102821 while( i<SQLITE_INDEX_SAMPLES && aSample[i].eType==SQLITE_NULL ) i++;
102822 }
102823 }else{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102824 sqlite3 *db = pParse->db;
102825 CollSeq *pColl;
102826 const u8 *z;
102827 int n;
102828
102829 /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */
102830 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
102831
102832 if( eType==SQLITE_BLOB ){
102833 z = (const u8 *)sqlite3_value_blob(pVal);
102834 pColl = db->pDfltColl;
102835 assert( pColl->enc==SQLITE_UTF8 );
102836 }else{
@@ -102845,16 +103207,16 @@
102845 return SQLITE_NOMEM;
102846 }
102847 assert( z && pColl && pColl->xCmp );
102848 }
102849 n = sqlite3ValueBytes(pVal, pColl->enc);
102850
102851 for(i=0; i<SQLITE_INDEX_SAMPLES; i++){
102852 int c;
102853 int eSampletype = aSample[i].eType;
102854 if( eSampletype==SQLITE_NULL || eSampletype<eType ) continue;
102855 if( (eSampletype!=eType) ) break;
102856 #ifndef SQLITE_OMIT_UTF16
102857 if( pColl->enc!=SQLITE_UTF8 ){
102858 int nSample;
102859 char *zSample = sqlite3Utf8to16(
102860 db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
@@ -102868,20 +103230,51 @@
102868 }else
102869 #endif
102870 {
102871 c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
102872 }
102873 if( c-roundUp>=0 ) break;
 
 
 
102874 }
102875 }
 
102876
102877 assert( i>=0 && i<=SQLITE_INDEX_SAMPLES );
102878 *piRegion = i;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102879 }
102880 return SQLITE_OK;
102881 }
102882 #endif /* #ifdef SQLITE_ENABLE_STAT2 */
102883
102884 /*
102885 ** If expression pExpr represents a literal value, set *pp to point to
102886 ** an sqlite3_value structure containing the same value, with affinity
102887 ** aff applied to it, before returning. It is the responsibility of the
@@ -102895,11 +103288,11 @@
102895 **
102896 ** If neither of the above apply, set *pp to NULL.
102897 **
102898 ** If an error occurs, return an error code. Otherwise, SQLITE_OK.
102899 */
102900 #ifdef SQLITE_ENABLE_STAT2
102901 static int valueFromExpr(
102902 Parse *pParse,
102903 Expr *pExpr,
102904 u8 aff,
102905 sqlite3_value **pp
@@ -102906,11 +103299,11 @@
102906 ){
102907 if( pExpr->op==TK_VARIABLE
102908 || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
102909 ){
102910 int iVar = pExpr->iColumn;
102911 sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-23257-02778 */
102912 *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
102913 return SQLITE_OK;
102914 }
102915 return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
102916 }
@@ -102943,106 +103336,92 @@
102943 **
102944 ** ... FROM t1 WHERE a > ? AND a < ? ...
102945 **
102946 ** then nEq should be passed 0.
102947 **
102948 ** The returned value is an integer between 1 and 100, inclusive. A return
102949 ** value of 1 indicates that the proposed range scan is expected to visit
102950 ** approximately 1/100th (1%) of the rows selected by the nEq equality
102951 ** constraints (if any). A return value of 100 indicates that it is expected
102952 ** that the range scan will visit every row (100%) selected by the equality
102953 ** constraints.
102954 **
102955 ** In the absence of sqlite_stat2 ANALYZE data, each range inequality
102956 ** reduces the search space by 3/4ths. Hence a single constraint (x>?)
102957 ** results in a return of 25 and a range constraint (x>? AND x<?) results
102958 ** in a return of 6.
102959 */
102960 static int whereRangeScanEst(
102961 Parse *pParse, /* Parsing & code generating context */
102962 Index *p, /* The index containing the range-compared column; "x" */
102963 int nEq, /* index into p->aCol[] of the range-compared column */
102964 WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
102965 WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
102966 int *piEst /* OUT: Return value */
102967 ){
102968 int rc = SQLITE_OK;
102969
102970 #ifdef SQLITE_ENABLE_STAT2
102971
102972 if( nEq==0 && p->aSample ){
102973 sqlite3_value *pLowerVal = 0;
102974 sqlite3_value *pUpperVal = 0;
102975 int iEst;
102976 int iLower = 0;
102977 int iUpper = SQLITE_INDEX_SAMPLES;
102978 int roundUpUpper = 0;
102979 int roundUpLower = 0;
102980 u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
102981
102982 if( pLower ){
102983 Expr *pExpr = pLower->pExpr->pRight;
102984 rc = valueFromExpr(pParse, pExpr, aff, &pLowerVal);
102985 assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE );
102986 roundUpLower = (pLower->eOperator==WO_GT) ?1:0;
 
 
 
 
 
 
102987 }
102988 if( rc==SQLITE_OK && pUpper ){
102989 Expr *pExpr = pUpper->pExpr->pRight;
102990 rc = valueFromExpr(pParse, pExpr, aff, &pUpperVal);
102991 assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE );
102992 roundUpUpper = (pUpper->eOperator==WO_LE) ?1:0;
102993 }
102994
102995 if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){
102996 sqlite3ValueFree(pLowerVal);
102997 sqlite3ValueFree(pUpperVal);
102998 goto range_est_fallback;
102999 }else if( pLowerVal==0 ){
103000 rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper);
103001 if( pLower ) iLower = iUpper/2;
103002 }else if( pUpperVal==0 ){
103003 rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower);
103004 if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2;
103005 }else{
103006 rc = whereRangeRegion(pParse, p, pUpperVal, roundUpUpper, &iUpper);
103007 if( rc==SQLITE_OK ){
103008 rc = whereRangeRegion(pParse, p, pLowerVal, roundUpLower, &iLower);
103009 }
103010 }
103011 WHERETRACE(("range scan regions: %d..%d\n", iLower, iUpper));
103012
103013 iEst = iUpper - iLower;
103014 testcase( iEst==SQLITE_INDEX_SAMPLES );
103015 assert( iEst<=SQLITE_INDEX_SAMPLES );
103016 if( iEst<1 ){
103017 *piEst = 50/SQLITE_INDEX_SAMPLES;
103018 }else{
103019 *piEst = (iEst*100)/SQLITE_INDEX_SAMPLES;
103020 }
103021 sqlite3ValueFree(pLowerVal);
103022 sqlite3ValueFree(pUpperVal);
103023 return rc;
103024 }
103025 range_est_fallback:
103026 #else
103027 UNUSED_PARAMETER(pParse);
103028 UNUSED_PARAMETER(p);
103029 UNUSED_PARAMETER(nEq);
103030 #endif
103031 assert( pLower || pUpper );
103032 *piEst = 100;
103033 if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *piEst /= 4;
103034 if( pUpper ) *piEst /= 4;
103035 return rc;
103036 }
103037
103038 #ifdef SQLITE_ENABLE_STAT2
103039 /*
103040 ** Estimate the number of rows that will be returned based on
103041 ** an equality constraint x=VALUE and where that VALUE occurs in
103042 ** the histogram data. This only works when x is the left-most
103043 ** column of an index and sqlite_stat2 histogram data is available
103044 ** for that index. When pExpr==NULL that means the constraint is
103045 ** "x IS NULL" instead of "x=VALUE".
103046 **
103047 ** Write the estimated row count into *pnRow and return SQLITE_OK.
103048 ** If unable to make an estimate, leave *pnRow unchanged and return
@@ -103058,44 +103437,36 @@
103058 Index *p, /* The index whose left-most column is pTerm */
103059 Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
103060 double *pnRow /* Write the revised row estimate here */
103061 ){
103062 sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
103063 int iLower, iUpper; /* Range of histogram regions containing pRhs */
103064 u8 aff; /* Column affinity */
103065 int rc; /* Subfunction return code */
103066 double nRowEst; /* New estimate of the number of rows */
103067
103068 assert( p->aSample!=0 );
 
103069 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
103070 if( pExpr ){
103071 rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
103072 if( rc ) goto whereEqualScanEst_cancel;
103073 }else{
103074 pRhs = sqlite3ValueNew(pParse->db);
103075 }
103076 if( pRhs==0 ) return SQLITE_NOTFOUND;
103077 rc = whereRangeRegion(pParse, p, pRhs, 0, &iLower);
103078 if( rc ) goto whereEqualScanEst_cancel;
103079 rc = whereRangeRegion(pParse, p, pRhs, 1, &iUpper);
103080 if( rc ) goto whereEqualScanEst_cancel;
103081 WHERETRACE(("equality scan regions: %d..%d\n", iLower, iUpper));
103082 if( iLower>=iUpper ){
103083 nRowEst = p->aiRowEst[0]/(SQLITE_INDEX_SAMPLES*2);
103084 if( nRowEst<*pnRow ) *pnRow = nRowEst;
103085 }else{
103086 nRowEst = (iUpper-iLower)*p->aiRowEst[0]/SQLITE_INDEX_SAMPLES;
103087 *pnRow = nRowEst;
103088 }
103089
103090 whereEqualScanEst_cancel:
103091 sqlite3ValueFree(pRhs);
103092 return rc;
103093 }
103094 #endif /* defined(SQLITE_ENABLE_STAT2) */
103095
103096 #ifdef SQLITE_ENABLE_STAT2
103097 /*
103098 ** Estimate the number of rows that will be returned based on
103099 ** an IN constraint where the right-hand side of the IN operator
103100 ** is a list of values. Example:
103101 **
@@ -103114,64 +103485,29 @@
103114 Parse *pParse, /* Parsing & code generating context */
103115 Index *p, /* The index whose left-most column is pTerm */
103116 ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
103117 double *pnRow /* Write the revised row estimate here */
103118 ){
103119 sqlite3_value *pVal = 0; /* One value from list */
103120 int iLower, iUpper; /* Range of histogram regions containing pRhs */
103121 u8 aff; /* Column affinity */
103122 int rc = SQLITE_OK; /* Subfunction return code */
103123 double nRowEst; /* New estimate of the number of rows */
103124 int nSpan = 0; /* Number of histogram regions spanned */
103125 int nSingle = 0; /* Histogram regions hit by a single value */
103126 int nNotFound = 0; /* Count of values that are not constants */
103127 int i; /* Loop counter */
103128 u8 aSpan[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions that are spanned */
103129 u8 aSingle[SQLITE_INDEX_SAMPLES+1]; /* Histogram regions hit once */
103130
103131 assert( p->aSample!=0 );
103132 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
103133 memset(aSpan, 0, sizeof(aSpan));
103134 memset(aSingle, 0, sizeof(aSingle));
103135 for(i=0; i<pList->nExpr; i++){
103136 sqlite3ValueFree(pVal);
103137 rc = valueFromExpr(pParse, pList->a[i].pExpr, aff, &pVal);
103138 if( rc ) break;
103139 if( pVal==0 || sqlite3_value_type(pVal)==SQLITE_NULL ){
103140 nNotFound++;
103141 continue;
103142 }
103143 rc = whereRangeRegion(pParse, p, pVal, 0, &iLower);
103144 if( rc ) break;
103145 rc = whereRangeRegion(pParse, p, pVal, 1, &iUpper);
103146 if( rc ) break;
103147 if( iLower>=iUpper ){
103148 aSingle[iLower] = 1;
103149 }else{
103150 assert( iLower>=0 && iUpper<=SQLITE_INDEX_SAMPLES );
103151 while( iLower<iUpper ) aSpan[iLower++] = 1;
103152 }
103153 }
103154 if( rc==SQLITE_OK ){
103155 for(i=nSpan=0; i<=SQLITE_INDEX_SAMPLES; i++){
103156 if( aSpan[i] ){
103157 nSpan++;
103158 }else if( aSingle[i] ){
103159 nSingle++;
103160 }
103161 }
103162 nRowEst = (nSpan*2+nSingle)*p->aiRowEst[0]/(2*SQLITE_INDEX_SAMPLES)
103163 + nNotFound*p->aiRowEst[1];
103164 if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
103165 *pnRow = nRowEst;
103166 WHERETRACE(("IN row estimate: nSpan=%d, nSingle=%d, nNotFound=%d, est=%g\n",
103167 nSpan, nSingle, nNotFound, nRowEst));
103168 }
103169 sqlite3ValueFree(pVal);
103170 return rc;
103171 }
103172 #endif /* defined(SQLITE_ENABLE_STAT2) */
103173
103174
103175 /*
103176 ** Find the best query plan for accessing a particular table. Write the
103177 ** best query plan and its cost into the WhereCost object supplied as the
@@ -103214,11 +103550,11 @@
103214 Index *pProbe; /* An index we are evaluating */
103215 Index *pIdx; /* Copy of pProbe, or zero for IPK index */
103216 int eqTermMask; /* Current mask of valid equality operators */
103217 int idxEqTermMask; /* Index mask of valid equality operators */
103218 Index sPk; /* A fake index object for the primary key */
103219 unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
103220 int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
103221 int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */
103222
103223 /* Initialize the cost to a worst-case value */
103224 memset(pCost, 0, sizeof(*pCost));
@@ -103269,14 +103605,14 @@
103269 }
103270
103271 /* Loop over all indices looking for the best one to use
103272 */
103273 for(; pProbe; pIdx=pProbe=pProbe->pNext){
103274 const unsigned int * const aiRowEst = pProbe->aiRowEst;
103275 double cost; /* Cost of using pProbe */
103276 double nRow; /* Estimated number of rows in result set */
103277 double log10N; /* base-10 logarithm of nRow (inexact) */
103278 int rev; /* True to scan in reverse order */
103279 int wsFlags = 0;
103280 Bitmask used = 0;
103281
103282 /* The following variables are populated based on the properties of
@@ -103312,18 +103648,16 @@
103312 ** Set to true if there was at least one "x IN (SELECT ...)" term used
103313 ** in determining the value of nInMul. Note that the RHS of the
103314 ** IN operator must be a SELECT, not a value list, for this variable
103315 ** to be true.
103316 **
103317 ** estBound:
103318 ** An estimate on the amount of the table that must be searched. A
103319 ** value of 100 means the entire table is searched. Range constraints
103320 ** might reduce this to a value less than 100 to indicate that only
103321 ** a fraction of the table needs searching. In the absence of
103322 ** sqlite_stat2 ANALYZE data, a single inequality reduces the search
103323 ** space to 1/4rd its original size. So an x>? constraint reduces
103324 ** estBound to 25. Two constraints (x>? AND x<?) reduce estBound to 6.
103325 **
103326 ** bSort:
103327 ** Boolean. True if there is an ORDER BY clause that will require an
103328 ** external sort (i.e. scanning the index being evaluated will not
103329 ** correctly order records).
@@ -103344,26 +103678,27 @@
103344 ** SELECT a, b, c FROM tbl WHERE a = 1;
103345 */
103346 int nEq; /* Number of == or IN terms matching index */
103347 int bInEst = 0; /* True if "x IN (SELECT...)" seen */
103348 int nInMul = 1; /* Number of distinct equalities to lookup */
103349 int estBound = 100; /* Estimated reduction in search space */
103350 int nBound = 0; /* Number of range constraints seen */
103351 int bSort = !!pOrderBy; /* True if external sort required */
103352 int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */
103353 int bLookup = 0; /* True if not a covering index */
103354 WhereTerm *pTerm; /* A single term of the WHERE clause */
103355 #ifdef SQLITE_ENABLE_STAT2
103356 WhereTerm *pFirstTerm = 0; /* First term matching the index */
103357 #endif
103358
103359 /* Determine the values of nEq and nInMul */
103360 for(nEq=0; nEq<pProbe->nColumn; nEq++){
103361 int j = pProbe->aiColumn[nEq];
103362 pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
103363 if( pTerm==0 ) break;
103364 wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
 
103365 if( pTerm->eOperator & WO_IN ){
103366 Expr *pExpr = pTerm->pExpr;
103367 wsFlags |= WHERE_COLUMN_IN;
103368 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
103369 /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */
@@ -103374,32 +103709,34 @@
103374 nInMul *= pExpr->x.pList->nExpr;
103375 }
103376 }else if( pTerm->eOperator & WO_ISNULL ){
103377 wsFlags |= WHERE_COLUMN_NULL;
103378 }
103379 #ifdef SQLITE_ENABLE_STAT2
103380 if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
103381 #endif
103382 used |= pTerm->prereqRight;
103383 }
103384
103385 /* Determine the value of estBound. */
103386 if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
103387 int j = pProbe->aiColumn[nEq];
103388 if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
103389 WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
103390 WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
103391 whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &estBound);
103392 if( pTop ){
103393 nBound = 1;
103394 wsFlags |= WHERE_TOP_LIMIT;
103395 used |= pTop->prereqRight;
 
103396 }
103397 if( pBtm ){
103398 nBound++;
103399 wsFlags |= WHERE_BTM_LIMIT;
103400 used |= pBtm->prereqRight;
 
103401 }
103402 wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
103403 }
103404 }else if( pProbe->onError!=OE_None ){
103405 testcase( wsFlags & WHERE_COLUMN_IN );
@@ -103458,32 +103795,34 @@
103458 if( bInEst && nRow*2>aiRowEst[0] ){
103459 nRow = aiRowEst[0]/2;
103460 nInMul = (int)(nRow / aiRowEst[nEq]);
103461 }
103462
103463 #ifdef SQLITE_ENABLE_STAT2
103464 /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
103465 ** and we do not think that values of x are unique and if histogram
103466 ** data is available for column x, then it might be possible
103467 ** to get a better estimate on the number of rows based on
103468 ** VALUE and how common that value is according to the histogram.
103469 */
103470 if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
 
103471 if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
103472 testcase( pFirstTerm->eOperator==WO_EQ );
103473 testcase( pFirstTerm->eOperator==WO_ISNULL );
103474 whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
103475 }else if( pFirstTerm->eOperator==WO_IN && bInEst==0 ){
 
103476 whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
103477 }
103478 }
103479 #endif /* SQLITE_ENABLE_STAT2 */
103480
103481 /* Adjust the number of output rows and downward to reflect rows
103482 ** that are excluded by range constraints.
103483 */
103484 nRow = (nRow * (double)estBound) / (double)100;
103485 if( nRow<1 ) nRow = 1;
103486
103487 /* Experiments run on real SQLite databases show that the time needed
103488 ** to do a binary search to locate a row in a table or index is roughly
103489 ** log10(N) times the time to move from one row to the next row within
@@ -103608,14 +103947,14 @@
103608 if( nRow<2 ) nRow = 2;
103609 }
103610
103611
103612 WHERETRACE((
103613 "%s(%s): nEq=%d nInMul=%d estBound=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
103614 " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
103615 pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"),
103616 nEq, nInMul, estBound, bSort, bLookup, wsFlags,
103617 notReady, log10N, nRow, cost, used
103618 ));
103619
103620 /* If this index is the best we have seen so far, then record this
103621 ** index and its cost in the pCost structure.
@@ -104115,11 +104454,12 @@
104115 */
104116 static Bitmask codeOneLoopStart(
104117 WhereInfo *pWInfo, /* Complete information about the WHERE clause */
104118 int iLevel, /* Which level of pWInfo->a[] should be coded */
104119 u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
104120 Bitmask notReady /* Which tables are currently available */
 
104121 ){
104122 int j, k; /* Loop counters */
104123 int iCur; /* The VDBE cursor for the table */
104124 int addrNxt; /* Where to jump to continue with the next IN case */
104125 int omitTable; /* True if we use the index only */
@@ -104597,11 +104937,12 @@
104597 int regRowset = 0; /* Register for RowSet object */
104598 int regRowid = 0; /* Register holding rowid */
104599 int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
104600 int iRetInit; /* Address of regReturn init */
104601 int untestedTerms = 0; /* Some terms not completely tested */
104602 int ii;
 
104603
104604 pTerm = pLevel->plan.u.pTerm;
104605 assert( pTerm!=0 );
104606 assert( pTerm->eOperator==WO_OR );
104607 assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -104646,18 +104987,33 @@
104646 regRowset = ++pParse->nMem;
104647 regRowid = ++pParse->nMem;
104648 sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
104649 }
104650 iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
 
 
 
 
 
 
 
 
 
 
104651
104652 for(ii=0; ii<pOrWc->nTerm; ii++){
104653 WhereTerm *pOrTerm = &pOrWc->a[ii];
104654 if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
104655 WhereInfo *pSubWInfo; /* Info for single OR-term scan */
 
 
 
 
 
104656 /* Loop through table entries that match term pOrTerm. */
104657 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrTerm->pExpr, 0, 0,
104658 WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE |
104659 WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY);
104660 if( pSubWInfo ){
104661 explainOneScan(
104662 pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
104663 );
@@ -104681,10 +105037,11 @@
104681 /* Finish the loop through table entries that match term pOrTerm. */
104682 sqlite3WhereEnd(pSubWInfo);
104683 }
104684 }
104685 }
 
104686 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
104687 sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
104688 sqlite3VdbeResolveLabel(v, iLoopBody);
104689
104690 if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
@@ -104962,11 +105319,11 @@
104962
104963 /* Split the WHERE clause into separate subexpressions where each
104964 ** subexpression is separated by an AND operator.
104965 */
104966 initMaskSet(pMaskSet);
104967 whereClauseInit(pWC, pParse, pMaskSet);
104968 sqlite3ExprCodeConstants(pParse, pWhere);
104969 whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
104970
104971 /* Special case: a WHERE clause that is constant. Evaluate the
104972 ** expression and either jump over all of the code or fall thru.
@@ -105201,11 +105558,12 @@
105201 assert( bestJ>=0 );
105202 assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
105203 WHERETRACE(("*** Optimizer selects table %d for loop %d"
105204 " with cost=%g and nRow=%g\n",
105205 bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
105206 if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 ){
 
105207 *ppOrderBy = 0;
105208 }
105209 if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
105210 assert( pWInfo->eDistinct==0 );
105211 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -105290,11 +105648,11 @@
105290 int iCur = pTabItem->iCursor;
105291 sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
105292 }else
105293 #endif
105294 if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
105295 && (wctrlFlags & WHERE_OMIT_OPEN)==0 ){
105296 int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
105297 sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
105298 testcase( pTab->nCol==BMS-1 );
105299 testcase( pTab->nCol==BMS );
105300 if( !pWInfo->okOnePass && pTab->nCol<BMS ){
@@ -105335,11 +105693,11 @@
105335 */
105336 notReady = ~(Bitmask)0;
105337 for(i=0; i<nTabList; i++){
105338 pLevel = &pWInfo->a[i];
105339 explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
105340 notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
105341 pWInfo->iContinue = pLevel->addrCont;
105342 }
105343
105344 #ifdef SQLITE_TEST /* For testing and debugging use only */
105345 /* Record in the query plan information about the current table
@@ -105470,11 +105828,11 @@
105470 struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
105471 Table *pTab = pTabItem->pTab;
105472 assert( pTab!=0 );
105473 if( (pTab->tabFlags & TF_Ephemeral)==0
105474 && pTab->pSelect==0
105475 && (pWInfo->wctrlFlags & WHERE_OMIT_CLOSE)==0
105476 ){
105477 int ws = pLevel->plan.wsFlags;
105478 if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
105479 sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
105480 }
@@ -108817,11 +109175,13 @@
108817 sqlite3ParserTOKENTYPE yyminor /* The value for the token */
108818 sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
108819 ){
108820 YYMINORTYPE yyminorunion;
108821 int yyact; /* The parser action. */
 
108822 int yyendofinput; /* True if we are at the end of input */
 
108823 #ifdef YYERRORSYMBOL
108824 int yyerrorhit = 0; /* True if yymajor has invoked an error */
108825 #endif
108826 yyParser *yypParser; /* The parser */
108827
@@ -108840,11 +109200,13 @@
108840 yypParser->yyerrcnt = -1;
108841 yypParser->yystack[0].stateno = 0;
108842 yypParser->yystack[0].major = 0;
108843 }
108844 yyminorunion.yy0 = yyminor;
 
108845 yyendofinput = (yymajor==0);
 
108846 sqlite3ParserARG_STORE;
108847
108848 #ifndef NDEBUG
108849 if( yyTraceFILE ){
108850 fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
@@ -108852,11 +109214,10 @@
108852 #endif
108853
108854 do{
108855 yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
108856 if( yyact<YYNSTATE ){
108857 assert( !yyendofinput ); /* Impossible to shift the $ token */
108858 yy_shift(yypParser,yyact,yymajor,&yyminorunion);
108859 yypParser->yyerrcnt--;
108860 yymajor = YYNOCODE;
108861 }else if( yyact < YYNSTATE + YYNRULE ){
108862 yy_reduce(yypParser,yyact-YYNSTATE);
@@ -110244,11 +110605,11 @@
110244 **
110245 ** * Recursive calls to this routine from thread X return immediately
110246 ** without blocking.
110247 */
110248 SQLITE_API int sqlite3_initialize(void){
110249 sqlite3_mutex *pMaster; /* The main static mutex */
110250 int rc; /* Result code */
110251
110252 #ifdef SQLITE_OMIT_WSD
110253 rc = sqlite3_wsd_init(4096, 24);
110254 if( rc!=SQLITE_OK ){
@@ -110278,11 +110639,11 @@
110278 ** This operation is protected by the STATIC_MASTER mutex. Note that
110279 ** MutexAlloc() is called for a static mutex prior to initializing the
110280 ** malloc subsystem - this implies that the allocation of a static
110281 ** mutex must not require support from the malloc subsystem.
110282 */
110283 pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
110284 sqlite3_mutex_enter(pMaster);
110285 sqlite3GlobalConfig.isMutexInit = 1;
110286 if( !sqlite3GlobalConfig.isMallocInit ){
110287 rc = sqlite3MallocInit();
110288 }
@@ -111352,17 +111713,17 @@
111352 sqlite3 *db,
111353 const char *zName,
111354 int nArg
111355 ){
111356 int nName = sqlite3Strlen30(zName);
111357 int rc;
111358 sqlite3_mutex_enter(db->mutex);
111359 if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
111360 sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
111361 0, sqlite3InvalidFunction, 0, 0, 0);
111362 }
111363 rc = sqlite3ApiExit(db, SQLITE_OK);
111364 sqlite3_mutex_leave(db->mutex);
111365 return rc;
111366 }
111367
111368 #ifndef SQLITE_OMIT_TRACE
@@ -112420,10 +112781,11 @@
112420 if( db ){
112421 assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
112422 sqlite3_mutex_leave(db->mutex);
112423 }
112424 rc = sqlite3_errcode(db);
 
112425 if( rc==SQLITE_NOMEM ){
112426 sqlite3_close(db);
112427 db = 0;
112428 }else if( rc!=SQLITE_OK ){
112429 db->magic = SQLITE_MAGIC_SICK;
@@ -114148,10 +114510,17 @@
114148 #else
114149 # define TESTONLY(X)
114150 #endif
114151
114152 #endif /* SQLITE_AMALGAMATION */
 
 
 
 
 
 
 
114153
114154 typedef struct Fts3Table Fts3Table;
114155 typedef struct Fts3Cursor Fts3Cursor;
114156 typedef struct Fts3Expr Fts3Expr;
114157 typedef struct Fts3Phrase Fts3Phrase;
@@ -114176,10 +114545,11 @@
114176 const char *zDb; /* logical database name */
114177 const char *zName; /* virtual table name */
114178 int nColumn; /* number of named columns in virtual table */
114179 char **azColumn; /* column names. malloced */
114180 sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */
 
114181
114182 /* Precompiled statements used by the implementation. Each of these
114183 ** statements is run and reset within a single virtual table API call.
114184 */
114185 sqlite3_stmt *aStmt[27];
@@ -114216,11 +114586,11 @@
114216 } *aIndex;
114217 int nMaxPendingData; /* Max pending data before flush to disk */
114218 int nPendingData; /* Current bytes of pending data */
114219 sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
114220
114221 #if defined(SQLITE_DEBUG)
114222 /* State variables used for validating that the transaction control
114223 ** methods of the virtual table are called at appropriate times. These
114224 ** values do not contribution to the FTS computation; they are used for
114225 ** verifying the SQLite core.
114226 */
@@ -114301,10 +114671,11 @@
114301 */
114302 struct Fts3PhraseToken {
114303 char *z; /* Text of the token */
114304 int n; /* Number of bytes in buffer z */
114305 int isPrefix; /* True if token ends with a "*" character */
 
114306
114307 /* Variables above this point are populated when the expression is
114308 ** parsed (by code in fts3_expr.c). Below this point the variables are
114309 ** used when evaluating the expression. */
114310 Fts3DeferredToken *pDeferred; /* Deferred token object for this token */
@@ -114419,10 +114790,11 @@
114419 #define FTS3_SEGMENT_REQUIRE_POS 0x00000001
114420 #define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002
114421 #define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
114422 #define FTS3_SEGMENT_PREFIX 0x00000008
114423 #define FTS3_SEGMENT_SCAN 0x00000010
 
114424
114425 /* Type passed as 4th argument to SegmentReaderIterate() */
114426 struct Fts3SegFilter {
114427 const char *zTerm;
114428 int nTerm;
@@ -114458,12 +114830,12 @@
114458 SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
114459 SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
114460 SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
114461 SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
114462 SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
114463
114464 SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
 
114465
114466 /* fts3_tokenizer.c */
114467 SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
114468 SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
114469 SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -114478,11 +114850,11 @@
114478 );
114479 SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
114480
114481 /* fts3_expr.c */
114482 SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *,
114483 char **, int, int, const char *, int, Fts3Expr **
114484 );
114485 SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
114486 #ifdef SQLITE_TEST
114487 SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
114488 SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
@@ -114649,11 +115021,11 @@
114649 char **pp,
114650 char *pStart,
114651 sqlite3_int64 *pVal
114652 ){
114653 sqlite3_int64 iVal;
114654 char *p = *pp;
114655
114656 /* Pointer p now points at the first byte past the varint we are
114657 ** interested in. So, unless the doclist is corrupt, the 0x80 bit is
114658 ** clear on character p[-1]. */
114659 for(p = (*pp)-2; p>=pStart && *p&0x80; p--);
@@ -114679,10 +115051,11 @@
114679 sqlite3_finalize(p->aStmt[i]);
114680 }
114681 sqlite3_free(p->zSegmentsTbl);
114682 sqlite3_free(p->zReadExprlist);
114683 sqlite3_free(p->zWriteExprlist);
 
114684
114685 /* Invoke the tokenizer destructor to free the tokenizer. */
114686 p->pTokenizer->pModule->xDestroy(p->pTokenizer);
114687
114688 sqlite3_free(p);
@@ -114718,20 +115091,23 @@
114718
114719 /*
114720 ** The xDestroy() virtual table method.
114721 */
114722 static int fts3DestroyMethod(sqlite3_vtab *pVtab){
114723 int rc = SQLITE_OK; /* Return code */
114724 Fts3Table *p = (Fts3Table *)pVtab;
114725 sqlite3 *db = p->db;
 
 
114726
114727 /* Drop the shadow tables */
114728 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", p->zDb, p->zName);
114729 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", p->zDb,p->zName);
114730 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", p->zDb, p->zName);
114731 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", p->zDb, p->zName);
114732 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", p->zDb, p->zName);
 
 
114733
114734 /* If everything has worked, invoke fts3DisconnectMethod() to free the
114735 ** memory associated with the Fts3Table structure and return SQLITE_OK.
114736 ** Otherwise, return an SQLite error code.
114737 */
@@ -114789,27 +115165,31 @@
114789 ** %_stat tables required by FTS4.
114790 */
114791 static int fts3CreateTables(Fts3Table *p){
114792 int rc = SQLITE_OK; /* Return code */
114793 int i; /* Iterator variable */
114794 char *zContentCols; /* Columns of %_content table */
114795 sqlite3 *db = p->db; /* The database connection */
114796
114797 /* Create a list of user columns for the content table */
114798 zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
114799 for(i=0; zContentCols && i<p->nColumn; i++){
114800 char *z = p->azColumn[i];
114801 zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
114802 }
114803 if( zContentCols==0 ) rc = SQLITE_NOMEM;
114804
114805 /* Create the content table */
114806 fts3DbExec(&rc, db,
114807 "CREATE TABLE %Q.'%q_content'(%s)",
114808 p->zDb, p->zName, zContentCols
114809 );
114810 sqlite3_free(zContentCols);
 
 
 
 
 
114811 /* Create other tables */
114812 fts3DbExec(&rc, db,
114813 "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
114814 p->zDb, p->zName
114815 );
@@ -114956,12 +115336,12 @@
114956 }
114957 return zRet;
114958 }
114959
114960 /*
114961 ** Return a list of comma separated SQL expressions that could be used
114962 ** in a SELECT statement such as the following:
114963 **
114964 ** SELECT <list of expressions> FROM %_content AS x ...
114965 **
114966 ** to return the docid, followed by each column of text data in order
114967 ** from left to write. If parameter zFunc is not NULL, then instead of
@@ -114968,11 +115348,11 @@
114968 ** being returned directly each column of text data is passed to an SQL
114969 ** function named zFunc first. For example, if zFunc is "unzip" and the
114970 ** table has the three user-defined columns "a", "b", and "c", the following
114971 ** string is returned:
114972 **
114973 ** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c')"
114974 **
114975 ** The pointer returned points to a buffer allocated by sqlite3_malloc(). It
114976 ** is the responsibility of the caller to eventually free it.
114977 **
114978 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and
@@ -114984,20 +115364,32 @@
114984 char *zRet = 0;
114985 char *zFree = 0;
114986 char *zFunction;
114987 int i;
114988
114989 if( !zFunc ){
114990 zFunction = "";
 
 
 
 
 
 
 
 
 
114991 }else{
114992 zFree = zFunction = fts3QuoteId(zFunc);
 
 
 
114993 }
114994 fts3Appendf(pRc, &zRet, "docid");
114995 for(i=0; i<p->nColumn; i++){
114996 fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
114997 }
114998 sqlite3_free(zFree);
114999 return zRet;
115000 }
115001
115002 /*
115003 ** Return a list of N comma separated question marks, where N is the number
@@ -115050,11 +115442,11 @@
115050 ** the output value undefined. Otherwise SQLITE_OK is returned.
115051 **
115052 ** This function is used when parsing the "prefix=" FTS4 parameter.
115053 */
115054 static int fts3GobbleInt(const char **pp, int *pnOut){
115055 const char *p = *pp; /* Iterator pointer */
115056 int nInt = 0; /* Output value */
115057
115058 for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
115059 nInt = nInt * 10 + (p[0] - '0');
115060 }
@@ -115116,10 +115508,95 @@
115116 }
115117 }
115118
115119 return SQLITE_OK;
115120 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115121
115122 /*
115123 ** This function is the implementation of both the xConnect and xCreate
115124 ** methods of the FTS3 virtual table.
115125 **
@@ -115161,10 +115638,11 @@
115161 int bNoDocsize = 0; /* True to omit %_docsize table */
115162 int bDescIdx = 0; /* True to store descending indexes */
115163 char *zPrefix = 0; /* Prefix parameter value (or NULL) */
115164 char *zCompress = 0; /* compress=? parameter (or NULL) */
115165 char *zUncompress = 0; /* uncompress=? parameter (or NULL) */
 
115166
115167 assert( strlen(argv[0])==4 );
115168 assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
115169 || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4)
115170 );
@@ -115204,17 +115682,17 @@
115204 /* Check if it is an FTS4 special argument. */
115205 else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){
115206 struct Fts4Option {
115207 const char *zOpt;
115208 int nOpt;
115209 char **pzVar;
115210 } aFts4Opt[] = {
115211 { "matchinfo", 9, 0 }, /* 0 -> MATCHINFO */
115212 { "prefix", 6, 0 }, /* 1 -> PREFIX */
115213 { "compress", 8, 0 }, /* 2 -> COMPRESS */
115214 { "uncompress", 10, 0 }, /* 3 -> UNCOMPRESS */
115215 { "order", 5, 0 } /* 4 -> ORDER */
 
115216 };
115217
115218 int iOpt;
115219 if( !zVal ){
115220 rc = SQLITE_NOMEM;
@@ -115256,17 +115734,24 @@
115256 zVal = 0;
115257 break;
115258
115259 case 4: /* ORDER */
115260 if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
115261 && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 3))
115262 ){
115263 *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
115264 rc = SQLITE_ERROR;
115265 }
115266 bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
115267 break;
 
 
 
 
 
 
 
115268 }
115269 }
115270 sqlite3_free(zVal);
115271 }
115272 }
@@ -115275,10 +115760,30 @@
115275 else {
115276 nString += (int)(strlen(z) + 1);
115277 aCol[nCol++] = z;
115278 }
115279 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115280 if( rc!=SQLITE_OK ) goto fts3_init_out;
115281
115282 if( nCol==0 ){
115283 assert( nString==0 );
115284 aCol[0] = "content";
@@ -115319,10 +115824,12 @@
115319 p->pTokenizer = pTokenizer;
115320 p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
115321 p->bHasDocsize = (isFts4 && bNoDocsize==0);
115322 p->bHasStat = isFts4;
115323 p->bDescIdx = bDescIdx;
 
 
115324 TESTONLY( p->inTransaction = -1 );
115325 TESTONLY( p->mxSavepoint = -1 );
115326
115327 p->aIndex = (struct Fts3Index *)&p->azColumn[nCol];
115328 memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex);
@@ -115380,10 +115887,11 @@
115380 fts3_init_out:
115381 sqlite3_free(zPrefix);
115382 sqlite3_free(aIndex);
115383 sqlite3_free(zCompress);
115384 sqlite3_free(zUncompress);
 
115385 sqlite3_free((void *)aCol);
115386 if( rc!=SQLITE_OK ){
115387 if( p ){
115388 fts3DisconnectMethod((sqlite3_vtab *)p);
115389 }else if( pTokenizer ){
@@ -115530,40 +116038,69 @@
115530 sqlite3_free(pCsr->aMatchinfo);
115531 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
115532 sqlite3_free(pCsr);
115533 return SQLITE_OK;
115534 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115535
115536 /*
115537 ** Position the pCsr->pStmt statement so that it is on the row
115538 ** of the %_content table that contains the last match. Return
115539 ** SQLITE_OK on success.
115540 */
115541 static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
 
115542 if( pCsr->isRequireSeek ){
115543 sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
115544 pCsr->isRequireSeek = 0;
115545 if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
115546 return SQLITE_OK;
115547 }else{
115548 int rc = sqlite3_reset(pCsr->pStmt);
115549 if( rc==SQLITE_OK ){
115550 /* If no row was found and no error has occured, then the %_content
115551 ** table is missing a row that is present in the full-text index.
115552 ** The data structures are corrupt.
115553 */
115554 rc = SQLITE_CORRUPT_VTAB;
115555 }
115556 pCsr->isEof = 1;
115557 if( pContext ){
115558 sqlite3_result_error_code(pContext, rc);
115559 }
115560 return rc;
115561 }
115562 }else{
115563 return SQLITE_OK;
115564 }
 
 
 
115565 }
115566
115567 /*
115568 ** This function is used to process a single interior node when searching
115569 ** a b-tree for a term or term prefix. The node data is passed to this
@@ -115609,11 +116146,11 @@
115609 ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
115610 */
115611 zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
115612 zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
115613 if( zCsr>zEnd ){
115614 return SQLITE_CORRUPT_VTAB;
115615 }
115616
115617 while( zCsr<zEnd && (piFirst || piLast) ){
115618 int cmp; /* memcmp() result */
115619 int nSuffix; /* Size of term suffix */
@@ -115627,11 +116164,11 @@
115627 }
115628 isFirstTerm = 0;
115629 zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
115630
115631 if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
115632 rc = SQLITE_CORRUPT_VTAB;
115633 goto finish_scan;
115634 }
115635 if( nPrefix+nSuffix>nAlloc ){
115636 char *zNew;
115637 nAlloc = (nPrefix+nSuffix) * 2;
@@ -115640,10 +116177,11 @@
115640 rc = SQLITE_NOMEM;
115641 goto finish_scan;
115642 }
115643 zBuffer = zNew;
115644 }
 
115645 memcpy(&zBuffer[nPrefix], zCsr, nSuffix);
115646 nBuffer = nPrefix + nSuffix;
115647 zCsr += nSuffix;
115648
115649 /* Compare the term we are searching for with the term just loaded from
@@ -115998,20 +116536,20 @@
115998 int isSaveLeft, /* Save the left position */
115999 int isExact, /* If *pp1 is exactly nTokens before *pp2 */
116000 char **pp1, /* IN/OUT: Left input list */
116001 char **pp2 /* IN/OUT: Right input list */
116002 ){
116003 char *p = (pp ? *pp : 0);
116004 char *p1 = *pp1;
116005 char *p2 = *pp2;
116006 int iCol1 = 0;
116007 int iCol2 = 0;
116008
116009 /* Never set both isSaveLeft and isExact for the same invocation. */
116010 assert( isSaveLeft==0 || isExact==0 );
116011
116012 assert( *p1!=0 && *p2!=0 );
116013 if( *p1==POS_COLUMN ){
116014 p1++;
116015 p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
116016 }
116017 if( *p2==POS_COLUMN ){
@@ -116024,11 +116562,11 @@
116024 char *pSave = p;
116025 sqlite3_int64 iPrev = 0;
116026 sqlite3_int64 iPos1 = 0;
116027 sqlite3_int64 iPos2 = 0;
116028
116029 if( pp && iCol1 ){
116030 *p++ = POS_COLUMN;
116031 p += sqlite3Fts3PutVarint(p, iCol1);
116032 }
116033
116034 assert( *p1!=POS_END && *p1!=POS_COLUMN );
@@ -116039,20 +116577,14 @@
116039 while( 1 ){
116040 if( iPos2==iPos1+nToken
116041 || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken)
116042 ){
116043 sqlite3_int64 iSave;
116044 if( !pp ){
116045 fts3PoslistCopy(0, &p2);
116046 fts3PoslistCopy(0, &p1);
116047 *pp1 = p1;
116048 *pp2 = p2;
116049 return 1;
116050 }
116051 iSave = isSaveLeft ? iPos1 : iPos2;
116052 fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2;
116053 pSave = 0;
 
116054 }
116055 if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){
116056 if( (*p2&0xFE)==0 ) break;
116057 fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
116058 }else{
@@ -116097,11 +116629,11 @@
116097
116098 fts3PoslistCopy(0, &p2);
116099 fts3PoslistCopy(0, &p1);
116100 *pp1 = p1;
116101 *pp2 = p2;
116102 if( !pp || *pp==p ){
116103 return 0;
116104 }
116105 *p++ = 0x00;
116106 *pp = p;
116107 return 1;
@@ -116399,10 +116931,60 @@
116399 }
116400 }
116401
116402 *pnRight = p - aOut;
116403 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116404
116405
116406 /*
116407 ** Merge all doclists in the TermSelect.aaOutput[] array into a single
116408 ** doclist stored in TermSelect.aaOutput[0]. If successful, delete all
@@ -116756,10 +117338,11 @@
116756 pSegcsr = pTok->pSegcsr;
116757 memset(&tsc, 0, sizeof(TermSelect));
116758
116759 filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS
116760 | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0)
 
116761 | (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0);
116762 filter.iCol = iColumn;
116763 filter.zTerm = pTok->z;
116764 filter.nTerm = pTok->n;
116765
@@ -116896,12 +117479,12 @@
116896
116897 if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
116898 return SQLITE_NOMEM;
116899 }
116900
116901 rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->nColumn,
116902 iCol, zQuery, -1, &pCsr->pExpr
116903 );
116904 if( rc!=SQLITE_OK ){
116905 if( rc==SQLITE_ERROR ){
116906 static const char *zErr = "malformed MATCH expression: [%s]";
116907 p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery);
@@ -116924,26 +117507,27 @@
116924 ** statement loops through all rows of the %_content table. For a
116925 ** full-text query or docid lookup, the statement retrieves a single
116926 ** row by docid.
116927 */
116928 if( idxNum==FTS3_FULLSCAN_SEARCH ){
116929 const char *zSort = (pCsr->bDesc ? "DESC" : "ASC");
116930 const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x ORDER BY docid %s";
116931 zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName, zSort);
116932 }else{
116933 const char *zTmpl = "SELECT %s FROM %Q.'%q_content' AS x WHERE docid = ?";
116934 zSql = sqlite3_mprintf(zTmpl, p->zReadExprlist, p->zDb, p->zName);
116935 }
116936 if( !zSql ) return SQLITE_NOMEM;
116937 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
116938 sqlite3_free(zSql);
116939 if( rc!=SQLITE_OK ) return rc;
116940
116941 if( idxNum==FTS3_DOCID_SEARCH ){
116942 rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
116943 if( rc!=SQLITE_OK ) return rc;
116944 }
 
116945
116946 return fts3NextMethod(pCursor);
116947 }
116948
116949 /*
@@ -116992,11 +117576,11 @@
116992 ** Return a blob which is a pointer to the cursor.
116993 */
116994 sqlite3_result_blob(pContext, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
116995 }else{
116996 rc = fts3CursorSeek(0, pCsr);
116997 if( rc==SQLITE_OK ){
116998 sqlite3_result_value(pContext, sqlite3_column_value(pCsr->pStmt, iCol+1));
116999 }
117000 }
117001
117002 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
@@ -117076,11 +117660,11 @@
117076 ** moves *ppPoslist so that it instead points to the first byte of the
117077 ** same position list.
117078 */
117079 static void fts3ReversePoslist(char *pStart, char **ppPoslist){
117080 char *p = &(*ppPoslist)[-2];
117081 char c;
117082
117083 while( p>pStart && (c=*p--)==0 );
117084 while( p>pStart && (*p & 0x80) | c ){
117085 c = *p--;
117086 }
@@ -117285,19 +117869,26 @@
117285 ){
117286 Fts3Table *p = (Fts3Table *)pVtab;
117287 sqlite3 *db = p->db; /* Database connection */
117288 int rc; /* Return Code */
117289
 
 
 
 
 
 
 
117290 rc = sqlite3Fts3PendingTermsFlush(p);
117291 if( rc!=SQLITE_OK ){
117292 return rc;
 
 
 
 
117293 }
117294
117295 fts3DbExec(&rc, db,
117296 "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';",
117297 p->zDb, p->zName, zName
117298 );
117299 if( p->bHasDocsize ){
117300 fts3DbExec(&rc, db,
117301 "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';",
117302 p->zDb, p->zName, zName
117303 );
@@ -117652,25 +118243,24 @@
117652 **
117653 ** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
117654 */
117655 static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
117656 int iToken; /* Used to iterate through phrase tokens */
117657 int rc = SQLITE_OK; /* Return code */
117658 char *aPoslist = 0; /* Position list for deferred tokens */
117659 int nPoslist = 0; /* Number of bytes in aPoslist */
117660 int iPrev = -1; /* Token number of previous deferred token */
117661
117662 assert( pPhrase->doclist.bFreeList==0 );
117663
117664 for(iToken=0; rc==SQLITE_OK && iToken<pPhrase->nToken; iToken++){
117665 Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
117666 Fts3DeferredToken *pDeferred = pToken->pDeferred;
117667
117668 if( pDeferred ){
117669 char *pList;
117670 int nList;
117671 rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
117672 if( rc!=SQLITE_OK ) return rc;
117673
117674 if( pList==0 ){
117675 sqlite3_free(aPoslist);
117676 pPhrase->doclist.pList = 0;
@@ -117767,10 +118357,11 @@
117767 if( pCsr->bDesc==pTab->bDescIdx
117768 && bOptOk==1
117769 && p->nToken==1
117770 && pFirst->pSegcsr
117771 && pFirst->pSegcsr->bLookup
 
117772 ){
117773 /* Use the incremental approach. */
117774 int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
117775 rc = sqlite3Fts3MsrIncrStart(
117776 pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
@@ -117996,11 +118587,11 @@
117996 Fts3Expr *pExpr, /* Expression to consider */
117997 Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */
117998 Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */
117999 int *pRc /* IN/OUT: Error code */
118000 ){
118001 if( *pRc==SQLITE_OK && pExpr ){
118002 if( pExpr->eType==FTSQUERY_PHRASE ){
118003 Fts3Phrase *pPhrase = pExpr->pPhrase;
118004 int i;
118005 for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
118006 Fts3TokenAndCost *pTC = (*ppTC)++;
@@ -118010,10 +118601,15 @@
118010 pTC->pToken = &pPhrase->aToken[i];
118011 pTC->iCol = pPhrase->iColumn;
118012 *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl);
118013 }
118014 }else if( pExpr->eType!=FTSQUERY_NOT ){
 
 
 
 
 
118015 if( pExpr->eType==FTSQUERY_OR ){
118016 pRoot = pExpr->pLeft;
118017 **ppOr = pRoot;
118018 (*ppOr)++;
118019 }
@@ -118070,11 +118666,11 @@
118070 while( a<pEnd ){
118071 a += sqlite3Fts3GetVarint(a, &nByte);
118072 }
118073 if( nDoc==0 || nByte==0 ){
118074 sqlite3_reset(pStmt);
118075 return SQLITE_CORRUPT_VTAB;
118076 }
118077
118078 pCsr->nDoc = nDoc;
118079 pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
118080 assert( pCsr->nRowAvg>0 );
@@ -118113,10 +118709,19 @@
118113 int nOvfl = 0; /* Total overflow pages used by doclists */
118114 int nToken = 0; /* Total number of tokens in cluster */
118115
118116 int nMinEst = 0; /* The minimum count for any phrase so far. */
118117 int nLoad4 = 1; /* (Phrases that will be loaded)^4. */
 
 
 
 
 
 
 
 
 
118118
118119 /* Count the tokens in this AND/NEAR cluster. If none of the doclists
118120 ** associated with the tokens spill onto overflow pages, or if there is
118121 ** only 1 token, exit early. No tokens to defer in this case. */
118122 for(ii=0; ii<nTC; ii++){
@@ -118176,11 +118781,15 @@
118176 Fts3PhraseToken *pToken = pTC->pToken;
118177 rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
118178 fts3SegReaderCursorFree(pToken->pSegcsr);
118179 pToken->pSegcsr = 0;
118180 }else{
118181 nLoad4 = nLoad4*4;
 
 
 
 
118182 if( ii==0 || pTC->pPhrase->nToken>1 ){
118183 /* Either this is the cheapest token in the entire query, or it is
118184 ** part of a multi-token phrase. Either way, the entire doclist will
118185 ** (eventually) be loaded into memory. It may as well be now. */
118186 Fts3PhraseToken *pToken = pTC->pToken;
@@ -118546,12 +119155,15 @@
118546 }
118547
118548 aPoslist = pExpr->pRight->pPhrase->doclist.pList;
118549 nToken = pExpr->pRight->pPhrase->nToken;
118550 for(p=pExpr->pLeft; p && res; p=p->pLeft){
118551 int nNear = p->pParent->nNear;
118552 Fts3Phrase *pPhrase = (
 
 
 
118553 p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
118554 );
118555 res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
118556 }
118557 }
@@ -119037,10 +119649,19 @@
119037 pPhrase->aToken[i].pSegcsr = 0;
119038 }
119039 }
119040 }
119041
 
 
 
 
 
 
 
 
 
119042 #if !SQLITE_CORE
119043 /*
119044 ** Initialize API pointer table, if required.
119045 */
119046 SQLITE_API int sqlite3_extension_init(
@@ -119625,10 +120246,11 @@
119625 */
119626 typedef struct ParseContext ParseContext;
119627 struct ParseContext {
119628 sqlite3_tokenizer *pTokenizer; /* Tokenizer module */
119629 const char **azCol; /* Array of column names for fts3 table */
 
119630 int nCol; /* Number of entries in azCol[] */
119631 int iDefaultCol; /* Default column to query */
119632 int isNot; /* True if getNextNode() sees a unary - */
119633 sqlite3_context *pCtx; /* Write error message here */
119634 int nNest; /* Number of nested brackets */
@@ -119712,13 +120334,25 @@
119712
119713 if( iEnd<n && z[iEnd]=='*' ){
119714 pRet->pPhrase->aToken[0].isPrefix = 1;
119715 iEnd++;
119716 }
119717 if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){
119718 pParse->isNot = 1;
 
 
 
 
 
 
 
 
 
 
 
119719 }
 
119720 }
119721 nConsumed = iEnd;
119722 }
119723
119724 pModule->xClose(pCursor);
@@ -119813,10 +120447,11 @@
119813 memcpy(&zTemp[nTemp], zByte, nByte);
119814 nTemp += nByte;
119815
119816 pToken->n = nByte;
119817 pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
 
119818 nToken = ii+1;
119819 }
119820 }
119821
119822 pModule->xClose(pCursor);
@@ -119834,12 +120469,16 @@
119834 p->pPhrase = (Fts3Phrase *)&p[1];
119835 p->pPhrase->iColumn = pParse->iDefaultCol;
119836 p->pPhrase->nToken = nToken;
119837
119838 zBuf = (char *)&p->pPhrase->aToken[nToken];
119839 memcpy(zBuf, zTemp, nTemp);
119840 sqlite3_free(zTemp);
 
 
 
 
119841
119842 for(jj=0; jj<p->pPhrase->nToken; jj++){
119843 p->pPhrase->aToken[jj].z = zBuf;
119844 zBuf += p->pPhrase->aToken[jj].n;
119845 }
@@ -120260,10 +120899,11 @@
120260 ** match any table column.
120261 */
120262 SQLITE_PRIVATE int sqlite3Fts3ExprParse(
120263 sqlite3_tokenizer *pTokenizer, /* Tokenizer module */
120264 char **azCol, /* Array of column names for fts3 table */
 
120265 int nCol, /* Number of entries in azCol[] */
120266 int iDefaultCol, /* Default column to query */
120267 const char *z, int n, /* Text of MATCH query */
120268 Fts3Expr **ppExpr /* OUT: Parsed query structure */
120269 ){
@@ -120273,10 +120913,11 @@
120273 sParse.pTokenizer = pTokenizer;
120274 sParse.azCol = (const char **)azCol;
120275 sParse.nCol = nCol;
120276 sParse.iDefaultCol = iDefaultCol;
120277 sParse.nNest = 0;
 
120278 if( z==0 ){
120279 *ppExpr = 0;
120280 return SQLITE_OK;
120281 }
120282 if( n<0 ){
@@ -120462,11 +121103,11 @@
120462 for(ii=0; ii<nCol; ii++){
120463 azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
120464 }
120465
120466 rc = sqlite3Fts3ExprParse(
120467 pTokenizer, azCol, nCol, nCol, zExpr, nExpr, &pExpr
120468 );
120469 if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
120470 sqlite3_result_error(context, "Error parsing expression", -1);
120471 }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
120472 sqlite3_result_error_nomem(context);
@@ -122509,11 +123150,11 @@
122509 /* 2 */ "DELETE FROM %Q.'%q_content'",
122510 /* 3 */ "DELETE FROM %Q.'%q_segments'",
122511 /* 4 */ "DELETE FROM %Q.'%q_segdir'",
122512 /* 5 */ "DELETE FROM %Q.'%q_docsize'",
122513 /* 6 */ "DELETE FROM %Q.'%q_stat'",
122514 /* 7 */ "SELECT %s FROM %Q.'%q_content' AS x WHERE rowid=?",
122515 /* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1",
122516 /* 9 */ "INSERT INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)",
122517 /* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)",
122518 /* 11 */ "INSERT INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)",
122519
@@ -122551,11 +123192,11 @@
122551 if( !pStmt ){
122552 char *zSql;
122553 if( eStmt==SQL_CONTENT_INSERT ){
122554 zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
122555 }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
122556 zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist, p->zDb, p->zName);
122557 }else{
122558 zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
122559 }
122560 if( !zSql ){
122561 rc = SQLITE_NOMEM;
@@ -122594,11 +123235,11 @@
122594 sqlite3_bind_int64(pStmt, 1, iDocid);
122595 }
122596 rc = sqlite3_step(pStmt);
122597 if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
122598 rc = sqlite3_reset(pStmt);
122599 if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT_VTAB;
122600 pStmt = 0;
122601 }else{
122602 rc = SQLITE_OK;
122603 }
122604 }
@@ -122662,21 +123303,28 @@
122662 ** We try to avoid this because if FTS3 returns any error when committing
122663 ** a transaction, the whole transaction will be rolled back. And this is
122664 ** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
122665 ** still happen if the user reads data directly from the %_segments or
122666 ** %_segdir tables instead of going through FTS3 though.
 
 
122667 */
122668 SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
122669 int rc; /* Return code */
122670 sqlite3_stmt *pStmt; /* Statement used to obtain lock */
122671
122672 rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
122673 if( rc==SQLITE_OK ){
122674 sqlite3_bind_null(pStmt, 1);
122675 sqlite3_step(pStmt);
122676 rc = sqlite3_reset(pStmt);
 
 
 
 
122677 }
 
122678 return rc;
122679 }
122680
122681 /*
122682 ** Set *ppStmt to a statement handle that may be used to iterate through
@@ -123032,10 +123680,22 @@
123032 sqlite3_value **apVal, /* Array of values to insert */
123033 sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */
123034 ){
123035 int rc; /* Return code */
123036 sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */
 
 
 
 
 
 
 
 
 
 
 
 
123037
123038 /* Locate the statement handle used to insert data into the %_content
123039 ** table. The SQL for this statement is:
123040 **
123041 ** INSERT INTO %_content VALUES(?, ?, ?, ...)
@@ -123083,18 +123743,20 @@
123083
123084 /*
123085 ** Remove all data from the FTS3 table. Clear the hash table containing
123086 ** pending terms.
123087 */
123088 static int fts3DeleteAll(Fts3Table *p){
123089 int rc = SQLITE_OK; /* Return code */
123090
123091 /* Discard the contents of the pending-terms hash table. */
123092 sqlite3Fts3PendingTermsClear(p);
123093
123094 /* Delete everything from the %_content, %_segments and %_segdir tables. */
123095 fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
 
 
123096 fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0);
123097 fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
123098 if( p->bHasDocsize ){
123099 fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
123100 }
@@ -123398,11 +124060,11 @@
123398 pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
123399 pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
123400 if( nPrefix<0 || nSuffix<=0
123401 || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
123402 ){
123403 return SQLITE_CORRUPT_VTAB;
123404 }
123405
123406 if( nPrefix+nSuffix>pReader->nTermAlloc ){
123407 int nNew = (nPrefix+nSuffix)*2;
123408 char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
@@ -123428,11 +124090,11 @@
123428 ** of these statements is untrue, then the data structure is corrupt.
123429 */
123430 if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
123431 || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
123432 ){
123433 return SQLITE_CORRUPT_VTAB;
123434 }
123435 return SQLITE_OK;
123436 }
123437
123438 /*
@@ -124378,16 +125040,22 @@
124378 ** error occurs, an SQLite error code is returned.
124379 */
124380 static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){
124381 sqlite3_stmt *pStmt;
124382 int rc;
124383 rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
124384 if( rc==SQLITE_OK ){
124385 if( SQLITE_ROW==sqlite3_step(pStmt) ){
124386 *pisEmpty = sqlite3_column_int(pStmt, 0);
 
 
 
 
 
 
 
124387 }
124388 rc = sqlite3_reset(pStmt);
124389 }
124390 return rc;
124391 }
124392
124393 /*
@@ -124735,10 +125403,11 @@
124735 int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY);
124736 int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS);
124737 int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER);
124738 int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX);
124739 int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN);
 
124740
124741 Fts3SegReader **apSegment = pCsr->apSegment;
124742 int nSegment = pCsr->nSegment;
124743 Fts3SegFilter *pFilter = pCsr->pFilter;
124744 int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
@@ -124794,10 +125463,11 @@
124794 }
124795
124796 assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
124797 if( nMerge==1
124798 && !isIgnoreEmpty
 
124799 && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
124800 ){
124801 pCsr->nDoclist = apSegment[0]->nDoclist;
124802 if( fts3SegReaderIsPending(apSegment[0]) ){
124803 rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
@@ -124859,16 +125529,28 @@
124859 if( !aNew ){
124860 return SQLITE_NOMEM;
124861 }
124862 pCsr->aBuffer = aNew;
124863 }
124864 nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
124865 iPrev = iDocid;
124866 if( isRequirePos ){
124867 memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
124868 nDoclist += nList;
124869 pCsr->aBuffer[nDoclist++] = '\0';
 
 
 
 
 
 
 
 
 
 
 
 
124870 }
124871 }
124872
124873 fts3SegReaderSort(apSegment, nMerge, j, xCmp);
124874 }
@@ -125040,13 +125722,13 @@
125040 ** Insert the sizes (in tokens) for each column of the document
125041 ** with docid equal to p->iPrevDocid. The sizes are encoded as
125042 ** a blob of varints.
125043 */
125044 static void fts3InsertDocsize(
125045 int *pRC, /* Result code */
125046 Fts3Table *p, /* Table into which to insert */
125047 u32 *aSz /* Sizes of each column */
125048 ){
125049 char *pBlob; /* The BLOB encoding of the document size */
125050 int nBlob; /* Number of bytes in the BLOB */
125051 sqlite3_stmt *pStmt; /* Statement used to insert the encoding */
125052 int rc; /* Result code from subfunctions */
@@ -125163,10 +125845,90 @@
125163 sqlite3Fts3SegmentsClose(p);
125164 sqlite3Fts3PendingTermsClear(p);
125165
125166 return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
125167 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125168
125169 /*
125170 ** Handle a 'special' INSERT of the form:
125171 **
125172 ** "INSERT INTO tbl(tbl) VALUES(<expr>)"
@@ -125181,10 +125943,12 @@
125181
125182 if( !zVal ){
125183 return SQLITE_NOMEM;
125184 }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
125185 rc = fts3DoOptimize(p, 0);
 
 
125186 #ifdef SQLITE_TEST
125187 }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
125188 p->nNodeSize = atoi(&zVal[9]);
125189 rc = SQLITE_OK;
125190 }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
@@ -125261,10 +126025,11 @@
125261 pTC->pTokenizer = pT;
125262 rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
125263 for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
125264 Fts3PhraseToken *pPT = pDef->pToken;
125265 if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
 
125266 && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
125267 && (0==memcmp(zToken, pPT->z, pPT->n))
125268 ){
125269 fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
125270 }
@@ -125352,18 +126117,22 @@
125352 if( rc==SQLITE_OK ){
125353 if( isEmpty ){
125354 /* Deleting this row means the whole table is empty. In this case
125355 ** delete the contents of all three tables and throw away any
125356 ** data in the pendingTerms hash table. */
125357 rc = fts3DeleteAll(p);
125358 *pnDoc = *pnDoc - 1;
125359 }else{
125360 sqlite3_int64 iRemove = sqlite3_value_int64(pRowid);
125361 rc = fts3PendingTermsDocid(p, iRemove);
125362 fts3DeleteTerms(&rc, p, pRowid, aSzDel);
125363 fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
125364 if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
 
 
 
 
125365 if( p->bHasDocsize ){
125366 fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
125367 }
125368 }
125369 }
@@ -125382,11 +126151,10 @@
125382 sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
125383 ){
125384 Fts3Table *p = (Fts3Table *)pVtab;
125385 int rc = SQLITE_OK; /* Return Code */
125386 int isRemove = 0; /* True for an UPDATE or DELETE */
125387 sqlite3_int64 iRemove = 0; /* Rowid removed by UPDATE or DELETE */
125388 u32 *aSzIns = 0; /* Sizes of inserted documents */
125389 u32 *aSzDel; /* Sizes of deleted documents */
125390 int nChng = 0; /* Net change in number of documents */
125391 int bInsertDone = 0;
125392
@@ -125420,11 +126188,11 @@
125420 ** should be deleted from the database before inserting the new row. Or,
125421 ** if the on-conflict mode is other than REPLACE, then this method must
125422 ** detect the conflict and return SQLITE_CONSTRAINT before beginning to
125423 ** modify the database file.
125424 */
125425 if( nArg>1 ){
125426 /* Find the value object that holds the new rowid value. */
125427 sqlite3_value *pNewRowid = apVal[3+p->nColumn];
125428 if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){
125429 pNewRowid = apVal[1];
125430 }
@@ -125465,23 +126233,25 @@
125465 /* If this is a DELETE or UPDATE operation, remove the old record. */
125466 if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
125467 assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
125468 rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
125469 isRemove = 1;
125470 iRemove = sqlite3_value_int64(apVal[0]);
125471 }
125472
125473 /* If this is an INSERT or UPDATE operation, insert the new record. */
125474 if( nArg>1 && rc==SQLITE_OK ){
125475 if( bInsertDone==0 ){
125476 rc = fts3InsertData(p, apVal, pRowid);
125477 if( rc==SQLITE_CONSTRAINT ) rc = SQLITE_CORRUPT_VTAB;
 
 
125478 }
125479 if( rc==SQLITE_OK && (!isRemove || *pRowid!=iRemove) ){
125480 rc = fts3PendingTermsDocid(p, *pRowid);
125481 }
125482 if( rc==SQLITE_OK ){
 
125483 rc = fts3InsertTerms(p, apVal, aSzIns);
125484 }
125485 if( p->bHasDocsize ){
125486 fts3InsertDocsize(&rc, p, aSzIns);
125487 }
@@ -125891,10 +126661,11 @@
125891 pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol);
125892 if( pCsr ){
125893 int iFirst = 0;
125894 pPhrase->pList = pCsr;
125895 fts3GetDeltaPosition(&pCsr, &iFirst);
 
125896 pPhrase->pHead = pCsr;
125897 pPhrase->pTail = pCsr;
125898 pPhrase->iHead = iFirst;
125899 pPhrase->iTail = iFirst;
125900 }else{
@@ -126371,11 +127142,11 @@
126371 pStmt = *ppStmt;
126372 assert( sqlite3_data_count(pStmt)==1 );
126373
126374 a = sqlite3_column_blob(pStmt, 0);
126375 a += sqlite3Fts3GetVarint(a, &nDoc);
126376 if( nDoc==0 ) return SQLITE_CORRUPT_VTAB;
126377 *pnDoc = (u32)nDoc;
126378
126379 if( paLen ) *paLen = a;
126380 return SQLITE_OK;
126381 }
@@ -126932,11 +127703,11 @@
126932 }
126933 }
126934
126935 if( !pTerm ){
126936 /* All offsets for this column have been gathered. */
126937 break;
126938 }else{
126939 assert( iCurrent<=iMinPos );
126940 if( 0==(0xFE&*pTerm->pList) ){
126941 pTerm->pList = 0;
126942 }else{
@@ -126949,12 +127720,12 @@
126949 char aBuffer[64];
126950 sqlite3_snprintf(sizeof(aBuffer), aBuffer,
126951 "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
126952 );
126953 rc = fts3StringAppend(&res, aBuffer, -1);
126954 }else if( rc==SQLITE_DONE ){
126955 rc = SQLITE_CORRUPT_VTAB;
126956 }
126957 }
126958 }
126959 if( rc==SQLITE_DONE ){
126960 rc = SQLITE_OK;
@@ -128291,11 +129062,12 @@
128291 pCsr->nConstraint = argc;
128292 if( !pCsr->aConstraint ){
128293 rc = SQLITE_NOMEM;
128294 }else{
128295 memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
128296 assert( (idxStr==0 && argc==0) || (int)strlen(idxStr)==argc*2 );
 
128297 for(ii=0; ii<argc; ii++){
128298 RtreeConstraint *p = &pCsr->aConstraint[ii];
128299 p->op = idxStr[ii*2];
128300 p->iCoord = idxStr[ii*2+1]-'a';
128301 if( p->op==RTREE_MATCH ){
@@ -128592,11 +129364,14 @@
128592 int iCell;
128593 sqlite3_int64 iBest = 0;
128594
128595 float fMinGrowth = 0.0;
128596 float fMinArea = 0.0;
 
128597 float fMinOverlap = 0.0;
 
 
128598
128599 int nCell = NCELL(pNode);
128600 RtreeCell cell;
128601 RtreeNode *pChild;
128602
@@ -128624,33 +129399,34 @@
128624 */
128625 for(iCell=0; iCell<nCell; iCell++){
128626 int bBest = 0;
128627 float growth;
128628 float area;
128629 float overlap = 0.0;
128630 nodeGetCell(pRtree, pNode, iCell, &cell);
128631 growth = cellGrowth(pRtree, &cell, pCell);
128632 area = cellArea(pRtree, &cell);
128633
128634 #if VARIANT_RSTARTREE_CHOOSESUBTREE
128635 if( ii==(pRtree->iDepth-1) ){
128636 overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
 
 
128637 }
128638 if( (iCell==0)
128639 || (overlap<fMinOverlap)
128640 || (overlap==fMinOverlap && growth<fMinGrowth)
128641 || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
128642 ){
128643 bBest = 1;
 
128644 }
128645 #else
128646 if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
128647 bBest = 1;
128648 }
128649 #endif
128650 if( bBest ){
128651 fMinOverlap = overlap;
128652 fMinGrowth = growth;
128653 fMinArea = area;
128654 iBest = cell.iRowid;
128655 }
128656 }
128657
--- 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.7.9. 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.
@@ -394,11 +394,11 @@
394 ** assert() macro is enabled, each call into the Win32 native heap subsystem
395 ** will cause HeapValidate to be called. If heap validation should fail, an
396 ** assertion will be triggered.
397 **
398 ** (Historical note: There used to be several other options, but we've
399 ** pared it down to just these three.)
400 **
401 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
402 ** the default.
403 */
404 #if defined(SQLITE_SYSTEM_MALLOC)+defined(SQLITE_WIN32_MALLOC)+defined(SQLITE_MEMDEBUG)>1
@@ -654,13 +654,13 @@
654 **
655 ** See also: [sqlite3_libversion()],
656 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
657 ** [sqlite_version()] and [sqlite_source_id()].
658 */
659 #define SQLITE_VERSION "3.7.9"
660 #define SQLITE_VERSION_NUMBER 3007009
661 #define SQLITE_SOURCE_ID "2011-10-20 00:55:54 4344483f7d7f64dffadde0053e6c745948db9486"
662
663 /*
664 ** CAPI3REF: Run-Time Library Version Numbers
665 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
666 **
@@ -1318,11 +1318,15 @@
1318 ** in order for the database to be readable. The fourth parameter to
1319 ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
1320 ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
1321 ** WAL mode. If the integer is -1, then it is overwritten with the current
1322 ** WAL persistence setting.
1323 **
1324 ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
1325 ** a write transaction to indicate that, unless it is rolled back for some
1326 ** reason, the entire database file will be overwritten by the current
1327 ** transaction. This is used by VACUUM operations.
1328 */
1329 #define SQLITE_FCNTL_LOCKSTATE 1
1330 #define SQLITE_GET_LOCKPROXYFILE 2
1331 #define SQLITE_SET_LOCKPROXYFILE 3
1332 #define SQLITE_LAST_ERRNO 4
@@ -1330,10 +1334,11 @@
1334 #define SQLITE_FCNTL_CHUNK_SIZE 6
1335 #define SQLITE_FCNTL_FILE_POINTER 7
1336 #define SQLITE_FCNTL_SYNC_OMITTED 8
1337 #define SQLITE_FCNTL_WIN32_AV_RETRY 9
1338 #define SQLITE_FCNTL_PERSIST_WAL 10
1339 #define SQLITE_FCNTL_OVERWRITE 11
1340
1341 /*
1342 ** CAPI3REF: Mutex Handle
1343 **
1344 ** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1946,12 +1951,12 @@
1951 ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
1952 ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
1953 ** allocator is engaged to handle all of SQLites memory allocation needs.
1954 ** The first pointer (the memory pointer) must be aligned to an 8-byte
1955 ** boundary or subsequent behavior of SQLite will be undefined.
1956 ** The minimum allocation size is capped at 2**12. Reasonable values
1957 ** for the minimum allocation size are 2**5 through 2**8.</dd>
1958 **
1959 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
1960 ** <dd> ^(This option takes a single argument which is a pointer to an
1961 ** instance of the [sqlite3_mutex_methods] structure. The argument specifies
1962 ** alternative low-level mutex routines to be used in place
@@ -3346,11 +3351,12 @@
3351 ** zSql string ends at either the first '\000' or '\u0000' character or
3352 ** the nByte-th byte, whichever comes first. If the caller knows
3353 ** that the supplied string is nul-terminated, then there is a small
3354 ** performance advantage to be gained by passing an nByte parameter that
3355 ** is equal to the number of bytes in the input string <i>including</i>
3356 ** the nul-terminator bytes as this saves SQLite from having to
3357 ** make a copy of the input string.
3358 **
3359 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
3360 ** past the end of the first SQL statement in zSql. These routines only
3361 ** compile the first statement in zSql, so *pzTail is left pointing to
3362 ** what remains uncompiled.
@@ -3397,11 +3403,11 @@
3403 ** a schema change, on the first [sqlite3_step()] call following any change
3404 ** to the [sqlite3_bind_text | bindings] of that [parameter].
3405 ** ^The specific value of WHERE-clause [parameter] might influence the
3406 ** choice of query plan if the parameter is the left-hand side of a [LIKE]
3407 ** or [GLOB] operator or if the parameter is compared to an indexed column
3408 ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
3409 ** the
3410 ** </li>
3411 ** </ol>
3412 */
3413 SQLITE_API int sqlite3_prepare(
@@ -3567,10 +3573,17 @@
3573 ** ^(In those routines that have a fourth argument, its value is the
3574 ** number of bytes in the parameter. To be clear: the value is the
3575 ** number of <u>bytes</u> in the value, not the number of characters.)^
3576 ** ^If the fourth parameter is negative, the length of the string is
3577 ** the number of bytes up to the first zero terminator.
3578 ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
3579 ** or sqlite3_bind_text16() then that parameter must be the byte offset
3580 ** where the NUL terminator would occur assuming the string were NUL
3581 ** terminated. If any NUL characters occur at byte offsets less than
3582 ** the value of the fourth parameter then the resulting string value will
3583 ** contain embedded NULs. The result of expressions involving strings
3584 ** with embedded NULs is undefined.
3585 **
3586 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3587 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3588 ** string after SQLite has finished with it. ^The destructor is called
3589 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
@@ -3900,10 +3913,16 @@
3913 ** current row of the result set of [prepared statement] P.
3914 ** ^If prepared statement P does not have results ready to return
3915 ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
3916 ** interfaces) then sqlite3_data_count(P) returns 0.
3917 ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
3918 ** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
3919 ** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P)
3920 ** will return non-zero if previous call to [sqlite3_step](P) returned
3921 ** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
3922 ** where it always returns zero since each step of that multi-step
3923 ** pragma returns 0 columns of data.
3924 **
3925 ** See also: [sqlite3_column_count()]
3926 */
3927 SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
3928
@@ -4579,11 +4598,16 @@
4598 ** is negative, then SQLite takes result text from the 2nd parameter
4599 ** through the first zero character.
4600 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
4601 ** is non-negative, then as many bytes (not characters) of the text
4602 ** pointed to by the 2nd parameter are taken as the application-defined
4603 ** function result. If the 3rd parameter is non-negative, then it
4604 ** must be the byte offset into the string where the NUL terminator would
4605 ** appear if the string where NUL terminated. If any NUL characters occur
4606 ** in the string at a byte offset that is less than the value of the 3rd
4607 ** parameter, then the resulting string will contain embedded NULs and the
4608 ** result of expressions operating on strings with embedded NULs is undefined.
4609 ** ^If the 4th parameter to the sqlite3_result_text* interfaces
4610 ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
4611 ** function as the destructor on the text or BLOB result when it has
4612 ** finished using that result.
4613 ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
@@ -6362,20 +6386,34 @@
6386 ** <dd>This parameter returns the approximate number of of bytes of heap
6387 ** and lookaside memory used by all prepared statements associated with
6388 ** the database connection.)^
6389 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
6390 ** </dd>
6391 **
6392 ** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
6393 ** <dd>This parameter returns the number of pager cache hits that have
6394 ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
6395 ** is always 0.
6396 ** </dd>
6397 **
6398 ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
6399 ** <dd>This parameter returns the number of pager cache misses that have
6400 ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
6401 ** is always 0.
6402 ** </dd>
6403 ** </dl>
6404 */
6405 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
6406 #define SQLITE_DBSTATUS_CACHE_USED 1
6407 #define SQLITE_DBSTATUS_SCHEMA_USED 2
6408 #define SQLITE_DBSTATUS_STMT_USED 3
6409 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
6410 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
6411 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6412 #define SQLITE_DBSTATUS_CACHE_HIT 7
6413 #define SQLITE_DBSTATUS_CACHE_MISS 8
6414 #define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */
6415
6416
6417 /*
6418 ** CAPI3REF: Prepared Statement Status
6419 **
@@ -6425,11 +6463,10 @@
6463 ** <dd>^This is the number of rows inserted into transient indices that
6464 ** were created automatically in order to help joins run faster.
6465 ** A non-zero value in this counter may indicate an opportunity to
6466 ** improvement performance by adding permanent indices that do not
6467 ** need to be reinitialized each time the statement is run.</dd>
 
6468 ** </dl>
6469 */
6470 #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
6471 #define SQLITE_STMTSTATUS_SORT 2
6472 #define SQLITE_STMTSTATUS_AUTOINDEX 3
@@ -7711,10 +7748,22 @@
7748 ** is 0x00000000ffffffff. But because of quirks of some compilers, we
7749 ** have to specify the value in the less intuitive manner shown:
7750 */
7751 #define SQLITE_MAX_U32 ((((u64)1)<<32)-1)
7752
7753 /*
7754 ** The datatype used to store estimates of the number of rows in a
7755 ** table or index. This is an unsigned integer type. For 99.9% of
7756 ** the world, a 32-bit integer is sufficient. But a 64-bit integer
7757 ** can be used at compile-time if desired.
7758 */
7759 #ifdef SQLITE_64BIT_STATS
7760 typedef u64 tRowcnt; /* 64-bit only if requested at compile-time */
7761 #else
7762 typedef u32 tRowcnt; /* 32-bit is the default */
7763 #endif
7764
7765 /*
7766 ** Macros to determine whether the machine is big or little endian,
7767 ** evaluated at runtime.
7768 */
7769 #ifdef SQLITE_AMALGAMATION
@@ -8742,10 +8791,11 @@
8791 SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*);
8792 SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*);
8793 SQLITE_PRIVATE int sqlite3PagerNosync(Pager*);
8794 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
8795 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*);
8796 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *);
8797
8798 /* Functions used to truncate the database file. */
8799 SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno);
8800
8801 #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL)
@@ -9278,18 +9328,21 @@
9328 /*
9329 ** If this is a no-op implementation, implement everything as macros.
9330 */
9331 #define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8)
9332 #define sqlite3_mutex_free(X)
9333 #define sqlite3_mutex_enter(X)
9334 #define sqlite3_mutex_try(X) SQLITE_OK
9335 #define sqlite3_mutex_leave(X)
9336 #define sqlite3_mutex_held(X) ((void)(X),1)
9337 #define sqlite3_mutex_notheld(X) ((void)(X),1)
9338 #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8)
9339 #define sqlite3MutexInit() SQLITE_OK
9340 #define sqlite3MutexEnd()
9341 #define MUTEX_LOGIC(X)
9342 #else
9343 #define MUTEX_LOGIC(X) X
9344 #endif /* defined(SQLITE_MUTEX_OMIT) */
9345
9346 /************** End of mutex.h ***********************************************/
9347 /************** Continuing where we left off in sqliteInt.h ******************/
9348
@@ -9918,11 +9971,11 @@
9971 int iPKey; /* If not negative, use aCol[iPKey] as the primary key */
9972 int nCol; /* Number of columns in this table */
9973 Column *aCol; /* Information about each column */
9974 Index *pIndex; /* List of SQL indexes on this table. */
9975 int tnum; /* Root BTree node for this table (see note above) */
9976 tRowcnt nRowEst; /* Estimated rows in table - from sqlite_stat1 table */
9977 Select *pSelect; /* NULL for tables. Points to definition if a view. */
9978 u16 nRef; /* Number of pointers to this Table */
9979 u8 tabFlags; /* Mask of TF_* values */
9980 u8 keyConf; /* What to do in case of uniqueness conflict on iPKey */
9981 FKey *pFKey; /* Linked list of all foreign keys in this table */
@@ -10117,11 +10170,11 @@
10170 */
10171 struct Index {
10172 char *zName; /* Name of this index */
10173 int nColumn; /* Number of columns in the table used by this index */
10174 int *aiColumn; /* Which columns are used by this index. 1st is 0 */
10175 tRowcnt *aiRowEst; /* Result of ANALYZE: Est. rows selected by each column */
10176 Table *pTable; /* The SQL table being indexed */
10177 int tnum; /* Page containing root of this index in database file */
10178 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10179 u8 autoIndex; /* True if is automatically created (ex: by UNIQUE) */
10180 u8 bUnordered; /* Use this index for == or IN queries only */
@@ -10128,24 +10181,32 @@
10181 char *zColAff; /* String defining the affinity of each column */
10182 Index *pNext; /* The next index associated with the same table */
10183 Schema *pSchema; /* Schema containing this index */
10184 u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */
10185 char **azColl; /* Array of collation sequence names for index */
10186 #ifdef SQLITE_ENABLE_STAT3
10187 int nSample; /* Number of elements in aSample[] */
10188 tRowcnt avgEq; /* Average nEq value for key values not in aSample */
10189 IndexSample *aSample; /* Samples of the left-most key */
10190 #endif
10191 };
10192
10193 /*
10194 ** Each sample stored in the sqlite_stat2 table is represented in memory
10195 ** using a structure of this type.
10196 */
10197 struct IndexSample {
10198 union {
10199 char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */
10200 double r; /* Value if eType is SQLITE_FLOAT */
10201 i64 i; /* Value if eType is SQLITE_INTEGER */
10202 } u;
10203 u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */
10204 int nByte; /* Size in byte of text or blob. */
10205 tRowcnt nEq; /* Est. number of rows where the key equals this sample */
10206 tRowcnt nLt; /* Est. number of rows where key is less than this sample */
10207 tRowcnt nDLt; /* Est. number of distinct keys less than this sample */
10208 };
10209
10210 /*
10211 ** Each token coming out of the lexer is an instance of
10212 ** this structure. Tokens are also used as part of an expression.
@@ -10593,14 +10654,14 @@
10654 #define WHERE_ORDERBY_NORMAL 0x0000 /* No-op */
10655 #define WHERE_ORDERBY_MIN 0x0001 /* ORDER BY processing for min() func */
10656 #define WHERE_ORDERBY_MAX 0x0002 /* ORDER BY processing for max() func */
10657 #define WHERE_ONEPASS_DESIRED 0x0004 /* Want to do one-pass UPDATE/DELETE */
10658 #define WHERE_DUPLICATES_OK 0x0008 /* Ok to return a row more than once */
10659 #define WHERE_OMIT_OPEN_CLOSE 0x0010 /* Table cursors are already open */
10660 #define WHERE_FORCE_TABLE 0x0020 /* Do not use an index-only search */
10661 #define WHERE_ONETABLE_ONLY 0x0040 /* Only code the 1st table in pTabList */
10662 #define WHERE_AND_ONLY 0x0080 /* Don't use indices for OR terms */
10663
10664 /*
10665 ** The WHERE clause processing routine has two halves. The
10666 ** first part does the start of the WHERE loop and the second
10667 ** half does the tail of the WHERE loop. An instance of
@@ -11350,10 +11411,11 @@
11411 #else
11412 # define sqlite3ViewGetColumnNames(A,B) 0
11413 #endif
11414
11415 SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int);
11416 SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int);
11417 SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*);
11418 #ifndef SQLITE_OMIT_AUTOINCREMENT
11419 SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse);
11420 SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse);
11421 #else
@@ -11606,11 +11668,11 @@
11668 SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8,
11669 void(*)(void*));
11670 SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*);
11671 SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *);
11672 SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
11673 #ifdef SQLITE_ENABLE_STAT3
11674 SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *);
11675 #endif
11676 SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
11677 SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
11678 #ifndef SQLITE_AMALGAMATION
@@ -11708,19 +11770,21 @@
11770 # define sqlite3VtabInSync(db) 0
11771 # define sqlite3VtabLock(X)
11772 # define sqlite3VtabUnlock(X)
11773 # define sqlite3VtabUnlockList(X)
11774 # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK
11775 # define sqlite3GetVTable(X,Y) ((VTable*)0)
11776 #else
11777 SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*);
11778 SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **);
11779 SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db);
11780 SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db);
11781 SQLITE_PRIVATE void sqlite3VtabLock(VTable *);
11782 SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *);
11783 SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*);
11784 SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int);
11785 SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*);
11786 # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0)
11787 #endif
11788 SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*);
11789 SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*);
11790 SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*);
@@ -11736,11 +11800,10 @@
11800 SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *);
11801 SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*);
11802 SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*);
11803 SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *);
11804 SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*);
 
11805 SQLITE_PRIVATE const char *sqlite3JournalModename(int);
11806 SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*);
11807 SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
11808
11809 /* Declarations for functions in fkey.c. All of these are replaced by
@@ -12232,10 +12295,13 @@
12295 #ifdef SQLITE_ENABLE_RTREE
12296 "ENABLE_RTREE",
12297 #endif
12298 #ifdef SQLITE_ENABLE_STAT2
12299 "ENABLE_STAT2",
12300 #endif
12301 #ifdef SQLITE_ENABLE_STAT3
12302 "ENABLE_STAT3",
12303 #endif
12304 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
12305 "ENABLE_UNLOCK_NOTIFY",
12306 #endif
12307 #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT
@@ -12445,13 +12511,10 @@
12511 "OMIT_WSD",
12512 #endif
12513 #ifdef SQLITE_OMIT_XFER_OPT
12514 "OMIT_XFER_OPT",
12515 #endif
 
 
 
12516 #ifdef SQLITE_PERFORMANCE_TRACE
12517 "PERFORMANCE_TRACE",
12518 #endif
12519 #ifdef SQLITE_PROXY_DEBUG
12520 "PROXY_DEBUG",
@@ -13189,10 +13252,32 @@
13252 *pHighwater = 0;
13253 *pCurrent = nByte;
13254
13255 break;
13256 }
13257
13258 /*
13259 ** Set *pCurrent to the total cache hits or misses encountered by all
13260 ** pagers the database handle is connected to. *pHighwater is always set
13261 ** to zero.
13262 */
13263 case SQLITE_DBSTATUS_CACHE_HIT:
13264 case SQLITE_DBSTATUS_CACHE_MISS: {
13265 int i;
13266 int nRet = 0;
13267 assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
13268
13269 for(i=0; i<db->nDb; i++){
13270 if( db->aDb[i].pBt ){
13271 Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
13272 sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
13273 }
13274 }
13275 *pHighwater = 0;
13276 *pCurrent = nRet;
13277 break;
13278 }
13279
13280 default: {
13281 rc = SQLITE_ERROR;
13282 }
13283 }
@@ -13490,16 +13575,22 @@
13575 }
13576 return 0;
13577 }
13578
13579 /*
13580 ** Set the time to the current time reported by the VFS.
13581 **
13582 ** Return the number of errors.
13583 */
13584 static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
13585 sqlite3 *db = sqlite3_context_db_handle(context);
13586 if( sqlite3OsCurrentTimeInt64(db->pVfs, &p->iJD)==SQLITE_OK ){
13587 p->validJD = 1;
13588 return 0;
13589 }else{
13590 return 1;
13591 }
13592 }
13593
13594 /*
13595 ** Attempt to parse the given string into a Julian Day Number. Return
13596 ** the number of errors.
@@ -13525,12 +13616,11 @@
13616 if( parseYyyyMmDd(zDate,p)==0 ){
13617 return 0;
13618 }else if( parseHhMmSs(zDate, p)==0 ){
13619 return 0;
13620 }else if( sqlite3StrICmp(zDate,"now")==0){
13621 return setDateTimeToCurrent(context, p);
 
13622 }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8) ){
13623 p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
13624 p->validJD = 1;
13625 return 0;
13626 }
@@ -13953,12 +14043,13 @@
14043 int i;
14044 const unsigned char *z;
14045 int eType;
14046 memset(p, 0, sizeof(*p));
14047 if( argc==0 ){
14048 return setDateTimeToCurrent(context, p);
14049 }
14050 if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
14051 || eType==SQLITE_INTEGER ){
14052 p->iJD = (sqlite3_int64)(sqlite3_value_double(argv[0])*86400000.0 + 0.5);
14053 p->validJD = 1;
14054 }else{
14055 z = sqlite3_value_text(argv[0]);
@@ -14266,35 +14357,32 @@
14357 ){
14358 time_t t;
14359 char *zFormat = (char *)sqlite3_user_data(context);
14360 sqlite3 *db;
14361 sqlite3_int64 iT;
14362 struct tm *pTm;
14363 struct tm sNow;
14364 char zBuf[20];
14365
14366 UNUSED_PARAMETER(argc);
14367 UNUSED_PARAMETER(argv);
14368
14369 db = sqlite3_context_db_handle(context);
14370 if( sqlite3OsCurrentTimeInt64(db->pVfs, &iT) ) return;
14371 t = iT/1000 - 10000*(sqlite3_int64)21086676;
14372 #ifdef HAVE_GMTIME_R
14373 pTm = gmtime_r(&t, &sNow);
14374 #else
14375 sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14376 pTm = gmtime(&t);
14377 if( pTm ) memcpy(&sNow, pTm, sizeof(sNow));
14378 sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
14379 #endif
14380 if( pTm ){
14381 strftime(zBuf, 20, zFormat, &sNow);
14382 sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
14383 }
 
 
 
 
 
 
 
 
 
 
14384 }
14385 #endif
14386
14387 /*
14388 ** This function registered all of the above C functions as SQL
@@ -14625,16 +14713,16 @@
14713 ** Register a VFS with the system. It is harmless to register the same
14714 ** VFS multiple times. The new VFS becomes the default if makeDflt is
14715 ** true.
14716 */
14717 SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
14718 MUTEX_LOGIC(sqlite3_mutex *mutex;)
14719 #ifndef SQLITE_OMIT_AUTOINIT
14720 int rc = sqlite3_initialize();
14721 if( rc ) return rc;
14722 #endif
14723 MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
14724 sqlite3_mutex_enter(mutex);
14725 vfsUnlink(pVfs);
14726 if( makeDflt || vfsList==0 ){
14727 pVfs->pNext = vfsList;
14728 vfsList = pVfs;
@@ -18878,52 +18966,14 @@
18966 ** an historical reference. Most of the "enhancements" have been backed
18967 ** out so that the functionality is now the same as standard printf().
18968 **
18969 **************************************************************************
18970 **
18971 ** This file contains code for a set of "printf"-like routines. These
18972 ** routines format strings much like the printf() from the standard C
18973 ** library, though the implementation here has enhancements to support
18974 ** SQLlite.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18975 */
18976
18977 /*
18978 ** Conversion types fall into various categories as defined by the
18979 ** following enumeration.
@@ -19057,47 +19107,19 @@
19107 }
19108 }
19109
19110 /*
19111 ** On machines with a small stack size, you can redefine the
19112 ** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
19113 */
19114 #ifndef SQLITE_PRINT_BUF_SIZE
19115 # define SQLITE_PRINT_BUF_SIZE 70
 
 
 
 
19116 #endif
19117 #define etBUFSIZE SQLITE_PRINT_BUF_SIZE /* Size of the output buffer */
19118
19119 /*
19120 ** Render a string given by "fmt" into the StrAccum object.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19121 */
19122 SQLITE_PRIVATE void sqlite3VXPrintf(
19123 StrAccum *pAccum, /* Accumulate results here */
19124 int useExtended, /* Allow extended %-conversions */
19125 const char *fmt, /* Format string */
@@ -19116,27 +19138,27 @@
19138 etByte flag_altform2; /* True if "!" flag is present */
19139 etByte flag_zeropad; /* True if field width constant starts with zero */
19140 etByte flag_long; /* True if "l" flag is present */
19141 etByte flag_longlong; /* True if the "ll" flag is present */
19142 etByte done; /* Loop termination flag */
19143 etByte xtype = 0; /* Conversion paradigm */
19144 char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */
19145 sqlite_uint64 longvalue; /* Value for integer types */
19146 LONGDOUBLE_TYPE realvalue; /* Value for real types */
19147 const et_info *infop; /* Pointer to the appropriate info structure */
19148 char *zOut; /* Rendering buffer */
19149 int nOut; /* Size of the rendering buffer */
19150 char *zExtra; /* Malloced memory used by some conversion */
 
19151 #ifndef SQLITE_OMIT_FLOATING_POINT
19152 int exp, e2; /* exponent of real numbers */
19153 int nsd; /* Number of significant digits returned */
19154 double rounder; /* Used for rounding floating point values */
19155 etByte flag_dp; /* True if decimal point should be shown */
19156 etByte flag_rtz; /* True if trailing zeros should be removed */
 
 
19157 #endif
19158 char buf[etBUFSIZE]; /* Conversion buffer */
19159
 
19160 bufpt = 0;
19161 for(; (c=(*fmt))!=0; ++fmt){
19162 if( c!='%' ){
19163 int amt;
19164 bufpt = (char *)fmt;
@@ -19177,13 +19199,10 @@
19199 while( c>='0' && c<='9' ){
19200 width = width*10 + c - '0';
19201 c = *++fmt;
19202 }
19203 }
 
 
 
19204 /* Get the precision */
19205 if( c=='.' ){
19206 precision = 0;
19207 c = *++fmt;
19208 if( c=='*' ){
@@ -19226,16 +19245,10 @@
19245 break;
19246 }
19247 }
19248 zExtra = 0;
19249
 
 
 
 
 
 
19250 /*
19251 ** At this point, variables are initialized as follows:
19252 **
19253 ** flag_alternateform TRUE if a '#' is present.
19254 ** flag_altform2 TRUE if a '!' is present.
@@ -19296,20 +19309,30 @@
19309 }
19310 if( longvalue==0 ) flag_alternateform = 0;
19311 if( flag_zeropad && precision<width-(prefix!=0) ){
19312 precision = width-(prefix!=0);
19313 }
19314 if( precision<etBUFSIZE-10 ){
19315 nOut = etBUFSIZE;
19316 zOut = buf;
19317 }else{
19318 nOut = precision + 10;
19319 zOut = zExtra = sqlite3Malloc( nOut );
19320 if( zOut==0 ){
19321 pAccum->mallocFailed = 1;
19322 return;
19323 }
19324 }
19325 bufpt = &zOut[nOut-1];
19326 if( xtype==etORDINAL ){
19327 static const char zOrd[] = "thstndrd";
19328 int x = (int)(longvalue % 10);
19329 if( x>=4 || (longvalue/10)%10==1 ){
19330 x = 0;
19331 }
19332 *(--bufpt) = zOrd[x*2+1];
19333 *(--bufpt) = zOrd[x*2];
 
19334 }
19335 {
19336 register const char *cset; /* Use registers for speed */
19337 register int base;
19338 cset = &aDigits[infop->charset];
@@ -19317,11 +19340,11 @@
19340 do{ /* Convert to ascii */
19341 *(--bufpt) = cset[longvalue%base];
19342 longvalue = longvalue/base;
19343 }while( longvalue>0 );
19344 }
19345 length = (int)(&zOut[nOut-1]-bufpt);
19346 for(idx=precision-length; idx>0; idx--){
19347 *(--bufpt) = '0'; /* Zero pad */
19348 }
19349 if( prefix ) *(--bufpt) = prefix; /* Add sign */
19350 if( flag_alternateform && infop->prefix ){ /* Add "0" or "0x" */
@@ -19328,21 +19351,20 @@
19351 const char *pre;
19352 char x;
19353 pre = &aPrefix[infop->prefix];
19354 for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
19355 }
19356 length = (int)(&zOut[nOut-1]-bufpt);
19357 break;
19358 case etFLOAT:
19359 case etEXP:
19360 case etGENERIC:
19361 realvalue = va_arg(ap,double);
19362 #ifdef SQLITE_OMIT_FLOATING_POINT
19363 length = 0;
19364 #else
19365 if( precision<0 ) precision = 6; /* Set default precision */
 
19366 if( realvalue<0.0 ){
19367 realvalue = -realvalue;
19368 prefix = '-';
19369 }else{
19370 if( flag_plussign ) prefix = '+';
@@ -19386,11 +19408,10 @@
19408 bufpt = buf;
19409 /*
19410 ** If the field type is etGENERIC, then convert to either etEXP
19411 ** or etFLOAT, as appropriate.
19412 */
 
19413 if( xtype!=etFLOAT ){
19414 realvalue += rounder;
19415 if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; }
19416 }
19417 if( xtype==etGENERIC ){
@@ -19407,10 +19428,18 @@
19428 if( xtype==etEXP ){
19429 e2 = 0;
19430 }else{
19431 e2 = exp;
19432 }
19433 if( e2+precision+width > etBUFSIZE - 15 ){
19434 bufpt = zExtra = sqlite3Malloc( e2+precision+width+15 );
19435 if( bufpt==0 ){
19436 pAccum->mallocFailed = 1;
19437 return;
19438 }
19439 }
19440 zOut = bufpt;
19441 nsd = 0;
19442 flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2;
19443 /* The sign in front of the number */
19444 if( prefix ){
19445 *(bufpt++) = prefix;
@@ -19438,21 +19467,21 @@
19467 *(bufpt++) = et_getdigit(&realvalue,&nsd);
19468 }
19469 /* Remove trailing zeros and the "." if no digits follow the "." */
19470 if( flag_rtz && flag_dp ){
19471 while( bufpt[-1]=='0' ) *(--bufpt) = 0;
19472 assert( bufpt>zOut );
19473 if( bufpt[-1]=='.' ){
19474 if( flag_altform2 ){
19475 *(bufpt++) = '0';
19476 }else{
19477 *(--bufpt) = 0;
19478 }
19479 }
19480 }
19481 /* Add the "eNNN" suffix */
19482 if( xtype==etEXP ){
19483 *(bufpt++) = aDigits[infop->charset];
19484 if( exp<0 ){
19485 *(bufpt++) = '-'; exp = -exp;
19486 }else{
19487 *(bufpt++) = '+';
@@ -19467,12 +19496,12 @@
19496 *bufpt = 0;
19497
19498 /* The converted number is in buf[] and zero terminated. Output it.
19499 ** Note that the number is in the usual order, not reversed as with
19500 ** integer conversions. */
19501 length = (int)(bufpt-zOut);
19502 bufpt = zOut;
19503
19504 /* Special case: Add leading zeros if the flag_zeropad flag is
19505 ** set and we are not left justified */
19506 if( flag_zeropad && !flag_leftjustify && length < width){
19507 int i;
@@ -19606,13 +19635,11 @@
19635 nspace = width-length;
19636 if( nspace>0 ){
19637 appendSpace(pAccum, nspace);
19638 }
19639 }
19640 sqlite3_free(zExtra);
 
 
19641 }/* End for loop over the format string */
19642 } /* End of function */
19643
19644 /*
19645 ** Append N bytes of text from z to the StrAccum object.
@@ -19622,10 +19649,11 @@
19649 if( p->tooBig | p->mallocFailed ){
19650 testcase(p->tooBig);
19651 testcase(p->mallocFailed);
19652 return;
19653 }
19654 assert( p->zText!=0 || p->nChar==0 );
19655 if( N<0 ){
19656 N = sqlite3Strlen30(z);
19657 }
19658 if( N==0 || NEVER(z==0) ){
19659 return;
@@ -19653,19 +19681,20 @@
19681 zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
19682 }else{
19683 zNew = sqlite3_realloc(zOld, p->nAlloc);
19684 }
19685 if( zNew ){
19686 if( zOld==0 && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
19687 p->zText = zNew;
19688 }else{
19689 p->mallocFailed = 1;
19690 sqlite3StrAccumReset(p);
19691 return;
19692 }
19693 }
19694 }
19695 assert( p->zText );
19696 memcpy(&p->zText[p->nChar], z, N);
19697 p->nChar += N;
19698 }
19699
19700 /*
@@ -20511,11 +20540,11 @@
20540 ** no longer required.
20541 **
20542 ** If a malloc failure occurs, NULL is returned and the db.mallocFailed
20543 ** flag set.
20544 */
20545 #ifdef SQLITE_ENABLE_STAT3
20546 SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){
20547 Mem m;
20548 memset(&m, 0, sizeof(m));
20549 m.db = db;
20550 sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC);
@@ -20940,11 +20969,11 @@
20969 }else if( *z=='+' ){
20970 z+=incr;
20971 }
20972 /* copy digits to exponent */
20973 while( z<zEnd && sqlite3Isdigit(*z) ){
20974 e = e<10000 ? (e*10 + (*z - '0')) : 10000;
20975 z+=incr;
20976 eValid = 1;
20977 }
20978 }
20979
@@ -20991,10 +21020,16 @@
21020 result /= 1.0e+308;
21021 }else{
21022 result = s * scale;
21023 result *= 1.0e+308;
21024 }
21025 }else if( e>=342 ){
21026 if( esign<0 ){
21027 result = 0.0*s;
21028 }else{
21029 result = 1e308*1e308*s; /* Infinity */
21030 }
21031 }else{
21032 /* 1.0e+22 is the largest power of 10 than can be
21033 ** represented exactly. */
21034 while( e%22 ) { scale *= 1.0e+1; e -= 1; }
21035 while( e>0 ) { scale *= 1.0e+22; e -= 22; }
@@ -25102,11 +25137,11 @@
25137 return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
25138 }
25139 #endif
25140
25141
25142 #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
25143 /*
25144 ** Helper function for printing out trace information from debugging
25145 ** binaries. This returns the string represetation of the supplied
25146 ** integer lock-type.
25147 */
@@ -25937,18 +25972,18 @@
25972 ** locking a random byte from a range, concurrent SHARED locks may exist
25973 ** even if the locking primitive used is always a write-lock.
25974 */
25975 int rc = SQLITE_OK;
25976 unixFile *pFile = (unixFile*)id;
25977 unixInodeInfo *pInode;
25978 struct flock lock;
25979 int tErrno = 0;
25980
25981 assert( pFile );
25982 OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (unix)\n", pFile->h,
25983 azFileLock(eFileLock), azFileLock(pFile->eFileLock),
25984 azFileLock(pFile->pInode->eFileLock), pFile->pInode->nShared , getpid()));
25985
25986 /* If there is already a lock of this type or more restrictive on the
25987 ** unixFile, do nothing. Don't use the end_lock: exit path, as
25988 ** unixEnterMutex() hasn't been called yet.
25989 */
@@ -26148,11 +26183,10 @@
26183 static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
26184 unixFile *pFile = (unixFile*)id;
26185 unixInodeInfo *pInode;
26186 struct flock lock;
26187 int rc = SQLITE_OK;
 
26188
26189 assert( pFile );
26190 OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (unix)\n", pFile->h, eFileLock,
26191 pFile->eFileLock, pFile->pInode->eFileLock, pFile->pInode->nShared,
26192 getpid()));
@@ -26160,18 +26194,14 @@
26194 assert( eFileLock<=SHARED_LOCK );
26195 if( pFile->eFileLock<=eFileLock ){
26196 return SQLITE_OK;
26197 }
26198 unixEnterMutex();
 
26199 pInode = pFile->pInode;
26200 assert( pInode->nShared!=0 );
26201 if( pFile->eFileLock>SHARED_LOCK ){
26202 assert( pInode->eFileLock==pFile->eFileLock );
 
 
 
26203
26204 #ifndef NDEBUG
26205 /* When reducing a lock such that other processes can start
26206 ** reading the database file again, make sure that the
26207 ** transaction counter was updated if any part of the database
@@ -26178,15 +26208,10 @@
26208 ** file changed. If the transaction counter is not updated,
26209 ** other connections to the same file might not realize that
26210 ** the file has changed and hence might not know to flush their
26211 ** cache. The use of a stale cache can lead to database corruption.
26212 */
 
 
 
 
 
26213 pFile->inNormalWrite = 0;
26214 #endif
26215
26216 /* downgrading to a shared lock on NFS involves clearing the write lock
26217 ** before establishing the readlock - to avoid a race condition we downgrade
@@ -26284,13 +26309,10 @@
26309 pInode->nShared--;
26310 if( pInode->nShared==0 ){
26311 lock.l_type = F_UNLCK;
26312 lock.l_whence = SEEK_SET;
26313 lock.l_start = lock.l_len = 0L;
 
 
 
26314 if( unixFileLock(pFile, &lock)==0 ){
26315 pInode->eFileLock = NO_LOCK;
26316 }else{
26317 rc = SQLITE_IOERR_UNLOCK;
26318 pFile->lastErrno = errno;
@@ -28428,20 +28450,19 @@
28450 rc = SQLITE_NOMEM;
28451 goto shm_open_err;
28452 }
28453
28454 if( pInode->bProcessLock==0 ){
28455 const char *zRO;
28456 int openFlags = O_RDWR | O_CREAT;
28457 zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
28458 if( zRO && sqlite3GetBoolean(zRO) ){
28459 openFlags = O_RDONLY;
28460 pShmNode->isReadonly = 1;
28461 }
28462 pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
28463 if( pShmNode->h<0 ){
 
 
 
 
 
 
 
28464 if( pShmNode->h<0 ){
28465 rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
28466 goto shm_open_err;
28467 }
28468 }
@@ -29122,10 +29143,13 @@
29143 assert( zFilename==0 || zFilename[0]=='/'
29144 || pVfs->pAppData==(void*)&autolockIoFinder );
29145 #else
29146 assert( zFilename==0 || zFilename[0]=='/' );
29147 #endif
29148
29149 /* No locking occurs in temporary files */
29150 assert( zFilename!=0 || noLock );
29151
29152 OSTRACE(("OPEN %-3d %s\n", h, zFilename));
29153 pNew->h = h;
29154 pNew->zPath = zFilename;
29155 if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
@@ -29224,10 +29248,11 @@
29248 /* Dotfile locking uses the file path so it needs to be included in
29249 ** the dotlockLockingContext
29250 */
29251 char *zLockFile;
29252 int nFilename;
29253 assert( zFilename!=0 );
29254 nFilename = (int)strlen(zFilename) + 6;
29255 zLockFile = (char *)sqlite3_malloc(nFilename);
29256 if( zLockFile==0 ){
29257 rc = SQLITE_NOMEM;
29258 }else{
@@ -29462,12 +29487,20 @@
29487 **
29488 ** where NN is a 4 digit decimal number. The NN naming schemes are
29489 ** used by the test_multiplex.c module.
29490 */
29491 nDb = sqlite3Strlen30(zPath) - 1;
29492 #ifdef SQLITE_ENABLE_8_3_NAMES
29493 while( nDb>0 && zPath[nDb]!='-' && zPath[nDb]!='/' ) nDb--;
29494 if( nDb==0 || zPath[nDb]=='/' ) return SQLITE_OK;
29495 #else
29496 while( zPath[nDb]!='-' ){
29497 assert( nDb>0 );
29498 assert( zPath[nDb]!='\n' );
29499 nDb--;
29500 }
29501 #endif
29502 memcpy(zDb, zPath, nDb);
29503 zDb[nDb] = '\0';
29504
29505 if( 0==osStat(zDb, &sStat) ){
29506 *pMode = sStat.st_mode & 0777;
@@ -29995,14 +30028,16 @@
30028 ** the current time and date as a Julian Day number times 86_400_000. In
30029 ** other words, write into *piNow the number of milliseconds since the Julian
30030 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
30031 ** proleptic Gregorian calendar.
30032 **
30033 ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
30034 ** cannot be found.
30035 */
30036 static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){
30037 static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000;
30038 int rc = SQLITE_OK;
30039 #if defined(NO_GETTOD)
30040 time_t t;
30041 time(&t);
30042 *piNow = ((sqlite3_int64)t)*1000 + unixEpoch;
30043 #elif OS_VXWORKS
@@ -30009,34 +30044,38 @@
30044 struct timespec sNow;
30045 clock_gettime(CLOCK_REALTIME, &sNow);
30046 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000;
30047 #else
30048 struct timeval sNow;
30049 if( gettimeofday(&sNow, 0)==0 ){
30050 *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000;
30051 }else{
30052 rc = SQLITE_ERROR;
30053 }
30054 #endif
30055
30056 #ifdef SQLITE_TEST
30057 if( sqlite3_current_time ){
30058 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
30059 }
30060 #endif
30061 UNUSED_PARAMETER(NotUsed);
30062 return rc;
30063 }
30064
30065 /*
30066 ** Find the current time (in Universal Coordinated Time). Write the
30067 ** current time and date as a Julian Day number into *prNow and
30068 ** return 0. Return 1 if the time and date cannot be found.
30069 */
30070 static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
30071 sqlite3_int64 i = 0;
30072 int rc;
30073 UNUSED_PARAMETER(NotUsed);
30074 rc = unixCurrentTimeInt64(0, &i);
30075 *prNow = i/86400000.0;
30076 return rc;
30077 }
30078
30079 /*
30080 ** We added the xGetLastError() method with the intention of providing
30081 ** better low-level error messages when operating-system problems come up
@@ -34169,11 +34208,11 @@
34208
34209 if( h==INVALID_HANDLE_VALUE ){
34210 pFile->lastErrno = GetLastError();
34211 winLogError(SQLITE_CANTOPEN, "winOpen", zUtf8Name);
34212 free(zConverted);
34213 if( isReadWrite && !isExclusive ){
34214 return winOpen(pVfs, zName, id,
34215 ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
34216 }else{
34217 return SQLITE_CANTOPEN_BKPT;
34218 }
@@ -34535,11 +34574,11 @@
34574 }
34575 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
34576 UNUSED_PARAMETER(pVfs);
34577 getLastErrorMsg(nBuf, zBufOut);
34578 }
34579 static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
34580 UNUSED_PARAMETER(pVfs);
34581 #if SQLITE_OS_WINCE
34582 /* The GetProcAddressA() routine is only available on wince. */
34583 return (void(*)(void))GetProcAddressA((HANDLE)pHandle, zSymbol);
34584 #else
@@ -34546,11 +34585,11 @@
34585 /* All other windows platforms expect GetProcAddress() to take
34586 ** an Ansi string regardless of the _UNICODE setting */
34587 return (void(*)(void))GetProcAddress((HANDLE)pHandle, zSymbol);
34588 #endif
34589 }
34590 static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
34591 UNUSED_PARAMETER(pVfs);
34592 FreeLibrary((HANDLE)pHandle);
34593 }
34594 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
34595 #define winDlOpen 0
@@ -34620,11 +34659,12 @@
34659 ** the current time and date as a Julian Day number times 86_400_000. In
34660 ** other words, write into *piNow the number of milliseconds since the Julian
34661 ** epoch of noon in Greenwich on November 24, 4714 B.C according to the
34662 ** proleptic Gregorian calendar.
34663 **
34664 ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date
34665 ** cannot be found.
34666 */
34667 static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
34668 /* FILETIME structure is a 64-bit value representing the number of
34669 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5).
34670 */
@@ -34640,11 +34680,11 @@
34680 #if SQLITE_OS_WINCE
34681 SYSTEMTIME time;
34682 GetSystemTime(&time);
34683 /* if SystemTimeToFileTime() fails, it returns zero. */
34684 if (!SystemTimeToFileTime(&time,&ft)){
34685 return SQLITE_ERROR;
34686 }
34687 #else
34688 GetSystemTimeAsFileTime( &ft );
34689 #endif
34690
@@ -34656,19 +34696,19 @@
34696 if( sqlite3_current_time ){
34697 *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
34698 }
34699 #endif
34700 UNUSED_PARAMETER(pVfs);
34701 return SQLITE_OK;
34702 }
34703
34704 /*
34705 ** Find the current time (in Universal Coordinated Time). Write the
34706 ** current time and date as a Julian Day number into *prNow and
34707 ** return 0. Return 1 if the time and date cannot be found.
34708 */
34709 static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){
34710 int rc;
34711 sqlite3_int64 i;
34712 rc = winCurrentTimeInt64(pVfs, &i);
34713 if( !rc ){
34714 *prNow = i/86400000.0;
@@ -35789,12 +35829,10 @@
35829 typedef struct PCache1 PCache1;
35830 typedef struct PgHdr1 PgHdr1;
35831 typedef struct PgFreeslot PgFreeslot;
35832 typedef struct PGroup PGroup;
35833
 
 
35834
35835 /* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set
35836 ** of one or more PCaches that are able to recycle each others unpinned
35837 ** pages when they are under memory pressure. A PGroup is an instance of
35838 ** the following object.
@@ -35821,69 +35859,11 @@
35859 int nMaxPage; /* Sum of nMax for purgeable caches */
35860 int nMinPage; /* Sum of nMin for purgeable caches */
35861 int mxPinned; /* nMaxpage + 10 - nMinPage */
35862 int nCurrentPage; /* Number of purgeable pages allocated */
35863 PgHdr1 *pLruHead, *pLruTail; /* LRU list of unpinned pages */
35864 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35865
35866 /* Each page cache is an instance of the following object. Every
35867 ** open database file (including each in-memory database and each
35868 ** temporary or transient database) has a single page cache which
35869 ** is an instance of this object.
@@ -35983,21 +35963,10 @@
35963 **
35964 ** assert( PGHDR1_TO_PAGE(PAGE_TO_PGHDR1(pCache, X))==X );
35965 */
35966 #define PGHDR1_TO_PAGE(p) (void*)(((char*)p) - p->pCache->szPage)
35967 #define PAGE_TO_PGHDR1(c, p) (PgHdr1*)(((char*)p) + c->szPage)
 
 
 
 
 
 
 
 
 
 
 
35968
35969 /*
35970 ** Macros to enter and leave the PCache LRU mutex.
35971 */
35972 #define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex)
@@ -36120,159 +36089,32 @@
36089 return iSize;
36090 }
36091 }
36092 #endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */
36093
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36094 /*
36095 ** Allocate a new page object initially associated with cache pCache.
36096 */
36097 static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
36098 int nByte = sizeof(PgHdr1) + pCache->szPage;
36099 PgHdr1 *p = 0;
36100 void *pPg;
36101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36102 /* The group mutex must be released before pcache1Alloc() is called. This
36103 ** is because it may call sqlite3_release_memory(), which assumes that
36104 ** this mutex is not held. */
36105 assert( sqlite3_mutex_held(pCache->pGroup->mutex) );
36106 pcache1LeaveMutex(pCache->pGroup);
36107 pPg = pcache1Alloc(nByte);
36108 pcache1EnterMutex(pCache->pGroup);
36109
36110 if( pPg ){
36111 p = PAGE_TO_PGHDR1(pCache, pPg);
36112 if( pCache->bPurgeable ){
36113 pCache->pGroup->nCurrentPage++;
36114 }
 
 
36115 }
 
36116 return p;
36117 }
36118
36119 /*
36120 ** Free a page object allocated by pcache1AllocPage().
@@ -36282,53 +36124,12 @@
36124 ** with a NULL pointer, so we mark the NULL test with ALWAYS().
36125 */
36126 static void pcache1FreePage(PgHdr1 *p){
36127 if( ALWAYS(p) ){
36128 PCache1 *pCache = p->pCache;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36129 assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) );
36130 pcache1Free(PGHDR1_TO_PAGE(p));
 
36131 if( pCache->bPurgeable ){
36132 pCache->pGroup->nCurrentPage--;
36133 }
36134 }
36135 }
@@ -36935,13 +36736,10 @@
36736 ** been released, the function returns. The return value is the total number
36737 ** of bytes of memory released.
36738 */
36739 SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){
36740 int nFree = 0;
 
 
 
36741 assert( sqlite3_mutex_notheld(pcache1.grp.mutex) );
36742 assert( sqlite3_mutex_notheld(pcache1.mutex) );
36743 if( pcache1.pStart==0 ){
36744 PgHdr1 *p;
36745 pcache1EnterMutex(&pcache1.grp);
@@ -38200,12 +37998,12 @@
37998 i64 journalSizeLimit; /* Size limit for persistent journal files */
37999 char *zFilename; /* Name of the database file */
38000 char *zJournal; /* Name of the journal file */
38001 int (*xBusyHandler)(void*); /* Function to call when busy */
38002 void *pBusyHandlerArg; /* Context argument for xBusyHandler */
38003 int nHit, nMiss; /* Total cache hits and misses */
38004 #ifdef SQLITE_TEST
 
38005 int nRead, nWrite; /* Database pages read/written */
38006 #endif
38007 void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */
38008 #ifdef SQLITE_HAS_CODEC
38009 void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */
@@ -40233,11 +40031,10 @@
40031 needPagerReset = 0;
40032 }
40033 rc = pager_playback_one_page(pPager,&pPager->journalOff,0,1,0);
40034 if( rc!=SQLITE_OK ){
40035 if( rc==SQLITE_DONE ){
 
40036 pPager->journalOff = szJ;
40037 break;
40038 }else if( rc==SQLITE_IOERR_SHORT_READ ){
40039 /* If the journal has been truncated, simply stop reading and
40040 ** processing the journal. This might happen if the journal was
@@ -40495,10 +40292,11 @@
40292 #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
40293 PgHdr *p; /* For looping over pages */
40294 #endif
40295
40296 assert( pPager->pWal );
40297 assert( pList );
40298 #ifdef SQLITE_DEBUG
40299 /* Verify that the page list is in accending order */
40300 for(p=pList; p && p->pDirty; p=p->pDirty){
40301 assert( p->pgno < p->pDirty->pgno );
40302 }
@@ -41699,11 +41497,11 @@
41497 ** The doNotSpill flag inhibits all cache spilling regardless of whether
41498 ** or not a sync is required. This is set during a rollback.
41499 **
41500 ** Spilling is also prohibited when in an error state since that could
41501 ** lead to database corruption. In the current implementaton it
41502 ** is impossible for sqlite3PcacheFetch() to be called with createFlag==1
41503 ** while in the error state, hence it is impossible for this routine to
41504 ** be called in the error state. Nevertheless, we include a NEVER()
41505 ** test for the error state as a safeguard against future changes.
41506 */
41507 if( NEVER(pPager->errCode) ) return SQLITE_OK;
@@ -42535,18 +42333,17 @@
42333
42334 if( (*ppPage)->pPager && !noContent ){
42335 /* In this case the pcache already contains an initialized copy of
42336 ** the page. Return without further ado. */
42337 assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) );
42338 pPager->nHit++;
42339 return SQLITE_OK;
42340
42341 }else{
42342 /* The pager cache has created a new page. Its content needs to
42343 ** be initialized. */
42344
 
42345 pPg = *ppPage;
42346 pPg->pPager = pPager;
42347
42348 /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page
42349 ** number greater than this, or the unused locking-page, is requested. */
@@ -42578,10 +42375,11 @@
42375 }
42376 memset(pPg->pData, 0, pPager->pageSize);
42377 IOTRACE(("ZERO %p %d\n", pPager, pgno));
42378 }else{
42379 assert( pPg->pPager==pPager );
42380 pPager->nMiss++;
42381 rc = readDbPage(pPg);
42382 if( rc!=SQLITE_OK ){
42383 goto pager_acquire_err;
42384 }
42385 }
@@ -43611,10 +43409,35 @@
43409 a[9] = pPager->nRead;
43410 a[10] = pPager->nWrite;
43411 return a;
43412 }
43413 #endif
43414
43415 /*
43416 ** Parameter eStat must be either SQLITE_DBSTATUS_CACHE_HIT or
43417 ** SQLITE_DBSTATUS_CACHE_MISS. Before returning, *pnVal is incremented by the
43418 ** current cache hit or miss count, according to the value of eStat. If the
43419 ** reset parameter is non-zero, the cache hit or miss count is zeroed before
43420 ** returning.
43421 */
43422 SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){
43423 int *piStat;
43424
43425 assert( eStat==SQLITE_DBSTATUS_CACHE_HIT
43426 || eStat==SQLITE_DBSTATUS_CACHE_MISS
43427 );
43428 if( eStat==SQLITE_DBSTATUS_CACHE_HIT ){
43429 piStat = &pPager->nHit;
43430 }else{
43431 piStat = &pPager->nMiss;
43432 }
43433
43434 *pnVal += *piStat;
43435 if( reset ){
43436 *piStat = 0;
43437 }
43438 }
43439
43440 /*
43441 ** Return true if this is an in-memory pager.
43442 */
43443 SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
@@ -46706,11 +46529,11 @@
46529 */
46530 if( iRead ){
46531 int sz;
46532 i64 iOffset;
46533 sz = pWal->hdr.szPage;
46534 sz = (sz&0xfe00) + ((sz&0x0001)<<16);
46535 testcase( sz<=32768 );
46536 testcase( sz>=65536 );
46537 iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE;
46538 *pInWal = 1;
46539 /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
@@ -50019,21 +49842,23 @@
49842 */
49843 if( isMemdb==0 && isTempDb==0 ){
49844 if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){
49845 int nFullPathname = pVfs->mxPathname+1;
49846 char *zFullPathname = sqlite3Malloc(nFullPathname);
49847 MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
49848 p->sharable = 1;
49849 if( !zFullPathname ){
49850 sqlite3_free(p);
49851 return SQLITE_NOMEM;
49852 }
49853 sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
49854 #if SQLITE_THREADSAFE
49855 mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN);
49856 sqlite3_mutex_enter(mutexOpen);
49857 mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
49858 sqlite3_mutex_enter(mutexShared);
49859 #endif
49860 for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){
49861 assert( pBt->nRef>0 );
49862 if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager))
49863 && sqlite3PagerVfs(pBt->pPager)==pVfs ){
49864 int iDb;
@@ -50135,13 +49960,13 @@
49960
49961 #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO)
49962 /* Add the new BtShared object to the linked list sharable BtShareds.
49963 */
49964 if( p->sharable ){
49965 MUTEX_LOGIC( sqlite3_mutex *mutexShared; )
49966 pBt->nRef = 1;
49967 MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);)
49968 if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){
49969 pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
49970 if( pBt->mutex==0 ){
49971 rc = SQLITE_NOMEM;
49972 db->mallocFailed = 0;
@@ -50219,16 +50044,16 @@
50044 ** true if the BtShared.nRef counter reaches zero and return
50045 ** false if it is still positive.
50046 */
50047 static int removeFromSharingList(BtShared *pBt){
50048 #ifndef SQLITE_OMIT_SHARED_CACHE
50049 MUTEX_LOGIC( sqlite3_mutex *pMaster; )
50050 BtShared *pList;
50051 int removed = 0;
50052
50053 assert( sqlite3_mutex_notheld(pBt->mutex) );
50054 MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
50055 sqlite3_mutex_enter(pMaster);
50056 pBt->nRef--;
50057 if( pBt->nRef<=0 ){
50058 if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){
50059 GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext;
@@ -52191,25 +52016,59 @@
52016 offset -= ovflSize;
52017 }else{
52018 /* Need to read this page properly. It contains some of the
52019 ** range of data that is being read (eOp==0) or written (eOp!=0).
52020 */
52021 #ifdef SQLITE_DIRECT_OVERFLOW_READ
52022 sqlite3_file *fd;
52023 #endif
52024 int a = amt;
52025 if( a + offset > ovflSize ){
52026 a = ovflSize - offset;
52027 }
52028
52029 #ifdef SQLITE_DIRECT_OVERFLOW_READ
52030 /* If all the following are true:
52031 **
52032 ** 1) this is a read operation, and
52033 ** 2) data is required from the start of this overflow page, and
52034 ** 3) the database is file-backed, and
52035 ** 4) there is no open write-transaction, and
52036 ** 5) the database is not a WAL database,
52037 **
52038 ** then data can be read directly from the database file into the
52039 ** output buffer, bypassing the page-cache altogether. This speeds
52040 ** up loading large records that span many overflow pages.
52041 */
52042 if( eOp==0 /* (1) */
52043 && offset==0 /* (2) */
52044 && pBt->inTransaction==TRANS_READ /* (4) */
52045 && (fd = sqlite3PagerFile(pBt->pPager))->pMethods /* (3) */
52046 && pBt->pPage1->aData[19]==0x01 /* (5) */
52047 ){
52048 u8 aSave[4];
52049 u8 *aWrite = &pBuf[-4];
52050 memcpy(aSave, aWrite, 4);
52051 rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1));
52052 nextPage = get4byte(aWrite);
52053 memcpy(aWrite, aSave, 4);
52054 }else
52055 #endif
52056
52057 {
52058 DbPage *pDbPage;
52059 rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage);
52060 if( rc==SQLITE_OK ){
52061 aPayload = sqlite3PagerGetData(pDbPage);
52062 nextPage = get4byte(aPayload);
52063 rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage);
52064 sqlite3PagerUnref(pDbPage);
52065 offset = 0;
52066 }
52067 }
52068 amt -= a;
52069 pBuf += a;
52070 }
52071 }
52072 }
52073
52074 if( rc==SQLITE_OK && amt>0 ){
@@ -52804,11 +52663,10 @@
52663 }
52664 }
52665 if( c==0 ){
52666 if( pPage->intKey && !pPage->leaf ){
52667 lwr = idx;
 
52668 break;
52669 }else{
52670 *pRes = 0;
52671 rc = SQLITE_OK;
52672 goto moveto_finish;
@@ -52822,11 +52680,11 @@
52680 if( lwr>upr ){
52681 break;
52682 }
52683 pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
52684 }
52685 assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
52686 assert( pPage->isInit );
52687 if( pPage->leaf ){
52688 chldPg = 0;
52689 }else if( lwr>=pPage->nCell ){
52690 chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
@@ -53087,10 +52945,12 @@
52945 }
52946 if( rc ){
52947 pTrunk = 0;
52948 goto end_allocate_page;
52949 }
52950 assert( pTrunk!=0 );
52951 assert( pTrunk->aData!=0 );
52952
52953 k = get4byte(&pTrunk->aData[4]); /* # of leaves on this trunk page */
52954 if( k==0 && !searchList ){
52955 /* The trunk has no leaves and the list is not being searched.
52956 ** So extract the trunk page itself and use it as the newly
@@ -54214,17 +54074,19 @@
54074 ** This is safe because dropping a cell only overwrites the first
54075 ** four bytes of it, and this function does not need the first
54076 ** four bytes of the divider cell. So the pointer is safe to use
54077 ** later on.
54078 **
54079 ** But not if we are in secure-delete mode. In secure-delete mode,
54080 ** the dropCell() routine will overwrite the entire cell with zeroes.
54081 ** In this case, temporarily copy the cell into the aOvflSpace[]
54082 ** buffer. It will be copied out again as soon as the aSpace[] buffer
54083 ** is allocated. */
54084 if( pBt->secureDelete ){
54085 int iOff;
54086
54087 iOff = SQLITE_PTR_TO_INT(apDiv[i]) - SQLITE_PTR_TO_INT(pParent->aData);
54088 if( (iOff+szNew[i])>(int)pBt->usableSize ){
54089 rc = SQLITE_CORRUPT_BKPT;
54090 memset(apOld, 0, (i+1)*sizeof(MemPage*));
54091 goto balance_cleanup;
54092 }else{
@@ -54640,10 +54502,11 @@
54502 int isDivider = 0;
54503 while( i==iNextOld ){
54504 /* Cell i is the cell immediately following the last cell on old
54505 ** sibling page j. If the siblings are not leaf pages of an
54506 ** intkey b-tree, then cell i was a divider cell. */
54507 assert( j+1 < ArraySize(apCopy) );
54508 pOld = apCopy[++j];
54509 iNextOld = i + !leafData + pOld->nCell + pOld->nOverflow;
54510 if( pOld->nOverflow ){
54511 nOverflow = pOld->nOverflow;
54512 iOverflow = i + !leafData + pOld->aOvfl[0].idx;
@@ -56982,18 +56845,18 @@
56845 /*
56846 ** Release all resources associated with an sqlite3_backup* handle.
56847 */
56848 SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){
56849 sqlite3_backup **pp; /* Ptr to head of pagers backup list */
56850 MUTEX_LOGIC( sqlite3_mutex *mutex; ) /* Mutex to protect source database */
56851 int rc; /* Value to return */
56852
56853 /* Enter the mutexes */
56854 if( p==0 ) return SQLITE_OK;
56855 sqlite3_mutex_enter(p->pSrcDb->mutex);
56856 sqlite3BtreeEnter(p->pSrc);
56857 MUTEX_LOGIC( mutex = p->pSrcDb->mutex; )
56858 if( p->pDestDb ){
56859 sqlite3_mutex_enter(p->pDestDb->mutex);
56860 }
56861
56862 /* Detach this backup from the source pager. */
@@ -57108,13 +56971,21 @@
56971 ** goes wrong, the transaction on pTo is rolled back. If successful, the
56972 ** transaction is committed before returning.
56973 */
56974 SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){
56975 int rc;
56976 sqlite3_file *pFd; /* File descriptor for database pTo */
56977 sqlite3_backup b;
56978 sqlite3BtreeEnter(pTo);
56979 sqlite3BtreeEnter(pFrom);
56980
56981 assert( sqlite3BtreeIsInTrans(pTo) );
56982 pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
56983 if( pFd->pMethods ){
56984 i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
56985 sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
56986 }
56987
56988 /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
56989 ** to 0. This is used by the implementations of sqlite3_backup_step()
56990 ** and sqlite3_backup_finish() to detect that they are being called
56991 ** from this function, not directly by the user.
@@ -57137,10 +57008,11 @@
57008 rc = sqlite3_backup_finish(&b);
57009 if( rc==SQLITE_OK ){
57010 pTo->pBt->pageSizeFixed = 0;
57011 }
57012
57013 assert( sqlite3BtreeIsInTrans(pTo)==0 );
57014 sqlite3BtreeLeave(pFrom);
57015 sqlite3BtreeLeave(pTo);
57016 return rc;
57017 }
57018 #endif /* SQLITE_OMIT_VACUUM */
@@ -58171,15 +58043,15 @@
58043 *ppVal = 0;
58044 return SQLITE_OK;
58045 }
58046 op = pExpr->op;
58047
58048 /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3.
58049 ** The ifdef here is to enable us to achieve 100% branch test coverage even
58050 ** when SQLITE_ENABLE_STAT3 is omitted.
58051 */
58052 #ifdef SQLITE_ENABLE_STAT3
58053 if( op==TK_REGISTER ) op = pExpr->op2;
58054 #else
58055 if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
58056 #endif
58057
@@ -58874,12 +58746,12 @@
58746 /*
58747 ** Change the P2 operand of instruction addr so that it points to
58748 ** the address of the next instruction to be coded.
58749 */
58750 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
58751 assert( addr>=0 || p->db->mallocFailed );
58752 if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
58753 }
58754
58755
58756 /*
58757 ** If the input FuncDef structure is ephemeral, then free it. If
@@ -59080,34 +58952,33 @@
58952 ** Change the comment on the the most recently coded instruction. Or
58953 ** insert a No-op and add the comment to that new instruction. This
58954 ** makes the code easier to read during debugging. None of this happens
58955 ** in a production build.
58956 */
58957 static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){
 
 
58958 assert( p->nOp>0 || p->aOp==0 );
58959 assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
58960 if( p->nOp ){
58961 assert( p->aOp );
58962 sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment);
58963 p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap);
58964 }
58965 }
58966 SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
58967 va_list ap;
58968 if( p ){
58969 va_start(ap, zFormat);
58970 vdbeVComment(p, zFormat, ap);
 
58971 va_end(ap);
58972 }
58973 }
58974 SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
58975 va_list ap;
58976 if( p ){
58977 sqlite3VdbeAddOp0(p, OP_Noop);
 
 
 
 
58978 va_start(ap, zFormat);
58979 vdbeVComment(p, zFormat, ap);
 
58980 va_end(ap);
58981 }
58982 }
58983 #endif /* NDEBUG */
58984
@@ -59441,11 +59312,11 @@
59312 SubProgram **apSub = 0; /* Array of sub-vdbes */
59313 Mem *pSub = 0; /* Memory cell hold array of subprogs */
59314 sqlite3 *db = p->db; /* The database connection */
59315 int i; /* Loop counter */
59316 int rc = SQLITE_OK; /* Return code */
59317 Mem *pMem = &p->aMem[1]; /* First Mem of result set */
59318
59319 assert( p->explain );
59320 assert( p->magic==VDBE_MAGIC_RUN );
59321 assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM );
59322
@@ -59452,10 +59323,11 @@
59323 /* Even though this opcode does not use dynamic strings for
59324 ** the result, result columns may become dynamic if the user calls
59325 ** sqlite3_column_text16(), causing a translation to UTF-16 encoding.
59326 */
59327 releaseMemArray(pMem, 8);
59328 p->pResultSet = 0;
59329
59330 if( p->rc==SQLITE_NOMEM ){
59331 /* This happens if a malloc() inside a call to sqlite3_column_text() or
59332 ** sqlite3_column_text16() failed. */
59333 db->mallocFailed = 1;
@@ -59606,10 +59478,11 @@
59478 pMem->type = SQLITE_NULL;
59479 }
59480 }
59481
59482 p->nResColumn = 8 - 4*(p->explain-1);
59483 p->pResultSet = &p->aMem[1];
59484 p->rc = SQLITE_OK;
59485 rc = SQLITE_ROW;
59486 }
59487 return rc;
59488 }
@@ -61361,11 +61234,11 @@
61234 ** than 2GiB are support - anything large must be database corruption.
61235 ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so
61236 ** this code can safely assume that nCellKey is 32-bits
61237 */
61238 assert( sqlite3BtreeCursorIsValid(pCur) );
61239 VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
61240 assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
61241 assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey );
61242
61243 /* Read in the complete content of the index entry */
61244 memset(&m, 0, sizeof(m));
@@ -61436,11 +61309,11 @@
61309 int rc;
61310 BtCursor *pCur = pC->pCursor;
61311 Mem m;
61312
61313 assert( sqlite3BtreeCursorIsValid(pCur) );
61314 VVA_ONLY(rc =) sqlite3BtreeKeySize(pCur, &nCellKey);
61315 assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */
61316 /* nCellKey will always be between 0 and 0xffffffff because of the say
61317 ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */
61318 if( nCellKey<=0 || nCellKey>0x7fffffff ){
61319 *res = 0;
@@ -65712,20 +65585,20 @@
65585 }else if( u.am.pC->cacheStatus==p->cacheCtr ){
65586 u.am.payloadSize = u.am.pC->payloadSize;
65587 u.am.zRec = (char*)u.am.pC->aRow;
65588 }else if( u.am.pC->isIndex ){
65589 assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
65590 VVA_ONLY(rc =) sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64);
65591 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
65592 /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the
65593 ** payload size, so it is impossible for u.am.payloadSize64 to be
65594 ** larger than 32 bits. */
65595 assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 );
65596 u.am.payloadSize = (u32)u.am.payloadSize64;
65597 }else{
65598 assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) );
65599 VVA_ONLY(rc =) sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize);
65600 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
65601 }
65602 }else if( ALWAYS(u.am.pC->pseudoTableReg>0) ){
65603 u.am.pReg = &aMem[u.am.pC->pseudoTableReg];
65604 assert( u.am.pReg->flags & MEM_Blob );
@@ -67773,18 +67646,18 @@
67646 rc = sqlite3VdbeCursorMoveto(u.bk.pC);
67647 if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
67648
67649 if( u.bk.pC->isIndex ){
67650 assert( !u.bk.pC->isTable );
67651 VVA_ONLY(rc =) sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64);
67652 assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */
67653 if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){
67654 goto too_big;
67655 }
67656 u.bk.n = (u32)u.bk.n64;
67657 }else{
67658 VVA_ONLY(rc =) sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n);
67659 assert( rc==SQLITE_OK ); /* DataSize() cannot fail */
67660 if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){
67661 goto too_big;
67662 }
67663 }
@@ -69095,11 +68968,11 @@
68968
68969 /* Do not allow a transition to journal_mode=WAL for a database
68970 ** in temporary storage or if the VFS does not support shared memory
68971 */
68972 if( u.ch.eNew==PAGER_JOURNALMODE_WAL
68973 && (sqlite3Strlen30(u.ch.zFilename)==0 /* Temp file */
68974 || !sqlite3PagerWalSupported(u.ch.pPager)) /* No shared-memory support */
68975 ){
68976 u.ch.eNew = u.ch.eOld;
68977 }
68978
@@ -69530,14 +69403,19 @@
69403 u.co.pName = &aMem[pOp->p1];
69404 assert( u.co.pVtab->pModule->xRename );
69405 assert( memIsValid(u.co.pName) );
69406 REGISTER_TRACE(pOp->p1, u.co.pName);
69407 assert( u.co.pName->flags & MEM_Str );
69408 testcase( u.co.pName->enc==SQLITE_UTF8 );
69409 testcase( u.co.pName->enc==SQLITE_UTF16BE );
69410 testcase( u.co.pName->enc==SQLITE_UTF16LE );
69411 rc = sqlite3VdbeChangeEncoding(u.co.pName, SQLITE_UTF8);
69412 if( rc==SQLITE_OK ){
69413 rc = u.co.pVtab->pModule->xRename(u.co.pVtab, u.co.pName->z);
69414 importVtabErrMsg(p, u.co.pVtab);
69415 p->expired = 0;
69416 }
69417 break;
69418 }
69419 #endif
69420
69421 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -71891,10 +71769,28 @@
71769 ExprSetProperty(pExpr, EP_Static);
71770 sqlite3ExprDelete(db, pExpr);
71771 memcpy(pExpr, pDup, sizeof(*pExpr));
71772 sqlite3DbFree(db, pDup);
71773 }
71774
71775
71776 /*
71777 ** Return TRUE if the name zCol occurs anywhere in the USING clause.
71778 **
71779 ** Return FALSE if the USING clause is NULL or if it does not contain
71780 ** zCol.
71781 */
71782 static int nameInUsingClause(IdList *pUsing, const char *zCol){
71783 if( pUsing ){
71784 int k;
71785 for(k=0; k<pUsing->nId; k++){
71786 if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1;
71787 }
71788 }
71789 return 0;
71790 }
71791
71792
71793 /*
71794 ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up
71795 ** that name in the set of source tables in pSrcList and make the pExpr
71796 ** expression node refer back to that source column. The following changes
@@ -71983,38 +71879,25 @@
71879 pSchema = pTab->pSchema;
71880 pMatch = pItem;
71881 }
71882 for(j=0, pCol=pTab->aCol; j<pTab->nCol; j++, pCol++){
71883 if( sqlite3StrICmp(pCol->zName, zCol)==0 ){
71884 /* If there has been exactly one prior match and this match
71885 ** is for the right-hand table of a NATURAL JOIN or is in a
71886 ** USING clause, then skip this match.
71887 */
71888 if( cnt==1 ){
71889 if( pItem->jointype & JT_NATURAL ) continue;
71890 if( nameInUsingClause(pItem->pUsing, zCol) ) continue;
71891 }
71892 cnt++;
71893 pExpr->iTable = pItem->iCursor;
71894 pExpr->pTab = pTab;
71895 pMatch = pItem;
71896 pSchema = pTab->pSchema;
71897 /* Substitute the rowid (column -1) for the INTEGER PRIMARY KEY */
71898 pExpr->iColumn = j==pTab->iPKey ? -1 : (i16)j;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71899 break;
71900 }
71901 }
71902 }
71903 }
@@ -73417,11 +73300,12 @@
73300 pNew->flags |= EP_IntValue;
73301 pNew->u.iValue = iValue;
73302 }else{
73303 int c;
73304 pNew->u.zToken = (char*)&pNew[1];
73305 assert( pToken->z!=0 || pToken->n==0 );
73306 if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n);
73307 pNew->u.zToken[pToken->n] = 0;
73308 if( dequote && nExtra>=3
73309 && ((c = pToken->z[0])=='\'' || c=='"' || c=='[' || c=='`') ){
73310 sqlite3Dequote(pNew->u.zToken);
73311 if( c=='"' ) pNew->flags |= EP_DblQuoted;
@@ -74456,15 +74340,23 @@
74340 ** ephemeral table.
74341 */
74342 p = (ExprHasProperty(pX, EP_xIsSelect) ? pX->x.pSelect : 0);
74343 if( ALWAYS(pParse->nErr==0) && isCandidateForInOpt(p) ){
74344 sqlite3 *db = pParse->db; /* Database connection */
 
 
74345 Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */
74346 Table *pTab; /* Table <table>. */
74347 Expr *pExpr; /* Expression <column> */
74348 int iCol; /* Index of column <column> */
74349 int iDb; /* Database idx for pTab */
74350
74351 assert( p ); /* Because of isCandidateForInOpt(p) */
74352 assert( p->pEList!=0 ); /* Because of isCandidateForInOpt(p) */
74353 assert( p->pEList->a[0].pExpr!=0 ); /* Because of isCandidateForInOpt(p) */
74354 assert( p->pSrc!=0 ); /* Because of isCandidateForInOpt(p) */
74355 pTab = p->pSrc->a[0].pTab;
74356 pExpr = p->pEList->a[0].pExpr;
74357 iCol = pExpr->iColumn;
74358
74359 /* Code an OP_VerifyCookie and OP_TableLock for <table>. */
74360 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
74361 sqlite3CodeVerifySchema(pParse, iDb);
74362 sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
@@ -76467,11 +76359,11 @@
76359 if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
76360 return 2;
76361 }
76362 }else if( pA->op!=TK_COLUMN && pA->u.zToken ){
76363 if( ExprHasProperty(pB, EP_IntValue) || NEVER(pB->u.zToken==0) ) return 2;
76364 if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
76365 return 2;
76366 }
76367 }
76368 if( (pA->flags & EP_ExpCollate)!=(pB->flags & EP_ExpCollate) ) return 1;
76369 if( (pA->flags & EP_ExpCollate)!=0 && pA->pColl!=pB->pColl ) return 2;
@@ -77610,10 +77502,112 @@
77502 ** May you find forgiveness for yourself and forgive others.
77503 ** May you share freely, never taking more than you give.
77504 **
77505 *************************************************************************
77506 ** This file contains code associated with the ANALYZE command.
77507 **
77508 ** The ANALYZE command gather statistics about the content of tables
77509 ** and indices. These statistics are made available to the query planner
77510 ** to help it make better decisions about how to perform queries.
77511 **
77512 ** The following system tables are or have been supported:
77513 **
77514 ** CREATE TABLE sqlite_stat1(tbl, idx, stat);
77515 ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample);
77516 ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample);
77517 **
77518 ** Additional tables might be added in future releases of SQLite.
77519 ** The sqlite_stat2 table is not created or used unless the SQLite version
77520 ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled
77521 ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated.
77522 ** The sqlite_stat2 table is superceded by sqlite_stat3, which is only
77523 ** created and used by SQLite versions 3.7.9 and later and with
77524 ** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3
77525 ** is a superset of sqlite_stat2.
77526 **
77527 ** Format of sqlite_stat1:
77528 **
77529 ** There is normally one row per index, with the index identified by the
77530 ** name in the idx column. The tbl column is the name of the table to
77531 ** which the index belongs. In each such row, the stat column will be
77532 ** a string consisting of a list of integers. The first integer in this
77533 ** list is the number of rows in the index and in the table. The second
77534 ** integer is the average number of rows in the index that have the same
77535 ** value in the first column of the index. The third integer is the average
77536 ** number of rows in the index that have the same value for the first two
77537 ** columns. The N-th integer (for N>1) is the average number of rows in
77538 ** the index which have the same value for the first N-1 columns. For
77539 ** a K-column index, there will be K+1 integers in the stat column. If
77540 ** the index is unique, then the last integer will be 1.
77541 **
77542 ** The list of integers in the stat column can optionally be followed
77543 ** by the keyword "unordered". The "unordered" keyword, if it is present,
77544 ** must be separated from the last integer by a single space. If the
77545 ** "unordered" keyword is present, then the query planner assumes that
77546 ** the index is unordered and will not use the index for a range query.
77547 **
77548 ** If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat
77549 ** column contains a single integer which is the (estimated) number of
77550 ** rows in the table identified by sqlite_stat1.tbl.
77551 **
77552 ** Format of sqlite_stat2:
77553 **
77554 ** The sqlite_stat2 is only created and is only used if SQLite is compiled
77555 ** with SQLITE_ENABLE_STAT2 and if the SQLite version number is between
77556 ** 3.6.18 and 3.7.8. The "stat2" table contains additional information
77557 ** about the distribution of keys within an index. The index is identified by
77558 ** the "idx" column and the "tbl" column is the name of the table to which
77559 ** the index belongs. There are usually 10 rows in the sqlite_stat2
77560 ** table for each index.
77561 **
77562 ** The sqlite_stat2 entries for an index that have sampleno between 0 and 9
77563 ** inclusive are samples of the left-most key value in the index taken at
77564 ** evenly spaced points along the index. Let the number of samples be S
77565 ** (10 in the standard build) and let C be the number of rows in the index.
77566 ** Then the sampled rows are given by:
77567 **
77568 ** rownumber = (i*C*2 + C)/(S*2)
77569 **
77570 ** For i between 0 and S-1. Conceptually, the index space is divided into
77571 ** S uniform buckets and the samples are the middle row from each bucket.
77572 **
77573 ** The format for sqlite_stat2 is recorded here for legacy reference. This
77574 ** version of SQLite does not support sqlite_stat2. It neither reads nor
77575 ** writes the sqlite_stat2 table. This version of SQLite only supports
77576 ** sqlite_stat3.
77577 **
77578 ** Format for sqlite_stat3:
77579 **
77580 ** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is
77581 ** used to avoid compatibility problems.
77582 **
77583 ** The format of the sqlite_stat3 table is similar to the format of
77584 ** the sqlite_stat2 table. There are multiple entries for each index.
77585 ** The idx column names the index and the tbl column is the table of the
77586 ** index. If the idx and tbl columns are the same, then the sample is
77587 ** of the INTEGER PRIMARY KEY. The sample column is a value taken from
77588 ** the left-most column of the index. The nEq column is the approximate
77589 ** number of entires in the index whose left-most column exactly matches
77590 ** the sample. nLt is the approximate number of entires whose left-most
77591 ** column is less than the sample. The nDLt column is the approximate
77592 ** number of distinct left-most entries in the index that are less than
77593 ** the sample.
77594 **
77595 ** Future versions of SQLite might change to store a string containing
77596 ** multiple integers values in the nDLt column of sqlite_stat3. The first
77597 ** integer will be the number of prior index entires that are distinct in
77598 ** the left-most column. The second integer will be the number of prior index
77599 ** entries that are distinct in the first two columns. The third integer
77600 ** will be the number of prior index entries that are distinct in the first
77601 ** three columns. And so forth. With that extension, the nDLt field is
77602 ** similar in function to the sqlite_stat1.stat field.
77603 **
77604 ** There can be an arbitrary number of sqlite_stat3 entries per index.
77605 ** The ANALYZE command will typically generate sqlite_stat3 tables
77606 ** that contain between 10 and 40 samples which are distributed across
77607 ** the key space, though not uniformly, and which include samples with
77608 ** largest possible nEq values.
77609 */
77610 #ifndef SQLITE_OMIT_ANALYZE
77611
77612 /*
77613 ** This routine generates code that opens the sqlite_stat1 table for
@@ -77641,12 +77635,12 @@
77635 static const struct {
77636 const char *zName;
77637 const char *zCols;
77638 } aTable[] = {
77639 { "sqlite_stat1", "tbl,idx,stat" },
77640 #ifdef SQLITE_ENABLE_STAT3
77641 { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" },
77642 #endif
77643 };
77644
77645 int aRoot[] = {0, 0};
77646 u8 aCreateTbl[] = {0, 0};
@@ -77658,10 +77652,13 @@
77652 if( v==0 ) return;
77653 assert( sqlite3BtreeHoldsAllMutexes(db) );
77654 assert( sqlite3VdbeDb(v)==db );
77655 pDb = &db->aDb[iDb];
77656
77657 /* Create new statistic tables if they do not exist, or clear them
77658 ** if they do already exist.
77659 */
77660 for(i=0; i<ArraySize(aTable); i++){
77661 const char *zTab = aTable[i].zName;
77662 Table *pStat;
77663 if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){
77664 /* The sqlite_stat[12] table does not exist. Create it. Note that a
@@ -77688,17 +77685,237 @@
77685 sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
77686 }
77687 }
77688 }
77689
77690 /* Open the sqlite_stat[13] tables for writing. */
77691 for(i=0; i<ArraySize(aTable); i++){
77692 sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb);
77693 sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32);
77694 sqlite3VdbeChangeP5(v, aCreateTbl[i]);
77695 }
77696 }
77697
77698 /*
77699 ** Recommended number of samples for sqlite_stat3
77700 */
77701 #ifndef SQLITE_STAT3_SAMPLES
77702 # define SQLITE_STAT3_SAMPLES 24
77703 #endif
77704
77705 /*
77706 ** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() -
77707 ** share an instance of the following structure to hold their state
77708 ** information.
77709 */
77710 typedef struct Stat3Accum Stat3Accum;
77711 struct Stat3Accum {
77712 tRowcnt nRow; /* Number of rows in the entire table */
77713 tRowcnt nPSample; /* How often to do a periodic sample */
77714 int iMin; /* Index of entry with minimum nEq and hash */
77715 int mxSample; /* Maximum number of samples to accumulate */
77716 int nSample; /* Current number of samples */
77717 u32 iPrn; /* Pseudo-random number used for sampling */
77718 struct Stat3Sample {
77719 i64 iRowid; /* Rowid in main table of the key */
77720 tRowcnt nEq; /* sqlite_stat3.nEq */
77721 tRowcnt nLt; /* sqlite_stat3.nLt */
77722 tRowcnt nDLt; /* sqlite_stat3.nDLt */
77723 u8 isPSample; /* True if a periodic sample */
77724 u32 iHash; /* Tiebreaker hash */
77725 } *a; /* An array of samples */
77726 };
77727
77728 #ifdef SQLITE_ENABLE_STAT3
77729 /*
77730 ** Implementation of the stat3_init(C,S) SQL function. The two parameters
77731 ** are the number of rows in the table or index (C) and the number of samples
77732 ** to accumulate (S).
77733 **
77734 ** This routine allocates the Stat3Accum object.
77735 **
77736 ** The return value is the Stat3Accum object (P).
77737 */
77738 static void stat3Init(
77739 sqlite3_context *context,
77740 int argc,
77741 sqlite3_value **argv
77742 ){
77743 Stat3Accum *p;
77744 tRowcnt nRow;
77745 int mxSample;
77746 int n;
77747
77748 UNUSED_PARAMETER(argc);
77749 nRow = (tRowcnt)sqlite3_value_int64(argv[0]);
77750 mxSample = sqlite3_value_int(argv[1]);
77751 n = sizeof(*p) + sizeof(p->a[0])*mxSample;
77752 p = sqlite3_malloc( n );
77753 if( p==0 ){
77754 sqlite3_result_error_nomem(context);
77755 return;
77756 }
77757 memset(p, 0, n);
77758 p->a = (struct Stat3Sample*)&p[1];
77759 p->nRow = nRow;
77760 p->mxSample = mxSample;
77761 p->nPSample = p->nRow/(mxSample/3+1) + 1;
77762 sqlite3_randomness(sizeof(p->iPrn), &p->iPrn);
77763 sqlite3_result_blob(context, p, sizeof(p), sqlite3_free);
77764 }
77765 static const FuncDef stat3InitFuncdef = {
77766 2, /* nArg */
77767 SQLITE_UTF8, /* iPrefEnc */
77768 0, /* flags */
77769 0, /* pUserData */
77770 0, /* pNext */
77771 stat3Init, /* xFunc */
77772 0, /* xStep */
77773 0, /* xFinalize */
77774 "stat3_init", /* zName */
77775 0, /* pHash */
77776 0 /* pDestructor */
77777 };
77778
77779
77780 /*
77781 ** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The
77782 ** arguments describe a single key instance. This routine makes the
77783 ** decision about whether or not to retain this key for the sqlite_stat3
77784 ** table.
77785 **
77786 ** The return value is NULL.
77787 */
77788 static void stat3Push(
77789 sqlite3_context *context,
77790 int argc,
77791 sqlite3_value **argv
77792 ){
77793 Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]);
77794 tRowcnt nEq = sqlite3_value_int64(argv[0]);
77795 tRowcnt nLt = sqlite3_value_int64(argv[1]);
77796 tRowcnt nDLt = sqlite3_value_int64(argv[2]);
77797 i64 rowid = sqlite3_value_int64(argv[3]);
77798 u8 isPSample = 0;
77799 u8 doInsert = 0;
77800 int iMin = p->iMin;
77801 struct Stat3Sample *pSample;
77802 int i;
77803 u32 h;
77804
77805 UNUSED_PARAMETER(context);
77806 UNUSED_PARAMETER(argc);
77807 if( nEq==0 ) return;
77808 h = p->iPrn = p->iPrn*1103515245 + 12345;
77809 if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){
77810 doInsert = isPSample = 1;
77811 }else if( p->nSample<p->mxSample ){
77812 doInsert = 1;
77813 }else{
77814 if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){
77815 doInsert = 1;
77816 }
77817 }
77818 if( !doInsert ) return;
77819 if( p->nSample==p->mxSample ){
77820 assert( p->nSample - iMin - 1 >= 0 );
77821 memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1));
77822 pSample = &p->a[p->nSample-1];
77823 }else{
77824 pSample = &p->a[p->nSample++];
77825 }
77826 pSample->iRowid = rowid;
77827 pSample->nEq = nEq;
77828 pSample->nLt = nLt;
77829 pSample->nDLt = nDLt;
77830 pSample->iHash = h;
77831 pSample->isPSample = isPSample;
77832
77833 /* Find the new minimum */
77834 if( p->nSample==p->mxSample ){
77835 pSample = p->a;
77836 i = 0;
77837 while( pSample->isPSample ){
77838 i++;
77839 pSample++;
77840 assert( i<p->nSample );
77841 }
77842 nEq = pSample->nEq;
77843 h = pSample->iHash;
77844 iMin = i;
77845 for(i++, pSample++; i<p->nSample; i++, pSample++){
77846 if( pSample->isPSample ) continue;
77847 if( pSample->nEq<nEq
77848 || (pSample->nEq==nEq && pSample->iHash<h)
77849 ){
77850 iMin = i;
77851 nEq = pSample->nEq;
77852 h = pSample->iHash;
77853 }
77854 }
77855 p->iMin = iMin;
77856 }
77857 }
77858 static const FuncDef stat3PushFuncdef = {
77859 5, /* nArg */
77860 SQLITE_UTF8, /* iPrefEnc */
77861 0, /* flags */
77862 0, /* pUserData */
77863 0, /* pNext */
77864 stat3Push, /* xFunc */
77865 0, /* xStep */
77866 0, /* xFinalize */
77867 "stat3_push", /* zName */
77868 0, /* pHash */
77869 0 /* pDestructor */
77870 };
77871
77872 /*
77873 ** Implementation of the stat3_get(P,N,...) SQL function. This routine is
77874 ** used to query the results. Content is returned for the Nth sqlite_stat3
77875 ** row where N is between 0 and S-1 and S is the number of samples. The
77876 ** value returned depends on the number of arguments.
77877 **
77878 ** argc==2 result: rowid
77879 ** argc==3 result: nEq
77880 ** argc==4 result: nLt
77881 ** argc==5 result: nDLt
77882 */
77883 static void stat3Get(
77884 sqlite3_context *context,
77885 int argc,
77886 sqlite3_value **argv
77887 ){
77888 int n = sqlite3_value_int(argv[1]);
77889 Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]);
77890
77891 assert( p!=0 );
77892 if( p->nSample<=n ) return;
77893 switch( argc ){
77894 case 2: sqlite3_result_int64(context, p->a[n].iRowid); break;
77895 case 3: sqlite3_result_int64(context, p->a[n].nEq); break;
77896 case 4: sqlite3_result_int64(context, p->a[n].nLt); break;
77897 default: sqlite3_result_int64(context, p->a[n].nDLt); break;
77898 }
77899 }
77900 static const FuncDef stat3GetFuncdef = {
77901 -1, /* nArg */
77902 SQLITE_UTF8, /* iPrefEnc */
77903 0, /* flags */
77904 0, /* pUserData */
77905 0, /* pNext */
77906 stat3Get, /* xFunc */
77907 0, /* xStep */
77908 0, /* xFinalize */
77909 "stat3_get", /* zName */
77910 0, /* pHash */
77911 0 /* pDestructor */
77912 };
77913 #endif /* SQLITE_ENABLE_STAT3 */
77914
77915
77916
77917
77918 /*
77919 ** Generate code to do an analysis of all indices associated with
77920 ** a single table.
77921 */
@@ -77718,24 +77935,31 @@
77935 int endOfLoop; /* The end of the loop */
77936 int jZeroRows = -1; /* Jump from here if number of rows is zero */
77937 int iDb; /* Index of database containing pTab */
77938 int regTabname = iMem++; /* Register containing table name */
77939 int regIdxname = iMem++; /* Register containing index name */
77940 int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
77941 #ifdef SQLITE_ENABLE_STAT3
77942 int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
77943 int regNumLt = iMem++; /* Number of keys less than regSample */
77944 int regNumDLt = iMem++; /* Number of distinct keys less than regSample */
77945 int regSample = iMem++; /* The next sample value */
77946 int regRowid = regSample; /* Rowid of a sample */
77947 int regAccum = iMem++; /* Register to hold Stat3Accum object */
77948 int regLoop = iMem++; /* Loop counter */
77949 int regCount = iMem++; /* Number of rows in the table or index */
77950 int regTemp1 = iMem++; /* Intermediate register */
77951 int regTemp2 = iMem++; /* Intermediate register */
77952 int once = 1; /* One-time initialization */
77953 int shortJump = 0; /* Instruction address */
77954 int iTabCur = pParse->nTab++; /* Table cursor */
77955 #endif
77956 int regCol = iMem++; /* Content of a column in analyzed table */
77957 int regRec = iMem++; /* Register holding completed record */
77958 int regTemp = iMem++; /* Temporary use register */
77959 int regNewRowid = iMem++; /* Rowid for the inserted record */
77960
 
 
 
 
 
 
 
 
77961
77962 v = sqlite3GetVdbe(pParse);
77963 if( v==0 || NEVER(pTab==0) ){
77964 return;
77965 }
@@ -77764,13 +77988,18 @@
77988 iIdxCur = pParse->nTab++;
77989 sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0);
77990 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
77991 int nCol;
77992 KeyInfo *pKey;
77993 int addrIfNot = 0; /* address of OP_IfNot */
77994 int *aChngAddr; /* Array of jump instruction addresses */
77995
77996 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
77997 VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
77998 nCol = pIdx->nColumn;
77999 aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
78000 if( aChngAddr==0 ) continue;
78001 pKey = sqlite3IndexKeyinfo(pParse, pIdx);
78002 if( iMem+1+(nCol*2)>pParse->nMem ){
78003 pParse->nMem = iMem+1+(nCol*2);
78004 }
78005
@@ -77781,35 +78010,24 @@
78010 VdbeComment((v, "%s", pIdx->zName));
78011
78012 /* Populate the register containing the index name. */
78013 sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0);
78014
78015 #ifdef SQLITE_ENABLE_STAT3
78016 if( once ){
78017 once = 0;
78018 sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
78019 }
78020 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
78021 sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
78022 sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq);
78023 sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt);
78024 sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
78025 sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
78026 (char*)&stat3InitFuncdef, P4_FUNCDEF);
78027 sqlite3VdbeChangeP5(v, 2);
78028 #endif /* SQLITE_ENABLE_STAT3 */
 
 
 
 
 
 
 
 
 
 
 
78029
78030 /* The block of memory cells initialized here is used as follows.
78031 **
78032 ** iMem:
78033 ** The total number of rows in the table.
@@ -77835,79 +78053,87 @@
78053 /* Start the analysis loop. This loop runs through all the entries in
78054 ** the index b-tree. */
78055 endOfLoop = sqlite3VdbeMakeLabel(v);
78056 sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop);
78057 topOfLoop = sqlite3VdbeCurrentAddr(v);
78058 sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */
78059
78060 for(i=0; i<nCol; i++){
78061 CollSeq *pColl;
78062 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol);
78063 if( i==0 ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78064 /* Always record the very first row */
78065 addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1);
78066 }
78067 assert( pIdx->azColl!=0 );
78068 assert( pIdx->azColl[i]!=0 );
78069 pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]);
78070 aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1,
78071 (char*)pColl, P4_COLLSEQ);
78072 sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
78073 VdbeComment((v, "jump if column %d changed", i));
78074 #ifdef SQLITE_ENABLE_STAT3
78075 if( i==0 ){
78076 sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1);
78077 VdbeComment((v, "incr repeat count"));
78078 }
78079 #endif
78080 }
78081 sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop);
78082 for(i=0; i<nCol; i++){
78083 sqlite3VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */
78084 if( i==0 ){
78085 sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */
78086 #ifdef SQLITE_ENABLE_STAT3
78087 sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
78088 (char*)&stat3PushFuncdef, P4_FUNCDEF);
78089 sqlite3VdbeChangeP5(v, 5);
78090 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid);
78091 sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt);
78092 sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1);
78093 sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq);
78094 #endif
78095 }
 
78096 sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1);
78097 sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1);
78098 }
78099 sqlite3DbFree(db, aChngAddr);
78100
78101 /* Always jump here after updating the iMem+1...iMem+1+nCol counters */
78102 sqlite3VdbeResolveLabel(v, endOfLoop);
78103
78104 sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop);
78105 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
78106 #ifdef SQLITE_ENABLE_STAT3
78107 sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2,
78108 (char*)&stat3PushFuncdef, P4_FUNCDEF);
78109 sqlite3VdbeChangeP5(v, 5);
78110 sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop);
78111 shortJump =
78112 sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1);
78113 sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1,
78114 (char*)&stat3GetFuncdef, P4_FUNCDEF);
78115 sqlite3VdbeChangeP5(v, 2);
78116 sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1);
78117 sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1);
78118 sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample);
78119 sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample);
78120 sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq,
78121 (char*)&stat3GetFuncdef, P4_FUNCDEF);
78122 sqlite3VdbeChangeP5(v, 3);
78123 sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt,
78124 (char*)&stat3GetFuncdef, P4_FUNCDEF);
78125 sqlite3VdbeChangeP5(v, 4);
78126 sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt,
78127 (char*)&stat3GetFuncdef, P4_FUNCDEF);
78128 sqlite3VdbeChangeP5(v, 5);
78129 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0);
78130 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
78131 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid);
78132 sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump);
78133 sqlite3VdbeJumpHere(v, shortJump+2);
78134 #endif
78135
78136 /* Store the results in sqlite_stat1.
78137 **
78138 ** The result is a single row of the sqlite_stat1 table. The first
78139 ** two columns are the names of the table and index. The third column
@@ -77923,50 +78149,51 @@
78149 **
78150 ** If K==0 then no entry is made into the sqlite_stat1 table.
78151 ** If K>0 then it is always the case the D>0 so division by zero
78152 ** is never possible.
78153 */
78154 sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
78155 if( jZeroRows<0 ){
78156 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
78157 }
78158 for(i=0; i<nCol; i++){
78159 sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
78160 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
78161 sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
78162 sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
78163 sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
78164 sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
78165 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
78166 }
78167 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
78168 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
78169 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
78170 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
78171 }
78172
78173 /* If the table has no indices, create a single sqlite_stat1 entry
78174 ** containing NULL as the index name and the row count as the content.
78175 */
78176 if( pTab->pIndex==0 ){
78177 sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
78178 VdbeComment((v, "%s", pTab->zName));
78179 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
78180 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
78181 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
78182 }else{
78183 sqlite3VdbeJumpHere(v, jZeroRows);
78184 jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
78185 }
78186 sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
78187 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
78188 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
78189 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
78190 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
78191 if( pParse->nMem<regRec ) pParse->nMem = regRec;
78192 sqlite3VdbeJumpHere(v, jZeroRows);
78193 }
78194
78195
78196 /*
78197 ** Generate code that will cause the most recent index analysis to
78198 ** be loaded into internal hash tables where is can be used.
78199 */
@@ -77987,11 +78214,11 @@
78214 int iStatCur;
78215 int iMem;
78216
78217 sqlite3BeginWriteOperation(pParse, 0, iDb);
78218 iStatCur = pParse->nTab;
78219 pParse->nTab += 3;
78220 openStatTable(pParse, iDb, iStatCur, 0, 0);
78221 iMem = pParse->nMem+1;
78222 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
78223 for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){
78224 Table *pTab = (Table*)sqliteHashData(k);
@@ -78012,11 +78239,11 @@
78239 assert( pTab!=0 );
78240 assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
78241 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
78242 sqlite3BeginWriteOperation(pParse, 0, iDb);
78243 iStatCur = pParse->nTab;
78244 pParse->nTab += 3;
78245 if( pOnlyIdx ){
78246 openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx");
78247 }else{
78248 openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl");
78249 }
@@ -78117,11 +78344,11 @@
78344 static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){
78345 analysisInfo *pInfo = (analysisInfo*)pData;
78346 Index *pIndex;
78347 Table *pTable;
78348 int i, c, n;
78349 tRowcnt v;
78350 const char *z;
78351
78352 assert( argc==3 );
78353 UNUSED_PARAMETER2(NotUsed, argc);
78354
@@ -78160,40 +78387,172 @@
78387 /*
78388 ** If the Index.aSample variable is not NULL, delete the aSample[] array
78389 ** and its contents.
78390 */
78391 SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){
78392 #ifdef SQLITE_ENABLE_STAT3
78393 if( pIdx->aSample ){
78394 int j;
78395 for(j=0; j<pIdx->nSample; j++){
78396 IndexSample *p = &pIdx->aSample[j];
78397 if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){
78398 sqlite3DbFree(db, p->u.z);
78399 }
78400 }
78401 sqlite3DbFree(db, pIdx->aSample);
78402 }
78403 if( db && db->pnBytesFreed==0 ){
78404 pIdx->nSample = 0;
78405 pIdx->aSample = 0;
78406 }
78407 #else
78408 UNUSED_PARAMETER(db);
78409 UNUSED_PARAMETER(pIdx);
78410 #endif
78411 }
78412
78413 #ifdef SQLITE_ENABLE_STAT3
78414 /*
78415 ** Load content from the sqlite_stat3 table into the Index.aSample[]
78416 ** arrays of all indices.
78417 */
78418 static int loadStat3(sqlite3 *db, const char *zDb){
78419 int rc; /* Result codes from subroutines */
78420 sqlite3_stmt *pStmt = 0; /* An SQL statement being run */
78421 char *zSql; /* Text of the SQL statement */
78422 Index *pPrevIdx = 0; /* Previous index in the loop */
78423 int idx = 0; /* slot in pIdx->aSample[] for next sample */
78424 int eType; /* Datatype of a sample */
78425 IndexSample *pSample; /* A slot in pIdx->aSample[] */
78426
78427 if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){
78428 return SQLITE_OK;
78429 }
78430
78431 zSql = sqlite3MPrintf(db,
78432 "SELECT idx,count(*) FROM %Q.sqlite_stat3"
78433 " GROUP BY idx", zDb);
78434 if( !zSql ){
78435 return SQLITE_NOMEM;
78436 }
78437 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
78438 sqlite3DbFree(db, zSql);
78439 if( rc ) return rc;
78440
78441 while( sqlite3_step(pStmt)==SQLITE_ROW ){
78442 char *zIndex; /* Index name */
78443 Index *pIdx; /* Pointer to the index object */
78444 int nSample; /* Number of samples */
78445
78446 zIndex = (char *)sqlite3_column_text(pStmt, 0);
78447 if( zIndex==0 ) continue;
78448 nSample = sqlite3_column_int(pStmt, 1);
78449 pIdx = sqlite3FindIndex(db, zIndex, zDb);
78450 if( pIdx==0 ) continue;
78451 assert( pIdx->nSample==0 );
78452 pIdx->nSample = nSample;
78453 pIdx->aSample = sqlite3MallocZero( nSample*sizeof(IndexSample) );
78454 pIdx->avgEq = pIdx->aiRowEst[1];
78455 if( pIdx->aSample==0 ){
78456 db->mallocFailed = 1;
78457 sqlite3_finalize(pStmt);
78458 return SQLITE_NOMEM;
78459 }
78460 }
78461 rc = sqlite3_finalize(pStmt);
78462 if( rc ) return rc;
78463
78464 zSql = sqlite3MPrintf(db,
78465 "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb);
78466 if( !zSql ){
78467 return SQLITE_NOMEM;
78468 }
78469 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
78470 sqlite3DbFree(db, zSql);
78471 if( rc ) return rc;
78472
78473 while( sqlite3_step(pStmt)==SQLITE_ROW ){
78474 char *zIndex; /* Index name */
78475 Index *pIdx; /* Pointer to the index object */
78476 int i; /* Loop counter */
78477 tRowcnt sumEq; /* Sum of the nEq values */
78478
78479 zIndex = (char *)sqlite3_column_text(pStmt, 0);
78480 if( zIndex==0 ) continue;
78481 pIdx = sqlite3FindIndex(db, zIndex, zDb);
78482 if( pIdx==0 ) continue;
78483 if( pIdx==pPrevIdx ){
78484 idx++;
78485 }else{
78486 pPrevIdx = pIdx;
78487 idx = 0;
78488 }
78489 assert( idx<pIdx->nSample );
78490 pSample = &pIdx->aSample[idx];
78491 pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1);
78492 pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2);
78493 pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3);
78494 if( idx==pIdx->nSample-1 ){
78495 if( pSample->nDLt>0 ){
78496 for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq;
78497 pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt;
78498 }
78499 if( pIdx->avgEq<=0 ) pIdx->avgEq = 1;
78500 }
78501 eType = sqlite3_column_type(pStmt, 4);
78502 pSample->eType = (u8)eType;
78503 switch( eType ){
78504 case SQLITE_INTEGER: {
78505 pSample->u.i = sqlite3_column_int64(pStmt, 4);
78506 break;
78507 }
78508 case SQLITE_FLOAT: {
78509 pSample->u.r = sqlite3_column_double(pStmt, 4);
78510 break;
78511 }
78512 case SQLITE_NULL: {
78513 break;
78514 }
78515 default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); {
78516 const char *z = (const char *)(
78517 (eType==SQLITE_BLOB) ?
78518 sqlite3_column_blob(pStmt, 4):
78519 sqlite3_column_text(pStmt, 4)
78520 );
78521 int n = z ? sqlite3_column_bytes(pStmt, 4) : 0;
78522 pSample->nByte = n;
78523 if( n < 1){
78524 pSample->u.z = 0;
78525 }else{
78526 pSample->u.z = sqlite3Malloc(n);
78527 if( pSample->u.z==0 ){
78528 db->mallocFailed = 1;
78529 sqlite3_finalize(pStmt);
78530 return SQLITE_NOMEM;
78531 }
78532 memcpy(pSample->u.z, z, n);
78533 }
78534 }
78535 }
78536 }
78537 return sqlite3_finalize(pStmt);
78538 }
78539 #endif /* SQLITE_ENABLE_STAT3 */
78540
78541 /*
78542 ** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The
78543 ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[]
78544 ** arrays. The contents of sqlite_stat3 are used to populate the
78545 ** Index.aSample[] arrays.
78546 **
78547 ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR
78548 ** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined
78549 ** during compilation and the sqlite_stat3 table is present, no data is
78550 ** read from it.
78551 **
78552 ** If SQLITE_ENABLE_STAT3 was defined during compilation and the
78553 ** sqlite_stat3 table is not present in the database, SQLITE_ERROR is
78554 ** returned. However, in this case, data is read from the sqlite_stat1
78555 ** table (if it is present) before returning.
78556 **
78557 ** If an OOM error occurs, this function always sets db->mallocFailed.
78558 ** This means if the caller does not care about other errors, the return
@@ -78211,12 +78570,14 @@
78570 /* Clear any prior statistics */
78571 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
78572 for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){
78573 Index *pIdx = sqliteHashData(i);
78574 sqlite3DefaultRowEst(pIdx);
78575 #ifdef SQLITE_ENABLE_STAT3
78576 sqlite3DeleteIndexSamples(db, pIdx);
78577 pIdx->aSample = 0;
78578 #endif
78579 }
78580
78581 /* Check to make sure the sqlite_stat1 table exists */
78582 sInfo.db = db;
78583 sInfo.zDatabase = db->aDb[iDb].zName;
@@ -78224,91 +78585,23 @@
78585 return SQLITE_ERROR;
78586 }
78587
78588 /* Load new statistics out of the sqlite_stat1 table */
78589 zSql = sqlite3MPrintf(db,
78590 "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
78591 if( zSql==0 ){
78592 rc = SQLITE_NOMEM;
78593 }else{
78594 rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
78595 sqlite3DbFree(db, zSql);
78596 }
78597
78598
78599 /* Load the statistics from the sqlite_stat3 table. */
78600 #ifdef SQLITE_ENABLE_STAT3
78601 if( rc==SQLITE_OK ){
78602 rc = loadStat3(db, sInfo.zDatabase);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78603 }
78604 #endif
78605
78606 if( rc==SQLITE_NOMEM ){
78607 db->mallocFailed = 1;
@@ -81120,11 +81413,15 @@
81413 Parse *pParse, /* The parsing context */
81414 int iDb, /* The database number */
81415 const char *zType, /* "idx" or "tbl" */
81416 const char *zName /* Name of index or table */
81417 ){
81418 static const char *azStatTab[] = {
81419 "sqlite_stat1",
81420 "sqlite_stat2",
81421 "sqlite_stat3",
81422 };
81423 int i;
81424 const char *zDbName = pParse->db->aDb[iDb].zName;
81425 for(i=0; i<ArraySize(azStatTab); i++){
81426 if( sqlite3FindTable(pParse->db, azStatTab[i], zDbName) ){
81427 sqlite3NestedParse(pParse,
@@ -81132,10 +81429,80 @@
81429 zDbName, azStatTab[i], zType, zName
81430 );
81431 }
81432 }
81433 }
81434
81435 /*
81436 ** Generate code to drop a table.
81437 */
81438 SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){
81439 Vdbe *v;
81440 sqlite3 *db = pParse->db;
81441 Trigger *pTrigger;
81442 Db *pDb = &db->aDb[iDb];
81443
81444 v = sqlite3GetVdbe(pParse);
81445 assert( v!=0 );
81446 sqlite3BeginWriteOperation(pParse, 1, iDb);
81447
81448 #ifndef SQLITE_OMIT_VIRTUALTABLE
81449 if( IsVirtual(pTab) ){
81450 sqlite3VdbeAddOp0(v, OP_VBegin);
81451 }
81452 #endif
81453
81454 /* Drop all triggers associated with the table being dropped. Code
81455 ** is generated to remove entries from sqlite_master and/or
81456 ** sqlite_temp_master if required.
81457 */
81458 pTrigger = sqlite3TriggerList(pParse, pTab);
81459 while( pTrigger ){
81460 assert( pTrigger->pSchema==pTab->pSchema ||
81461 pTrigger->pSchema==db->aDb[1].pSchema );
81462 sqlite3DropTriggerPtr(pParse, pTrigger);
81463 pTrigger = pTrigger->pNext;
81464 }
81465
81466 #ifndef SQLITE_OMIT_AUTOINCREMENT
81467 /* Remove any entries of the sqlite_sequence table associated with
81468 ** the table being dropped. This is done before the table is dropped
81469 ** at the btree level, in case the sqlite_sequence table needs to
81470 ** move as a result of the drop (can happen in auto-vacuum mode).
81471 */
81472 if( pTab->tabFlags & TF_Autoincrement ){
81473 sqlite3NestedParse(pParse,
81474 "DELETE FROM %Q.sqlite_sequence WHERE name=%Q",
81475 pDb->zName, pTab->zName
81476 );
81477 }
81478 #endif
81479
81480 /* Drop all SQLITE_MASTER table and index entries that refer to the
81481 ** table. The program name loops through the master table and deletes
81482 ** every row that refers to a table of the same name as the one being
81483 ** dropped. Triggers are handled seperately because a trigger can be
81484 ** created in the temp database that refers to a table in another
81485 ** database.
81486 */
81487 sqlite3NestedParse(pParse,
81488 "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'",
81489 pDb->zName, SCHEMA_TABLE(iDb), pTab->zName);
81490 if( !isView && !IsVirtual(pTab) ){
81491 destroyTable(pParse, pTab);
81492 }
81493
81494 /* Remove the table entry from SQLite's internal schema and modify
81495 ** the schema cookie.
81496 */
81497 if( IsVirtual(pTab) ){
81498 sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
81499 }
81500 sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
81501 sqlite3ChangeCookie(pParse, iDb);
81502 sqliteViewResetAll(db, iDb);
81503 }
81504
81505 /*
81506 ** This routine is called to do the work of a DROP TABLE statement.
81507 ** pName is the name of the table to be dropped.
81508 */
@@ -81201,11 +81568,12 @@
81568 if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){
81569 goto exit_drop_table;
81570 }
81571 }
81572 #endif
81573 if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0
81574 && sqlite3StrNICmp(pTab->zName, "sqlite_stat", 11)!=0 ){
81575 sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName);
81576 goto exit_drop_table;
81577 }
81578
81579 #ifndef SQLITE_OMIT_VIEW
@@ -81225,72 +81593,15 @@
81593 /* Generate code to remove the table from the master table
81594 ** on disk.
81595 */
81596 v = sqlite3GetVdbe(pParse);
81597 if( v ){
 
 
81598 sqlite3BeginWriteOperation(pParse, 1, iDb);
81599 sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName);
 
 
 
 
 
81600 sqlite3FkDropTable(pParse, pName, pTab);
81601 sqlite3CodeDropTable(pParse, pTab, iDb, isView);
81602 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81603
81604 exit_drop_table:
81605 sqlite3SrcListDelete(db, pName);
81606 }
81607
@@ -81454,17 +81765,19 @@
81765 */
81766 static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
81767 Table *pTab = pIndex->pTable; /* The table that is indexed */
81768 int iTab = pParse->nTab++; /* Btree cursor used for pTab */
81769 int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
81770 int iSorter; /* Cursor opened by OpenSorter (if in use) */
81771 int addr1; /* Address of top of loop */
81772 int addr2; /* Address to jump to for next iteration */
81773 int tnum; /* Root page of index */
81774 Vdbe *v; /* Generate code into this virtual machine */
81775 KeyInfo *pKey; /* KeyInfo for index */
81776 #ifdef SQLITE_OMIT_MERGE_SORT
81777 int regIdxKey; /* Registers containing the index key */
81778 #endif
81779 int regRecord; /* Register holding assemblied index record */
81780 sqlite3 *db = pParse->db; /* The database connection */
81781 int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
81782
81783 #ifndef SQLITE_OMIT_AUTHORIZATION
@@ -81494,21 +81807,22 @@
81807
81808 #ifndef SQLITE_OMIT_MERGE_SORT
81809 /* Open the sorter cursor if we are to use one. */
81810 iSorter = pParse->nTab++;
81811 sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO);
81812 #else
81813 iSorter = iTab;
81814 #endif
81815
81816 /* Open the table. Loop through all rows of the table, inserting index
81817 ** records into the sorter. */
81818 sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
81819 addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
 
81820 regRecord = sqlite3GetTempReg(pParse);
 
81821
81822 #ifndef SQLITE_OMIT_MERGE_SORT
81823 sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
81824 sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
81825 sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
81826 sqlite3VdbeJumpHere(v, addr1);
81827 addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
81828 if( pIndex->onError!=OE_None ){
@@ -81524,10 +81838,12 @@
81838 }
81839 sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
81840 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 1);
81841 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
81842 #else
81843 regIdxKey = sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
81844 addr2 = addr1 + 1;
81845 if( pIndex->onError!=OE_None ){
81846 const int regRowid = regIdxKey + pIndex->nColumn;
81847 const int j2 = sqlite3VdbeCurrentAddr(v) + 2;
81848 void * const pRegKey = SQLITE_INT_TO_PTR(regIdxKey);
81849
@@ -81621,10 +81937,11 @@
81937 ** before looking up the table.
81938 */
81939 assert( pName1 && pName2 );
81940 iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName);
81941 if( iDb<0 ) goto exit_create_index;
81942 assert( pName && pName->z );
81943
81944 #ifndef SQLITE_OMIT_TEMPDB
81945 /* If the index name was unqualified, check if the the table
81946 ** is a temp table. If so, set the database to 1. Do not do this
81947 ** if initialising a database schema.
@@ -81648,10 +81965,11 @@
81965 pTblName->a[0].zDatabase);
81966 if( !pTab || db->mallocFailed ) goto exit_create_index;
81967 assert( db->aDb[iDb].pSchema==pTab->pSchema );
81968 }else{
81969 assert( pName==0 );
81970 assert( pStart==0 );
81971 pTab = pParse->pNewTable;
81972 if( !pTab ) goto exit_create_index;
81973 iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
81974 }
81975 pDb = &db->aDb[iDb];
@@ -81690,10 +82008,11 @@
82008 ** own name.
82009 */
82010 if( pName ){
82011 zName = sqlite3NameFromToken(db, pName);
82012 if( zName==0 ) goto exit_create_index;
82013 assert( pName->z!=0 );
82014 if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
82015 goto exit_create_index;
82016 }
82017 if( !db->init.busy ){
82018 if( sqlite3FindTable(db, zName, 0)!=0 ){
@@ -81769,24 +82088,24 @@
82088 */
82089 nName = sqlite3Strlen30(zName);
82090 nCol = pList->nExpr;
82091 pIndex = sqlite3DbMallocZero(db,
82092 sizeof(Index) + /* Index structure */
82093 sizeof(tRowcnt)*(nCol+1) + /* Index.aiRowEst */
82094 sizeof(int)*nCol + /* Index.aiColumn */
 
82095 sizeof(char *)*nCol + /* Index.azColl */
82096 sizeof(u8)*nCol + /* Index.aSortOrder */
82097 nName + 1 + /* Index.zName */
82098 nExtra /* Collation sequence names */
82099 );
82100 if( db->mallocFailed ){
82101 goto exit_create_index;
82102 }
82103 pIndex->aiRowEst = (tRowcnt*)(&pIndex[1]);
82104 pIndex->azColl = (char**)(&pIndex->aiRowEst[nCol+1]);
82105 pIndex->aiColumn = (int *)(&pIndex->azColl[nCol]);
82106 pIndex->aSortOrder = (u8 *)(&pIndex->aiColumn[nCol]);
 
82107 pIndex->zName = (char *)(&pIndex->aSortOrder[nCol]);
82108 zExtra = (char *)(&pIndex->zName[nName+1]);
82109 memcpy(pIndex->zName, zName, nName+1);
82110 pIndex->pTable = pTab;
82111 pIndex->nColumn = pList->nExpr;
@@ -82059,13 +82378,13 @@
82378 ** Apart from that, we have little to go on besides intuition as to
82379 ** how aiRowEst[] should be initialized. The numbers generated here
82380 ** are based on typical values found in actual indices.
82381 */
82382 SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){
82383 tRowcnt *a = pIdx->aiRowEst;
82384 int i;
82385 tRowcnt n;
82386 assert( a!=0 );
82387 a[0] = pIdx->pTable->nRowEst;
82388 if( a[0]<10 ) a[0] = 10;
82389 n = 10;
82390 for(i=1; i<=pIdx->nColumn; i++){
@@ -82545,17 +82864,14 @@
82864
82865 /*
82866 ** Commit a transaction
82867 */
82868 SQLITE_PRIVATE void sqlite3CommitTransaction(Parse *pParse){
 
82869 Vdbe *v;
82870
82871 assert( pParse!=0 );
82872 assert( pParse->db!=0 );
 
 
82873 if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
82874 return;
82875 }
82876 v = sqlite3GetVdbe(pParse);
82877 if( v ){
@@ -82565,17 +82881,14 @@
82881
82882 /*
82883 ** Rollback a transaction
82884 */
82885 SQLITE_PRIVATE void sqlite3RollbackTransaction(Parse *pParse){
 
82886 Vdbe *v;
82887
82888 assert( pParse!=0 );
82889 assert( pParse->db!=0 );
 
 
82890 if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
82891 return;
82892 }
82893 v = sqlite3GetVdbe(pParse);
82894 if( v ){
@@ -84377,20 +84690,19 @@
84690 /* Verify that the call to _bytes() does not invalidate the _text() pointer */
84691 assert( z2==(char*)sqlite3_value_text(argv[0]) );
84692 if( z2 ){
84693 z1 = contextMalloc(context, ((i64)n)+1);
84694 if( z1 ){
84695 for(i=0; i<n; i++){
84696 z1[i] = (char)sqlite3Toupper(z2[i]);
 
84697 }
84698 sqlite3_result_text(context, z1, n, sqlite3_free);
84699 }
84700 }
84701 }
84702 static void lowerFunc(sqlite3_context *context, int argc, sqlite3_value **argv){
84703 char *z1;
84704 const char *z2;
84705 int i, n;
84706 UNUSED_PARAMETER(argc);
84707 z2 = (char*)sqlite3_value_text(argv[0]);
84708 n = sqlite3_value_bytes(argv[0]);
@@ -84397,15 +84709,14 @@
84709 /* Verify that the call to _bytes() does not invalidate the _text() pointer */
84710 assert( z2==(char*)sqlite3_value_text(argv[0]) );
84711 if( z2 ){
84712 z1 = contextMalloc(context, ((i64)n)+1);
84713 if( z1 ){
84714 for(i=0; i<n; i++){
84715 z1[i] = sqlite3Tolower(z2[i]);
 
84716 }
84717 sqlite3_result_text(context, z1, n, sqlite3_free);
84718 }
84719 }
84720 }
84721
84722
@@ -86778,10 +87089,11 @@
87089 sqlite3SelectDelete(db, pSelect);
87090 if( db->mallocFailed==1 ){
87091 fkTriggerDelete(db, pTrigger);
87092 return 0;
87093 }
87094 assert( pStep!=0 );
87095
87096 switch( action ){
87097 case OE_Restrict:
87098 pStep->op = TK_SELECT;
87099 break;
@@ -88621,10 +88933,13 @@
88933 */
88934 if( (pParse->db->flags & SQLITE_ForeignKeys)!=0 && pDest->pFKey!=0 ){
88935 return 0;
88936 }
88937 #endif
88938 if( (pParse->db->flags & SQLITE_CountRows)!=0 ){
88939 return 0;
88940 }
88941
88942 /* If we get this far, it means either:
88943 **
88944 ** * We can always do the transfer if the table contains an
88945 ** an integer primary key
@@ -89698,11 +90013,11 @@
90013 sqlite3_vfs *pVfs = db->pVfs;
90014 void *handle;
90015 int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
90016 char *zErrmsg = 0;
90017 void **aHandle;
90018 int nMsg = 300 + sqlite3Strlen30(zFile);
90019
90020 if( pzErrMsg ) *pzErrMsg = 0;
90021
90022 /* Ticket #1863. To avoid a creating security problems for older
90023 ** applications that relink against newer versions of SQLite, the
@@ -89735,10 +90050,11 @@
90050 }
90051 xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
90052 sqlite3OsDlSym(pVfs, handle, zProc);
90053 if( xInit==0 ){
90054 if( pzErrMsg ){
90055 nMsg += sqlite3Strlen30(zProc);
90056 *pzErrMsg = zErrmsg = sqlite3_malloc(nMsg);
90057 if( zErrmsg ){
90058 sqlite3_snprintf(nMsg, zErrmsg,
90059 "no entry point [%s] in shared library [%s]", zProc,zFile);
90060 sqlite3OsDlError(pVfs, nMsg-1, zErrmsg);
@@ -90420,11 +90736,11 @@
90736 ){
90737 int iReg;
90738 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
90739 sqlite3CodeVerifySchema(pParse, iDb);
90740 iReg = ++pParse->nMem;
90741 if( sqlite3Tolower(zLeft[0])=='p' ){
90742 sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
90743 }else{
90744 sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, sqlite3Atoi(zRight));
90745 }
90746 sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
@@ -90486,12 +90802,14 @@
90802 */
90803 if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
90804 int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */
90805 int ii; /* Loop counter */
90806
90807 /* Force the schema to be loaded on all databases. This causes all
90808 ** database files to be opened and the journal_modes set. This is
90809 ** necessary because subsequent processing must know if the databases
90810 ** are in WAL mode. */
90811 if( sqlite3ReadSchema(pParse) ){
90812 goto pragma_out;
90813 }
90814
90815 sqlite3VdbeSetNumCols(v, 1);
@@ -91031,11 +91349,11 @@
91349 { OP_IfNeg, 1, 0, 0}, /* 1 */
91350 { OP_String8, 0, 3, 0}, /* 2 */
91351 { OP_ResultRow, 3, 1, 0},
91352 };
91353
91354 int isQuick = (sqlite3Tolower(zLeft[0])=='q');
91355
91356 /* Initialize the VDBE program */
91357 if( sqlite3ReadSchema(pParse) ) goto pragma_out;
91358 pParse->nMem = 6;
91359 sqlite3VdbeSetNumCols(v, 1);
@@ -92406,10 +92724,11 @@
92724 Select standin;
92725 sqlite3 *db = pParse->db;
92726 pNew = sqlite3DbMallocZero(db, sizeof(*pNew) );
92727 assert( db->mallocFailed || !pOffset || pLimit ); /* OFFSET implies LIMIT */
92728 if( pNew==0 ){
92729 assert( db->mallocFailed );
92730 pNew = &standin;
92731 memset(pNew, 0, sizeof(*pNew));
92732 }
92733 if( pEList==0 ){
92734 pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ALL,0));
@@ -92433,10 +92752,11 @@
92752 if( pNew!=&standin ) sqlite3DbFree(db, pNew);
92753 pNew = 0;
92754 }else{
92755 assert( pNew->pSrc!=0 || pParse->nErr>0 );
92756 }
92757 assert( pNew!=&standin );
92758 return pNew;
92759 }
92760
92761 /*
92762 ** Delete the given Select structure and all of its substructures.
@@ -93611,11 +93931,14 @@
93931 /* If the column contains an "AS <name>" phrase, use <name> as the name */
93932 zName = sqlite3DbStrDup(db, zName);
93933 }else{
93934 Expr *pColExpr = p; /* The expression that is the result column name */
93935 Table *pTab; /* Table associated with this expression */
93936 while( pColExpr->op==TK_DOT ){
93937 pColExpr = pColExpr->pRight;
93938 assert( pColExpr!=0 );
93939 }
93940 if( pColExpr->op==TK_COLUMN && ALWAYS(pColExpr->pTab!=0) ){
93941 /* For columns use the column name name */
93942 int iCol = pColExpr->iColumn;
93943 pTab = pColExpr->pTab;
93944 if( iCol<0 ) iCol = pTab->iPKey;
@@ -98609,10 +98932,11 @@
98932 break;
98933 }
98934 }
98935 }
98936 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
98937 assert( aRegIdx );
98938 if( openAll || aRegIdx[i]>0 ){
98939 KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx);
98940 sqlite3VdbeAddOp4(v, OP_OpenWrite, iCur+i+1, pIdx->tnum, iDb,
98941 (char*)pKey, P4_KEYINFO_HANDOFF);
98942 assert( pParse->nTab>iCur+i+1 );
@@ -98782,10 +99106,11 @@
99106 sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
99107 sqlite3VdbeJumpHere(v, addr);
99108
99109 /* Close all tables */
99110 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
99111 assert( aRegIdx );
99112 if( openAll || aRegIdx[i]>0 ){
99113 sqlite3VdbeAddOp2(v, OP_Close, iCur+i+1, 0);
99114 }
99115 }
99116 sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
@@ -98969,11 +99294,11 @@
99294 if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){
99295 sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db));
99296 return sqlite3_errcode(db);
99297 }
99298 VVA_ONLY( rc = ) sqlite3_step(pStmt);
99299 assert( rc!=SQLITE_ROW || (db->flags&SQLITE_CountRows) );
99300 return vacuumFinalize(db, pStmt, pzErrMsg);
99301 }
99302
99303 /*
99304 ** Execute zSql on database db. The statement returns exactly
@@ -99187,17 +99512,15 @@
99512 " WHERE type='view' OR type='trigger'"
99513 " OR (type='table' AND rootpage=0)"
99514 );
99515 if( rc ) goto end_of_vacuum;
99516
99517 /* At this point, there is a write transaction open on both the
99518 ** vacuum database and the main database. Assuming no error occurs,
99519 ** both transactions are closed by this block - the main database
99520 ** transaction by sqlite3BtreeCopyFile() and the other by an explicit
99521 ** call to sqlite3BtreeCommit().
 
 
99522 */
99523 {
99524 u32 meta;
99525 int i;
99526
@@ -100457,25 +100780,35 @@
100780 #define TERM_CODED 0x04 /* This term is already coded */
100781 #define TERM_COPIED 0x08 /* Has a child */
100782 #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */
100783 #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */
100784 #define TERM_OR_OK 0x40 /* Used during OR-clause processing */
100785 #ifdef SQLITE_ENABLE_STAT3
100786 # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */
100787 #else
100788 # define TERM_VNULL 0x00 /* Disabled if not using stat3 */
100789 #endif
100790
100791 /*
100792 ** An instance of the following structure holds all information about a
100793 ** WHERE clause. Mostly this is a container for one or more WhereTerms.
100794 **
100795 ** Explanation of pOuter: For a WHERE clause of the form
100796 **
100797 ** a AND ((b AND c) OR (d AND e)) AND f
100798 **
100799 ** There are separate WhereClause objects for the whole clause and for
100800 ** the subclauses "(b AND c)" and "(d AND e)". The pOuter field of the
100801 ** subclauses points to the WhereClause object for the whole clause.
100802 */
100803 struct WhereClause {
100804 Parse *pParse; /* The parser context */
100805 WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
100806 Bitmask vmask; /* Bitmask identifying virtual table cursors */
100807 WhereClause *pOuter; /* Outer conjunction */
100808 u8 op; /* Split operator. TK_AND or TK_OR */
100809 u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
100810 int nTerm; /* Number of terms */
100811 int nSlot; /* Number of entries in a[] */
100812 WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */
100813 #if defined(SQLITE_SMALL_STACK)
100814 WhereTerm aStatic[1]; /* Initial static space for a[] */
@@ -100600,18 +100933,21 @@
100933 ** Initialize a preallocated WhereClause structure.
100934 */
100935 static void whereClauseInit(
100936 WhereClause *pWC, /* The WhereClause to be initialized */
100937 Parse *pParse, /* The parsing context */
100938 WhereMaskSet *pMaskSet, /* Mapping from table cursor numbers to bitmasks */
100939 u16 wctrlFlags /* Might include WHERE_AND_ONLY */
100940 ){
100941 pWC->pParse = pParse;
100942 pWC->pMaskSet = pMaskSet;
100943 pWC->pOuter = 0;
100944 pWC->nTerm = 0;
100945 pWC->nSlot = ArraySize(pWC->aStatic);
100946 pWC->a = pWC->aStatic;
100947 pWC->vmask = 0;
100948 pWC->wctrlFlags = wctrlFlags;
100949 }
100950
100951 /* Forward reference */
100952 static void whereClauseClear(WhereClause*);
100953
@@ -100923,40 +101259,42 @@
101259 ){
101260 WhereTerm *pTerm;
101261 int k;
101262 assert( iCur>=0 );
101263 op &= WO_ALL;
101264 for(; pWC; pWC=pWC->pOuter){
101265 for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
101266 if( pTerm->leftCursor==iCur
101267 && (pTerm->prereqRight & notReady)==0
101268 && pTerm->u.leftColumn==iColumn
101269 && (pTerm->eOperator & op)!=0
101270 ){
101271 if( pIdx && pTerm->eOperator!=WO_ISNULL ){
101272 Expr *pX = pTerm->pExpr;
101273 CollSeq *pColl;
101274 char idxaff;
101275 int j;
101276 Parse *pParse = pWC->pParse;
101277
101278 idxaff = pIdx->pTable->aCol[iColumn].affinity;
101279 if( !sqlite3IndexAffinityOk(pX, idxaff) ) continue;
101280
101281 /* Figure out the collation sequence required from an index for
101282 ** it to be useful for optimising expression pX. Store this
101283 ** value in variable pColl.
101284 */
101285 assert(pX->pLeft);
101286 pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
101287 assert(pColl || pParse->nErr);
101288
101289 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
101290 if( NEVER(j>=pIdx->nColumn) ) return 0;
101291 }
101292 if( pColl && sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
101293 }
101294 return pTerm;
101295 }
101296 }
101297 }
101298 return 0;
101299 }
101300
@@ -101029,11 +101367,11 @@
101367 int iCol = pRight->iColumn;
101368 pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
101369 if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
101370 z = (char *)sqlite3_value_text(pVal);
101371 }
101372 sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); /* IMP: R-31526-56213 */
101373 assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
101374 }else if( op==TK_STRING ){
101375 z = pRight->u.zToken;
101376 }
101377 if( z ){
@@ -101047,11 +101385,11 @@
101385 pPrefix = sqlite3Expr(db, TK_STRING, z);
101386 if( pPrefix ) pPrefix->u.zToken[cnt] = 0;
101387 *ppPrefix = pPrefix;
101388 if( op==TK_VARIABLE ){
101389 Vdbe *v = pParse->pVdbe;
101390 sqlite3VdbeSetVarmask(v, pRight->iColumn); /* IMP: R-31526-56213 */
101391 if( *pisComplete && pRight->u.zToken[1] ){
101392 /* If the rhs of the LIKE expression is a variable, and the current
101393 ** value of the variable means there is no need to invoke the LIKE
101394 ** function, then no OP_Variable will be added to the program.
101395 ** This causes problems for the sqlite3_bind_parameter_name()
@@ -101216,11 +101554,11 @@
101554 assert( pExpr->op==TK_OR );
101555 pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo));
101556 if( pOrInfo==0 ) return;
101557 pTerm->wtFlags |= TERM_ORINFO;
101558 pOrWc = &pOrInfo->wc;
101559 whereClauseInit(pOrWc, pWC->pParse, pMaskSet, pWC->wctrlFlags);
101560 whereSplit(pOrWc, pExpr, TK_OR);
101561 exprAnalyzeAll(pSrc, pOrWc);
101562 if( db->mallocFailed ) return;
101563 assert( pOrWc->nTerm>=2 );
101564
@@ -101243,13 +101581,14 @@
101581 Bitmask b = 0;
101582 pOrTerm->u.pAndInfo = pAndInfo;
101583 pOrTerm->wtFlags |= TERM_ANDINFO;
101584 pOrTerm->eOperator = WO_AND;
101585 pAndWC = &pAndInfo->wc;
101586 whereClauseInit(pAndWC, pWC->pParse, pMaskSet, pWC->wctrlFlags);
101587 whereSplit(pAndWC, pOrTerm->pExpr, TK_AND);
101588 exprAnalyzeAll(pSrc, pAndWC);
101589 pAndWC->pOuter = pWC;
101590 testcase( db->mallocFailed );
101591 if( !db->mallocFailed ){
101592 for(j=0, pAndTerm=pAndWC->a; j<pAndWC->nTerm; j++, pAndTerm++){
101593 assert( pAndTerm->pExpr );
101594 if( allowedOp(pAndTerm->pExpr->op) ){
@@ -101679,12 +102018,12 @@
102018 pNewTerm->prereqAll = pTerm->prereqAll;
102019 }
102020 }
102021 #endif /* SQLITE_OMIT_VIRTUALTABLE */
102022
102023 #ifdef SQLITE_ENABLE_STAT3
102024 /* When sqlite_stat3 histogram data is available an operator of the
102025 ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
102026 ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
102027 ** virtual term of that form.
102028 **
102029 ** Note that the virtual term must be tagged with TERM_VNULL. This
@@ -101718,11 +102057,11 @@
102057 pTerm->nChild = 1;
102058 pTerm->wtFlags |= TERM_COPIED;
102059 pNewTerm->prereqAll = pTerm->prereqAll;
102060 }
102061 }
102062 #endif /* SQLITE_ENABLE_STAT */
102063
102064 /* Prevent ON clause terms of a LEFT JOIN from being used to drive
102065 ** an index for tables to the left of the join.
102066 */
102067 pTerm->prereqRight |= extraRight;
@@ -102140,14 +102479,17 @@
102479 const int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */
102480 const Bitmask maskSrc = getMask(pWC->pMaskSet, iCur); /* Bitmask for pSrc */
102481 WhereTerm * const pWCEnd = &pWC->a[pWC->nTerm]; /* End of pWC->a[] */
102482 WhereTerm *pTerm; /* A single term of the WHERE clause */
102483
102484 /* The OR-clause optimization is disallowed if the INDEXED BY or
102485 ** NOT INDEXED clauses are used or if the WHERE_AND_ONLY bit is set. */
102486 if( pSrc->notIndexed || pSrc->pIndex!=0 ){
102487 return;
102488 }
102489 if( pWC->wctrlFlags & WHERE_AND_ONLY ){
102490 return;
102491 }
102492
102493 /* Search the WHERE clause terms for a usable WO_OR term. */
102494 for(pTerm=pWC->a; pTerm<pWCEnd; pTerm++){
102495 if( pTerm->eOperator==WO_OR
@@ -102172,12 +102514,14 @@
102514 bestIndex(pParse, pAndWC, pSrc, notReady, notValid, 0, &sTermCost);
102515 }else if( pOrTerm->leftCursor==iCur ){
102516 WhereClause tempWC;
102517 tempWC.pParse = pWC->pParse;
102518 tempWC.pMaskSet = pWC->pMaskSet;
102519 tempWC.pOuter = pWC;
102520 tempWC.op = TK_AND;
102521 tempWC.a = pOrTerm;
102522 tempWC.wctrlFlags = 0;
102523 tempWC.nTerm = 1;
102524 bestIndex(pParse, &tempWC, pSrc, notReady, notValid, 0, &sTermCost);
102525 }else{
102526 continue;
102527 }
@@ -102766,71 +103110,89 @@
103110 */
103111 bestOrClauseIndex(pParse, pWC, pSrc, notReady, notValid, pOrderBy, pCost);
103112 }
103113 #endif /* SQLITE_OMIT_VIRTUALTABLE */
103114
103115 #ifdef SQLITE_ENABLE_STAT3
103116 /*
103117 ** Estimate the location of a particular key among all keys in an
103118 ** index. Store the results in aStat as follows:
103119 **
103120 ** aStat[0] Est. number of rows less than pVal
103121 ** aStat[1] Est. number of rows equal to pVal
103122 **
103123 ** Return SQLITE_OK on success.
103124 */
103125 static int whereKeyStats(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103126 Parse *pParse, /* Database connection */
103127 Index *pIdx, /* Index to consider domain of */
103128 sqlite3_value *pVal, /* Value to consider */
103129 int roundUp, /* Round up if true. Round down if false */
103130 tRowcnt *aStat /* OUT: stats written here */
103131 ){
103132 tRowcnt n;
103133 IndexSample *aSample;
103134 int i, eType;
103135 int isEq = 0;
103136 i64 v;
103137 double r, rS;
103138
103139 assert( roundUp==0 || roundUp==1 );
103140 assert( pIdx->nSample>0 );
103141 if( pVal==0 ) return SQLITE_ERROR;
103142 n = pIdx->aiRowEst[0];
103143 aSample = pIdx->aSample;
103144 eType = sqlite3_value_type(pVal);
103145
103146 if( eType==SQLITE_INTEGER ){
103147 v = sqlite3_value_int64(pVal);
103148 r = (i64)v;
103149 for(i=0; i<pIdx->nSample; i++){
103150 if( aSample[i].eType==SQLITE_NULL ) continue;
103151 if( aSample[i].eType>=SQLITE_TEXT ) break;
103152 if( aSample[i].eType==SQLITE_INTEGER ){
103153 if( aSample[i].u.i>=v ){
103154 isEq = aSample[i].u.i==v;
103155 break;
103156 }
103157 }else{
103158 assert( aSample[i].eType==SQLITE_FLOAT );
103159 if( aSample[i].u.r>=r ){
103160 isEq = aSample[i].u.r==r;
103161 break;
103162 }
103163 }
103164 }
103165 }else if( eType==SQLITE_FLOAT ){
103166 r = sqlite3_value_double(pVal);
103167 for(i=0; i<pIdx->nSample; i++){
103168 if( aSample[i].eType==SQLITE_NULL ) continue;
103169 if( aSample[i].eType>=SQLITE_TEXT ) break;
103170 if( aSample[i].eType==SQLITE_FLOAT ){
103171 rS = aSample[i].u.r;
103172 }else{
103173 rS = aSample[i].u.i;
103174 }
103175 if( rS>=r ){
103176 isEq = rS==r;
103177 break;
103178 }
103179 }
103180 }else if( eType==SQLITE_NULL ){
103181 i = 0;
103182 if( aSample[0].eType==SQLITE_NULL ) isEq = 1;
103183 }else{
103184 assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB );
103185 for(i=0; i<pIdx->nSample; i++){
103186 if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){
103187 break;
103188 }
103189 }
103190 if( i<pIdx->nSample ){
103191 sqlite3 *db = pParse->db;
103192 CollSeq *pColl;
103193 const u8 *z;
 
 
 
 
 
103194 if( eType==SQLITE_BLOB ){
103195 z = (const u8 *)sqlite3_value_blob(pVal);
103196 pColl = db->pDfltColl;
103197 assert( pColl->enc==SQLITE_UTF8 );
103198 }else{
@@ -102845,16 +103207,16 @@
103207 return SQLITE_NOMEM;
103208 }
103209 assert( z && pColl && pColl->xCmp );
103210 }
103211 n = sqlite3ValueBytes(pVal, pColl->enc);
103212
103213 for(; i<pIdx->nSample; i++){
103214 int c;
103215 int eSampletype = aSample[i].eType;
103216 if( eSampletype<eType ) continue;
103217 if( eSampletype!=eType ) break;
103218 #ifndef SQLITE_OMIT_UTF16
103219 if( pColl->enc!=SQLITE_UTF8 ){
103220 int nSample;
103221 char *zSample = sqlite3Utf8to16(
103222 db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample
@@ -102868,20 +103230,51 @@
103230 }else
103231 #endif
103232 {
103233 c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z);
103234 }
103235 if( c>=0 ){
103236 if( c==0 ) isEq = 1;
103237 break;
103238 }
103239 }
103240 }
103241 }
103242
103243 /* At this point, aSample[i] is the first sample that is greater than
103244 ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less
103245 ** than pVal. If aSample[i]==pVal, then isEq==1.
103246 */
103247 if( isEq ){
103248 assert( i<pIdx->nSample );
103249 aStat[0] = aSample[i].nLt;
103250 aStat[1] = aSample[i].nEq;
103251 }else{
103252 tRowcnt iLower, iUpper, iGap;
103253 if( i==0 ){
103254 iLower = 0;
103255 iUpper = aSample[0].nLt;
103256 }else{
103257 iUpper = i>=pIdx->nSample ? n : aSample[i].nLt;
103258 iLower = aSample[i-1].nEq + aSample[i-1].nLt;
103259 }
103260 aStat[1] = pIdx->avgEq;
103261 if( iLower>=iUpper ){
103262 iGap = 0;
103263 }else{
103264 iGap = iUpper - iLower;
103265 }
103266 if( roundUp ){
103267 iGap = (iGap*2)/3;
103268 }else{
103269 iGap = iGap/3;
103270 }
103271 aStat[0] = iLower + iGap;
103272 }
103273 return SQLITE_OK;
103274 }
103275 #endif /* SQLITE_ENABLE_STAT3 */
103276
103277 /*
103278 ** If expression pExpr represents a literal value, set *pp to point to
103279 ** an sqlite3_value structure containing the same value, with affinity
103280 ** aff applied to it, before returning. It is the responsibility of the
@@ -102895,11 +103288,11 @@
103288 **
103289 ** If neither of the above apply, set *pp to NULL.
103290 **
103291 ** If an error occurs, return an error code. Otherwise, SQLITE_OK.
103292 */
103293 #ifdef SQLITE_ENABLE_STAT3
103294 static int valueFromExpr(
103295 Parse *pParse,
103296 Expr *pExpr,
103297 u8 aff,
103298 sqlite3_value **pp
@@ -102906,11 +103299,11 @@
103299 ){
103300 if( pExpr->op==TK_VARIABLE
103301 || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
103302 ){
103303 int iVar = pExpr->iColumn;
103304 sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); /* IMP: R-31526-56213 */
103305 *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
103306 return SQLITE_OK;
103307 }
103308 return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
103309 }
@@ -102943,106 +103336,92 @@
103336 **
103337 ** ... FROM t1 WHERE a > ? AND a < ? ...
103338 **
103339 ** then nEq should be passed 0.
103340 **
103341 ** The returned value is an integer divisor to reduce the estimated
103342 ** search space. A return value of 1 means that range constraints are
103343 ** no help at all. A return value of 2 means range constraints are
103344 ** expected to reduce the search space by half. And so forth...
 
 
103345 **
103346 ** In the absence of sqlite_stat3 ANALYZE data, each range inequality
103347 ** reduces the search space by a factor of 4. Hence a single constraint (x>?)
103348 ** results in a return of 4 and a range constraint (x>? AND x<?) results
103349 ** in a return of 16.
103350 */
103351 static int whereRangeScanEst(
103352 Parse *pParse, /* Parsing & code generating context */
103353 Index *p, /* The index containing the range-compared column; "x" */
103354 int nEq, /* index into p->aCol[] of the range-compared column */
103355 WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
103356 WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
103357 double *pRangeDiv /* OUT: Reduce search space by this divisor */
103358 ){
103359 int rc = SQLITE_OK;
103360
103361 #ifdef SQLITE_ENABLE_STAT3
103362
103363 if( nEq==0 && p->nSample ){
103364 sqlite3_value *pRangeVal;
103365 tRowcnt iLower = 0;
103366 tRowcnt iUpper = p->aiRowEst[0];
103367 tRowcnt a[2];
 
 
 
103368 u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
103369
103370 if( pLower ){
103371 Expr *pExpr = pLower->pExpr->pRight;
103372 rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
103373 assert( pLower->eOperator==WO_GT || pLower->eOperator==WO_GE );
103374 if( rc==SQLITE_OK
103375 && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK
103376 ){
103377 iLower = a[0];
103378 if( pLower->eOperator==WO_GT ) iLower += a[1];
103379 }
103380 sqlite3ValueFree(pRangeVal);
103381 }
103382 if( rc==SQLITE_OK && pUpper ){
103383 Expr *pExpr = pUpper->pExpr->pRight;
103384 rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal);
103385 assert( pUpper->eOperator==WO_LT || pUpper->eOperator==WO_LE );
103386 if( rc==SQLITE_OK
103387 && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK
103388 ){
103389 iUpper = a[0];
103390 if( pUpper->eOperator==WO_LE ) iUpper += a[1];
103391 }
103392 sqlite3ValueFree(pRangeVal);
103393 }
103394 if( rc==SQLITE_OK ){
103395 if( iUpper<=iLower ){
103396 *pRangeDiv = (double)p->aiRowEst[0];
103397 }else{
103398 *pRangeDiv = (double)p->aiRowEst[0]/(double)(iUpper - iLower);
103399 }
103400 WHERETRACE(("range scan regions: %u..%u div=%g\n",
103401 (u32)iLower, (u32)iUpper, *pRangeDiv));
103402 return SQLITE_OK;
103403 }
103404 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103405 #else
103406 UNUSED_PARAMETER(pParse);
103407 UNUSED_PARAMETER(p);
103408 UNUSED_PARAMETER(nEq);
103409 #endif
103410 assert( pLower || pUpper );
103411 *pRangeDiv = (double)1;
103412 if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ) *pRangeDiv *= (double)4;
103413 if( pUpper ) *pRangeDiv *= (double)4;
103414 return rc;
103415 }
103416
103417 #ifdef SQLITE_ENABLE_STAT3
103418 /*
103419 ** Estimate the number of rows that will be returned based on
103420 ** an equality constraint x=VALUE and where that VALUE occurs in
103421 ** the histogram data. This only works when x is the left-most
103422 ** column of an index and sqlite_stat3 histogram data is available
103423 ** for that index. When pExpr==NULL that means the constraint is
103424 ** "x IS NULL" instead of "x=VALUE".
103425 **
103426 ** Write the estimated row count into *pnRow and return SQLITE_OK.
103427 ** If unable to make an estimate, leave *pnRow unchanged and return
@@ -103058,44 +103437,36 @@
103437 Index *p, /* The index whose left-most column is pTerm */
103438 Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */
103439 double *pnRow /* Write the revised row estimate here */
103440 ){
103441 sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */
 
103442 u8 aff; /* Column affinity */
103443 int rc; /* Subfunction return code */
103444 tRowcnt a[2]; /* Statistics */
103445
103446 assert( p->aSample!=0 );
103447 assert( p->nSample>0 );
103448 aff = p->pTable->aCol[p->aiColumn[0]].affinity;
103449 if( pExpr ){
103450 rc = valueFromExpr(pParse, pExpr, aff, &pRhs);
103451 if( rc ) goto whereEqualScanEst_cancel;
103452 }else{
103453 pRhs = sqlite3ValueNew(pParse->db);
103454 }
103455 if( pRhs==0 ) return SQLITE_NOTFOUND;
103456 rc = whereKeyStats(pParse, p, pRhs, 0, a);
103457 if( rc==SQLITE_OK ){
103458 WHERETRACE(("equality scan regions: %d\n", (int)a[1]));
103459 *pnRow = a[1];
103460 }
 
 
 
 
 
 
 
 
103461 whereEqualScanEst_cancel:
103462 sqlite3ValueFree(pRhs);
103463 return rc;
103464 }
103465 #endif /* defined(SQLITE_ENABLE_STAT3) */
103466
103467 #ifdef SQLITE_ENABLE_STAT3
103468 /*
103469 ** Estimate the number of rows that will be returned based on
103470 ** an IN constraint where the right-hand side of the IN operator
103471 ** is a list of values. Example:
103472 **
@@ -103114,64 +103485,29 @@
103485 Parse *pParse, /* Parsing & code generating context */
103486 Index *p, /* The index whose left-most column is pTerm */
103487 ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */
103488 double *pnRow /* Write the revised row estimate here */
103489 ){
103490 int rc = SQLITE_OK; /* Subfunction return code */
103491 double nEst; /* Number of rows for a single term */
103492 double nRowEst = (double)0; /* New estimate of the number of rows */
103493 int i; /* Loop counter */
 
 
 
 
 
 
 
103494
103495 assert( p->aSample!=0 );
103496 for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){
103497 nEst = p->aiRowEst[0];
103498 rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst);
103499 nRowEst += nEst;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103500 }
103501 if( rc==SQLITE_OK ){
 
 
 
 
 
 
 
 
 
103502 if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0];
103503 *pnRow = nRowEst;
103504 WHERETRACE(("IN row estimate: est=%g\n", nRowEst));
 
103505 }
 
103506 return rc;
103507 }
103508 #endif /* defined(SQLITE_ENABLE_STAT3) */
103509
103510
103511 /*
103512 ** Find the best query plan for accessing a particular table. Write the
103513 ** best query plan and its cost into the WhereCost object supplied as the
@@ -103214,11 +103550,11 @@
103550 Index *pProbe; /* An index we are evaluating */
103551 Index *pIdx; /* Copy of pProbe, or zero for IPK index */
103552 int eqTermMask; /* Current mask of valid equality operators */
103553 int idxEqTermMask; /* Index mask of valid equality operators */
103554 Index sPk; /* A fake index object for the primary key */
103555 tRowcnt aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */
103556 int aiColumnPk = -1; /* The aColumn[] value for the sPk index */
103557 int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */
103558
103559 /* Initialize the cost to a worst-case value */
103560 memset(pCost, 0, sizeof(*pCost));
@@ -103269,14 +103605,14 @@
103605 }
103606
103607 /* Loop over all indices looking for the best one to use
103608 */
103609 for(; pProbe; pIdx=pProbe=pProbe->pNext){
103610 const tRowcnt * const aiRowEst = pProbe->aiRowEst;
103611 double cost; /* Cost of using pProbe */
103612 double nRow; /* Estimated number of rows in result set */
103613 double log10N = (double)1; /* base-10 logarithm of nRow (inexact) */
103614 int rev; /* True to scan in reverse order */
103615 int wsFlags = 0;
103616 Bitmask used = 0;
103617
103618 /* The following variables are populated based on the properties of
@@ -103312,18 +103648,16 @@
103648 ** Set to true if there was at least one "x IN (SELECT ...)" term used
103649 ** in determining the value of nInMul. Note that the RHS of the
103650 ** IN operator must be a SELECT, not a value list, for this variable
103651 ** to be true.
103652 **
103653 ** rangeDiv:
103654 ** An estimate of a divisor by which to reduce the search space due
103655 ** to inequality constraints. In the absence of sqlite_stat3 ANALYZE
103656 ** data, a single inequality reduces the search space to 1/4rd its
103657 ** original size (rangeDiv==4). Two inequalities reduce the search
103658 ** space to 1/16th of its original size (rangeDiv==16).
 
 
103659 **
103660 ** bSort:
103661 ** Boolean. True if there is an ORDER BY clause that will require an
103662 ** external sort (i.e. scanning the index being evaluated will not
103663 ** correctly order records).
@@ -103344,26 +103678,27 @@
103678 ** SELECT a, b, c FROM tbl WHERE a = 1;
103679 */
103680 int nEq; /* Number of == or IN terms matching index */
103681 int bInEst = 0; /* True if "x IN (SELECT...)" seen */
103682 int nInMul = 1; /* Number of distinct equalities to lookup */
103683 double rangeDiv = (double)1; /* Estimated reduction in search space */
103684 int nBound = 0; /* Number of range constraints seen */
103685 int bSort = !!pOrderBy; /* True if external sort required */
103686 int bDist = !!pDistinct; /* True if index cannot help with DISTINCT */
103687 int bLookup = 0; /* True if not a covering index */
103688 WhereTerm *pTerm; /* A single term of the WHERE clause */
103689 #ifdef SQLITE_ENABLE_STAT3
103690 WhereTerm *pFirstTerm = 0; /* First term matching the index */
103691 #endif
103692
103693 /* Determine the values of nEq and nInMul */
103694 for(nEq=0; nEq<pProbe->nColumn; nEq++){
103695 int j = pProbe->aiColumn[nEq];
103696 pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx);
103697 if( pTerm==0 ) break;
103698 wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ);
103699 testcase( pTerm->pWC!=pWC );
103700 if( pTerm->eOperator & WO_IN ){
103701 Expr *pExpr = pTerm->pExpr;
103702 wsFlags |= WHERE_COLUMN_IN;
103703 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
103704 /* "x IN (SELECT ...)": Assume the SELECT returns 25 rows */
@@ -103374,32 +103709,34 @@
103709 nInMul *= pExpr->x.pList->nExpr;
103710 }
103711 }else if( pTerm->eOperator & WO_ISNULL ){
103712 wsFlags |= WHERE_COLUMN_NULL;
103713 }
103714 #ifdef SQLITE_ENABLE_STAT3
103715 if( nEq==0 && pProbe->aSample ) pFirstTerm = pTerm;
103716 #endif
103717 used |= pTerm->prereqRight;
103718 }
103719
103720 /* Determine the value of rangeDiv */
103721 if( nEq<pProbe->nColumn && pProbe->bUnordered==0 ){
103722 int j = pProbe->aiColumn[nEq];
103723 if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){
103724 WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx);
103725 WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx);
103726 whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &rangeDiv);
103727 if( pTop ){
103728 nBound = 1;
103729 wsFlags |= WHERE_TOP_LIMIT;
103730 used |= pTop->prereqRight;
103731 testcase( pTop->pWC!=pWC );
103732 }
103733 if( pBtm ){
103734 nBound++;
103735 wsFlags |= WHERE_BTM_LIMIT;
103736 used |= pBtm->prereqRight;
103737 testcase( pBtm->pWC!=pWC );
103738 }
103739 wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE);
103740 }
103741 }else if( pProbe->onError!=OE_None ){
103742 testcase( wsFlags & WHERE_COLUMN_IN );
@@ -103458,32 +103795,34 @@
103795 if( bInEst && nRow*2>aiRowEst[0] ){
103796 nRow = aiRowEst[0]/2;
103797 nInMul = (int)(nRow / aiRowEst[nEq]);
103798 }
103799
103800 #ifdef SQLITE_ENABLE_STAT3
103801 /* If the constraint is of the form x=VALUE or x IN (E1,E2,...)
103802 ** and we do not think that values of x are unique and if histogram
103803 ** data is available for column x, then it might be possible
103804 ** to get a better estimate on the number of rows based on
103805 ** VALUE and how common that value is according to the histogram.
103806 */
103807 if( nRow>(double)1 && nEq==1 && pFirstTerm!=0 && aiRowEst[1]>1 ){
103808 assert( (pFirstTerm->eOperator & (WO_EQ|WO_ISNULL|WO_IN))!=0 );
103809 if( pFirstTerm->eOperator & (WO_EQ|WO_ISNULL) ){
103810 testcase( pFirstTerm->eOperator==WO_EQ );
103811 testcase( pFirstTerm->eOperator==WO_ISNULL );
103812 whereEqualScanEst(pParse, pProbe, pFirstTerm->pExpr->pRight, &nRow);
103813 }else if( bInEst==0 ){
103814 assert( pFirstTerm->eOperator==WO_IN );
103815 whereInScanEst(pParse, pProbe, pFirstTerm->pExpr->x.pList, &nRow);
103816 }
103817 }
103818 #endif /* SQLITE_ENABLE_STAT3 */
103819
103820 /* Adjust the number of output rows and downward to reflect rows
103821 ** that are excluded by range constraints.
103822 */
103823 nRow = nRow/rangeDiv;
103824 if( nRow<1 ) nRow = 1;
103825
103826 /* Experiments run on real SQLite databases show that the time needed
103827 ** to do a binary search to locate a row in a table or index is roughly
103828 ** log10(N) times the time to move from one row to the next row within
@@ -103608,14 +103947,14 @@
103947 if( nRow<2 ) nRow = 2;
103948 }
103949
103950
103951 WHERETRACE((
103952 "%s(%s): nEq=%d nInMul=%d rangeDiv=%d bSort=%d bLookup=%d wsFlags=0x%x\n"
103953 " notReady=0x%llx log10N=%.1f nRow=%.1f cost=%.1f used=0x%llx\n",
103954 pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"),
103955 nEq, nInMul, (int)rangeDiv, bSort, bLookup, wsFlags,
103956 notReady, log10N, nRow, cost, used
103957 ));
103958
103959 /* If this index is the best we have seen so far, then record this
103960 ** index and its cost in the pCost structure.
@@ -104115,11 +104454,12 @@
104454 */
104455 static Bitmask codeOneLoopStart(
104456 WhereInfo *pWInfo, /* Complete information about the WHERE clause */
104457 int iLevel, /* Which level of pWInfo->a[] should be coded */
104458 u16 wctrlFlags, /* One of the WHERE_* flags defined in sqliteInt.h */
104459 Bitmask notReady, /* Which tables are currently available */
104460 Expr *pWhere /* Complete WHERE clause */
104461 ){
104462 int j, k; /* Loop counters */
104463 int iCur; /* The VDBE cursor for the table */
104464 int addrNxt; /* Where to jump to continue with the next IN case */
104465 int omitTable; /* True if we use the index only */
@@ -104597,11 +104937,12 @@
104937 int regRowset = 0; /* Register for RowSet object */
104938 int regRowid = 0; /* Register holding rowid */
104939 int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */
104940 int iRetInit; /* Address of regReturn init */
104941 int untestedTerms = 0; /* Some terms not completely tested */
104942 int ii; /* Loop counter */
104943 Expr *pAndExpr = 0; /* An ".. AND (...)" expression */
104944
104945 pTerm = pLevel->plan.u.pTerm;
104946 assert( pTerm!=0 );
104947 assert( pTerm->eOperator==WO_OR );
104948 assert( (pTerm->wtFlags & TERM_ORINFO)!=0 );
@@ -104646,18 +104987,33 @@
104987 regRowset = ++pParse->nMem;
104988 regRowid = ++pParse->nMem;
104989 sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
104990 }
104991 iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
104992
104993 /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y
104994 ** Then for every term xN, evaluate as the subexpression: xN AND z
104995 ** That way, terms in y that are factored into the disjunction will
104996 ** be picked up by the recursive calls to sqlite3WhereBegin() below.
104997 */
104998 if( pWC->nTerm>1 ){
104999 pAndExpr = sqlite3ExprAlloc(pParse->db, TK_AND, 0, 0);
105000 pAndExpr->pRight = pWhere;
105001 }
105002
105003 for(ii=0; ii<pOrWc->nTerm; ii++){
105004 WhereTerm *pOrTerm = &pOrWc->a[ii];
105005 if( pOrTerm->leftCursor==iCur || pOrTerm->eOperator==WO_AND ){
105006 WhereInfo *pSubWInfo; /* Info for single OR-term scan */
105007 Expr *pOrExpr = pOrTerm->pExpr;
105008 if( pAndExpr ){
105009 pAndExpr->pLeft = pOrExpr;
105010 pOrExpr = pAndExpr;
105011 }
105012 /* Loop through table entries that match term pOrTerm. */
105013 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
105014 WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
105015 WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY);
105016 if( pSubWInfo ){
105017 explainOneScan(
105018 pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
105019 );
@@ -104681,10 +105037,11 @@
105037 /* Finish the loop through table entries that match term pOrTerm. */
105038 sqlite3WhereEnd(pSubWInfo);
105039 }
105040 }
105041 }
105042 sqlite3DbFree(pParse->db, pAndExpr);
105043 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
105044 sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
105045 sqlite3VdbeResolveLabel(v, iLoopBody);
105046
105047 if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
@@ -104962,11 +105319,11 @@
105319
105320 /* Split the WHERE clause into separate subexpressions where each
105321 ** subexpression is separated by an AND operator.
105322 */
105323 initMaskSet(pMaskSet);
105324 whereClauseInit(pWC, pParse, pMaskSet, wctrlFlags);
105325 sqlite3ExprCodeConstants(pParse, pWhere);
105326 whereSplit(pWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
105327
105328 /* Special case: a WHERE clause that is constant. Evaluate the
105329 ** expression and either jump over all of the code or fall thru.
@@ -105201,11 +105558,12 @@
105558 assert( bestJ>=0 );
105559 assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) );
105560 WHERETRACE(("*** Optimizer selects table %d for loop %d"
105561 " with cost=%g and nRow=%g\n",
105562 bestJ, pLevel-pWInfo->a, bestPlan.rCost, bestPlan.plan.nRow));
105563 /* The ALWAYS() that follows was added to hush up clang scan-build */
105564 if( (bestPlan.plan.wsFlags & WHERE_ORDERBY)!=0 && ALWAYS(ppOrderBy) ){
105565 *ppOrderBy = 0;
105566 }
105567 if( (bestPlan.plan.wsFlags & WHERE_DISTINCT)!=0 ){
105568 assert( pWInfo->eDistinct==0 );
105569 pWInfo->eDistinct = WHERE_DISTINCT_ORDERED;
@@ -105290,11 +105648,11 @@
105648 int iCur = pTabItem->iCursor;
105649 sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB);
105650 }else
105651 #endif
105652 if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0
105653 && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 ){
105654 int op = pWInfo->okOnePass ? OP_OpenWrite : OP_OpenRead;
105655 sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op);
105656 testcase( pTab->nCol==BMS-1 );
105657 testcase( pTab->nCol==BMS );
105658 if( !pWInfo->okOnePass && pTab->nCol<BMS ){
@@ -105335,11 +105693,11 @@
105693 */
105694 notReady = ~(Bitmask)0;
105695 for(i=0; i<nTabList; i++){
105696 pLevel = &pWInfo->a[i];
105697 explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
105698 notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady, pWhere);
105699 pWInfo->iContinue = pLevel->addrCont;
105700 }
105701
105702 #ifdef SQLITE_TEST /* For testing and debugging use only */
105703 /* Record in the query plan information about the current table
@@ -105470,11 +105828,11 @@
105828 struct SrcList_item *pTabItem = &pTabList->a[pLevel->iFrom];
105829 Table *pTab = pTabItem->pTab;
105830 assert( pTab!=0 );
105831 if( (pTab->tabFlags & TF_Ephemeral)==0
105832 && pTab->pSelect==0
105833 && (pWInfo->wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0
105834 ){
105835 int ws = pLevel->plan.wsFlags;
105836 if( !pWInfo->okOnePass && (ws & WHERE_IDX_ONLY)==0 ){
105837 sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor);
105838 }
@@ -108817,11 +109175,13 @@
109175 sqlite3ParserTOKENTYPE yyminor /* The value for the token */
109176 sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */
109177 ){
109178 YYMINORTYPE yyminorunion;
109179 int yyact; /* The parser action. */
109180 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
109181 int yyendofinput; /* True if we are at the end of input */
109182 #endif
109183 #ifdef YYERRORSYMBOL
109184 int yyerrorhit = 0; /* True if yymajor has invoked an error */
109185 #endif
109186 yyParser *yypParser; /* The parser */
109187
@@ -108840,11 +109200,13 @@
109200 yypParser->yyerrcnt = -1;
109201 yypParser->yystack[0].stateno = 0;
109202 yypParser->yystack[0].major = 0;
109203 }
109204 yyminorunion.yy0 = yyminor;
109205 #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY)
109206 yyendofinput = (yymajor==0);
109207 #endif
109208 sqlite3ParserARG_STORE;
109209
109210 #ifndef NDEBUG
109211 if( yyTraceFILE ){
109212 fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
@@ -108852,11 +109214,10 @@
109214 #endif
109215
109216 do{
109217 yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
109218 if( yyact<YYNSTATE ){
 
109219 yy_shift(yypParser,yyact,yymajor,&yyminorunion);
109220 yypParser->yyerrcnt--;
109221 yymajor = YYNOCODE;
109222 }else if( yyact < YYNSTATE + YYNRULE ){
109223 yy_reduce(yypParser,yyact-YYNSTATE);
@@ -110244,11 +110605,11 @@
110605 **
110606 ** * Recursive calls to this routine from thread X return immediately
110607 ** without blocking.
110608 */
110609 SQLITE_API int sqlite3_initialize(void){
110610 MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */
110611 int rc; /* Result code */
110612
110613 #ifdef SQLITE_OMIT_WSD
110614 rc = sqlite3_wsd_init(4096, 24);
110615 if( rc!=SQLITE_OK ){
@@ -110278,11 +110639,11 @@
110639 ** This operation is protected by the STATIC_MASTER mutex. Note that
110640 ** MutexAlloc() is called for a static mutex prior to initializing the
110641 ** malloc subsystem - this implies that the allocation of a static
110642 ** mutex must not require support from the malloc subsystem.
110643 */
110644 MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); )
110645 sqlite3_mutex_enter(pMaster);
110646 sqlite3GlobalConfig.isMutexInit = 1;
110647 if( !sqlite3GlobalConfig.isMallocInit ){
110648 rc = sqlite3MallocInit();
110649 }
@@ -111352,17 +111713,17 @@
111713 sqlite3 *db,
111714 const char *zName,
111715 int nArg
111716 ){
111717 int nName = sqlite3Strlen30(zName);
111718 int rc = SQLITE_OK;
111719 sqlite3_mutex_enter(db->mutex);
111720 if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
111721 rc = sqlite3CreateFunc(db, zName, nArg, SQLITE_UTF8,
111722 0, sqlite3InvalidFunction, 0, 0, 0);
111723 }
111724 rc = sqlite3ApiExit(db, rc);
111725 sqlite3_mutex_leave(db->mutex);
111726 return rc;
111727 }
111728
111729 #ifndef SQLITE_OMIT_TRACE
@@ -112420,10 +112781,11 @@
112781 if( db ){
112782 assert( db->mutex!=0 || isThreadsafe==0 || sqlite3GlobalConfig.bFullMutex==0 );
112783 sqlite3_mutex_leave(db->mutex);
112784 }
112785 rc = sqlite3_errcode(db);
112786 assert( db!=0 || rc==SQLITE_NOMEM );
112787 if( rc==SQLITE_NOMEM ){
112788 sqlite3_close(db);
112789 db = 0;
112790 }else if( rc!=SQLITE_OK ){
112791 db->magic = SQLITE_MAGIC_SICK;
@@ -114148,10 +114510,17 @@
114510 #else
114511 # define TESTONLY(X)
114512 #endif
114513
114514 #endif /* SQLITE_AMALGAMATION */
114515
114516 #ifdef SQLITE_DEBUG
114517 SQLITE_PRIVATE int sqlite3Fts3Corrupt(void);
114518 # define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt()
114519 #else
114520 # define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB
114521 #endif
114522
114523 typedef struct Fts3Table Fts3Table;
114524 typedef struct Fts3Cursor Fts3Cursor;
114525 typedef struct Fts3Expr Fts3Expr;
114526 typedef struct Fts3Phrase Fts3Phrase;
@@ -114176,10 +114545,11 @@
114545 const char *zDb; /* logical database name */
114546 const char *zName; /* virtual table name */
114547 int nColumn; /* number of named columns in virtual table */
114548 char **azColumn; /* column names. malloced */
114549 sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */
114550 char *zContentTbl; /* content=xxx option, or NULL */
114551
114552 /* Precompiled statements used by the implementation. Each of these
114553 ** statements is run and reset within a single virtual table API call.
114554 */
114555 sqlite3_stmt *aStmt[27];
@@ -114216,11 +114586,11 @@
114586 } *aIndex;
114587 int nMaxPendingData; /* Max pending data before flush to disk */
114588 int nPendingData; /* Current bytes of pending data */
114589 sqlite_int64 iPrevDocid; /* Docid of most recently inserted document */
114590
114591 #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
114592 /* State variables used for validating that the transaction control
114593 ** methods of the virtual table are called at appropriate times. These
114594 ** values do not contribution to the FTS computation; they are used for
114595 ** verifying the SQLite core.
114596 */
@@ -114301,10 +114671,11 @@
114671 */
114672 struct Fts3PhraseToken {
114673 char *z; /* Text of the token */
114674 int n; /* Number of bytes in buffer z */
114675 int isPrefix; /* True if token ends with a "*" character */
114676 int bFirst; /* True if token must appear at position 0 */
114677
114678 /* Variables above this point are populated when the expression is
114679 ** parsed (by code in fts3_expr.c). Below this point the variables are
114680 ** used when evaluating the expression. */
114681 Fts3DeferredToken *pDeferred; /* Deferred token object for this token */
@@ -114419,10 +114790,11 @@
114790 #define FTS3_SEGMENT_REQUIRE_POS 0x00000001
114791 #define FTS3_SEGMENT_IGNORE_EMPTY 0x00000002
114792 #define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
114793 #define FTS3_SEGMENT_PREFIX 0x00000008
114794 #define FTS3_SEGMENT_SCAN 0x00000010
114795 #define FTS3_SEGMENT_FIRST 0x00000020
114796
114797 /* Type passed as 4th argument to SegmentReaderIterate() */
114798 struct Fts3SegFilter {
114799 const char *zTerm;
114800 int nTerm;
@@ -114458,12 +114830,12 @@
114830 SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
114831 SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *);
114832 SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64);
114833 SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
114834 SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
 
114835 SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
114836 SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
114837
114838 /* fts3_tokenizer.c */
114839 SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
114840 SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
114841 SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -114478,11 +114850,11 @@
114850 );
114851 SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
114852
114853 /* fts3_expr.c */
114854 SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *,
114855 char **, int, int, int, const char *, int, Fts3Expr **
114856 );
114857 SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *);
114858 #ifdef SQLITE_TEST
114859 SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
114860 SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db);
@@ -114649,11 +115021,11 @@
115021 char **pp,
115022 char *pStart,
115023 sqlite3_int64 *pVal
115024 ){
115025 sqlite3_int64 iVal;
115026 char *p;
115027
115028 /* Pointer p now points at the first byte past the varint we are
115029 ** interested in. So, unless the doclist is corrupt, the 0x80 bit is
115030 ** clear on character p[-1]. */
115031 for(p = (*pp)-2; p>=pStart && *p&0x80; p--);
@@ -114679,10 +115051,11 @@
115051 sqlite3_finalize(p->aStmt[i]);
115052 }
115053 sqlite3_free(p->zSegmentsTbl);
115054 sqlite3_free(p->zReadExprlist);
115055 sqlite3_free(p->zWriteExprlist);
115056 sqlite3_free(p->zContentTbl);
115057
115058 /* Invoke the tokenizer destructor to free the tokenizer. */
115059 p->pTokenizer->pModule->xDestroy(p->pTokenizer);
115060
115061 sqlite3_free(p);
@@ -114718,20 +115091,23 @@
115091
115092 /*
115093 ** The xDestroy() virtual table method.
115094 */
115095 static int fts3DestroyMethod(sqlite3_vtab *pVtab){
 
115096 Fts3Table *p = (Fts3Table *)pVtab;
115097 int rc = SQLITE_OK; /* Return code */
115098 const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */
115099 sqlite3 *db = p->db; /* Database handle */
115100
115101 /* Drop the shadow tables */
115102 if( p->zContentTbl==0 ){
115103 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_content'", zDb, p->zName);
115104 }
115105 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segments'", zDb,p->zName);
115106 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_segdir'", zDb, p->zName);
115107 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_docsize'", zDb, p->zName);
115108 fts3DbExec(&rc, db, "DROP TABLE IF EXISTS %Q.'%q_stat'", zDb, p->zName);
115109
115110 /* If everything has worked, invoke fts3DisconnectMethod() to free the
115111 ** memory associated with the Fts3Table structure and return SQLITE_OK.
115112 ** Otherwise, return an SQLite error code.
115113 */
@@ -114789,27 +115165,31 @@
115165 ** %_stat tables required by FTS4.
115166 */
115167 static int fts3CreateTables(Fts3Table *p){
115168 int rc = SQLITE_OK; /* Return code */
115169 int i; /* Iterator variable */
 
115170 sqlite3 *db = p->db; /* The database connection */
115171
115172 if( p->zContentTbl==0 ){
115173 char *zContentCols; /* Columns of %_content table */
115174
115175 /* Create a list of user columns for the content table */
115176 zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY");
115177 for(i=0; zContentCols && i<p->nColumn; i++){
115178 char *z = p->azColumn[i];
115179 zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z);
115180 }
115181 if( zContentCols==0 ) rc = SQLITE_NOMEM;
115182
115183 /* Create the content table */
115184 fts3DbExec(&rc, db,
115185 "CREATE TABLE %Q.'%q_content'(%s)",
115186 p->zDb, p->zName, zContentCols
115187 );
115188 sqlite3_free(zContentCols);
115189 }
115190
115191 /* Create other tables */
115192 fts3DbExec(&rc, db,
115193 "CREATE TABLE %Q.'%q_segments'(blockid INTEGER PRIMARY KEY, block BLOB);",
115194 p->zDb, p->zName
115195 );
@@ -114956,12 +115336,12 @@
115336 }
115337 return zRet;
115338 }
115339
115340 /*
115341 ** Return a list of comma separated SQL expressions and a FROM clause that
115342 ** could be used in a SELECT statement such as the following:
115343 **
115344 ** SELECT <list of expressions> FROM %_content AS x ...
115345 **
115346 ** to return the docid, followed by each column of text data in order
115347 ** from left to write. If parameter zFunc is not NULL, then instead of
@@ -114968,11 +115348,11 @@
115348 ** being returned directly each column of text data is passed to an SQL
115349 ** function named zFunc first. For example, if zFunc is "unzip" and the
115350 ** table has the three user-defined columns "a", "b", and "c", the following
115351 ** string is returned:
115352 **
115353 ** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x"
115354 **
115355 ** The pointer returned points to a buffer allocated by sqlite3_malloc(). It
115356 ** is the responsibility of the caller to eventually free it.
115357 **
115358 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and
@@ -114984,20 +115364,32 @@
115364 char *zRet = 0;
115365 char *zFree = 0;
115366 char *zFunction;
115367 int i;
115368
115369 if( p->zContentTbl==0 ){
115370 if( !zFunc ){
115371 zFunction = "";
115372 }else{
115373 zFree = zFunction = fts3QuoteId(zFunc);
115374 }
115375 fts3Appendf(pRc, &zRet, "docid");
115376 for(i=0; i<p->nColumn; i++){
115377 fts3Appendf(pRc, &zRet, ",%s(x.'c%d%q')", zFunction, i, p->azColumn[i]);
115378 }
115379 sqlite3_free(zFree);
115380 }else{
115381 fts3Appendf(pRc, &zRet, "rowid");
115382 for(i=0; i<p->nColumn; i++){
115383 fts3Appendf(pRc, &zRet, ", x.'%q'", p->azColumn[i]);
115384 }
115385 }
115386 fts3Appendf(pRc, &zRet, "FROM '%q'.'%q%s' AS x",
115387 p->zDb,
115388 (p->zContentTbl ? p->zContentTbl : p->zName),
115389 (p->zContentTbl ? "" : "_content")
115390 );
115391 return zRet;
115392 }
115393
115394 /*
115395 ** Return a list of N comma separated question marks, where N is the number
@@ -115050,11 +115442,11 @@
115442 ** the output value undefined. Otherwise SQLITE_OK is returned.
115443 **
115444 ** This function is used when parsing the "prefix=" FTS4 parameter.
115445 */
115446 static int fts3GobbleInt(const char **pp, int *pnOut){
115447 const char *p; /* Iterator pointer */
115448 int nInt = 0; /* Output value */
115449
115450 for(p=*pp; p[0]>='0' && p[0]<='9'; p++){
115451 nInt = nInt * 10 + (p[0] - '0');
115452 }
@@ -115116,10 +115508,95 @@
115508 }
115509 }
115510
115511 return SQLITE_OK;
115512 }
115513
115514 /*
115515 ** This function is called when initializing an FTS4 table that uses the
115516 ** content=xxx option. It determines the number of and names of the columns
115517 ** of the new FTS4 table.
115518 **
115519 ** The third argument passed to this function is the value passed to the
115520 ** config=xxx option (i.e. "xxx"). This function queries the database for
115521 ** a table of that name. If found, the output variables are populated
115522 ** as follows:
115523 **
115524 ** *pnCol: Set to the number of columns table xxx has,
115525 **
115526 ** *pnStr: Set to the total amount of space required to store a copy
115527 ** of each columns name, including the nul-terminator.
115528 **
115529 ** *pazCol: Set to point to an array of *pnCol strings. Each string is
115530 ** the name of the corresponding column in table xxx. The array
115531 ** and its contents are allocated using a single allocation. It
115532 ** is the responsibility of the caller to free this allocation
115533 ** by eventually passing the *pazCol value to sqlite3_free().
115534 **
115535 ** If the table cannot be found, an error code is returned and the output
115536 ** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is
115537 ** returned (and the output variables are undefined).
115538 */
115539 static int fts3ContentColumns(
115540 sqlite3 *db, /* Database handle */
115541 const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */
115542 const char *zTbl, /* Name of content table */
115543 const char ***pazCol, /* OUT: Malloc'd array of column names */
115544 int *pnCol, /* OUT: Size of array *pazCol */
115545 int *pnStr /* OUT: Bytes of string content */
115546 ){
115547 int rc = SQLITE_OK; /* Return code */
115548 char *zSql; /* "SELECT *" statement on zTbl */
115549 sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */
115550
115551 zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl);
115552 if( !zSql ){
115553 rc = SQLITE_NOMEM;
115554 }else{
115555 rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0);
115556 }
115557 sqlite3_free(zSql);
115558
115559 if( rc==SQLITE_OK ){
115560 const char **azCol; /* Output array */
115561 int nStr = 0; /* Size of all column names (incl. 0x00) */
115562 int nCol; /* Number of table columns */
115563 int i; /* Used to iterate through columns */
115564
115565 /* Loop through the returned columns. Set nStr to the number of bytes of
115566 ** space required to store a copy of each column name, including the
115567 ** nul-terminator byte. */
115568 nCol = sqlite3_column_count(pStmt);
115569 for(i=0; i<nCol; i++){
115570 const char *zCol = sqlite3_column_name(pStmt, i);
115571 nStr += strlen(zCol) + 1;
115572 }
115573
115574 /* Allocate and populate the array to return. */
115575 azCol = (const char **)sqlite3_malloc(sizeof(char *) * nCol + nStr);
115576 if( azCol==0 ){
115577 rc = SQLITE_NOMEM;
115578 }else{
115579 char *p = (char *)&azCol[nCol];
115580 for(i=0; i<nCol; i++){
115581 const char *zCol = sqlite3_column_name(pStmt, i);
115582 int n = strlen(zCol)+1;
115583 memcpy(p, zCol, n);
115584 azCol[i] = p;
115585 p += n;
115586 }
115587 }
115588 sqlite3_finalize(pStmt);
115589
115590 /* Set the output variables. */
115591 *pnCol = nCol;
115592 *pnStr = nStr;
115593 *pazCol = azCol;
115594 }
115595
115596 return rc;
115597 }
115598
115599 /*
115600 ** This function is the implementation of both the xConnect and xCreate
115601 ** methods of the FTS3 virtual table.
115602 **
@@ -115161,10 +115638,11 @@
115638 int bNoDocsize = 0; /* True to omit %_docsize table */
115639 int bDescIdx = 0; /* True to store descending indexes */
115640 char *zPrefix = 0; /* Prefix parameter value (or NULL) */
115641 char *zCompress = 0; /* compress=? parameter (or NULL) */
115642 char *zUncompress = 0; /* uncompress=? parameter (or NULL) */
115643 char *zContent = 0; /* content=? parameter (or NULL) */
115644
115645 assert( strlen(argv[0])==4 );
115646 assert( (sqlite3_strnicmp(argv[0], "fts4", 4)==0 && isFts4)
115647 || (sqlite3_strnicmp(argv[0], "fts3", 4)==0 && !isFts4)
115648 );
@@ -115204,17 +115682,17 @@
115682 /* Check if it is an FTS4 special argument. */
115683 else if( isFts4 && fts3IsSpecialColumn(z, &nKey, &zVal) ){
115684 struct Fts4Option {
115685 const char *zOpt;
115686 int nOpt;
 
115687 } aFts4Opt[] = {
115688 { "matchinfo", 9 }, /* 0 -> MATCHINFO */
115689 { "prefix", 6 }, /* 1 -> PREFIX */
115690 { "compress", 8 }, /* 2 -> COMPRESS */
115691 { "uncompress", 10 }, /* 3 -> UNCOMPRESS */
115692 { "order", 5 }, /* 4 -> ORDER */
115693 { "content", 7 } /* 5 -> CONTENT */
115694 };
115695
115696 int iOpt;
115697 if( !zVal ){
115698 rc = SQLITE_NOMEM;
@@ -115256,17 +115734,24 @@
115734 zVal = 0;
115735 break;
115736
115737 case 4: /* ORDER */
115738 if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3))
115739 && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4))
115740 ){
115741 *pzErr = sqlite3_mprintf("unrecognized order: %s", zVal);
115742 rc = SQLITE_ERROR;
115743 }
115744 bDescIdx = (zVal[0]=='d' || zVal[0]=='D');
115745 break;
115746
115747 default: /* CONTENT */
115748 assert( iOpt==5 );
115749 sqlite3_free(zUncompress);
115750 zContent = zVal;
115751 zVal = 0;
115752 break;
115753 }
115754 }
115755 sqlite3_free(zVal);
115756 }
115757 }
@@ -115275,10 +115760,30 @@
115760 else {
115761 nString += (int)(strlen(z) + 1);
115762 aCol[nCol++] = z;
115763 }
115764 }
115765
115766 /* If a content=xxx option was specified, the following:
115767 **
115768 ** 1. Ignore any compress= and uncompress= options.
115769 **
115770 ** 2. If no column names were specified as part of the CREATE VIRTUAL
115771 ** TABLE statement, use all columns from the content table.
115772 */
115773 if( rc==SQLITE_OK && zContent ){
115774 sqlite3_free(zCompress);
115775 sqlite3_free(zUncompress);
115776 zCompress = 0;
115777 zUncompress = 0;
115778 if( nCol==0 ){
115779 sqlite3_free((void*)aCol);
115780 aCol = 0;
115781 rc = fts3ContentColumns(db, argv[1], zContent, &aCol, &nCol, &nString);
115782 }
115783 assert( rc!=SQLITE_OK || nCol>0 );
115784 }
115785 if( rc!=SQLITE_OK ) goto fts3_init_out;
115786
115787 if( nCol==0 ){
115788 assert( nString==0 );
115789 aCol[0] = "content";
@@ -115319,10 +115824,12 @@
115824 p->pTokenizer = pTokenizer;
115825 p->nMaxPendingData = FTS3_MAX_PENDING_DATA;
115826 p->bHasDocsize = (isFts4 && bNoDocsize==0);
115827 p->bHasStat = isFts4;
115828 p->bDescIdx = bDescIdx;
115829 p->zContentTbl = zContent;
115830 zContent = 0;
115831 TESTONLY( p->inTransaction = -1 );
115832 TESTONLY( p->mxSavepoint = -1 );
115833
115834 p->aIndex = (struct Fts3Index *)&p->azColumn[nCol];
115835 memcpy(p->aIndex, aIndex, sizeof(struct Fts3Index) * nIndex);
@@ -115380,10 +115887,11 @@
115887 fts3_init_out:
115888 sqlite3_free(zPrefix);
115889 sqlite3_free(aIndex);
115890 sqlite3_free(zCompress);
115891 sqlite3_free(zUncompress);
115892 sqlite3_free(zContent);
115893 sqlite3_free((void *)aCol);
115894 if( rc!=SQLITE_OK ){
115895 if( p ){
115896 fts3DisconnectMethod((sqlite3_vtab *)p);
115897 }else if( pTokenizer ){
@@ -115530,40 +116038,69 @@
116038 sqlite3_free(pCsr->aMatchinfo);
116039 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
116040 sqlite3_free(pCsr);
116041 return SQLITE_OK;
116042 }
116043
116044 /*
116045 ** If pCsr->pStmt has not been prepared (i.e. if pCsr->pStmt==0), then
116046 ** compose and prepare an SQL statement of the form:
116047 **
116048 ** "SELECT <columns> FROM %_content WHERE rowid = ?"
116049 **
116050 ** (or the equivalent for a content=xxx table) and set pCsr->pStmt to
116051 ** it. If an error occurs, return an SQLite error code.
116052 **
116053 ** Otherwise, set *ppStmt to point to pCsr->pStmt and return SQLITE_OK.
116054 */
116055 static int fts3CursorSeekStmt(Fts3Cursor *pCsr, sqlite3_stmt **ppStmt){
116056 int rc = SQLITE_OK;
116057 if( pCsr->pStmt==0 ){
116058 Fts3Table *p = (Fts3Table *)pCsr->base.pVtab;
116059 char *zSql;
116060 zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist);
116061 if( !zSql ) return SQLITE_NOMEM;
116062 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
116063 sqlite3_free(zSql);
116064 }
116065 *ppStmt = pCsr->pStmt;
116066 return rc;
116067 }
116068
116069 /*
116070 ** Position the pCsr->pStmt statement so that it is on the row
116071 ** of the %_content table that contains the last match. Return
116072 ** SQLITE_OK on success.
116073 */
116074 static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){
116075 int rc = SQLITE_OK;
116076 if( pCsr->isRequireSeek ){
116077 sqlite3_stmt *pStmt = 0;
116078
116079 rc = fts3CursorSeekStmt(pCsr, &pStmt);
116080 if( rc==SQLITE_OK ){
116081 sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId);
116082 pCsr->isRequireSeek = 0;
116083 if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){
116084 return SQLITE_OK;
116085 }else{
116086 rc = sqlite3_reset(pCsr->pStmt);
116087 if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){
116088 /* If no row was found and no error has occured, then the %_content
116089 ** table is missing a row that is present in the full-text index.
116090 ** The data structures are corrupt. */
116091 rc = FTS_CORRUPT_VTAB;
116092 pCsr->isEof = 1;
116093 }
116094 }
116095 }
116096 }
116097
116098 if( rc!=SQLITE_OK && pContext ){
116099 sqlite3_result_error_code(pContext, rc);
116100 }
116101 return rc;
116102 }
116103
116104 /*
116105 ** This function is used to process a single interior node when searching
116106 ** a b-tree for a term or term prefix. The node data is passed to this
@@ -115609,11 +116146,11 @@
116146 ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details).
116147 */
116148 zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
116149 zCsr += sqlite3Fts3GetVarint(zCsr, &iChild);
116150 if( zCsr>zEnd ){
116151 return FTS_CORRUPT_VTAB;
116152 }
116153
116154 while( zCsr<zEnd && (piFirst || piLast) ){
116155 int cmp; /* memcmp() result */
116156 int nSuffix; /* Size of term suffix */
@@ -115627,11 +116164,11 @@
116164 }
116165 isFirstTerm = 0;
116166 zCsr += sqlite3Fts3GetVarint32(zCsr, &nSuffix);
116167
116168 if( nPrefix<0 || nSuffix<0 || &zCsr[nSuffix]>zEnd ){
116169 rc = FTS_CORRUPT_VTAB;
116170 goto finish_scan;
116171 }
116172 if( nPrefix+nSuffix>nAlloc ){
116173 char *zNew;
116174 nAlloc = (nPrefix+nSuffix) * 2;
@@ -115640,10 +116177,11 @@
116177 rc = SQLITE_NOMEM;
116178 goto finish_scan;
116179 }
116180 zBuffer = zNew;
116181 }
116182 assert( zBuffer );
116183 memcpy(&zBuffer[nPrefix], zCsr, nSuffix);
116184 nBuffer = nPrefix + nSuffix;
116185 zCsr += nSuffix;
116186
116187 /* Compare the term we are searching for with the term just loaded from
@@ -115998,20 +116536,20 @@
116536 int isSaveLeft, /* Save the left position */
116537 int isExact, /* If *pp1 is exactly nTokens before *pp2 */
116538 char **pp1, /* IN/OUT: Left input list */
116539 char **pp2 /* IN/OUT: Right input list */
116540 ){
116541 char *p = *pp;
116542 char *p1 = *pp1;
116543 char *p2 = *pp2;
116544 int iCol1 = 0;
116545 int iCol2 = 0;
116546
116547 /* Never set both isSaveLeft and isExact for the same invocation. */
116548 assert( isSaveLeft==0 || isExact==0 );
116549
116550 assert( p!=0 && *p1!=0 && *p2!=0 );
116551 if( *p1==POS_COLUMN ){
116552 p1++;
116553 p1 += sqlite3Fts3GetVarint32(p1, &iCol1);
116554 }
116555 if( *p2==POS_COLUMN ){
@@ -116024,11 +116562,11 @@
116562 char *pSave = p;
116563 sqlite3_int64 iPrev = 0;
116564 sqlite3_int64 iPos1 = 0;
116565 sqlite3_int64 iPos2 = 0;
116566
116567 if( iCol1 ){
116568 *p++ = POS_COLUMN;
116569 p += sqlite3Fts3PutVarint(p, iCol1);
116570 }
116571
116572 assert( *p1!=POS_END && *p1!=POS_COLUMN );
@@ -116039,20 +116577,14 @@
116577 while( 1 ){
116578 if( iPos2==iPos1+nToken
116579 || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken)
116580 ){
116581 sqlite3_int64 iSave;
 
 
 
 
 
 
 
116582 iSave = isSaveLeft ? iPos1 : iPos2;
116583 fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2;
116584 pSave = 0;
116585 assert( p );
116586 }
116587 if( (!isSaveLeft && iPos2<=(iPos1+nToken)) || iPos2<=iPos1 ){
116588 if( (*p2&0xFE)==0 ) break;
116589 fts3GetDeltaVarint(&p2, &iPos2); iPos2 -= 2;
116590 }else{
@@ -116097,11 +116629,11 @@
116629
116630 fts3PoslistCopy(0, &p2);
116631 fts3PoslistCopy(0, &p1);
116632 *pp1 = p1;
116633 *pp2 = p2;
116634 if( *pp==p ){
116635 return 0;
116636 }
116637 *p++ = 0x00;
116638 *pp = p;
116639 return 1;
@@ -116399,10 +116931,60 @@
116931 }
116932 }
116933
116934 *pnRight = p - aOut;
116935 }
116936
116937 /*
116938 ** Argument pList points to a position list nList bytes in size. This
116939 ** function checks to see if the position list contains any entries for
116940 ** a token in position 0 (of any column). If so, it writes argument iDelta
116941 ** to the output buffer pOut, followed by a position list consisting only
116942 ** of the entries from pList at position 0, and terminated by an 0x00 byte.
116943 ** The value returned is the number of bytes written to pOut (if any).
116944 */
116945 SQLITE_PRIVATE int sqlite3Fts3FirstFilter(
116946 sqlite3_int64 iDelta, /* Varint that may be written to pOut */
116947 char *pList, /* Position list (no 0x00 term) */
116948 int nList, /* Size of pList in bytes */
116949 char *pOut /* Write output here */
116950 ){
116951 int nOut = 0;
116952 int bWritten = 0; /* True once iDelta has been written */
116953 char *p = pList;
116954 char *pEnd = &pList[nList];
116955
116956 if( *p!=0x01 ){
116957 if( *p==0x02 ){
116958 nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
116959 pOut[nOut++] = 0x02;
116960 bWritten = 1;
116961 }
116962 fts3ColumnlistCopy(0, &p);
116963 }
116964
116965 while( p<pEnd && *p==0x01 ){
116966 sqlite3_int64 iCol;
116967 p++;
116968 p += sqlite3Fts3GetVarint(p, &iCol);
116969 if( *p==0x02 ){
116970 if( bWritten==0 ){
116971 nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta);
116972 bWritten = 1;
116973 }
116974 pOut[nOut++] = 0x01;
116975 nOut += sqlite3Fts3PutVarint(&pOut[nOut], iCol);
116976 pOut[nOut++] = 0x02;
116977 }
116978 fts3ColumnlistCopy(0, &p);
116979 }
116980 if( bWritten ){
116981 pOut[nOut++] = 0x00;
116982 }
116983
116984 return nOut;
116985 }
116986
116987
116988 /*
116989 ** Merge all doclists in the TermSelect.aaOutput[] array into a single
116990 ** doclist stored in TermSelect.aaOutput[0]. If successful, delete all
@@ -116756,10 +117338,11 @@
117338 pSegcsr = pTok->pSegcsr;
117339 memset(&tsc, 0, sizeof(TermSelect));
117340
117341 filter.flags = FTS3_SEGMENT_IGNORE_EMPTY | FTS3_SEGMENT_REQUIRE_POS
117342 | (pTok->isPrefix ? FTS3_SEGMENT_PREFIX : 0)
117343 | (pTok->bFirst ? FTS3_SEGMENT_FIRST : 0)
117344 | (iColumn<p->nColumn ? FTS3_SEGMENT_COLUMN_FILTER : 0);
117345 filter.iCol = iColumn;
117346 filter.zTerm = pTok->z;
117347 filter.nTerm = pTok->n;
117348
@@ -116896,12 +117479,12 @@
117479
117480 if( zQuery==0 && sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
117481 return SQLITE_NOMEM;
117482 }
117483
117484 rc = sqlite3Fts3ExprParse(p->pTokenizer, p->azColumn, p->bHasStat,
117485 p->nColumn, iCol, zQuery, -1, &pCsr->pExpr
117486 );
117487 if( rc!=SQLITE_OK ){
117488 if( rc==SQLITE_ERROR ){
117489 static const char *zErr = "malformed MATCH expression: [%s]";
117490 p->base.zErrMsg = sqlite3_mprintf(zErr, zQuery);
@@ -116924,26 +117507,27 @@
117507 ** statement loops through all rows of the %_content table. For a
117508 ** full-text query or docid lookup, the statement retrieves a single
117509 ** row by docid.
117510 */
117511 if( idxNum==FTS3_FULLSCAN_SEARCH ){
117512 zSql = sqlite3_mprintf(
117513 "SELECT %s ORDER BY rowid %s",
117514 p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC")
117515 );
117516 if( zSql ){
117517 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0);
117518 sqlite3_free(zSql);
117519 }else{
117520 rc = SQLITE_NOMEM;
117521 }
117522 }else if( idxNum==FTS3_DOCID_SEARCH ){
117523 rc = fts3CursorSeekStmt(pCsr, &pCsr->pStmt);
117524 if( rc==SQLITE_OK ){
117525 rc = sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]);
117526 }
117527 }
117528 if( rc!=SQLITE_OK ) return rc;
117529
117530 return fts3NextMethod(pCursor);
117531 }
117532
117533 /*
@@ -116992,11 +117576,11 @@
117576 ** Return a blob which is a pointer to the cursor.
117577 */
117578 sqlite3_result_blob(pContext, &pCsr, sizeof(pCsr), SQLITE_TRANSIENT);
117579 }else{
117580 rc = fts3CursorSeek(0, pCsr);
117581 if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)>(iCol+1) ){
117582 sqlite3_result_value(pContext, sqlite3_column_value(pCsr->pStmt, iCol+1));
117583 }
117584 }
117585
117586 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
@@ -117076,11 +117660,11 @@
117660 ** moves *ppPoslist so that it instead points to the first byte of the
117661 ** same position list.
117662 */
117663 static void fts3ReversePoslist(char *pStart, char **ppPoslist){
117664 char *p = &(*ppPoslist)[-2];
117665 char c = 0;
117666
117667 while( p>pStart && (c=*p--)==0 );
117668 while( p>pStart && (*p & 0x80) | c ){
117669 c = *p--;
117670 }
@@ -117285,19 +117869,26 @@
117869 ){
117870 Fts3Table *p = (Fts3Table *)pVtab;
117871 sqlite3 *db = p->db; /* Database connection */
117872 int rc; /* Return Code */
117873
117874 /* As it happens, the pending terms table is always empty here. This is
117875 ** because an "ALTER TABLE RENAME TABLE" statement inside a transaction
117876 ** always opens a savepoint transaction. And the xSavepoint() method
117877 ** flushes the pending terms table. But leave the (no-op) call to
117878 ** PendingTermsFlush() in in case that changes.
117879 */
117880 assert( p->nPendingData==0 );
117881 rc = sqlite3Fts3PendingTermsFlush(p);
117882
117883 if( p->zContentTbl==0 ){
117884 fts3DbExec(&rc, db,
117885 "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';",
117886 p->zDb, p->zName, zName
117887 );
117888 }
117889
 
 
 
 
117890 if( p->bHasDocsize ){
117891 fts3DbExec(&rc, db,
117892 "ALTER TABLE %Q.'%q_docsize' RENAME TO '%q_docsize';",
117893 p->zDb, p->zName, zName
117894 );
@@ -117652,25 +118243,24 @@
118243 **
118244 ** SQLITE_OK is returned if no error occurs, otherwise an SQLite error code.
118245 */
118246 static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){
118247 int iToken; /* Used to iterate through phrase tokens */
 
118248 char *aPoslist = 0; /* Position list for deferred tokens */
118249 int nPoslist = 0; /* Number of bytes in aPoslist */
118250 int iPrev = -1; /* Token number of previous deferred token */
118251
118252 assert( pPhrase->doclist.bFreeList==0 );
118253
118254 for(iToken=0; iToken<pPhrase->nToken; iToken++){
118255 Fts3PhraseToken *pToken = &pPhrase->aToken[iToken];
118256 Fts3DeferredToken *pDeferred = pToken->pDeferred;
118257
118258 if( pDeferred ){
118259 char *pList;
118260 int nList;
118261 int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList);
118262 if( rc!=SQLITE_OK ) return rc;
118263
118264 if( pList==0 ){
118265 sqlite3_free(aPoslist);
118266 pPhrase->doclist.pList = 0;
@@ -117767,10 +118357,11 @@
118357 if( pCsr->bDesc==pTab->bDescIdx
118358 && bOptOk==1
118359 && p->nToken==1
118360 && pFirst->pSegcsr
118361 && pFirst->pSegcsr->bLookup
118362 && pFirst->bFirst==0
118363 ){
118364 /* Use the incremental approach. */
118365 int iCol = (p->iColumn >= pTab->nColumn ? -1 : p->iColumn);
118366 rc = sqlite3Fts3MsrIncrStart(
118367 pTab, pFirst->pSegcsr, iCol, pFirst->z, pFirst->n);
@@ -117996,11 +118587,11 @@
118587 Fts3Expr *pExpr, /* Expression to consider */
118588 Fts3TokenAndCost **ppTC, /* Write new entries to *(*ppTC)++ */
118589 Fts3Expr ***ppOr, /* Write new OR root to *(*ppOr)++ */
118590 int *pRc /* IN/OUT: Error code */
118591 ){
118592 if( *pRc==SQLITE_OK ){
118593 if( pExpr->eType==FTSQUERY_PHRASE ){
118594 Fts3Phrase *pPhrase = pExpr->pPhrase;
118595 int i;
118596 for(i=0; *pRc==SQLITE_OK && i<pPhrase->nToken; i++){
118597 Fts3TokenAndCost *pTC = (*ppTC)++;
@@ -118010,10 +118601,15 @@
118601 pTC->pToken = &pPhrase->aToken[i];
118602 pTC->iCol = pPhrase->iColumn;
118603 *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl);
118604 }
118605 }else if( pExpr->eType!=FTSQUERY_NOT ){
118606 assert( pExpr->eType==FTSQUERY_OR
118607 || pExpr->eType==FTSQUERY_AND
118608 || pExpr->eType==FTSQUERY_NEAR
118609 );
118610 assert( pExpr->pLeft && pExpr->pRight );
118611 if( pExpr->eType==FTSQUERY_OR ){
118612 pRoot = pExpr->pLeft;
118613 **ppOr = pRoot;
118614 (*ppOr)++;
118615 }
@@ -118070,11 +118666,11 @@
118666 while( a<pEnd ){
118667 a += sqlite3Fts3GetVarint(a, &nByte);
118668 }
118669 if( nDoc==0 || nByte==0 ){
118670 sqlite3_reset(pStmt);
118671 return FTS_CORRUPT_VTAB;
118672 }
118673
118674 pCsr->nDoc = nDoc;
118675 pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz);
118676 assert( pCsr->nRowAvg>0 );
@@ -118113,10 +118709,19 @@
118709 int nOvfl = 0; /* Total overflow pages used by doclists */
118710 int nToken = 0; /* Total number of tokens in cluster */
118711
118712 int nMinEst = 0; /* The minimum count for any phrase so far. */
118713 int nLoad4 = 1; /* (Phrases that will be loaded)^4. */
118714
118715 /* Tokens are never deferred for FTS tables created using the content=xxx
118716 ** option. The reason being that it is not guaranteed that the content
118717 ** table actually contains the same data as the index. To prevent this from
118718 ** causing any problems, the deferred token optimization is completely
118719 ** disabled for content=xxx tables. */
118720 if( pTab->zContentTbl ){
118721 return SQLITE_OK;
118722 }
118723
118724 /* Count the tokens in this AND/NEAR cluster. If none of the doclists
118725 ** associated with the tokens spill onto overflow pages, or if there is
118726 ** only 1 token, exit early. No tokens to defer in this case. */
118727 for(ii=0; ii<nTC; ii++){
@@ -118176,11 +118781,15 @@
118781 Fts3PhraseToken *pToken = pTC->pToken;
118782 rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol);
118783 fts3SegReaderCursorFree(pToken->pSegcsr);
118784 pToken->pSegcsr = 0;
118785 }else{
118786 /* Set nLoad4 to the value of (4^nOther) for the next iteration of the
118787 ** for-loop. Except, limit the value to 2^24 to prevent it from
118788 ** overflowing the 32-bit integer it is stored in. */
118789 if( ii<12 ) nLoad4 = nLoad4*4;
118790
118791 if( ii==0 || pTC->pPhrase->nToken>1 ){
118792 /* Either this is the cheapest token in the entire query, or it is
118793 ** part of a multi-token phrase. Either way, the entire doclist will
118794 ** (eventually) be loaded into memory. It may as well be now. */
118795 Fts3PhraseToken *pToken = pTC->pToken;
@@ -118546,12 +119155,15 @@
119155 }
119156
119157 aPoslist = pExpr->pRight->pPhrase->doclist.pList;
119158 nToken = pExpr->pRight->pPhrase->nToken;
119159 for(p=pExpr->pLeft; p && res; p=p->pLeft){
119160 int nNear;
119161 Fts3Phrase *pPhrase;
119162 assert( p->pParent && p->pParent->pLeft==p );
119163 nNear = p->pParent->nNear;
119164 pPhrase = (
119165 p->eType==FTSQUERY_NEAR ? p->pRight->pPhrase : p->pPhrase
119166 );
119167 res = fts3EvalNearTrim(nNear, aTmp, &aPoslist, &nToken, pPhrase);
119168 }
119169 }
@@ -119037,10 +119649,19 @@
119649 pPhrase->aToken[i].pSegcsr = 0;
119650 }
119651 }
119652 }
119653
119654 /*
119655 ** Return SQLITE_CORRUPT_VTAB.
119656 */
119657 #ifdef SQLITE_DEBUG
119658 SQLITE_PRIVATE int sqlite3Fts3Corrupt(){
119659 return SQLITE_CORRUPT_VTAB;
119660 }
119661 #endif
119662
119663 #if !SQLITE_CORE
119664 /*
119665 ** Initialize API pointer table, if required.
119666 */
119667 SQLITE_API int sqlite3_extension_init(
@@ -119625,10 +120246,11 @@
120246 */
120247 typedef struct ParseContext ParseContext;
120248 struct ParseContext {
120249 sqlite3_tokenizer *pTokenizer; /* Tokenizer module */
120250 const char **azCol; /* Array of column names for fts3 table */
120251 int bFts4; /* True to allow FTS4-only syntax */
120252 int nCol; /* Number of entries in azCol[] */
120253 int iDefaultCol; /* Default column to query */
120254 int isNot; /* True if getNextNode() sees a unary - */
120255 sqlite3_context *pCtx; /* Write error message here */
120256 int nNest; /* Number of nested brackets */
@@ -119712,13 +120334,25 @@
120334
120335 if( iEnd<n && z[iEnd]=='*' ){
120336 pRet->pPhrase->aToken[0].isPrefix = 1;
120337 iEnd++;
120338 }
120339
120340 while( 1 ){
120341 if( !sqlite3_fts3_enable_parentheses
120342 && iStart>0 && z[iStart-1]=='-'
120343 ){
120344 pParse->isNot = 1;
120345 iStart--;
120346 }else if( pParse->bFts4 && iStart>0 && z[iStart-1]=='^' ){
120347 pRet->pPhrase->aToken[0].bFirst = 1;
120348 iStart--;
120349 }else{
120350 break;
120351 }
120352 }
120353
120354 }
120355 nConsumed = iEnd;
120356 }
120357
120358 pModule->xClose(pCursor);
@@ -119813,10 +120447,11 @@
120447 memcpy(&zTemp[nTemp], zByte, nByte);
120448 nTemp += nByte;
120449
120450 pToken->n = nByte;
120451 pToken->isPrefix = (iEnd<nInput && zInput[iEnd]=='*');
120452 pToken->bFirst = (iBegin>0 && zInput[iBegin-1]=='^');
120453 nToken = ii+1;
120454 }
120455 }
120456
120457 pModule->xClose(pCursor);
@@ -119834,12 +120469,16 @@
120469 p->pPhrase = (Fts3Phrase *)&p[1];
120470 p->pPhrase->iColumn = pParse->iDefaultCol;
120471 p->pPhrase->nToken = nToken;
120472
120473 zBuf = (char *)&p->pPhrase->aToken[nToken];
120474 if( zTemp ){
120475 memcpy(zBuf, zTemp, nTemp);
120476 sqlite3_free(zTemp);
120477 }else{
120478 assert( nTemp==0 );
120479 }
120480
120481 for(jj=0; jj<p->pPhrase->nToken; jj++){
120482 p->pPhrase->aToken[jj].z = zBuf;
120483 zBuf += p->pPhrase->aToken[jj].n;
120484 }
@@ -120260,10 +120899,11 @@
120899 ** match any table column.
120900 */
120901 SQLITE_PRIVATE int sqlite3Fts3ExprParse(
120902 sqlite3_tokenizer *pTokenizer, /* Tokenizer module */
120903 char **azCol, /* Array of column names for fts3 table */
120904 int bFts4, /* True to allow FTS4-only syntax */
120905 int nCol, /* Number of entries in azCol[] */
120906 int iDefaultCol, /* Default column to query */
120907 const char *z, int n, /* Text of MATCH query */
120908 Fts3Expr **ppExpr /* OUT: Parsed query structure */
120909 ){
@@ -120273,10 +120913,11 @@
120913 sParse.pTokenizer = pTokenizer;
120914 sParse.azCol = (const char **)azCol;
120915 sParse.nCol = nCol;
120916 sParse.iDefaultCol = iDefaultCol;
120917 sParse.nNest = 0;
120918 sParse.bFts4 = bFts4;
120919 if( z==0 ){
120920 *ppExpr = 0;
120921 return SQLITE_OK;
120922 }
120923 if( n<0 ){
@@ -120462,11 +121103,11 @@
121103 for(ii=0; ii<nCol; ii++){
121104 azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
121105 }
121106
121107 rc = sqlite3Fts3ExprParse(
121108 pTokenizer, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr
121109 );
121110 if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM ){
121111 sqlite3_result_error(context, "Error parsing expression", -1);
121112 }else if( rc==SQLITE_NOMEM || !(zBuf = exprToString(pExpr, 0)) ){
121113 sqlite3_result_error_nomem(context);
@@ -122509,11 +123150,11 @@
123150 /* 2 */ "DELETE FROM %Q.'%q_content'",
123151 /* 3 */ "DELETE FROM %Q.'%q_segments'",
123152 /* 4 */ "DELETE FROM %Q.'%q_segdir'",
123153 /* 5 */ "DELETE FROM %Q.'%q_docsize'",
123154 /* 6 */ "DELETE FROM %Q.'%q_stat'",
123155 /* 7 */ "SELECT %s WHERE rowid=?",
123156 /* 8 */ "SELECT (SELECT max(idx) FROM %Q.'%q_segdir' WHERE level = ?) + 1",
123157 /* 9 */ "INSERT INTO %Q.'%q_segments'(blockid, block) VALUES(?, ?)",
123158 /* 10 */ "SELECT coalesce((SELECT max(blockid) FROM %Q.'%q_segments') + 1, 1)",
123159 /* 11 */ "INSERT INTO %Q.'%q_segdir' VALUES(?,?,?,?,?,?)",
123160
@@ -122551,11 +123192,11 @@
123192 if( !pStmt ){
123193 char *zSql;
123194 if( eStmt==SQL_CONTENT_INSERT ){
123195 zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
123196 }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
123197 zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
123198 }else{
123199 zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
123200 }
123201 if( !zSql ){
123202 rc = SQLITE_NOMEM;
@@ -122594,11 +123235,11 @@
123235 sqlite3_bind_int64(pStmt, 1, iDocid);
123236 }
123237 rc = sqlite3_step(pStmt);
123238 if( rc!=SQLITE_ROW || sqlite3_column_type(pStmt, 0)!=SQLITE_BLOB ){
123239 rc = sqlite3_reset(pStmt);
123240 if( rc==SQLITE_OK ) rc = FTS_CORRUPT_VTAB;
123241 pStmt = 0;
123242 }else{
123243 rc = SQLITE_OK;
123244 }
123245 }
@@ -122662,21 +123303,28 @@
123303 ** We try to avoid this because if FTS3 returns any error when committing
123304 ** a transaction, the whole transaction will be rolled back. And this is
123305 ** not what users expect when they get SQLITE_LOCKED_SHAREDCACHE. It can
123306 ** still happen if the user reads data directly from the %_segments or
123307 ** %_segdir tables instead of going through FTS3 though.
123308 **
123309 ** This reasoning does not apply to a content=xxx table.
123310 */
123311 SQLITE_PRIVATE int sqlite3Fts3ReadLock(Fts3Table *p){
123312 int rc; /* Return code */
123313 sqlite3_stmt *pStmt; /* Statement used to obtain lock */
123314
123315 if( p->zContentTbl==0 ){
123316 rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pStmt, 0);
123317 if( rc==SQLITE_OK ){
123318 sqlite3_bind_null(pStmt, 1);
123319 sqlite3_step(pStmt);
123320 rc = sqlite3_reset(pStmt);
123321 }
123322 }else{
123323 rc = SQLITE_OK;
123324 }
123325
123326 return rc;
123327 }
123328
123329 /*
123330 ** Set *ppStmt to a statement handle that may be used to iterate through
@@ -123032,10 +123680,22 @@
123680 sqlite3_value **apVal, /* Array of values to insert */
123681 sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */
123682 ){
123683 int rc; /* Return code */
123684 sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */
123685
123686 if( p->zContentTbl ){
123687 sqlite3_value *pRowid = apVal[p->nColumn+3];
123688 if( sqlite3_value_type(pRowid)==SQLITE_NULL ){
123689 pRowid = apVal[1];
123690 }
123691 if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){
123692 return SQLITE_CONSTRAINT;
123693 }
123694 *piDocid = sqlite3_value_int64(pRowid);
123695 return SQLITE_OK;
123696 }
123697
123698 /* Locate the statement handle used to insert data into the %_content
123699 ** table. The SQL for this statement is:
123700 **
123701 ** INSERT INTO %_content VALUES(?, ?, ?, ...)
@@ -123083,18 +123743,20 @@
123743
123744 /*
123745 ** Remove all data from the FTS3 table. Clear the hash table containing
123746 ** pending terms.
123747 */
123748 static int fts3DeleteAll(Fts3Table *p, int bContent){
123749 int rc = SQLITE_OK; /* Return code */
123750
123751 /* Discard the contents of the pending-terms hash table. */
123752 sqlite3Fts3PendingTermsClear(p);
123753
123754 /* Delete everything from the shadow tables. Except, leave %_content as
123755 ** is if bContent is false. */
123756 assert( p->zContentTbl==0 || bContent==0 );
123757 if( bContent ) fts3SqlExec(&rc, p, SQL_DELETE_ALL_CONTENT, 0);
123758 fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGMENTS, 0);
123759 fts3SqlExec(&rc, p, SQL_DELETE_ALL_SEGDIR, 0);
123760 if( p->bHasDocsize ){
123761 fts3SqlExec(&rc, p, SQL_DELETE_ALL_DOCSIZE, 0);
123762 }
@@ -123398,11 +124060,11 @@
124060 pNext += sqlite3Fts3GetVarint32(pNext, &nPrefix);
124061 pNext += sqlite3Fts3GetVarint32(pNext, &nSuffix);
124062 if( nPrefix<0 || nSuffix<=0
124063 || &pNext[nSuffix]>&pReader->aNode[pReader->nNode]
124064 ){
124065 return FTS_CORRUPT_VTAB;
124066 }
124067
124068 if( nPrefix+nSuffix>pReader->nTermAlloc ){
124069 int nNew = (nPrefix+nSuffix)*2;
124070 char *zNew = sqlite3_realloc(pReader->zTerm, nNew);
@@ -123428,11 +124090,11 @@
124090 ** of these statements is untrue, then the data structure is corrupt.
124091 */
124092 if( &pReader->aDoclist[pReader->nDoclist]>&pReader->aNode[pReader->nNode]
124093 || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
124094 ){
124095 return FTS_CORRUPT_VTAB;
124096 }
124097 return SQLITE_OK;
124098 }
124099
124100 /*
@@ -124378,16 +125040,22 @@
125040 ** error occurs, an SQLite error code is returned.
125041 */
125042 static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){
125043 sqlite3_stmt *pStmt;
125044 int rc;
125045 if( p->zContentTbl ){
125046 /* If using the content=xxx option, assume the table is never empty */
125047 *pisEmpty = 0;
125048 rc = SQLITE_OK;
125049 }else{
125050 rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid);
125051 if( rc==SQLITE_OK ){
125052 if( SQLITE_ROW==sqlite3_step(pStmt) ){
125053 *pisEmpty = sqlite3_column_int(pStmt, 0);
125054 }
125055 rc = sqlite3_reset(pStmt);
125056 }
 
125057 }
125058 return rc;
125059 }
125060
125061 /*
@@ -124735,10 +125403,11 @@
125403 int isIgnoreEmpty = (pCsr->pFilter->flags & FTS3_SEGMENT_IGNORE_EMPTY);
125404 int isRequirePos = (pCsr->pFilter->flags & FTS3_SEGMENT_REQUIRE_POS);
125405 int isColFilter = (pCsr->pFilter->flags & FTS3_SEGMENT_COLUMN_FILTER);
125406 int isPrefix = (pCsr->pFilter->flags & FTS3_SEGMENT_PREFIX);
125407 int isScan = (pCsr->pFilter->flags & FTS3_SEGMENT_SCAN);
125408 int isFirst = (pCsr->pFilter->flags & FTS3_SEGMENT_FIRST);
125409
125410 Fts3SegReader **apSegment = pCsr->apSegment;
125411 int nSegment = pCsr->nSegment;
125412 Fts3SegFilter *pFilter = pCsr->pFilter;
125413 int (*xCmp)(Fts3SegReader *, Fts3SegReader *) = (
@@ -124794,10 +125463,11 @@
125463 }
125464
125465 assert( isIgnoreEmpty || (isRequirePos && !isColFilter) );
125466 if( nMerge==1
125467 && !isIgnoreEmpty
125468 && !isFirst
125469 && (p->bDescIdx==0 || fts3SegReaderIsPending(apSegment[0])==0)
125470 ){
125471 pCsr->nDoclist = apSegment[0]->nDoclist;
125472 if( fts3SegReaderIsPending(apSegment[0]) ){
125473 rc = fts3MsrBufferData(pCsr, apSegment[0]->aDoclist, pCsr->nDoclist);
@@ -124859,16 +125529,28 @@
125529 if( !aNew ){
125530 return SQLITE_NOMEM;
125531 }
125532 pCsr->aBuffer = aNew;
125533 }
125534
125535 if( isFirst ){
125536 char *a = &pCsr->aBuffer[nDoclist];
125537 int nWrite;
125538
125539 nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a);
125540 if( nWrite ){
125541 iPrev = iDocid;
125542 nDoclist += nWrite;
125543 }
125544 }else{
125545 nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta);
125546 iPrev = iDocid;
125547 if( isRequirePos ){
125548 memcpy(&pCsr->aBuffer[nDoclist], pList, nList);
125549 nDoclist += nList;
125550 pCsr->aBuffer[nDoclist++] = '\0';
125551 }
125552 }
125553 }
125554
125555 fts3SegReaderSort(apSegment, nMerge, j, xCmp);
125556 }
@@ -125040,13 +125722,13 @@
125722 ** Insert the sizes (in tokens) for each column of the document
125723 ** with docid equal to p->iPrevDocid. The sizes are encoded as
125724 ** a blob of varints.
125725 */
125726 static void fts3InsertDocsize(
125727 int *pRC, /* Result code */
125728 Fts3Table *p, /* Table into which to insert */
125729 u32 *aSz /* Sizes of each column, in tokens */
125730 ){
125731 char *pBlob; /* The BLOB encoding of the document size */
125732 int nBlob; /* Number of bytes in the BLOB */
125733 sqlite3_stmt *pStmt; /* Statement used to insert the encoding */
125734 int rc; /* Result code from subfunctions */
@@ -125163,10 +125845,90 @@
125845 sqlite3Fts3SegmentsClose(p);
125846 sqlite3Fts3PendingTermsClear(p);
125847
125848 return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc;
125849 }
125850
125851 /*
125852 ** This function is called when the user executes the following statement:
125853 **
125854 ** INSERT INTO <tbl>(<tbl>) VALUES('rebuild');
125855 **
125856 ** The entire FTS index is discarded and rebuilt. If the table is one
125857 ** created using the content=xxx option, then the new index is based on
125858 ** the current contents of the xxx table. Otherwise, it is rebuilt based
125859 ** on the contents of the %_content table.
125860 */
125861 static int fts3DoRebuild(Fts3Table *p){
125862 int rc; /* Return Code */
125863
125864 rc = fts3DeleteAll(p, 0);
125865 if( rc==SQLITE_OK ){
125866 u32 *aSz = 0;
125867 u32 *aSzIns = 0;
125868 u32 *aSzDel = 0;
125869 sqlite3_stmt *pStmt = 0;
125870 int nEntry = 0;
125871
125872 /* Compose and prepare an SQL statement to loop through the content table */
125873 char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist);
125874 if( !zSql ){
125875 rc = SQLITE_NOMEM;
125876 }else{
125877 rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
125878 sqlite3_free(zSql);
125879 }
125880
125881 if( rc==SQLITE_OK ){
125882 int nByte = sizeof(u32) * (p->nColumn+1)*3;
125883 aSz = (u32 *)sqlite3_malloc(nByte);
125884 if( aSz==0 ){
125885 rc = SQLITE_NOMEM;
125886 }else{
125887 memset(aSz, 0, nByte);
125888 aSzIns = &aSz[p->nColumn+1];
125889 aSzDel = &aSzIns[p->nColumn+1];
125890 }
125891 }
125892
125893 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
125894 int iCol;
125895 rc = fts3PendingTermsDocid(p, sqlite3_column_int64(pStmt, 0));
125896 aSz[p->nColumn] = 0;
125897 for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
125898 const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
125899 rc = fts3PendingTermsAdd(p, z, iCol, &aSz[iCol]);
125900 aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
125901 }
125902 if( p->bHasDocsize ){
125903 fts3InsertDocsize(&rc, p, aSz);
125904 }
125905 if( rc!=SQLITE_OK ){
125906 sqlite3_finalize(pStmt);
125907 pStmt = 0;
125908 }else{
125909 nEntry++;
125910 for(iCol=0; iCol<=p->nColumn; iCol++){
125911 aSzIns[iCol] += aSz[iCol];
125912 }
125913 }
125914 }
125915 if( p->bHasStat ){
125916 fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry);
125917 }
125918 sqlite3_free(aSz);
125919
125920 if( pStmt ){
125921 int rc2 = sqlite3_finalize(pStmt);
125922 if( rc==SQLITE_OK ){
125923 rc = rc2;
125924 }
125925 }
125926 }
125927
125928 return rc;
125929 }
125930
125931 /*
125932 ** Handle a 'special' INSERT of the form:
125933 **
125934 ** "INSERT INTO tbl(tbl) VALUES(<expr>)"
@@ -125181,10 +125943,12 @@
125943
125944 if( !zVal ){
125945 return SQLITE_NOMEM;
125946 }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){
125947 rc = fts3DoOptimize(p, 0);
125948 }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){
125949 rc = fts3DoRebuild(p);
125950 #ifdef SQLITE_TEST
125951 }else if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
125952 p->nNodeSize = atoi(&zVal[9]);
125953 rc = SQLITE_OK;
125954 }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){
@@ -125261,10 +126025,11 @@
126025 pTC->pTokenizer = pT;
126026 rc = pModule->xNext(pTC, &zToken, &nToken, &iDum1, &iDum2, &iPos);
126027 for(pDef=pCsr->pDeferred; pDef && rc==SQLITE_OK; pDef=pDef->pNext){
126028 Fts3PhraseToken *pPT = pDef->pToken;
126029 if( (pDef->iCol>=p->nColumn || pDef->iCol==i)
126030 && (pPT->bFirst==0 || iPos==0)
126031 && (pPT->n==nToken || (pPT->isPrefix && pPT->n<nToken))
126032 && (0==memcmp(zToken, pPT->z, pPT->n))
126033 ){
126034 fts3PendingListAppend(&pDef->pList, iDocid, i, iPos, &rc);
126035 }
@@ -125352,18 +126117,22 @@
126117 if( rc==SQLITE_OK ){
126118 if( isEmpty ){
126119 /* Deleting this row means the whole table is empty. In this case
126120 ** delete the contents of all three tables and throw away any
126121 ** data in the pendingTerms hash table. */
126122 rc = fts3DeleteAll(p, 1);
126123 *pnDoc = *pnDoc - 1;
126124 }else{
126125 sqlite3_int64 iRemove = sqlite3_value_int64(pRowid);
126126 rc = fts3PendingTermsDocid(p, iRemove);
126127 fts3DeleteTerms(&rc, p, pRowid, aSzDel);
126128 if( p->zContentTbl==0 ){
126129 fts3SqlExec(&rc, p, SQL_DELETE_CONTENT, &pRowid);
126130 if( sqlite3_changes(p->db) ) *pnDoc = *pnDoc - 1;
126131 }else{
126132 *pnDoc = *pnDoc - 1;
126133 }
126134 if( p->bHasDocsize ){
126135 fts3SqlExec(&rc, p, SQL_DELETE_DOCSIZE, &pRowid);
126136 }
126137 }
126138 }
@@ -125382,11 +126151,10 @@
126151 sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */
126152 ){
126153 Fts3Table *p = (Fts3Table *)pVtab;
126154 int rc = SQLITE_OK; /* Return Code */
126155 int isRemove = 0; /* True for an UPDATE or DELETE */
 
126156 u32 *aSzIns = 0; /* Sizes of inserted documents */
126157 u32 *aSzDel; /* Sizes of deleted documents */
126158 int nChng = 0; /* Net change in number of documents */
126159 int bInsertDone = 0;
126160
@@ -125420,11 +126188,11 @@
126188 ** should be deleted from the database before inserting the new row. Or,
126189 ** if the on-conflict mode is other than REPLACE, then this method must
126190 ** detect the conflict and return SQLITE_CONSTRAINT before beginning to
126191 ** modify the database file.
126192 */
126193 if( nArg>1 && p->zContentTbl==0 ){
126194 /* Find the value object that holds the new rowid value. */
126195 sqlite3_value *pNewRowid = apVal[3+p->nColumn];
126196 if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){
126197 pNewRowid = apVal[1];
126198 }
@@ -125465,23 +126233,25 @@
126233 /* If this is a DELETE or UPDATE operation, remove the old record. */
126234 if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
126235 assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
126236 rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
126237 isRemove = 1;
 
126238 }
126239
126240 /* If this is an INSERT or UPDATE operation, insert the new record. */
126241 if( nArg>1 && rc==SQLITE_OK ){
126242 if( bInsertDone==0 ){
126243 rc = fts3InsertData(p, apVal, pRowid);
126244 if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
126245 rc = FTS_CORRUPT_VTAB;
126246 }
126247 }
126248 if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
126249 rc = fts3PendingTermsDocid(p, *pRowid);
126250 }
126251 if( rc==SQLITE_OK ){
126252 assert( p->iPrevDocid==*pRowid );
126253 rc = fts3InsertTerms(p, apVal, aSzIns);
126254 }
126255 if( p->bHasDocsize ){
126256 fts3InsertDocsize(&rc, p, aSzIns);
126257 }
@@ -125891,10 +126661,11 @@
126661 pCsr = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol);
126662 if( pCsr ){
126663 int iFirst = 0;
126664 pPhrase->pList = pCsr;
126665 fts3GetDeltaPosition(&pCsr, &iFirst);
126666 assert( iFirst>=0 );
126667 pPhrase->pHead = pCsr;
126668 pPhrase->pTail = pCsr;
126669 pPhrase->iHead = iFirst;
126670 pPhrase->iTail = iFirst;
126671 }else{
@@ -126371,11 +127142,11 @@
127142 pStmt = *ppStmt;
127143 assert( sqlite3_data_count(pStmt)==1 );
127144
127145 a = sqlite3_column_blob(pStmt, 0);
127146 a += sqlite3Fts3GetVarint(a, &nDoc);
127147 if( nDoc==0 ) return FTS_CORRUPT_VTAB;
127148 *pnDoc = (u32)nDoc;
127149
127150 if( paLen ) *paLen = a;
127151 return SQLITE_OK;
127152 }
@@ -126932,11 +127703,11 @@
127703 }
127704 }
127705
127706 if( !pTerm ){
127707 /* All offsets for this column have been gathered. */
127708 rc = SQLITE_DONE;
127709 }else{
127710 assert( iCurrent<=iMinPos );
127711 if( 0==(0xFE&*pTerm->pList) ){
127712 pTerm->pList = 0;
127713 }else{
@@ -126949,12 +127720,12 @@
127720 char aBuffer[64];
127721 sqlite3_snprintf(sizeof(aBuffer), aBuffer,
127722 "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart
127723 );
127724 rc = fts3StringAppend(&res, aBuffer, -1);
127725 }else if( rc==SQLITE_DONE && pTab->zContentTbl==0 ){
127726 rc = FTS_CORRUPT_VTAB;
127727 }
127728 }
127729 }
127730 if( rc==SQLITE_DONE ){
127731 rc = SQLITE_OK;
@@ -128291,11 +129062,12 @@
129062 pCsr->nConstraint = argc;
129063 if( !pCsr->aConstraint ){
129064 rc = SQLITE_NOMEM;
129065 }else{
129066 memset(pCsr->aConstraint, 0, sizeof(RtreeConstraint)*argc);
129067 assert( (idxStr==0 && argc==0)
129068 || (idxStr && (int)strlen(idxStr)==argc*2) );
129069 for(ii=0; ii<argc; ii++){
129070 RtreeConstraint *p = &pCsr->aConstraint[ii];
129071 p->op = idxStr[ii*2];
129072 p->iCoord = idxStr[ii*2+1]-'a';
129073 if( p->op==RTREE_MATCH ){
@@ -128592,11 +129364,14 @@
129364 int iCell;
129365 sqlite3_int64 iBest = 0;
129366
129367 float fMinGrowth = 0.0;
129368 float fMinArea = 0.0;
129369 #if VARIANT_RSTARTREE_CHOOSESUBTREE
129370 float fMinOverlap = 0.0;
129371 float overlap;
129372 #endif
129373
129374 int nCell = NCELL(pNode);
129375 RtreeCell cell;
129376 RtreeNode *pChild;
129377
@@ -128624,33 +129399,34 @@
129399 */
129400 for(iCell=0; iCell<nCell; iCell++){
129401 int bBest = 0;
129402 float growth;
129403 float area;
 
129404 nodeGetCell(pRtree, pNode, iCell, &cell);
129405 growth = cellGrowth(pRtree, &cell, pCell);
129406 area = cellArea(pRtree, &cell);
129407
129408 #if VARIANT_RSTARTREE_CHOOSESUBTREE
129409 if( ii==(pRtree->iDepth-1) ){
129410 overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
129411 }else{
129412 overlap = 0.0;
129413 }
129414 if( (iCell==0)
129415 || (overlap<fMinOverlap)
129416 || (overlap==fMinOverlap && growth<fMinGrowth)
129417 || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
129418 ){
129419 bBest = 1;
129420 fMinOverlap = overlap;
129421 }
129422 #else
129423 if( iCell==0||growth<fMinGrowth||(growth==fMinGrowth && area<fMinArea) ){
129424 bBest = 1;
129425 }
129426 #endif
129427 if( bBest ){
 
129428 fMinGrowth = growth;
129429 fMinArea = area;
129430 iBest = cell.iRowid;
129431 }
129432 }
129433
+48 -11
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105105
**
106106
** See also: [sqlite3_libversion()],
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110
-#define SQLITE_VERSION "3.7.8"
111
-#define SQLITE_VERSION_NUMBER 3007008
112
-#define SQLITE_SOURCE_ID "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177"
110
+#define SQLITE_VERSION "3.7.9"
111
+#define SQLITE_VERSION_NUMBER 3007009
112
+#define SQLITE_SOURCE_ID "2011-10-20 00:55:54 4344483f7d7f64dffadde0053e6c745948db9486"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -769,11 +769,15 @@
769769
** in order for the database to be readable. The fourth parameter to
770770
** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
771771
** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
772772
** WAL mode. If the integer is -1, then it is overwritten with the current
773773
** WAL persistence setting.
774
-**
774
+**
775
+** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
776
+** a write transaction to indicate that, unless it is rolled back for some
777
+** reason, the entire database file will be overwritten by the current
778
+** transaction. This is used by VACUUM operations.
775779
*/
776780
#define SQLITE_FCNTL_LOCKSTATE 1
777781
#define SQLITE_GET_LOCKPROXYFILE 2
778782
#define SQLITE_SET_LOCKPROXYFILE 3
779783
#define SQLITE_LAST_ERRNO 4
@@ -781,10 +785,11 @@
781785
#define SQLITE_FCNTL_CHUNK_SIZE 6
782786
#define SQLITE_FCNTL_FILE_POINTER 7
783787
#define SQLITE_FCNTL_SYNC_OMITTED 8
784788
#define SQLITE_FCNTL_WIN32_AV_RETRY 9
785789
#define SQLITE_FCNTL_PERSIST_WAL 10
790
+#define SQLITE_FCNTL_OVERWRITE 11
786791
787792
/*
788793
** CAPI3REF: Mutex Handle
789794
**
790795
** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1397,12 +1402,12 @@
13971402
** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
13981403
** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
13991404
** allocator is engaged to handle all of SQLites memory allocation needs.
14001405
** The first pointer (the memory pointer) must be aligned to an 8-byte
14011406
** boundary or subsequent behavior of SQLite will be undefined.
1402
-** The minimum allocation size is capped at 2^12. Reasonable values
1403
-** for the minimum allocation size are 2^5 through 2^8.</dd>
1407
+** The minimum allocation size is capped at 2**12. Reasonable values
1408
+** for the minimum allocation size are 2**5 through 2**8.</dd>
14041409
**
14051410
** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
14061411
** <dd> ^(This option takes a single argument which is a pointer to an
14071412
** instance of the [sqlite3_mutex_methods] structure. The argument specifies
14081413
** alternative low-level mutex routines to be used in place
@@ -2797,11 +2802,12 @@
27972802
** zSql string ends at either the first '\000' or '\u0000' character or
27982803
** the nByte-th byte, whichever comes first. If the caller knows
27992804
** that the supplied string is nul-terminated, then there is a small
28002805
** performance advantage to be gained by passing an nByte parameter that
28012806
** is equal to the number of bytes in the input string <i>including</i>
2802
-** the nul-terminator bytes.
2807
+** the nul-terminator bytes as this saves SQLite from having to
2808
+** make a copy of the input string.
28032809
**
28042810
** ^If pzTail is not NULL then *pzTail is made to point to the first byte
28052811
** past the end of the first SQL statement in zSql. These routines only
28062812
** compile the first statement in zSql, so *pzTail is left pointing to
28072813
** what remains uncompiled.
@@ -2848,11 +2854,11 @@
28482854
** a schema change, on the first [sqlite3_step()] call following any change
28492855
** to the [sqlite3_bind_text | bindings] of that [parameter].
28502856
** ^The specific value of WHERE-clause [parameter] might influence the
28512857
** choice of query plan if the parameter is the left-hand side of a [LIKE]
28522858
** or [GLOB] operator or if the parameter is compared to an indexed column
2853
-** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
2859
+** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
28542860
** the
28552861
** </li>
28562862
** </ol>
28572863
*/
28582864
SQLITE_API int sqlite3_prepare(
@@ -3018,10 +3024,17 @@
30183024
** ^(In those routines that have a fourth argument, its value is the
30193025
** number of bytes in the parameter. To be clear: the value is the
30203026
** number of <u>bytes</u> in the value, not the number of characters.)^
30213027
** ^If the fourth parameter is negative, the length of the string is
30223028
** the number of bytes up to the first zero terminator.
3029
+** If a non-negative fourth parameter is provided to sqlite3_bind_text()
3030
+** or sqlite3_bind_text16() then that parameter must be the byte offset
3031
+** where the NUL terminator would occur assuming the string were NUL
3032
+** terminated. If any NUL characters occur at byte offsets less than
3033
+** the value of the fourth parameter then the resulting string value will
3034
+** contain embedded NULs. The result of expressions involving strings
3035
+** with embedded NULs is undefined.
30233036
**
30243037
** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
30253038
** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
30263039
** string after SQLite has finished with it. ^The destructor is called
30273040
** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
@@ -3351,10 +3364,16 @@
33513364
** current row of the result set of [prepared statement] P.
33523365
** ^If prepared statement P does not have results ready to return
33533366
** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
33543367
** interfaces) then sqlite3_data_count(P) returns 0.
33553368
** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
3369
+** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
3370
+** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P)
3371
+** will return non-zero if previous call to [sqlite3_step](P) returned
3372
+** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
3373
+** where it always returns zero since each step of that multi-step
3374
+** pragma returns 0 columns of data.
33563375
**
33573376
** See also: [sqlite3_column_count()]
33583377
*/
33593378
SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
33603379
@@ -4030,11 +4049,16 @@
40304049
** is negative, then SQLite takes result text from the 2nd parameter
40314050
** through the first zero character.
40324051
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
40334052
** is non-negative, then as many bytes (not characters) of the text
40344053
** pointed to by the 2nd parameter are taken as the application-defined
4035
-** function result.
4054
+** function result. If the 3rd parameter is non-negative, then it
4055
+** must be the byte offset into the string where the NUL terminator would
4056
+** appear if the string where NUL terminated. If any NUL characters occur
4057
+** in the string at a byte offset that is less than the value of the 3rd
4058
+** parameter, then the resulting string will contain embedded NULs and the
4059
+** result of expressions operating on strings with embedded NULs is undefined.
40364060
** ^If the 4th parameter to the sqlite3_result_text* interfaces
40374061
** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
40384062
** function as the destructor on the text or BLOB result when it has
40394063
** finished using that result.
40404064
** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
@@ -5813,20 +5837,34 @@
58135837
** <dd>This parameter returns the approximate number of of bytes of heap
58145838
** and lookaside memory used by all prepared statements associated with
58155839
** the database connection.)^
58165840
** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
58175841
** </dd>
5842
+**
5843
+** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
5844
+** <dd>This parameter returns the number of pager cache hits that have
5845
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
5846
+** is always 0.
5847
+** </dd>
5848
+**
5849
+** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
5850
+** <dd>This parameter returns the number of pager cache misses that have
5851
+** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
5852
+** is always 0.
5853
+** </dd>
58185854
** </dl>
58195855
*/
58205856
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
58215857
#define SQLITE_DBSTATUS_CACHE_USED 1
58225858
#define SQLITE_DBSTATUS_SCHEMA_USED 2
58235859
#define SQLITE_DBSTATUS_STMT_USED 3
58245860
#define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
58255861
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
58265862
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
5827
-#define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */
5863
+#define SQLITE_DBSTATUS_CACHE_HIT 7
5864
+#define SQLITE_DBSTATUS_CACHE_MISS 8
5865
+#define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */
58285866
58295867
58305868
/*
58315869
** CAPI3REF: Prepared Statement Status
58325870
**
@@ -5876,11 +5914,10 @@
58765914
** <dd>^This is the number of rows inserted into transient indices that
58775915
** were created automatically in order to help joins run faster.
58785916
** A non-zero value in this counter may indicate an opportunity to
58795917
** improvement performance by adding permanent indices that do not
58805918
** need to be reinitialized each time the statement is run.</dd>
5881
-**
58825919
** </dl>
58835920
*/
58845921
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
58855922
#define SQLITE_STMTSTATUS_SORT 2
58865923
#define SQLITE_STMTSTATUS_AUTOINDEX 3
58875924
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.8"
111 #define SQLITE_VERSION_NUMBER 3007008
112 #define SQLITE_SOURCE_ID "2011-09-19 14:49:19 3e0da808d2f5b4d12046e05980ca04578f581177"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -769,11 +769,15 @@
769 ** in order for the database to be readable. The fourth parameter to
770 ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
771 ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
772 ** WAL mode. If the integer is -1, then it is overwritten with the current
773 ** WAL persistence setting.
774 **
 
 
 
 
775 */
776 #define SQLITE_FCNTL_LOCKSTATE 1
777 #define SQLITE_GET_LOCKPROXYFILE 2
778 #define SQLITE_SET_LOCKPROXYFILE 3
779 #define SQLITE_LAST_ERRNO 4
@@ -781,10 +785,11 @@
781 #define SQLITE_FCNTL_CHUNK_SIZE 6
782 #define SQLITE_FCNTL_FILE_POINTER 7
783 #define SQLITE_FCNTL_SYNC_OMITTED 8
784 #define SQLITE_FCNTL_WIN32_AV_RETRY 9
785 #define SQLITE_FCNTL_PERSIST_WAL 10
 
786
787 /*
788 ** CAPI3REF: Mutex Handle
789 **
790 ** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1397,12 +1402,12 @@
1397 ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
1398 ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
1399 ** allocator is engaged to handle all of SQLites memory allocation needs.
1400 ** The first pointer (the memory pointer) must be aligned to an 8-byte
1401 ** boundary or subsequent behavior of SQLite will be undefined.
1402 ** The minimum allocation size is capped at 2^12. Reasonable values
1403 ** for the minimum allocation size are 2^5 through 2^8.</dd>
1404 **
1405 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
1406 ** <dd> ^(This option takes a single argument which is a pointer to an
1407 ** instance of the [sqlite3_mutex_methods] structure. The argument specifies
1408 ** alternative low-level mutex routines to be used in place
@@ -2797,11 +2802,12 @@
2797 ** zSql string ends at either the first '\000' or '\u0000' character or
2798 ** the nByte-th byte, whichever comes first. If the caller knows
2799 ** that the supplied string is nul-terminated, then there is a small
2800 ** performance advantage to be gained by passing an nByte parameter that
2801 ** is equal to the number of bytes in the input string <i>including</i>
2802 ** the nul-terminator bytes.
 
2803 **
2804 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
2805 ** past the end of the first SQL statement in zSql. These routines only
2806 ** compile the first statement in zSql, so *pzTail is left pointing to
2807 ** what remains uncompiled.
@@ -2848,11 +2854,11 @@
2848 ** a schema change, on the first [sqlite3_step()] call following any change
2849 ** to the [sqlite3_bind_text | bindings] of that [parameter].
2850 ** ^The specific value of WHERE-clause [parameter] might influence the
2851 ** choice of query plan if the parameter is the left-hand side of a [LIKE]
2852 ** or [GLOB] operator or if the parameter is compared to an indexed column
2853 ** and the [SQLITE_ENABLE_STAT2] compile-time option is enabled.
2854 ** the
2855 ** </li>
2856 ** </ol>
2857 */
2858 SQLITE_API int sqlite3_prepare(
@@ -3018,10 +3024,17 @@
3018 ** ^(In those routines that have a fourth argument, its value is the
3019 ** number of bytes in the parameter. To be clear: the value is the
3020 ** number of <u>bytes</u> in the value, not the number of characters.)^
3021 ** ^If the fourth parameter is negative, the length of the string is
3022 ** the number of bytes up to the first zero terminator.
 
 
 
 
 
 
 
3023 **
3024 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3025 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3026 ** string after SQLite has finished with it. ^The destructor is called
3027 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
@@ -3351,10 +3364,16 @@
3351 ** current row of the result set of [prepared statement] P.
3352 ** ^If prepared statement P does not have results ready to return
3353 ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
3354 ** interfaces) then sqlite3_data_count(P) returns 0.
3355 ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
 
 
 
 
 
 
3356 **
3357 ** See also: [sqlite3_column_count()]
3358 */
3359 SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
3360
@@ -4030,11 +4049,16 @@
4030 ** is negative, then SQLite takes result text from the 2nd parameter
4031 ** through the first zero character.
4032 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
4033 ** is non-negative, then as many bytes (not characters) of the text
4034 ** pointed to by the 2nd parameter are taken as the application-defined
4035 ** function result.
 
 
 
 
 
4036 ** ^If the 4th parameter to the sqlite3_result_text* interfaces
4037 ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
4038 ** function as the destructor on the text or BLOB result when it has
4039 ** finished using that result.
4040 ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
@@ -5813,20 +5837,34 @@
5813 ** <dd>This parameter returns the approximate number of of bytes of heap
5814 ** and lookaside memory used by all prepared statements associated with
5815 ** the database connection.)^
5816 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
5817 ** </dd>
 
 
 
 
 
 
 
 
 
 
 
 
5818 ** </dl>
5819 */
5820 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
5821 #define SQLITE_DBSTATUS_CACHE_USED 1
5822 #define SQLITE_DBSTATUS_SCHEMA_USED 2
5823 #define SQLITE_DBSTATUS_STMT_USED 3
5824 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
5825 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
5826 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
5827 #define SQLITE_DBSTATUS_MAX 6 /* Largest defined DBSTATUS */
 
 
5828
5829
5830 /*
5831 ** CAPI3REF: Prepared Statement Status
5832 **
@@ -5876,11 +5914,10 @@
5876 ** <dd>^This is the number of rows inserted into transient indices that
5877 ** were created automatically in order to help joins run faster.
5878 ** A non-zero value in this counter may indicate an opportunity to
5879 ** improvement performance by adding permanent indices that do not
5880 ** need to be reinitialized each time the statement is run.</dd>
5881 **
5882 ** </dl>
5883 */
5884 #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
5885 #define SQLITE_STMTSTATUS_SORT 2
5886 #define SQLITE_STMTSTATUS_AUTOINDEX 3
5887
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -105,13 +105,13 @@
105 **
106 ** See also: [sqlite3_libversion()],
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.9"
111 #define SQLITE_VERSION_NUMBER 3007009
112 #define SQLITE_SOURCE_ID "2011-10-20 00:55:54 4344483f7d7f64dffadde0053e6c745948db9486"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -769,11 +769,15 @@
769 ** in order for the database to be readable. The fourth parameter to
770 ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
771 ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
772 ** WAL mode. If the integer is -1, then it is overwritten with the current
773 ** WAL persistence setting.
774 **
775 ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
776 ** a write transaction to indicate that, unless it is rolled back for some
777 ** reason, the entire database file will be overwritten by the current
778 ** transaction. This is used by VACUUM operations.
779 */
780 #define SQLITE_FCNTL_LOCKSTATE 1
781 #define SQLITE_GET_LOCKPROXYFILE 2
782 #define SQLITE_SET_LOCKPROXYFILE 3
783 #define SQLITE_LAST_ERRNO 4
@@ -781,10 +785,11 @@
785 #define SQLITE_FCNTL_CHUNK_SIZE 6
786 #define SQLITE_FCNTL_FILE_POINTER 7
787 #define SQLITE_FCNTL_SYNC_OMITTED 8
788 #define SQLITE_FCNTL_WIN32_AV_RETRY 9
789 #define SQLITE_FCNTL_PERSIST_WAL 10
790 #define SQLITE_FCNTL_OVERWRITE 11
791
792 /*
793 ** CAPI3REF: Mutex Handle
794 **
795 ** The mutex module within SQLite defines [sqlite3_mutex] to be an
@@ -1397,12 +1402,12 @@
1402 ** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
1403 ** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
1404 ** allocator is engaged to handle all of SQLites memory allocation needs.
1405 ** The first pointer (the memory pointer) must be aligned to an 8-byte
1406 ** boundary or subsequent behavior of SQLite will be undefined.
1407 ** The minimum allocation size is capped at 2**12. Reasonable values
1408 ** for the minimum allocation size are 2**5 through 2**8.</dd>
1409 **
1410 ** [[SQLITE_CONFIG_MUTEX]] <dt>SQLITE_CONFIG_MUTEX</dt>
1411 ** <dd> ^(This option takes a single argument which is a pointer to an
1412 ** instance of the [sqlite3_mutex_methods] structure. The argument specifies
1413 ** alternative low-level mutex routines to be used in place
@@ -2797,11 +2802,12 @@
2802 ** zSql string ends at either the first '\000' or '\u0000' character or
2803 ** the nByte-th byte, whichever comes first. If the caller knows
2804 ** that the supplied string is nul-terminated, then there is a small
2805 ** performance advantage to be gained by passing an nByte parameter that
2806 ** is equal to the number of bytes in the input string <i>including</i>
2807 ** the nul-terminator bytes as this saves SQLite from having to
2808 ** make a copy of the input string.
2809 **
2810 ** ^If pzTail is not NULL then *pzTail is made to point to the first byte
2811 ** past the end of the first SQL statement in zSql. These routines only
2812 ** compile the first statement in zSql, so *pzTail is left pointing to
2813 ** what remains uncompiled.
@@ -2848,11 +2854,11 @@
2854 ** a schema change, on the first [sqlite3_step()] call following any change
2855 ** to the [sqlite3_bind_text | bindings] of that [parameter].
2856 ** ^The specific value of WHERE-clause [parameter] might influence the
2857 ** choice of query plan if the parameter is the left-hand side of a [LIKE]
2858 ** or [GLOB] operator or if the parameter is compared to an indexed column
2859 ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
2860 ** the
2861 ** </li>
2862 ** </ol>
2863 */
2864 SQLITE_API int sqlite3_prepare(
@@ -3018,10 +3024,17 @@
3024 ** ^(In those routines that have a fourth argument, its value is the
3025 ** number of bytes in the parameter. To be clear: the value is the
3026 ** number of <u>bytes</u> in the value, not the number of characters.)^
3027 ** ^If the fourth parameter is negative, the length of the string is
3028 ** the number of bytes up to the first zero terminator.
3029 ** If a non-negative fourth parameter is provided to sqlite3_bind_text()
3030 ** or sqlite3_bind_text16() then that parameter must be the byte offset
3031 ** where the NUL terminator would occur assuming the string were NUL
3032 ** terminated. If any NUL characters occur at byte offsets less than
3033 ** the value of the fourth parameter then the resulting string value will
3034 ** contain embedded NULs. The result of expressions involving strings
3035 ** with embedded NULs is undefined.
3036 **
3037 ** ^The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
3038 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
3039 ** string after SQLite has finished with it. ^The destructor is called
3040 ** to dispose of the BLOB or string even if the call to sqlite3_bind_blob(),
@@ -3351,10 +3364,16 @@
3364 ** current row of the result set of [prepared statement] P.
3365 ** ^If prepared statement P does not have results ready to return
3366 ** (via calls to the [sqlite3_column_int | sqlite3_column_*()] of
3367 ** interfaces) then sqlite3_data_count(P) returns 0.
3368 ** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer.
3369 ** ^The sqlite3_data_count(P) routine returns 0 if the previous call to
3370 ** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P)
3371 ** will return non-zero if previous call to [sqlite3_step](P) returned
3372 ** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum]
3373 ** where it always returns zero since each step of that multi-step
3374 ** pragma returns 0 columns of data.
3375 **
3376 ** See also: [sqlite3_column_count()]
3377 */
3378 SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
3379
@@ -4030,11 +4049,16 @@
4049 ** is negative, then SQLite takes result text from the 2nd parameter
4050 ** through the first zero character.
4051 ** ^If the 3rd parameter to the sqlite3_result_text* interfaces
4052 ** is non-negative, then as many bytes (not characters) of the text
4053 ** pointed to by the 2nd parameter are taken as the application-defined
4054 ** function result. If the 3rd parameter is non-negative, then it
4055 ** must be the byte offset into the string where the NUL terminator would
4056 ** appear if the string where NUL terminated. If any NUL characters occur
4057 ** in the string at a byte offset that is less than the value of the 3rd
4058 ** parameter, then the resulting string will contain embedded NULs and the
4059 ** result of expressions operating on strings with embedded NULs is undefined.
4060 ** ^If the 4th parameter to the sqlite3_result_text* interfaces
4061 ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that
4062 ** function as the destructor on the text or BLOB result when it has
4063 ** finished using that result.
4064 ** ^If the 4th parameter to the sqlite3_result_text* interfaces or to
@@ -5813,20 +5837,34 @@
5837 ** <dd>This parameter returns the approximate number of of bytes of heap
5838 ** and lookaside memory used by all prepared statements associated with
5839 ** the database connection.)^
5840 ** ^The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0.
5841 ** </dd>
5842 **
5843 ** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(<dt>SQLITE_DBSTATUS_CACHE_HIT</dt>
5844 ** <dd>This parameter returns the number of pager cache hits that have
5845 ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT
5846 ** is always 0.
5847 ** </dd>
5848 **
5849 ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(<dt>SQLITE_DBSTATUS_CACHE_MISS</dt>
5850 ** <dd>This parameter returns the number of pager cache misses that have
5851 ** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS
5852 ** is always 0.
5853 ** </dd>
5854 ** </dl>
5855 */
5856 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
5857 #define SQLITE_DBSTATUS_CACHE_USED 1
5858 #define SQLITE_DBSTATUS_SCHEMA_USED 2
5859 #define SQLITE_DBSTATUS_STMT_USED 3
5860 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4
5861 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
5862 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
5863 #define SQLITE_DBSTATUS_CACHE_HIT 7
5864 #define SQLITE_DBSTATUS_CACHE_MISS 8
5865 #define SQLITE_DBSTATUS_MAX 8 /* Largest defined DBSTATUS */
5866
5867
5868 /*
5869 ** CAPI3REF: Prepared Statement Status
5870 **
@@ -5876,11 +5914,10 @@
5914 ** <dd>^This is the number of rows inserted into transient indices that
5915 ** were created automatically in order to help joins run faster.
5916 ** A non-zero value in this counter may indicate an opportunity to
5917 ** improvement performance by adding permanent indices that do not
5918 ** need to be reinitialized each time the statement is run.</dd>
 
5919 ** </dl>
5920 */
5921 #define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
5922 #define SQLITE_STMTSTATUS_SORT 2
5923 #define SQLITE_STMTSTATUS_AUTOINDEX 3
5924
+6 -6
--- src/stash.c
+++ src/stash.c
@@ -482,11 +482,11 @@
482482
db_finalize(&q);
483483
if( n==0 ) fossil_print("empty stash\n");
484484
}else
485485
if( memcmp(zCmd, "drop", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 ){
486486
int allFlag = find_option("all", 0, 0)!=0;
487
- if( g.argc>4 ) usage("stash apply STASHID");
487
+ if( g.argc>4 ) usage("apply STASHID");
488488
if( allFlag ){
489489
db_multi_exec("DELETE FROM stash; DELETE FROM stashfile;");
490490
}else{
491491
stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
492492
undo_begin();
@@ -494,30 +494,30 @@
494494
stash_drop(stashid);
495495
undo_finish();
496496
}
497497
}else
498498
if( memcmp(zCmd, "pop", nCmd)==0 ){
499
- if( g.argc>3 ) usage("stash pop");
499
+ if( g.argc>3 ) usage("pop");
500500
stashid = stash_get_id(0);
501501
undo_begin();
502502
stash_apply(stashid, 0);
503503
undo_save_stash(stashid);
504504
undo_finish();
505505
stash_drop(stashid);
506506
}else
507507
if( memcmp(zCmd, "apply", nCmd)==0 ){
508
- if( g.argc>4 ) usage("stash apply STASHID");
508
+ if( g.argc>4 ) usage("apply STASHID");
509509
stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
510510
undo_begin();
511511
stash_apply(stashid, 0);
512512
undo_finish();
513513
}else
514514
if( memcmp(zCmd, "goto", nCmd)==0 ){
515515
int nConflict;
516516
int vid;
517517
518
- if( g.argc>4 ) usage("stash apply STASHID");
518
+ if( g.argc>4 ) usage("apply STASHID");
519519
stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
520520
undo_begin();
521521
vid = db_int(0, "SELECT vid FROM stash WHERE stashid=%d", stashid);
522522
nConflict = update_to(vid);
523523
stash_apply(stashid, nConflict);
@@ -526,20 +526,20 @@
526526
stashid);
527527
undo_finish();
528528
}else
529529
if( memcmp(zCmd, "diff", nCmd)==0 ){
530530
const char *zDiffCmd = db_get("diff-command", 0);
531
- if( g.argc>4 ) usage("stash diff STASHID");
531
+ if( g.argc>4 ) usage("diff STASHID");
532532
stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
533533
stash_diff(stashid, zDiffCmd);
534534
}else
535535
if( memcmp(zCmd, "gdiff", nCmd)==0 ){
536536
const char *zDiffCmd = db_get("gdiff-command", 0);
537
- if( g.argc>4 ) usage("stash diff STASHID");
537
+ if( g.argc>4 ) usage("diff STASHID");
538538
stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
539539
stash_diff(stashid, zDiffCmd);
540540
}else
541541
{
542542
usage("SUBCOMMAND ARGS...");
543543
}
544544
db_end_transaction(0);
545545
}
546546
--- src/stash.c
+++ src/stash.c
@@ -482,11 +482,11 @@
482 db_finalize(&q);
483 if( n==0 ) fossil_print("empty stash\n");
484 }else
485 if( memcmp(zCmd, "drop", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 ){
486 int allFlag = find_option("all", 0, 0)!=0;
487 if( g.argc>4 ) usage("stash apply STASHID");
488 if( allFlag ){
489 db_multi_exec("DELETE FROM stash; DELETE FROM stashfile;");
490 }else{
491 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
492 undo_begin();
@@ -494,30 +494,30 @@
494 stash_drop(stashid);
495 undo_finish();
496 }
497 }else
498 if( memcmp(zCmd, "pop", nCmd)==0 ){
499 if( g.argc>3 ) usage("stash pop");
500 stashid = stash_get_id(0);
501 undo_begin();
502 stash_apply(stashid, 0);
503 undo_save_stash(stashid);
504 undo_finish();
505 stash_drop(stashid);
506 }else
507 if( memcmp(zCmd, "apply", nCmd)==0 ){
508 if( g.argc>4 ) usage("stash apply STASHID");
509 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
510 undo_begin();
511 stash_apply(stashid, 0);
512 undo_finish();
513 }else
514 if( memcmp(zCmd, "goto", nCmd)==0 ){
515 int nConflict;
516 int vid;
517
518 if( g.argc>4 ) usage("stash apply STASHID");
519 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
520 undo_begin();
521 vid = db_int(0, "SELECT vid FROM stash WHERE stashid=%d", stashid);
522 nConflict = update_to(vid);
523 stash_apply(stashid, nConflict);
@@ -526,20 +526,20 @@
526 stashid);
527 undo_finish();
528 }else
529 if( memcmp(zCmd, "diff", nCmd)==0 ){
530 const char *zDiffCmd = db_get("diff-command", 0);
531 if( g.argc>4 ) usage("stash diff STASHID");
532 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
533 stash_diff(stashid, zDiffCmd);
534 }else
535 if( memcmp(zCmd, "gdiff", nCmd)==0 ){
536 const char *zDiffCmd = db_get("gdiff-command", 0);
537 if( g.argc>4 ) usage("stash diff STASHID");
538 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
539 stash_diff(stashid, zDiffCmd);
540 }else
541 {
542 usage("SUBCOMMAND ARGS...");
543 }
544 db_end_transaction(0);
545 }
546
--- src/stash.c
+++ src/stash.c
@@ -482,11 +482,11 @@
482 db_finalize(&q);
483 if( n==0 ) fossil_print("empty stash\n");
484 }else
485 if( memcmp(zCmd, "drop", nCmd)==0 || memcmp(zCmd, "rm", nCmd)==0 ){
486 int allFlag = find_option("all", 0, 0)!=0;
487 if( g.argc>4 ) usage("apply STASHID");
488 if( allFlag ){
489 db_multi_exec("DELETE FROM stash; DELETE FROM stashfile;");
490 }else{
491 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
492 undo_begin();
@@ -494,30 +494,30 @@
494 stash_drop(stashid);
495 undo_finish();
496 }
497 }else
498 if( memcmp(zCmd, "pop", nCmd)==0 ){
499 if( g.argc>3 ) usage("pop");
500 stashid = stash_get_id(0);
501 undo_begin();
502 stash_apply(stashid, 0);
503 undo_save_stash(stashid);
504 undo_finish();
505 stash_drop(stashid);
506 }else
507 if( memcmp(zCmd, "apply", nCmd)==0 ){
508 if( g.argc>4 ) usage("apply STASHID");
509 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
510 undo_begin();
511 stash_apply(stashid, 0);
512 undo_finish();
513 }else
514 if( memcmp(zCmd, "goto", nCmd)==0 ){
515 int nConflict;
516 int vid;
517
518 if( g.argc>4 ) usage("apply STASHID");
519 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
520 undo_begin();
521 vid = db_int(0, "SELECT vid FROM stash WHERE stashid=%d", stashid);
522 nConflict = update_to(vid);
523 stash_apply(stashid, nConflict);
@@ -526,20 +526,20 @@
526 stashid);
527 undo_finish();
528 }else
529 if( memcmp(zCmd, "diff", nCmd)==0 ){
530 const char *zDiffCmd = db_get("diff-command", 0);
531 if( g.argc>4 ) usage("diff STASHID");
532 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
533 stash_diff(stashid, zDiffCmd);
534 }else
535 if( memcmp(zCmd, "gdiff", nCmd)==0 ){
536 const char *zDiffCmd = db_get("gdiff-command", 0);
537 if( g.argc>4 ) usage("diff STASHID");
538 stashid = stash_get_id(g.argc==4 ? g.argv[3] : 0);
539 stash_diff(stashid, zDiffCmd);
540 }else
541 {
542 usage("SUBCOMMAND ARGS...");
543 }
544 db_end_transaction(0);
545 }
546
+100 -27
--- src/style.c
+++ src/style.c
@@ -210,37 +210,38 @@
210210
@ } else {
211211
@ puts "Not logged in"
212212
@ }
213213
@ </th1></div>
214214
@ </div>
215
-@ <div class="mainmenu"><th1>
216
-@ html "<a href='$home$index_page'>Home</a> "
215
+@ <div class="mainmenu">
216
+@ <th1>
217
+@ html "<a href='$home$index_page'>Home</a>\n"
217218
@ if {[anycap jor]} {
218
-@ html "<a href='$home/timeline'>Timeline</a> "
219
+@ html "<a href='$home/timeline'>Timeline</a>\n"
219220
@ }
220221
@ if {[hascap oh]} {
221
-@ html "<a href='$home/dir?ci=tip'>Files</a> "
222
+@ html "<a href='$home/dir?ci=tip'>Files</a>\n"
222223
@ }
223224
@ if {[hascap o]} {
224
-@ html "<a href='$home/brlist'>Branches</a> "
225
-@ html "<a href='$home/taglist'>Tags</a> "
225
+@ html "<a href='$home/brlist'>Branches</a>\n"
226
+@ html "<a href='$home/taglist'>Tags</a>\n"
226227
@ }
227228
@ if {[hascap r]} {
228
-@ html "<a href='$home/reportlist'>Tickets</a> "
229
+@ html "<a href='$home/reportlist'>Tickets</a>\n"
229230
@ }
230231
@ if {[hascap j]} {
231
-@ html "<a href='$home/wiki'>Wiki</a> "
232
+@ html "<a href='$home/wiki'>Wiki</a>\n"
232233
@ }
233234
@ if {[hascap s]} {
234
-@ html "<a href='$home/setup'>Admin</a> "
235
+@ html "<a href='$home/setup'>Admin</a>\n"
235236
@ } elseif {[hascap a]} {
236
-@ html "<a href='$home/setup_ulist'>Users</a> "
237
+@ html "<a href='$home/setup_ulist'>Users</a>\n"
237238
@ }
238239
@ if {[info exists login]} {
239
-@ html "<a href='$home/login'>Logout</a> "
240
+@ html "<a href='$home/login'>Logout</a>\n"
240241
@ } else {
241
-@ html "<a href='$home/login'>Login</a> "
242
+@ html "<a href='$home/login'>Login</a>\n"
242243
@ }
243244
@ </th1></div>
244245
;
245246
246247
/*
@@ -320,23 +321,24 @@
320321
@ background-color: #558195;
321322
@ color: white;
322323
@ }
323324
@
324325
@ /* The submenu bar that *sometimes* appears below the main menu */
325
-@ div.submenu {
326
+@ div.submenu, div.sectionmenu {
326327
@ padding: 3px 10px 3px 0px;
327328
@ font-size: 0.9em;
328329
@ text-align: center;
329330
@ background-color: #456878;
330331
@ color: white;
331332
@ }
332
-@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
333
+@ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited,
334
+@ div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited {
333335
@ padding: 3px 10px 3px 10px;
334336
@ color: white;
335337
@ text-decoration: none;
336338
@ }
337
-@ div.mainmenu a:hover, div.submenu a:hover {
339
+@ div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover {
338340
@ color: #558195;
339341
@ background-color: white;
340342
@ }
341343
@
342344
@ /* All page content from the bottom of the menu or submenu down to
@@ -396,10 +398,69 @@
396398
@ table.label-value th {
397399
@ vertical-align: top;
398400
@ text-align: right;
399401
@ padding: 0.2ex 2ex;
400402
@ }
403
+@
404
+@ /* Side-by-side diff */
405
+@ table.sbsdiff {
406
+@ background-color: white;
407
+@ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
408
+@ font-size: 8pt;
409
+@ border-collapse:collapse;
410
+@ white-space: pre;
411
+@ width: 98%;
412
+@ border: 1px #000 dashed;
413
+@ margin-left: auto;
414
+@ margin-right: auto;
415
+@ }
416
+@
417
+@ table.sbsdiff th.diffhdr {
418
+@ border-bottom: dotted;
419
+@ border-width: 1px;
420
+@ }
421
+@
422
+@ table.sbsdiff tr td {
423
+@ white-space: pre;
424
+@ padding-left: 3px;
425
+@ padding-right: 3px;
426
+@ margin: 0px;
427
+@ vertical-align: top;
428
+@ }
429
+@
430
+@ table.sbsdiff tr td.lineno {
431
+@ text-align: right;
432
+@ }
433
+@
434
+@ table.sbsdiff tr td.srcline {
435
+@ }
436
+@
437
+@ table.sbsdiff tr td.meta {
438
+@ background-color: rgb(170, 160, 255);
439
+@ text-align: center;
440
+@ }
441
+@
442
+@ table.sbsdiff tr td.added {
443
+@ background-color: rgb(180, 250, 180);
444
+@ }
445
+@ table.sbsdiff tr td.addedvoid {
446
+@ background-color: rgb(190, 190, 180);
447
+@ }
448
+@
449
+@ table.sbsdiff tr td.removed {
450
+@ background-color: rgb(250, 130, 130);
451
+@ }
452
+@ table.sbsdiff tr td.removedvoid {
453
+@ background-color: rgb(190, 190, 180);
454
+@ }
455
+@
456
+@ table.sbsdiff tr td.changed {
457
+@ background-color: rgb(210, 210, 200);
458
+@ }
459
+@ table.sbsdiff tr td.changedvoid {
460
+@ background-color: rgb(190, 190, 180);
461
+@ }
401462
@
402463
;
403464
404465
405466
/* The following table contains bits of default CSS that must
@@ -470,11 +531,11 @@
470531
@ vertical-align: top;
471532
@ text-align: right;
472533
},
473534
{ "td.timelineGraph",
474535
"the format for the grap placeholder cells in timelines",
475
- @ width: 20;
536
+ @ width: 20px;
476537
@ text-align: left;
477538
@ vertical-align: top;
478539
},
479540
{ "a.tagLink",
480541
"the format for the tag links",
@@ -564,11 +625,11 @@
564625
@ vertical-align: top
565626
},
566627
{ "table.usetupUserList",
567628
"format for the user list table on the user setup page",
568629
@ outline-style: double;
569
- @ outline-width: 1;
630
+ @ outline-width: 1px;
570631
@ padding: 10px;
571632
},
572633
{ "th.usetupListUser",
573634
"format for table header user in user list on user setup page",
574635
@ text-align: right;
@@ -688,17 +749,17 @@
688749
@ border-color: #000000;
689750
@ border-style: solid;
690751
},
691752
{ "input.checkinUserColor",
692753
"format for user color input on checkin edit page",
693
- @ # no special definitions, class defined, to enable color pickers, f.e.:
694
- @ # add the color picker found at http:jscolor.com as java script include
695
- @ # to the header and configure the java script file with
696
- @ # 1. use as bindClass :checkinUserColor
697
- @ # 2. change the default hash adding behaviour to ON
698
- @ # or change the class defition of element identified by id="clrcust"
699
- @ # to a standard jscolor definition with java script in the footer.
754
+ @ /* no special definitions, class defined, to enable color pickers, f.e.:
755
+ @ ** add the color picker found at http:jscolor.com as java script include
756
+ @ ** to the header and configure the java script file with
757
+ @ ** 1. use as bindClass :checkinUserColor
758
+ @ ** 2. change the default hash adding behaviour to ON
759
+ @ ** or change the class defition of element identified by id="clrcust"
760
+ @ ** to a standard jscolor definition with java script in the footer. */
700761
},
701762
{ "div.endContent",
702763
"format for end of content area, to be used to clear page flow(sidebox on branch,..",
703764
@ clear: both;
704765
},
@@ -718,11 +779,11 @@
718779
},
719780
{ "span.thTrace",
720781
"format for th script trace messages",
721782
@ color: red;
722783
},
723
- { "p:reportError",
784
+ { "p.reportError",
724785
"format for report configuration errors",
725786
@ color: red;
726787
@ font-weight: bold;
727788
},
728789
{ "blockquote.reportError",
@@ -803,14 +864,26 @@
803864
** WEBPAGE: test_env
804865
*/
805866
void page_test_env(void){
806867
char c;
807868
int i;
869
+ int showAll;
808870
char zCap[30];
809871
login_check_credentials();
810
- if( !g.perm.Admin && !g.perm.Setup ){ login_needed(); return; }
872
+ if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){
873
+ login_needed();
874
+ return;
875
+ }
811876
style_header("Environment Test");
877
+ showAll = atoi(PD("showall","0"));
878
+ if( !showAll ){
879
+ style_submenu_element("Show Cookies", "Show Cookies",
880
+ "%s/test_env?showall=1", g.zTop);
881
+ }else{
882
+ style_submenu_element("Hide Cookies", "Hide Cookies",
883
+ "%s/test_env", g.zTop);
884
+ }
812885
#if !defined(_WIN32)
813886
@ uid=%d(getuid()), gid=%d(getgid())<br />
814887
#endif
815888
@ g.zBaseURL = %h(g.zBaseURL)<br />
816889
@ g.zTop = %h(g.zTop)<br />
@@ -820,12 +893,12 @@
820893
zCap[i] = 0;
821894
@ g.userUid = %d(g.userUid)<br />
822895
@ g.zLogin = %h(g.zLogin)<br />
823896
@ capabilities = %s(zCap)<br />
824897
@ <hr>
825
- cgi_print_all();
898
+ cgi_print_all(atoi(PD("showall","0")));
826899
if( g.perm.Setup ){
827900
const char *zRedir = P("redirect");
828901
if( zRedir ) cgi_redirect(zRedir);
829902
}
830903
style_footer();
831904
}
832905
--- src/style.c
+++ src/style.c
@@ -210,37 +210,38 @@
210 @ } else {
211 @ puts "Not logged in"
212 @ }
213 @ </th1></div>
214 @ </div>
215 @ <div class="mainmenu"><th1>
216 @ html "<a href='$home$index_page'>Home</a> "
 
217 @ if {[anycap jor]} {
218 @ html "<a href='$home/timeline'>Timeline</a> "
219 @ }
220 @ if {[hascap oh]} {
221 @ html "<a href='$home/dir?ci=tip'>Files</a> "
222 @ }
223 @ if {[hascap o]} {
224 @ html "<a href='$home/brlist'>Branches</a> "
225 @ html "<a href='$home/taglist'>Tags</a> "
226 @ }
227 @ if {[hascap r]} {
228 @ html "<a href='$home/reportlist'>Tickets</a> "
229 @ }
230 @ if {[hascap j]} {
231 @ html "<a href='$home/wiki'>Wiki</a> "
232 @ }
233 @ if {[hascap s]} {
234 @ html "<a href='$home/setup'>Admin</a> "
235 @ } elseif {[hascap a]} {
236 @ html "<a href='$home/setup_ulist'>Users</a> "
237 @ }
238 @ if {[info exists login]} {
239 @ html "<a href='$home/login'>Logout</a> "
240 @ } else {
241 @ html "<a href='$home/login'>Login</a> "
242 @ }
243 @ </th1></div>
244 ;
245
246 /*
@@ -320,23 +321,24 @@
320 @ background-color: #558195;
321 @ color: white;
322 @ }
323 @
324 @ /* The submenu bar that *sometimes* appears below the main menu */
325 @ div.submenu {
326 @ padding: 3px 10px 3px 0px;
327 @ font-size: 0.9em;
328 @ text-align: center;
329 @ background-color: #456878;
330 @ color: white;
331 @ }
332 @ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited {
 
333 @ padding: 3px 10px 3px 10px;
334 @ color: white;
335 @ text-decoration: none;
336 @ }
337 @ div.mainmenu a:hover, div.submenu a:hover {
338 @ color: #558195;
339 @ background-color: white;
340 @ }
341 @
342 @ /* All page content from the bottom of the menu or submenu down to
@@ -396,10 +398,69 @@
396 @ table.label-value th {
397 @ vertical-align: top;
398 @ text-align: right;
399 @ padding: 0.2ex 2ex;
400 @ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
401 @
402 ;
403
404
405 /* The following table contains bits of default CSS that must
@@ -470,11 +531,11 @@
470 @ vertical-align: top;
471 @ text-align: right;
472 },
473 { "td.timelineGraph",
474 "the format for the grap placeholder cells in timelines",
475 @ width: 20;
476 @ text-align: left;
477 @ vertical-align: top;
478 },
479 { "a.tagLink",
480 "the format for the tag links",
@@ -564,11 +625,11 @@
564 @ vertical-align: top
565 },
566 { "table.usetupUserList",
567 "format for the user list table on the user setup page",
568 @ outline-style: double;
569 @ outline-width: 1;
570 @ padding: 10px;
571 },
572 { "th.usetupListUser",
573 "format for table header user in user list on user setup page",
574 @ text-align: right;
@@ -688,17 +749,17 @@
688 @ border-color: #000000;
689 @ border-style: solid;
690 },
691 { "input.checkinUserColor",
692 "format for user color input on checkin edit page",
693 @ # no special definitions, class defined, to enable color pickers, f.e.:
694 @ # add the color picker found at http:jscolor.com as java script include
695 @ # to the header and configure the java script file with
696 @ # 1. use as bindClass :checkinUserColor
697 @ # 2. change the default hash adding behaviour to ON
698 @ # or change the class defition of element identified by id="clrcust"
699 @ # to a standard jscolor definition with java script in the footer.
700 },
701 { "div.endContent",
702 "format for end of content area, to be used to clear page flow(sidebox on branch,..",
703 @ clear: both;
704 },
@@ -718,11 +779,11 @@
718 },
719 { "span.thTrace",
720 "format for th script trace messages",
721 @ color: red;
722 },
723 { "p:reportError",
724 "format for report configuration errors",
725 @ color: red;
726 @ font-weight: bold;
727 },
728 { "blockquote.reportError",
@@ -803,14 +864,26 @@
803 ** WEBPAGE: test_env
804 */
805 void page_test_env(void){
806 char c;
807 int i;
 
808 char zCap[30];
809 login_check_credentials();
810 if( !g.perm.Admin && !g.perm.Setup ){ login_needed(); return; }
 
 
 
811 style_header("Environment Test");
 
 
 
 
 
 
 
 
812 #if !defined(_WIN32)
813 @ uid=%d(getuid()), gid=%d(getgid())<br />
814 #endif
815 @ g.zBaseURL = %h(g.zBaseURL)<br />
816 @ g.zTop = %h(g.zTop)<br />
@@ -820,12 +893,12 @@
820 zCap[i] = 0;
821 @ g.userUid = %d(g.userUid)<br />
822 @ g.zLogin = %h(g.zLogin)<br />
823 @ capabilities = %s(zCap)<br />
824 @ <hr>
825 cgi_print_all();
826 if( g.perm.Setup ){
827 const char *zRedir = P("redirect");
828 if( zRedir ) cgi_redirect(zRedir);
829 }
830 style_footer();
831 }
832
--- src/style.c
+++ src/style.c
@@ -210,37 +210,38 @@
210 @ } else {
211 @ puts "Not logged in"
212 @ }
213 @ </th1></div>
214 @ </div>
215 @ <div class="mainmenu">
216 @ <th1>
217 @ html "<a href='$home$index_page'>Home</a>\n"
218 @ if {[anycap jor]} {
219 @ html "<a href='$home/timeline'>Timeline</a>\n"
220 @ }
221 @ if {[hascap oh]} {
222 @ html "<a href='$home/dir?ci=tip'>Files</a>\n"
223 @ }
224 @ if {[hascap o]} {
225 @ html "<a href='$home/brlist'>Branches</a>\n"
226 @ html "<a href='$home/taglist'>Tags</a>\n"
227 @ }
228 @ if {[hascap r]} {
229 @ html "<a href='$home/reportlist'>Tickets</a>\n"
230 @ }
231 @ if {[hascap j]} {
232 @ html "<a href='$home/wiki'>Wiki</a>\n"
233 @ }
234 @ if {[hascap s]} {
235 @ html "<a href='$home/setup'>Admin</a>\n"
236 @ } elseif {[hascap a]} {
237 @ html "<a href='$home/setup_ulist'>Users</a>\n"
238 @ }
239 @ if {[info exists login]} {
240 @ html "<a href='$home/login'>Logout</a>\n"
241 @ } else {
242 @ html "<a href='$home/login'>Login</a>\n"
243 @ }
244 @ </th1></div>
245 ;
246
247 /*
@@ -320,23 +321,24 @@
321 @ background-color: #558195;
322 @ color: white;
323 @ }
324 @
325 @ /* The submenu bar that *sometimes* appears below the main menu */
326 @ div.submenu, div.sectionmenu {
327 @ padding: 3px 10px 3px 0px;
328 @ font-size: 0.9em;
329 @ text-align: center;
330 @ background-color: #456878;
331 @ color: white;
332 @ }
333 @ div.mainmenu a, div.mainmenu a:visited, div.submenu a, div.submenu a:visited,
334 @ div.sectionmenu>a.button:link, div.sectionmenu>a.button:visited {
335 @ padding: 3px 10px 3px 10px;
336 @ color: white;
337 @ text-decoration: none;
338 @ }
339 @ div.mainmenu a:hover, div.submenu a:hover, div.sectionmenu>a.button:hover {
340 @ color: #558195;
341 @ background-color: white;
342 @ }
343 @
344 @ /* All page content from the bottom of the menu or submenu down to
@@ -396,10 +398,69 @@
398 @ table.label-value th {
399 @ vertical-align: top;
400 @ text-align: right;
401 @ padding: 0.2ex 2ex;
402 @ }
403 @
404 @ /* Side-by-side diff */
405 @ table.sbsdiff {
406 @ background-color: white;
407 @ font-family: fixed, Dejavu Sans Mono, Monaco, Lucida Console, monospace;
408 @ font-size: 8pt;
409 @ border-collapse:collapse;
410 @ white-space: pre;
411 @ width: 98%;
412 @ border: 1px #000 dashed;
413 @ margin-left: auto;
414 @ margin-right: auto;
415 @ }
416 @
417 @ table.sbsdiff th.diffhdr {
418 @ border-bottom: dotted;
419 @ border-width: 1px;
420 @ }
421 @
422 @ table.sbsdiff tr td {
423 @ white-space: pre;
424 @ padding-left: 3px;
425 @ padding-right: 3px;
426 @ margin: 0px;
427 @ vertical-align: top;
428 @ }
429 @
430 @ table.sbsdiff tr td.lineno {
431 @ text-align: right;
432 @ }
433 @
434 @ table.sbsdiff tr td.srcline {
435 @ }
436 @
437 @ table.sbsdiff tr td.meta {
438 @ background-color: rgb(170, 160, 255);
439 @ text-align: center;
440 @ }
441 @
442 @ table.sbsdiff tr td.added {
443 @ background-color: rgb(180, 250, 180);
444 @ }
445 @ table.sbsdiff tr td.addedvoid {
446 @ background-color: rgb(190, 190, 180);
447 @ }
448 @
449 @ table.sbsdiff tr td.removed {
450 @ background-color: rgb(250, 130, 130);
451 @ }
452 @ table.sbsdiff tr td.removedvoid {
453 @ background-color: rgb(190, 190, 180);
454 @ }
455 @
456 @ table.sbsdiff tr td.changed {
457 @ background-color: rgb(210, 210, 200);
458 @ }
459 @ table.sbsdiff tr td.changedvoid {
460 @ background-color: rgb(190, 190, 180);
461 @ }
462 @
463 ;
464
465
466 /* The following table contains bits of default CSS that must
@@ -470,11 +531,11 @@
531 @ vertical-align: top;
532 @ text-align: right;
533 },
534 { "td.timelineGraph",
535 "the format for the grap placeholder cells in timelines",
536 @ width: 20px;
537 @ text-align: left;
538 @ vertical-align: top;
539 },
540 { "a.tagLink",
541 "the format for the tag links",
@@ -564,11 +625,11 @@
625 @ vertical-align: top
626 },
627 { "table.usetupUserList",
628 "format for the user list table on the user setup page",
629 @ outline-style: double;
630 @ outline-width: 1px;
631 @ padding: 10px;
632 },
633 { "th.usetupListUser",
634 "format for table header user in user list on user setup page",
635 @ text-align: right;
@@ -688,17 +749,17 @@
749 @ border-color: #000000;
750 @ border-style: solid;
751 },
752 { "input.checkinUserColor",
753 "format for user color input on checkin edit page",
754 @ /* no special definitions, class defined, to enable color pickers, f.e.:
755 @ ** add the color picker found at http:jscolor.com as java script include
756 @ ** to the header and configure the java script file with
757 @ ** 1. use as bindClass :checkinUserColor
758 @ ** 2. change the default hash adding behaviour to ON
759 @ ** or change the class defition of element identified by id="clrcust"
760 @ ** to a standard jscolor definition with java script in the footer. */
761 },
762 { "div.endContent",
763 "format for end of content area, to be used to clear page flow(sidebox on branch,..",
764 @ clear: both;
765 },
@@ -718,11 +779,11 @@
779 },
780 { "span.thTrace",
781 "format for th script trace messages",
782 @ color: red;
783 },
784 { "p.reportError",
785 "format for report configuration errors",
786 @ color: red;
787 @ font-weight: bold;
788 },
789 { "blockquote.reportError",
@@ -803,14 +864,26 @@
864 ** WEBPAGE: test_env
865 */
866 void page_test_env(void){
867 char c;
868 int i;
869 int showAll;
870 char zCap[30];
871 login_check_credentials();
872 if( !g.perm.Admin && !g.perm.Setup && !db_get_boolean("test_env_enable",0) ){
873 login_needed();
874 return;
875 }
876 style_header("Environment Test");
877 showAll = atoi(PD("showall","0"));
878 if( !showAll ){
879 style_submenu_element("Show Cookies", "Show Cookies",
880 "%s/test_env?showall=1", g.zTop);
881 }else{
882 style_submenu_element("Hide Cookies", "Hide Cookies",
883 "%s/test_env", g.zTop);
884 }
885 #if !defined(_WIN32)
886 @ uid=%d(getuid()), gid=%d(getgid())<br />
887 #endif
888 @ g.zBaseURL = %h(g.zBaseURL)<br />
889 @ g.zTop = %h(g.zTop)<br />
@@ -820,12 +893,12 @@
893 zCap[i] = 0;
894 @ g.userUid = %d(g.userUid)<br />
895 @ g.zLogin = %h(g.zLogin)<br />
896 @ capabilities = %s(zCap)<br />
897 @ <hr>
898 cgi_print_all(atoi(PD("showall","0")));
899 if( g.perm.Setup ){
900 const char *zRedir = P("redirect");
901 if( zRedir ) cgi_redirect(zRedir);
902 }
903 style_footer();
904 }
905
+2 -2
--- src/th.c
+++ src/th.c
@@ -1817,12 +1817,12 @@
18171817
rc = thSubstWord(interp, pExpr->zValue, pExpr->nValue);
18181818
}else{
18191819
int eArgType = 0; /* Actual type of arguments */
18201820
18211821
/* Argument values */
1822
- int iLeft;
1823
- int iRight;
1822
+ int iLeft = 0;
1823
+ int iRight = 0;
18241824
double fLeft;
18251825
double fRight;
18261826
18271827
/* Left and right arguments as strings */
18281828
char *zLeft = 0; int nLeft = 0;
18291829
--- src/th.c
+++ src/th.c
@@ -1817,12 +1817,12 @@
1817 rc = thSubstWord(interp, pExpr->zValue, pExpr->nValue);
1818 }else{
1819 int eArgType = 0; /* Actual type of arguments */
1820
1821 /* Argument values */
1822 int iLeft;
1823 int iRight;
1824 double fLeft;
1825 double fRight;
1826
1827 /* Left and right arguments as strings */
1828 char *zLeft = 0; int nLeft = 0;
1829
--- src/th.c
+++ src/th.c
@@ -1817,12 +1817,12 @@
1817 rc = thSubstWord(interp, pExpr->zValue, pExpr->nValue);
1818 }else{
1819 int eArgType = 0; /* Actual type of arguments */
1820
1821 /* Argument values */
1822 int iLeft = 0;
1823 int iRight = 0;
1824 double fLeft;
1825 double fRight;
1826
1827 /* Left and right arguments as strings */
1828 char *zLeft = 0; int nLeft = 0;
1829
+28 -12
--- src/timeline.c
+++ src/timeline.c
@@ -179,11 +179,11 @@
179179
** 2. Date/Time
180180
** 3. Comment string
181181
** 4. User
182182
** 5. True if is a leaf
183183
** 6. background color
184
-** 7. type ("ci", "w", "t", "e", "div")
184
+** 7. type ("ci", "w", "t", "e", "g", "div")
185185
** 8. list of symbolic tags.
186186
** 9. tagid for ticket or wiki or event
187187
** 10. Short comment to user for repeated tickets and wiki
188188
*/
189189
void www_print_timeline(
@@ -316,10 +316,13 @@
316316
@</td>
317317
if( zBgClr && zBgClr[0] ){
318318
@ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
319319
}else{
320320
@ <td class="timelineTableCell">
321
+ }
322
+ if( pGraph && zType[0]!='c' ){
323
+ @ &bull;
321324
}
322325
if( zType[0]=='c' ){
323326
hyperlink_to_uuid(zUuid);
324327
if( isLeaf ){
325328
if( db_exists("SELECT 1 FROM tagxref"
@@ -840,23 +843,24 @@
840843
**
841844
** a=TIMESTAMP after this date
842845
** b=TIMESTAMP before this date.
843846
** c=TIMESTAMP "circa" this date.
844847
** n=COUNT number of events in output
845
-** p=RID artifact RID and up to COUNT parents and ancestors
846
-** d=RID artifact RID and up to COUNT descendants
848
+** p=UUID artifact and up to COUNT parents and ancestors
849
+** d=UUID artifact and up to COUNT descendants
850
+** dp=UUUID The same as d=UUID&p=UUID
847851
** t=TAGID show only check-ins with the given tagid
848852
** r=TAGID show check-ins related to tagid
849853
** u=USER only if belonging to this user
850854
** y=TYPE 'ci', 'w', 't', 'e'
851855
** s=TEXT string search (comment and brief)
852856
** ng Suppress the graph if present
853857
** nd Suppress "divider" lines
854858
** fc Show details of files changed
855
-** f=RID Show family (immediate parents and children) of RID
856
-** from=RID Path from...
857
-** to=RID ... to this
859
+** f=UUID Show family (immediate parents and children) of UUID
860
+** from=UUID Path from...
861
+** to=UUID ... to this
858862
** nomerge ... avoid merge links on the path
859863
** brbg Background color from branch name
860864
** ubg Background color from user
861865
**
862866
** p= and d= can appear individually or together. If either p= or d=
@@ -892,15 +896,23 @@
892896
int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
893897
int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
894898
int noMerge = P("nomerge")!=0; /* Do not follow merge links */
895899
int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */
896900
int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
901
+ int pd_rid;
897902
898903
/* To view the timeline, must have permission to read project data.
899904
*/
905
+ pd_rid = name_to_typed_rid(P("dp"),"ci");
906
+ if( pd_rid ){
907
+ p_rid = d_rid = pd_rid;
908
+ }
900909
login_check_credentials();
901
- if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; }
910
+ if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){
911
+ login_needed();
912
+ return;
913
+ }
902914
if( zTagName && g.perm.Read ){
903915
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
904916
zThisTag = zTagName;
905917
}else if( zBrName && g.perm.Read ){
906918
tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
@@ -988,14 +1000,12 @@
9881000
blob_appendf(&sql, " AND event.objid IN ok");
9891001
nd = 0;
9901002
if( d_rid ){
9911003
compute_descendants(d_rid, nEntry+1);
9921004
nd = db_int(0, "SELECT count(*)-1 FROM ok");
993
- if( nd>=0 ){
994
- db_multi_exec("%s", blob_str(&sql));
995
- blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
996
- }
1005
+ if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
1006
+ if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
9971007
if( useDividers ) timeline_add_dividers(0, d_rid);
9981008
db_multi_exec("DELETE FROM ok");
9991009
}
10001010
if( p_rid ){
10011011
compute_ancestors(p_rid, nEntry+1);
@@ -1075,19 +1085,20 @@
10751085
}
10761086
if( (zType[0]=='w' && !g.perm.RdWiki)
10771087
|| (zType[0]=='t' && !g.perm.RdTkt)
10781088
|| (zType[0]=='e' && !g.perm.RdWiki)
10791089
|| (zType[0]=='c' && !g.perm.Read)
1090
+ || (zType[0]=='g' && !g.perm.Read)
10801091
){
10811092
zType = "all";
10821093
}
10831094
if( zType[0]=='a' ){
10841095
if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
10851096
char cSep = '(';
10861097
blob_appendf(&sql, " AND event.type IN ");
10871098
if( g.perm.Read ){
1088
- blob_appendf(&sql, "%c'ci'", cSep);
1099
+ blob_appendf(&sql, "%c'ci','g'", cSep);
10891100
cSep = ',';
10901101
}
10911102
if( g.perm.RdWiki ){
10921103
blob_appendf(&sql, "%c'w','e'", cSep);
10931104
cSep = ',';
@@ -1107,10 +1118,12 @@
11071118
zEType = "wiki edit";
11081119
}else if( zType[0]=='t' ){
11091120
zEType = "ticket change";
11101121
}else if( zType[0]=='e' ){
11111122
zEType = "event";
1123
+ }else if( zType[0]=='g' ){
1124
+ zEType = "tag";
11121125
}
11131126
}
11141127
if( zUser ){
11151128
blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
11161129
zUser, zUser);
@@ -1226,10 +1239,13 @@
12261239
timeline_submenu(&url, "Tickets Only", "y", "t", 0);
12271240
}
12281241
if( zType[0]!='e' && g.perm.RdWiki ){
12291242
timeline_submenu(&url, "Events Only", "y", "e", 0);
12301243
}
1244
+ if( zType[0]!='g' && g.perm.Read ){
1245
+ timeline_submenu(&url, "Tags Only", "y", "g", 0);
1246
+ }
12311247
}
12321248
if( nEntry>20 ){
12331249
timeline_submenu(&url, "20 Entries", "n", "20", 0);
12341250
}
12351251
if( nEntry<200 ){
12361252
--- src/timeline.c
+++ src/timeline.c
@@ -179,11 +179,11 @@
179 ** 2. Date/Time
180 ** 3. Comment string
181 ** 4. User
182 ** 5. True if is a leaf
183 ** 6. background color
184 ** 7. type ("ci", "w", "t", "e", "div")
185 ** 8. list of symbolic tags.
186 ** 9. tagid for ticket or wiki or event
187 ** 10. Short comment to user for repeated tickets and wiki
188 */
189 void www_print_timeline(
@@ -316,10 +316,13 @@
316 @</td>
317 if( zBgClr && zBgClr[0] ){
318 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
319 }else{
320 @ <td class="timelineTableCell">
 
 
 
321 }
322 if( zType[0]=='c' ){
323 hyperlink_to_uuid(zUuid);
324 if( isLeaf ){
325 if( db_exists("SELECT 1 FROM tagxref"
@@ -840,23 +843,24 @@
840 **
841 ** a=TIMESTAMP after this date
842 ** b=TIMESTAMP before this date.
843 ** c=TIMESTAMP "circa" this date.
844 ** n=COUNT number of events in output
845 ** p=RID artifact RID and up to COUNT parents and ancestors
846 ** d=RID artifact RID and up to COUNT descendants
 
847 ** t=TAGID show only check-ins with the given tagid
848 ** r=TAGID show check-ins related to tagid
849 ** u=USER only if belonging to this user
850 ** y=TYPE 'ci', 'w', 't', 'e'
851 ** s=TEXT string search (comment and brief)
852 ** ng Suppress the graph if present
853 ** nd Suppress "divider" lines
854 ** fc Show details of files changed
855 ** f=RID Show family (immediate parents and children) of RID
856 ** from=RID Path from...
857 ** to=RID ... to this
858 ** nomerge ... avoid merge links on the path
859 ** brbg Background color from branch name
860 ** ubg Background color from user
861 **
862 ** p= and d= can appear individually or together. If either p= or d=
@@ -892,15 +896,23 @@
892 int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
893 int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
894 int noMerge = P("nomerge")!=0; /* Do not follow merge links */
895 int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */
896 int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
 
897
898 /* To view the timeline, must have permission to read project data.
899 */
 
 
 
 
900 login_check_credentials();
901 if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){ login_needed(); return; }
 
 
 
902 if( zTagName && g.perm.Read ){
903 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
904 zThisTag = zTagName;
905 }else if( zBrName && g.perm.Read ){
906 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
@@ -988,14 +1000,12 @@
988 blob_appendf(&sql, " AND event.objid IN ok");
989 nd = 0;
990 if( d_rid ){
991 compute_descendants(d_rid, nEntry+1);
992 nd = db_int(0, "SELECT count(*)-1 FROM ok");
993 if( nd>=0 ){
994 db_multi_exec("%s", blob_str(&sql));
995 blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
996 }
997 if( useDividers ) timeline_add_dividers(0, d_rid);
998 db_multi_exec("DELETE FROM ok");
999 }
1000 if( p_rid ){
1001 compute_ancestors(p_rid, nEntry+1);
@@ -1075,19 +1085,20 @@
1075 }
1076 if( (zType[0]=='w' && !g.perm.RdWiki)
1077 || (zType[0]=='t' && !g.perm.RdTkt)
1078 || (zType[0]=='e' && !g.perm.RdWiki)
1079 || (zType[0]=='c' && !g.perm.Read)
 
1080 ){
1081 zType = "all";
1082 }
1083 if( zType[0]=='a' ){
1084 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
1085 char cSep = '(';
1086 blob_appendf(&sql, " AND event.type IN ");
1087 if( g.perm.Read ){
1088 blob_appendf(&sql, "%c'ci'", cSep);
1089 cSep = ',';
1090 }
1091 if( g.perm.RdWiki ){
1092 blob_appendf(&sql, "%c'w','e'", cSep);
1093 cSep = ',';
@@ -1107,10 +1118,12 @@
1107 zEType = "wiki edit";
1108 }else if( zType[0]=='t' ){
1109 zEType = "ticket change";
1110 }else if( zType[0]=='e' ){
1111 zEType = "event";
 
 
1112 }
1113 }
1114 if( zUser ){
1115 blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1116 zUser, zUser);
@@ -1226,10 +1239,13 @@
1226 timeline_submenu(&url, "Tickets Only", "y", "t", 0);
1227 }
1228 if( zType[0]!='e' && g.perm.RdWiki ){
1229 timeline_submenu(&url, "Events Only", "y", "e", 0);
1230 }
 
 
 
1231 }
1232 if( nEntry>20 ){
1233 timeline_submenu(&url, "20 Entries", "n", "20", 0);
1234 }
1235 if( nEntry<200 ){
1236
--- src/timeline.c
+++ src/timeline.c
@@ -179,11 +179,11 @@
179 ** 2. Date/Time
180 ** 3. Comment string
181 ** 4. User
182 ** 5. True if is a leaf
183 ** 6. background color
184 ** 7. type ("ci", "w", "t", "e", "g", "div")
185 ** 8. list of symbolic tags.
186 ** 9. tagid for ticket or wiki or event
187 ** 10. Short comment to user for repeated tickets and wiki
188 */
189 void www_print_timeline(
@@ -316,10 +316,13 @@
316 @</td>
317 if( zBgClr && zBgClr[0] ){
318 @ <td class="timelineTableCell" style="background-color: %h(zBgClr);">
319 }else{
320 @ <td class="timelineTableCell">
321 }
322 if( pGraph && zType[0]!='c' ){
323 @ &bull;
324 }
325 if( zType[0]=='c' ){
326 hyperlink_to_uuid(zUuid);
327 if( isLeaf ){
328 if( db_exists("SELECT 1 FROM tagxref"
@@ -840,23 +843,24 @@
843 **
844 ** a=TIMESTAMP after this date
845 ** b=TIMESTAMP before this date.
846 ** c=TIMESTAMP "circa" this date.
847 ** n=COUNT number of events in output
848 ** p=UUID artifact and up to COUNT parents and ancestors
849 ** d=UUID artifact and up to COUNT descendants
850 ** dp=UUUID The same as d=UUID&p=UUID
851 ** t=TAGID show only check-ins with the given tagid
852 ** r=TAGID show check-ins related to tagid
853 ** u=USER only if belonging to this user
854 ** y=TYPE 'ci', 'w', 't', 'e'
855 ** s=TEXT string search (comment and brief)
856 ** ng Suppress the graph if present
857 ** nd Suppress "divider" lines
858 ** fc Show details of files changed
859 ** f=UUID Show family (immediate parents and children) of UUID
860 ** from=UUID Path from...
861 ** to=UUID ... to this
862 ** nomerge ... avoid merge links on the path
863 ** brbg Background color from branch name
864 ** ubg Background color from user
865 **
866 ** p= and d= can appear individually or together. If either p= or d=
@@ -892,15 +896,23 @@
896 int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
897 int to_rid = name_to_typed_rid(P("to"),"ci"); /* to= for path timelines */
898 int noMerge = P("nomerge")!=0; /* Do not follow merge links */
899 int me_rid = name_to_typed_rid(P("me"),"ci"); /* me= for common ancestory */
900 int you_rid = name_to_typed_rid(P("you"),"ci");/* you= for common ancst */
901 int pd_rid;
902
903 /* To view the timeline, must have permission to read project data.
904 */
905 pd_rid = name_to_typed_rid(P("dp"),"ci");
906 if( pd_rid ){
907 p_rid = d_rid = pd_rid;
908 }
909 login_check_credentials();
910 if( !g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki ){
911 login_needed();
912 return;
913 }
914 if( zTagName && g.perm.Read ){
915 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
916 zThisTag = zTagName;
917 }else if( zBrName && g.perm.Read ){
918 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
@@ -988,14 +1000,12 @@
1000 blob_appendf(&sql, " AND event.objid IN ok");
1001 nd = 0;
1002 if( d_rid ){
1003 compute_descendants(d_rid, nEntry+1);
1004 nd = db_int(0, "SELECT count(*)-1 FROM ok");
1005 if( nd>=0 ) db_multi_exec("%s", blob_str(&sql));
1006 if( nd>0 ) blob_appendf(&desc, "%d descendant%s", nd,(1==nd)?"":"s");
 
 
1007 if( useDividers ) timeline_add_dividers(0, d_rid);
1008 db_multi_exec("DELETE FROM ok");
1009 }
1010 if( p_rid ){
1011 compute_ancestors(p_rid, nEntry+1);
@@ -1075,19 +1085,20 @@
1085 }
1086 if( (zType[0]=='w' && !g.perm.RdWiki)
1087 || (zType[0]=='t' && !g.perm.RdTkt)
1088 || (zType[0]=='e' && !g.perm.RdWiki)
1089 || (zType[0]=='c' && !g.perm.Read)
1090 || (zType[0]=='g' && !g.perm.Read)
1091 ){
1092 zType = "all";
1093 }
1094 if( zType[0]=='a' ){
1095 if( !g.perm.Read || !g.perm.RdWiki || !g.perm.RdTkt ){
1096 char cSep = '(';
1097 blob_appendf(&sql, " AND event.type IN ");
1098 if( g.perm.Read ){
1099 blob_appendf(&sql, "%c'ci','g'", cSep);
1100 cSep = ',';
1101 }
1102 if( g.perm.RdWiki ){
1103 blob_appendf(&sql, "%c'w','e'", cSep);
1104 cSep = ',';
@@ -1107,10 +1118,12 @@
1118 zEType = "wiki edit";
1119 }else if( zType[0]=='t' ){
1120 zEType = "ticket change";
1121 }else if( zType[0]=='e' ){
1122 zEType = "event";
1123 }else if( zType[0]=='g' ){
1124 zEType = "tag";
1125 }
1126 }
1127 if( zUser ){
1128 blob_appendf(&sql, " AND (event.user=%Q OR event.euser=%Q)",
1129 zUser, zUser);
@@ -1226,10 +1239,13 @@
1239 timeline_submenu(&url, "Tickets Only", "y", "t", 0);
1240 }
1241 if( zType[0]!='e' && g.perm.RdWiki ){
1242 timeline_submenu(&url, "Events Only", "y", "e", 0);
1243 }
1244 if( zType[0]!='g' && g.perm.Read ){
1245 timeline_submenu(&url, "Tags Only", "y", "g", 0);
1246 }
1247 }
1248 if( nEntry>20 ){
1249 timeline_submenu(&url, "20 Entries", "n", "20", 0);
1250 }
1251 if( nEntry<200 ){
1252
-2
--- src/tkt.c
+++ src/tkt.c
@@ -170,11 +170,10 @@
170170
*/
171171
int ticket_insert(const Manifest *p, int createFlag, int rid){
172172
Blob sql;
173173
Stmt q;
174174
int i;
175
- const char *zSep;
176175
int rc = 0;
177176
178177
getAllTicketFields();
179178
if( createFlag ){
180179
db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) "
@@ -181,11 +180,10 @@
181180
"VALUES(%Q, 0)", p->zTicketUuid);
182181
rc = db_changes();
183182
}
184183
blob_zero(&sql);
185184
blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
186
- zSep = "SET";
187185
for(i=0; i<p->nField; i++){
188186
const char *zName = p->aField[i].zName;
189187
if( zName[0]=='+' ){
190188
zName++;
191189
if( fieldId(zName)<0 ) continue;
192190
--- src/tkt.c
+++ src/tkt.c
@@ -170,11 +170,10 @@
170 */
171 int ticket_insert(const Manifest *p, int createFlag, int rid){
172 Blob sql;
173 Stmt q;
174 int i;
175 const char *zSep;
176 int rc = 0;
177
178 getAllTicketFields();
179 if( createFlag ){
180 db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) "
@@ -181,11 +180,10 @@
181 "VALUES(%Q, 0)", p->zTicketUuid);
182 rc = db_changes();
183 }
184 blob_zero(&sql);
185 blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
186 zSep = "SET";
187 for(i=0; i<p->nField; i++){
188 const char *zName = p->aField[i].zName;
189 if( zName[0]=='+' ){
190 zName++;
191 if( fieldId(zName)<0 ) continue;
192
--- src/tkt.c
+++ src/tkt.c
@@ -170,11 +170,10 @@
170 */
171 int ticket_insert(const Manifest *p, int createFlag, int rid){
172 Blob sql;
173 Stmt q;
174 int i;
 
175 int rc = 0;
176
177 getAllTicketFields();
178 if( createFlag ){
179 db_multi_exec("INSERT OR IGNORE INTO ticket(tkt_uuid, tkt_mtime) "
@@ -181,11 +180,10 @@
180 "VALUES(%Q, 0)", p->zTicketUuid);
181 rc = db_changes();
182 }
183 blob_zero(&sql);
184 blob_appendf(&sql, "UPDATE OR REPLACE ticket SET tkt_mtime=:mtime");
 
185 for(i=0; i<p->nField; i++){
186 const char *zName = p->aField[i].zName;
187 if( zName[0]=='+' ){
188 zName++;
189 if( fieldId(zName)<0 ) continue;
190
+19 -8
--- src/update.c
+++ src/update.c
@@ -96,10 +96,11 @@
9696
int debugFlag; /* --debug option */
9797
int nChng; /* Number of file renames */
9898
int *aChng; /* Array of file renames */
9999
int i; /* Loop counter */
100100
int nConflict = 0; /* Number of merge conflicts */
101
+ int nOverwrite = 0; /* Number of unmanaged files overwritten */
101102
Stmt mtimeXfer; /* Statment to transfer mtimes */
102103
103104
if( !internalUpdate ){
104105
undo_capture_command_line();
105106
url_proxy_options();
@@ -359,11 +360,16 @@
359360
*/
360361
fossil_print("CONFLICT %s\n", zName);
361362
nConflict++;
362363
}else if( idt>0 && idv==0 ){
363364
/* File added in the target. */
364
- fossil_print("ADD %s\n", zName);
365
+ if( file_wd_isfile_or_link(zFullPath) ){
366
+ fossil_print("ADD %s (overwrites an unmanaged file)\n", zName);
367
+ nOverwrite++;
368
+ }else{
369
+ fossil_print("ADD %s\n", zName);
370
+ }
365371
undo_save(zName);
366372
if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
367373
}else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
368374
/* The file is unedited. Change it to the target version */
369375
undo_save(zName);
@@ -449,17 +455,22 @@
449455
fossil_print("--------------\n");
450456
show_common_info(tid, "updated-to:", 1, 0);
451457
452458
/* Report on conflicts
453459
*/
454
- if( nConflict && !nochangeFlag ){
455
- if( internalUpdate ){
456
- internalConflictCnt = nConflict;
457
- }else{
458
- fossil_print(
459
- "WARNING: %d merge conflicts - see messages above for details.\n",
460
- nConflict);
460
+ if( !nochangeFlag ){
461
+ if( nConflict ){
462
+ if( internalUpdate ){
463
+ internalConflictCnt = nConflict;
464
+ nConflict = 0;
465
+ }else{
466
+ fossil_print("WARNING: %d merge conflicts", nConflict);
467
+ }
468
+ }
469
+ if( nOverwrite ){
470
+ fossil_warning("WARNING: %d unmanaged files were overwritten",
471
+ nOverwrite);
461472
}
462473
}
463474
464475
/*
465476
** Clean up the mid and pid VFILE entries. Then commit the changes.
466477
--- src/update.c
+++ src/update.c
@@ -96,10 +96,11 @@
96 int debugFlag; /* --debug option */
97 int nChng; /* Number of file renames */
98 int *aChng; /* Array of file renames */
99 int i; /* Loop counter */
100 int nConflict = 0; /* Number of merge conflicts */
 
101 Stmt mtimeXfer; /* Statment to transfer mtimes */
102
103 if( !internalUpdate ){
104 undo_capture_command_line();
105 url_proxy_options();
@@ -359,11 +360,16 @@
359 */
360 fossil_print("CONFLICT %s\n", zName);
361 nConflict++;
362 }else if( idt>0 && idv==0 ){
363 /* File added in the target. */
364 fossil_print("ADD %s\n", zName);
 
 
 
 
 
365 undo_save(zName);
366 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
367 }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
368 /* The file is unedited. Change it to the target version */
369 undo_save(zName);
@@ -449,17 +455,22 @@
449 fossil_print("--------------\n");
450 show_common_info(tid, "updated-to:", 1, 0);
451
452 /* Report on conflicts
453 */
454 if( nConflict && !nochangeFlag ){
455 if( internalUpdate ){
456 internalConflictCnt = nConflict;
457 }else{
458 fossil_print(
459 "WARNING: %d merge conflicts - see messages above for details.\n",
460 nConflict);
 
 
 
 
 
461 }
462 }
463
464 /*
465 ** Clean up the mid and pid VFILE entries. Then commit the changes.
466
--- src/update.c
+++ src/update.c
@@ -96,10 +96,11 @@
96 int debugFlag; /* --debug option */
97 int nChng; /* Number of file renames */
98 int *aChng; /* Array of file renames */
99 int i; /* Loop counter */
100 int nConflict = 0; /* Number of merge conflicts */
101 int nOverwrite = 0; /* Number of unmanaged files overwritten */
102 Stmt mtimeXfer; /* Statment to transfer mtimes */
103
104 if( !internalUpdate ){
105 undo_capture_command_line();
106 url_proxy_options();
@@ -359,11 +360,16 @@
360 */
361 fossil_print("CONFLICT %s\n", zName);
362 nConflict++;
363 }else if( idt>0 && idv==0 ){
364 /* File added in the target. */
365 if( file_wd_isfile_or_link(zFullPath) ){
366 fossil_print("ADD %s (overwrites an unmanaged file)\n", zName);
367 nOverwrite++;
368 }else{
369 fossil_print("ADD %s\n", zName);
370 }
371 undo_save(zName);
372 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0);
373 }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){
374 /* The file is unedited. Change it to the target version */
375 undo_save(zName);
@@ -449,17 +455,22 @@
455 fossil_print("--------------\n");
456 show_common_info(tid, "updated-to:", 1, 0);
457
458 /* Report on conflicts
459 */
460 if( !nochangeFlag ){
461 if( nConflict ){
462 if( internalUpdate ){
463 internalConflictCnt = nConflict;
464 nConflict = 0;
465 }else{
466 fossil_print("WARNING: %d merge conflicts", nConflict);
467 }
468 }
469 if( nOverwrite ){
470 fossil_warning("WARNING: %d unmanaged files were overwritten",
471 nOverwrite);
472 }
473 }
474
475 /*
476 ** Clean up the mid and pid VFILE entries. Then commit the changes.
477
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1708,20 +1708,18 @@
17081708
/* Enter <verbatim> processing. With verbatim enabled, all other
17091709
** markup other than the corresponding end-tag with the same ID is
17101710
** ignored.
17111711
*/
17121712
if( markup.iCode==MARKUP_VERBATIM ){
1713
- int vAttrIdx, vAttrDidAppend=0;
1713
+ int vAttrIdx;
17141714
renderer.zVerbatimId = 0;
17151715
renderer.inVerbatim = 1;
17161716
renderer.preVerbState = renderer.state;
17171717
renderer.state &= ~ALLOW_WIKI;
17181718
for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
17191719
if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
17201720
renderer.zVerbatimId = markup.aAttr[0].zValue;
1721
- }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
1722
- vAttrDidAppend=1;
17231721
}
17241722
}
17251723
renderer.wantAutoParagraph = 0;
17261724
}
17271725
17281726
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1708,20 +1708,18 @@
1708 /* Enter <verbatim> processing. With verbatim enabled, all other
1709 ** markup other than the corresponding end-tag with the same ID is
1710 ** ignored.
1711 */
1712 if( markup.iCode==MARKUP_VERBATIM ){
1713 int vAttrIdx, vAttrDidAppend=0;
1714 renderer.zVerbatimId = 0;
1715 renderer.inVerbatim = 1;
1716 renderer.preVerbState = renderer.state;
1717 renderer.state &= ~ALLOW_WIKI;
1718 for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
1719 if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
1720 renderer.zVerbatimId = markup.aAttr[0].zValue;
1721 }else if( markup.aAttr[vAttrIdx].iACode == ATTR_TYPE ){
1722 vAttrDidAppend=1;
1723 }
1724 }
1725 renderer.wantAutoParagraph = 0;
1726 }
1727
1728
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1708,20 +1708,18 @@
1708 /* Enter <verbatim> processing. With verbatim enabled, all other
1709 ** markup other than the corresponding end-tag with the same ID is
1710 ** ignored.
1711 */
1712 if( markup.iCode==MARKUP_VERBATIM ){
1713 int vAttrIdx;
1714 renderer.zVerbatimId = 0;
1715 renderer.inVerbatim = 1;
1716 renderer.preVerbState = renderer.state;
1717 renderer.state &= ~ALLOW_WIKI;
1718 for (vAttrIdx = 0; vAttrIdx < markup.nAttr; vAttrIdx++){
1719 if( markup.aAttr[vAttrIdx].iACode == ATTR_ID ){
1720 renderer.zVerbatimId = markup.aAttr[0].zValue;
 
 
1721 }
1722 }
1723 renderer.wantAutoParagraph = 0;
1724 }
1725
1726
+1 -4
--- src/xfer.c
+++ src/xfer.c
@@ -1198,20 +1198,19 @@
11981198
**
11991199
** gdb fossil
12001200
** r test-xfer out.txt
12011201
*/
12021202
void cmd_test_xfer(void){
1203
- int notUsed;
12041203
db_find_and_open_repository(0,0);
12051204
if( g.argc!=2 && g.argc!=3 ){
12061205
usage("?MESSAGEFILE?");
12071206
}
12081207
blob_zero(&g.cgiIn);
12091208
blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]);
12101209
disableLogin = 1;
12111210
page_xfer();
1212
- fossil_print("%s\n", cgi_extract_content(&notUsed));
1211
+ fossil_print("%s\n", cgi_extract_content());
12131212
}
12141213
12151214
/*
12161215
** Format strings for progress reporting.
12171216
*/
@@ -1238,11 +1237,10 @@
12381237
int go = 1; /* Loop until zero */
12391238
int nCardSent = 0; /* Number of cards sent */
12401239
int nCardRcvd = 0; /* Number of cards received */
12411240
int nCycle = 0; /* Number of round trips to the server */
12421241
int size; /* Size of a config value */
1243
- int nFileSend = 0;
12441242
int origConfigRcvMask; /* Original value of configRcvMask */
12451243
int nFileRecv; /* Number of files received */
12461244
int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
12471245
const char *zCookie; /* Server cookie */
12481246
i64 nSent, nRcvd; /* Bytes sent and received (after compression) */
@@ -1380,11 +1378,10 @@
13801378
zRandomness = db_text(0, "SELECT hex(randomblob(20))");
13811379
blob_appendf(&send, "# %s\n", zRandomness);
13821380
free(zRandomness);
13831381
13841382
/* Exchange messages with the server */
1385
- nFileSend = xfer.nFileSent + xfer.nDeltaSent;
13861383
fossil_print(zValueFormat, "Sent:",
13871384
blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
13881385
xfer.nFileSent, xfer.nDeltaSent);
13891386
nCardSent = 0;
13901387
nCardRcvd = 0;
13911388
--- src/xfer.c
+++ src/xfer.c
@@ -1198,20 +1198,19 @@
1198 **
1199 ** gdb fossil
1200 ** r test-xfer out.txt
1201 */
1202 void cmd_test_xfer(void){
1203 int notUsed;
1204 db_find_and_open_repository(0,0);
1205 if( g.argc!=2 && g.argc!=3 ){
1206 usage("?MESSAGEFILE?");
1207 }
1208 blob_zero(&g.cgiIn);
1209 blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]);
1210 disableLogin = 1;
1211 page_xfer();
1212 fossil_print("%s\n", cgi_extract_content(&notUsed));
1213 }
1214
1215 /*
1216 ** Format strings for progress reporting.
1217 */
@@ -1238,11 +1237,10 @@
1238 int go = 1; /* Loop until zero */
1239 int nCardSent = 0; /* Number of cards sent */
1240 int nCardRcvd = 0; /* Number of cards received */
1241 int nCycle = 0; /* Number of round trips to the server */
1242 int size; /* Size of a config value */
1243 int nFileSend = 0;
1244 int origConfigRcvMask; /* Original value of configRcvMask */
1245 int nFileRecv; /* Number of files received */
1246 int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
1247 const char *zCookie; /* Server cookie */
1248 i64 nSent, nRcvd; /* Bytes sent and received (after compression) */
@@ -1380,11 +1378,10 @@
1380 zRandomness = db_text(0, "SELECT hex(randomblob(20))");
1381 blob_appendf(&send, "# %s\n", zRandomness);
1382 free(zRandomness);
1383
1384 /* Exchange messages with the server */
1385 nFileSend = xfer.nFileSent + xfer.nDeltaSent;
1386 fossil_print(zValueFormat, "Sent:",
1387 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1388 xfer.nFileSent, xfer.nDeltaSent);
1389 nCardSent = 0;
1390 nCardRcvd = 0;
1391
--- src/xfer.c
+++ src/xfer.c
@@ -1198,20 +1198,19 @@
1198 **
1199 ** gdb fossil
1200 ** r test-xfer out.txt
1201 */
1202 void cmd_test_xfer(void){
 
1203 db_find_and_open_repository(0,0);
1204 if( g.argc!=2 && g.argc!=3 ){
1205 usage("?MESSAGEFILE?");
1206 }
1207 blob_zero(&g.cgiIn);
1208 blob_read_from_file(&g.cgiIn, g.argc==2 ? "-" : g.argv[2]);
1209 disableLogin = 1;
1210 page_xfer();
1211 fossil_print("%s\n", cgi_extract_content());
1212 }
1213
1214 /*
1215 ** Format strings for progress reporting.
1216 */
@@ -1238,11 +1237,10 @@
1237 int go = 1; /* Loop until zero */
1238 int nCardSent = 0; /* Number of cards sent */
1239 int nCardRcvd = 0; /* Number of cards received */
1240 int nCycle = 0; /* Number of round trips to the server */
1241 int size; /* Size of a config value */
 
1242 int origConfigRcvMask; /* Original value of configRcvMask */
1243 int nFileRecv; /* Number of files received */
1244 int mxPhantomReq = 200; /* Max number of phantoms to request per comm */
1245 const char *zCookie; /* Server cookie */
1246 i64 nSent, nRcvd; /* Bytes sent and received (after compression) */
@@ -1380,11 +1378,10 @@
1378 zRandomness = db_text(0, "SELECT hex(randomblob(20))");
1379 blob_appendf(&send, "# %s\n", zRandomness);
1380 free(zRandomness);
1381
1382 /* Exchange messages with the server */
 
1383 fossil_print(zValueFormat, "Sent:",
1384 blob_size(&send), nCardSent+xfer.nGimmeSent+xfer.nIGotSent,
1385 xfer.nFileSent, xfer.nDeltaSent);
1386 nCardSent = 0;
1387 nCardRcvd = 0;
1388
--- test/merge5.test
+++ test/merge5.test
@@ -38,14 +38,18 @@
3838
}
3939
}
4040
4141
catch {exec $::fossilexe info} res
4242
puts res=$res
43
-if {![regexp {not within an open checkout} $res]} {
43
+if {![regexp {use --repository} $res]} {
4444
puts stderr "Cannot run this test within an open checkout"
4545
return
4646
}
47
+#
48
+# Fossil will write data on $HOME, running 'fossil open' here.
49
+# We need not to clutter the $HOME of the test caller.
50
+set env(HOME) [pwd]
4751
4852
# Construct a test repository
4953
#
5054
exec sqlite3 m5.fossil <$testdir/${testfile}_repo.sql
5155
fossil rebuild m5.fossil
5256
--- test/merge5.test
+++ test/merge5.test
@@ -38,14 +38,18 @@
38 }
39 }
40
41 catch {exec $::fossilexe info} res
42 puts res=$res
43 if {![regexp {not within an open checkout} $res]} {
44 puts stderr "Cannot run this test within an open checkout"
45 return
46 }
 
 
 
 
47
48 # Construct a test repository
49 #
50 exec sqlite3 m5.fossil <$testdir/${testfile}_repo.sql
51 fossil rebuild m5.fossil
52
--- test/merge5.test
+++ test/merge5.test
@@ -38,14 +38,18 @@
38 }
39 }
40
41 catch {exec $::fossilexe info} res
42 puts res=$res
43 if {![regexp {use --repository} $res]} {
44 puts stderr "Cannot run this test within an open checkout"
45 return
46 }
47 #
48 # Fossil will write data on $HOME, running 'fossil open' here.
49 # We need not to clutter the $HOME of the test caller.
50 set env(HOME) [pwd]
51
52 # Construct a test repository
53 #
54 exec sqlite3 m5.fossil <$testdir/${testfile}_repo.sql
55 fossil rebuild m5.fossil
56
--- test/merge_renames.test
+++ test/merge_renames.test
@@ -3,14 +3,20 @@
33
#
44
#
55
66
catch {exec $::fossilexe info} res
77
puts res=$res
8
-if {![regexp {not within an open checkout} $res]} {
8
+if {![regexp {use --repository} $res]} {
99
puts stderr "Cannot run this test within an open checkout"
1010
return
1111
}
12
+
13
+
14
+# Fossil will write data on $HOME, running 'fossil new' here.
15
+# We need not to clutter the $HOME of the test caller.
16
+set env(HOME) [pwd]
17
+
1218
1319
######################################
1420
# Test 1 #
1521
# Reported: Ticket [554f44ee74e3d] #
1622
######################################
1723
--- test/merge_renames.test
+++ test/merge_renames.test
@@ -3,14 +3,20 @@
3 #
4 #
5
6 catch {exec $::fossilexe info} res
7 puts res=$res
8 if {![regexp {not within an open checkout} $res]} {
9 puts stderr "Cannot run this test within an open checkout"
10 return
11 }
 
 
 
 
 
 
12
13 ######################################
14 # Test 1 #
15 # Reported: Ticket [554f44ee74e3d] #
16 ######################################
17
--- test/merge_renames.test
+++ test/merge_renames.test
@@ -3,14 +3,20 @@
3 #
4 #
5
6 catch {exec $::fossilexe info} res
7 puts res=$res
8 if {![regexp {use --repository} $res]} {
9 puts stderr "Cannot run this test within an open checkout"
10 return
11 }
12
13
14 # Fossil will write data on $HOME, running 'fossil new' here.
15 # We need not to clutter the $HOME of the test caller.
16 set env(HOME) [pwd]
17
18
19 ######################################
20 # Test 1 #
21 # Reported: Ticket [554f44ee74e3d] #
22 ######################################
23
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -19,11 +19,11 @@
1919
<blockquote><center><table border=1 cellpadding=5>
2020
<tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
2121
<tr><td>File versioning only</td>
2222
<td>Versioning, Tickets, Wiki, and Blog/News</td></tr>
2323
<tr><td>Sharding</td><td>Replicating</td></tr>
24
-<tr><td>Huge community</td><td>Road less traveled</td></tr>
24
+<tr><td>Developer branches</td><td>Feature branches</td></tr>
2525
<tr><td>Complex</td><td>Intuitive</td></tr>
2626
<tr><td>Separate web tools</td><td>Integrated Web interface</td></tr>
2727
<tr><td>Lots of little tools</td><td>Single executable</td></tr>
2828
<tr><td>Pile-of-files repository</td><td>Single file repository</td></tr>
2929
<tr><td>Uses "<tt>rebase</tt>"</td><td>Immutable</td></tr>
@@ -79,38 +79,49 @@
7979
The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy
8080
for multiple developers to work on a single branch and maintain
8181
linear development on that branch and avoid needless forking
8282
and merging.
8383
84
-<h3>3.3 Community</h3>
85
-
86
-Git has a huge user community. If following the herd and being
87
-like everybody else is important to you, then you should choose Git.
88
-
89
-Fossil is clearly the "road less traveled":
90
-
91
-<blockquote>
92
-Two roads diverged in a wood, and I &#151;<br>
93
-I took the one less traveled by,<br>
94
-And that has made all the difference.<br>
95
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
96
-<small>- Robert Frost, <i>The Road Not Taken</i>, 1916</small>
97
-</blockquote>
98
-</i></blockquote>
99
-
100
-Among the advantages of Git's huge user community are that new team
101
-members may already be familiar with Git's operation and hence can
102
-bypass the VCS learning curve. Also, if you need an add-on tool or
103
-script of some kind, a Google search will likely turn up a suitable
104
-tool that you can just download and use. A huge community also means
105
-that somebody else has likely already encountered and fixed the bugs
106
-so that Git will work for you and your project as advertised.
107
-
108
-Among the advantages of the "road less traveled" is that your particular
109
-project will be bigger percentage of the total user base, and is thus
110
-more likely to receive personal attention from the Fossil maintainers
111
-if you do encounter problems.
84
+<h3>3.3 Branches</h3>
85
+
86
+Git (and especially GitHub) encourages a workflow where each developer
87
+has his or her own branch or branches. Developers then send "pull requests"
88
+to have their changes be merged into "official" branches by integrators.
89
+For example, the Linux kernel team has a hierarchy of integrators with
90
+Linus Torvalds at the root. Individual developers each have their own
91
+private branches of the source tree into which they make their own changes.
92
+They then encourage first-tier integrators to pull those changes. The
93
+first-tier integrators merge together changes from multiple contributors
94
+then try to get second-tier integrators to pull their branches. The
95
+changes merge up the the hierarchy until (hopefully) they are pulled into
96
+"Linus's branch", at which time they become part of the "official" Linux.
97
+
98
+In Git, each branch is "owned" by the person who creates it and works
99
+on it. The owner might pull changes from others, but the owner is always
100
+in control of the branch. Branches are developer-centric.
101
+
102
+Fossil, on the other hand, encourages a workflow where branches are
103
+associated with features or releases, not individual developers.
104
+All developers share all branches in common, and two
105
+or more developers can and often do intersperse commits onto the same branch.
106
+Branches do not belong to individuals. All branches are read/write
107
+accessible to all developers at all times. There is no need
108
+for integrators to merge together changes from various independent
109
+developers. Instead, all of the developers work together cooperatively
110
+and the changes stay integrated naturally.
111
+
112
+So to a first approximation, branches in Git are developer-centric whereas
113
+branches in Fossil are feature-centric.
114
+
115
+The Git approach scales much better for large projects like the Linux
116
+kernel with thousands of contributors who in many cases don't even know
117
+each others names. The integrators serve a gatekeeper role to help keep
118
+undesirable code out of the official Linux source tree. On the other hand,
119
+not many projects are as big or as loosely organized as the Linux kernel.
120
+Most project, have a small team of developers who all know each other
121
+well and trust each other, and who enjoy working together collaboratively
122
+without the overhead and hierarchy of integrators.
112123
113124
<h3>3.4 Complexity</h3>
114125
115126
Git is a complex system. It can be tricky to use and requires a fair
116127
amount of knowledge and experience to master. Fossil strives to be
117128
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -19,11 +19,11 @@
19 <blockquote><center><table border=1 cellpadding=5>
20 <tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
21 <tr><td>File versioning only</td>
22 <td>Versioning, Tickets, Wiki, and Blog/News</td></tr>
23 <tr><td>Sharding</td><td>Replicating</td></tr>
24 <tr><td>Huge community</td><td>Road less traveled</td></tr>
25 <tr><td>Complex</td><td>Intuitive</td></tr>
26 <tr><td>Separate web tools</td><td>Integrated Web interface</td></tr>
27 <tr><td>Lots of little tools</td><td>Single executable</td></tr>
28 <tr><td>Pile-of-files repository</td><td>Single file repository</td></tr>
29 <tr><td>Uses "<tt>rebase</tt>"</td><td>Immutable</td></tr>
@@ -79,38 +79,49 @@
79 The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy
80 for multiple developers to work on a single branch and maintain
81 linear development on that branch and avoid needless forking
82 and merging.
83
84 <h3>3.3 Community</h3>
85
86 Git has a huge user community. If following the herd and being
87 like everybody else is important to you, then you should choose Git.
88
89 Fossil is clearly the "road less traveled":
90
91 <blockquote>
92 Two roads diverged in a wood, and I &#151;<br>
93 I took the one less traveled by,<br>
94 And that has made all the difference.<br>
95 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
96 <small>- Robert Frost, <i>The Road Not Taken</i>, 1916</small>
97 </blockquote>
98 </i></blockquote>
99
100 Among the advantages of Git's huge user community are that new team
101 members may already be familiar with Git's operation and hence can
102 bypass the VCS learning curve. Also, if you need an add-on tool or
103 script of some kind, a Google search will likely turn up a suitable
104 tool that you can just download and use. A huge community also means
105 that somebody else has likely already encountered and fixed the bugs
106 so that Git will work for you and your project as advertised.
107
108 Among the advantages of the "road less traveled" is that your particular
109 project will be bigger percentage of the total user base, and is thus
110 more likely to receive personal attention from the Fossil maintainers
111 if you do encounter problems.
 
 
 
 
 
 
 
 
 
 
 
112
113 <h3>3.4 Complexity</h3>
114
115 Git is a complex system. It can be tricky to use and requires a fair
116 amount of knowledge and experience to master. Fossil strives to be
117
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -19,11 +19,11 @@
19 <blockquote><center><table border=1 cellpadding=5>
20 <tr><th width="50%">GIT</th><th width="50%">FOSSIL</th></tr>
21 <tr><td>File versioning only</td>
22 <td>Versioning, Tickets, Wiki, and Blog/News</td></tr>
23 <tr><td>Sharding</td><td>Replicating</td></tr>
24 <tr><td>Developer branches</td><td>Feature branches</td></tr>
25 <tr><td>Complex</td><td>Intuitive</td></tr>
26 <tr><td>Separate web tools</td><td>Integrated Web interface</td></tr>
27 <tr><td>Lots of little tools</td><td>Single executable</td></tr>
28 <tr><td>Pile-of-files repository</td><td>Single file repository</td></tr>
29 <tr><td>Uses "<tt>rebase</tt>"</td><td>Immutable</td></tr>
@@ -79,38 +79,49 @@
79 The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy
80 for multiple developers to work on a single branch and maintain
81 linear development on that branch and avoid needless forking
82 and merging.
83
84 <h3>3.3 Branches</h3>
85
86 Git (and especially GitHub) encourages a workflow where each developer
87 has his or her own branch or branches. Developers then send "pull requests"
88 to have their changes be merged into "official" branches by integrators.
89 For example, the Linux kernel team has a hierarchy of integrators with
90 Linus Torvalds at the root. Individual developers each have their own
91 private branches of the source tree into which they make their own changes.
92 They then encourage first-tier integrators to pull those changes. The
93 first-tier integrators merge together changes from multiple contributors
94 then try to get second-tier integrators to pull their branches. The
95 changes merge up the the hierarchy until (hopefully) they are pulled into
96 "Linus's branch", at which time they become part of the "official" Linux.
97
98 In Git, each branch is "owned" by the person who creates it and works
99 on it. The owner might pull changes from others, but the owner is always
100 in control of the branch. Branches are developer-centric.
101
102 Fossil, on the other hand, encourages a workflow where branches are
103 associated with features or releases, not individual developers.
104 All developers share all branches in common, and two
105 or more developers can and often do intersperse commits onto the same branch.
106 Branches do not belong to individuals. All branches are read/write
107 accessible to all developers at all times. There is no need
108 for integrators to merge together changes from various independent
109 developers. Instead, all of the developers work together cooperatively
110 and the changes stay integrated naturally.
111
112 So to a first approximation, branches in Git are developer-centric whereas
113 branches in Fossil are feature-centric.
114
115 The Git approach scales much better for large projects like the Linux
116 kernel with thousands of contributors who in many cases don't even know
117 each others names. The integrators serve a gatekeeper role to help keep
118 undesirable code out of the official Linux source tree. On the other hand,
119 not many projects are as big or as loosely organized as the Linux kernel.
120 Most project, have a small team of developers who all know each other
121 well and trust each other, and who enjoy working together collaboratively
122 without the overhead and hierarchy of integrators.
123
124 <h3>3.4 Complexity</h3>
125
126 Git is a complex system. It can be tricky to use and requires a fair
127 amount of knowledge and experience to master. Fossil strives to be
128
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -85,6 +85,19 @@
8585
been a smoother ride than Git was.
8686
8787
<blockquote>
8888
<i>viablepanic at [http://www.reddit.com/r/programming/comments/bxcto/why_not_fossil_scm/]</i>
8989
</blockquote>
90
+
91
+<li>In the fossil community - and hence in fossil itself - development history
92
+is pretty much sacrosanct. The very name "fossil" was to chosen to
93
+reflect the unchanging nature of things in that history.
94
+
95
+<p>In git (or rather, the git community), the development history is part of
96
+the published aspect of the project, so it provides tools for rearranging
97
+that history so you can present what you "should" have done rather
98
+than what you actually did.
99
+
100
+<blockquote>
101
+<i>Mike Meyer on the Fossil mailing list, 2011-10-04</i>
102
+</blockquote>
90103
</ol>
91104
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -85,6 +85,19 @@
85 been a smoother ride than Git was.
86
87 <blockquote>
88 <i>viablepanic at [http://www.reddit.com/r/programming/comments/bxcto/why_not_fossil_scm/]</i>
89 </blockquote>
 
 
 
 
 
 
 
 
 
 
 
 
 
90 </ol>
91
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -85,6 +85,19 @@
85 been a smoother ride than Git was.
86
87 <blockquote>
88 <i>viablepanic at [http://www.reddit.com/r/programming/comments/bxcto/why_not_fossil_scm/]</i>
89 </blockquote>
90
91 <li>In the fossil community - and hence in fossil itself - development history
92 is pretty much sacrosanct. The very name "fossil" was to chosen to
93 reflect the unchanging nature of things in that history.
94
95 <p>In git (or rather, the git community), the development history is part of
96 the published aspect of the project, so it provides tools for rearranging
97 that history so you can present what you "should" have done rather
98 than what you actually did.
99
100 <blockquote>
101 <i>Mike Meyer on the Fossil mailing list, 2011-10-04</i>
102 </blockquote>
103 </ol>
104

Keyboard Shortcuts

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