Fossil SCM

Bring in latest fixes.

andybradford 2014-07-07 04:52 cluster-changes merge
Commit 088e961a2bcf223957a3a022cf42039852aa114b
--- src/clone.c
+++ src/clone.c
@@ -195,10 +195,11 @@
195195
}
196196
db_begin_transaction();
197197
fossil_print("Rebuilding repository meta-data...\n");
198198
rebuild_db(0, 1, 0);
199199
fossil_print("project-id: %s\n", db_get("project-code", 0));
200
+ fossil_print("server-id: %s\n", db_get("server-code", 0));
200201
zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
201202
fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
202203
db_end_transaction(0);
203204
}
204205
205206
--- src/clone.c
+++ src/clone.c
@@ -195,10 +195,11 @@
195 }
196 db_begin_transaction();
197 fossil_print("Rebuilding repository meta-data...\n");
198 rebuild_db(0, 1, 0);
199 fossil_print("project-id: %s\n", db_get("project-code", 0));
 
200 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
201 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
202 db_end_transaction(0);
203 }
204
205
--- src/clone.c
+++ src/clone.c
@@ -195,10 +195,11 @@
195 }
196 db_begin_transaction();
197 fossil_print("Rebuilding repository meta-data...\n");
198 rebuild_db(0, 1, 0);
199 fossil_print("project-id: %s\n", db_get("project-code", 0));
200 fossil_print("server-id: %s\n", db_get("server-code", 0));
201 zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
202 fossil_print("admin-user: %s (password is \"%s\")\n", g.zLogin, zPassword);
203 db_end_transaction(0);
204 }
205
206
--- src/http_socket.c
+++ src/http_socket.c
@@ -20,11 +20,11 @@
2020
**
2121
** This file implements a singleton. A single client socket may be active
2222
** at a time. State information is stored in static variables. The identity
2323
** of the server is held in global variables that are set by url_parse().
2424
**
25
-** Low-level sockets are abstracted out into this module because they
25
+** Low-level sockets are abstracted out into this module because they
2626
** are handled different on Unix and windows.
2727
*/
2828
2929
#include "config.h"
3030
#include "http_socket.h"
@@ -63,11 +63,11 @@
6363
}
6464
6565
/*
6666
** Set the socket error message.
6767
*/
68
-void socket_set_errmsg(char *zFormat, ...){
68
+void socket_set_errmsg(const char *zFormat, ...){
6969
va_list ap;
7070
socket_clear_errmsg();
7171
va_start(ap, zFormat);
7272
socketErrMsg = vmprintf(zFormat, ap);
7373
va_end(ap);
7474
--- src/http_socket.c
+++ src/http_socket.c
@@ -20,11 +20,11 @@
20 **
21 ** This file implements a singleton. A single client socket may be active
22 ** at a time. State information is stored in static variables. The identity
23 ** of the server is held in global variables that are set by url_parse().
24 **
25 ** Low-level sockets are abstracted out into this module because they
26 ** are handled different on Unix and windows.
27 */
28
29 #include "config.h"
30 #include "http_socket.h"
@@ -63,11 +63,11 @@
63 }
64
65 /*
66 ** Set the socket error message.
67 */
68 void socket_set_errmsg(char *zFormat, ...){
69 va_list ap;
70 socket_clear_errmsg();
71 va_start(ap, zFormat);
72 socketErrMsg = vmprintf(zFormat, ap);
73 va_end(ap);
74
--- src/http_socket.c
+++ src/http_socket.c
@@ -20,11 +20,11 @@
20 **
21 ** This file implements a singleton. A single client socket may be active
22 ** at a time. State information is stored in static variables. The identity
23 ** of the server is held in global variables that are set by url_parse().
24 **
25 ** Low-level sockets are abstracted out into this module because they
26 ** are handled different on Unix and windows.
27 */
28
29 #include "config.h"
30 #include "http_socket.h"
@@ -63,11 +63,11 @@
63 }
64
65 /*
66 ** Set the socket error message.
67 */
68 void socket_set_errmsg(const char *zFormat, ...){
69 va_list ap;
70 socket_clear_errmsg();
71 va_start(ap, zFormat);
72 socketErrMsg = vmprintf(zFormat, ap);
73 va_end(ap);
74
+16 -16
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -58,11 +58,11 @@
5858
}
5959
6060
/*
6161
** Set the SSL error message.
6262
*/
63
-void ssl_set_errmsg(char *zFormat, ...){
63
+void ssl_set_errmsg(const char *zFormat, ...){
6464
va_list ap;
6565
ssl_clear_errmsg();
6666
va_start(ap, zFormat);
6767
sslErrMsg = vmprintf(zFormat, ap);
6868
va_end(ap);
@@ -82,30 +82,30 @@
8282
static int ssl_client_cert_callback(SSL *ssl, X509 **x509, EVP_PKEY **pkey){
8383
fossil_warning("The remote server requested a client certificate for "
8484
"authentication. Specify the pathname to a file containing the PEM "
8585
"encoded certificate and private key with the --ssl-identity option "
8686
"or the ssl-identity setting.");
87
- return 0; /* no cert available */
87
+ return 0; /* no cert available */
8888
}
8989
9090
/*
9191
** Call this routine once before any other use of the SSL interface.
9292
** This routine does initial configuration of the SSL module.
9393
*/
9494
void ssl_global_init(void){
9595
const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
9696
const char *identityFile;
97
-
97
+
9898
if( sslIsInit==0 ){
9999
SSL_library_init();
100100
SSL_load_error_strings();
101101
ERR_load_BIO_strings();
102
- OpenSSL_add_all_algorithms();
102
+ OpenSSL_add_all_algorithms();
103103
sslCtx = SSL_CTX_new(SSLv23_client_method());
104104
/* Disable SSLv2 */
105105
SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2);
106
-
106
+
107107
/* Set up acceptable CA root certificates */
108108
zCaSetting = db_get("ssl-ca-location", 0);
109109
if( zCaSetting==0 || zCaSetting[0]=='\0' ){
110110
/* CA location not specified, use platform's default certificate store */
111111
X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
@@ -129,11 +129,11 @@
129129
if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
130130
fossil_fatal("Failed to use CA root certificates from "
131131
"ssl-ca-location '%s'", zCaSetting);
132132
}
133133
}
134
-
134
+
135135
/* Load client SSL identity, preferring the filename specified on the
136136
** command line */
137137
if( g.zSSLIdentity!=0 ){
138138
identityFile = g.zSSLIdentity;
139139
}else{
@@ -164,11 +164,11 @@
164164
sslIsInit = 0;
165165
}
166166
}
167167
168168
/*
169
-** Close the currently open SSL connection. If no connection is open,
169
+** Close the currently open SSL connection. If no connection is open,
170170
** this routine is a no-op.
171171
*/
172172
void ssl_close(void){
173173
if( iBio!=NULL ){
174174
(void)BIO_reset(iBio);
@@ -276,11 +276,11 @@
276276
BIO_push(iBio, sBio);
277277
}else{
278278
iBio = BIO_new_ssl_connect(sslCtx);
279279
}
280280
if( iBio==NULL ) {
281
- ssl_set_errmsg("SSL: cannot open SSL (%s)",
281
+ ssl_set_errmsg("SSL: cannot open SSL (%s)",
282282
ERR_reason_error_string(ERR_get_error()));
283283
return 1;
284284
}
285285
BIO_get_ssl(iBio, &ssl);
286286
@@ -295,19 +295,19 @@
295295
296296
if( !pUrlData->useProxy ){
297297
BIO_set_conn_hostname(iBio, pUrlData->name);
298298
BIO_set_conn_int_port(iBio, &pUrlData->port);
299299
if( BIO_do_connect(iBio)<=0 ){
300
- ssl_set_errmsg("SSL: cannot connect to host %s:%d (%s)",
300
+ ssl_set_errmsg("SSL: cannot connect to host %s:%d (%s)",
301301
pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error()));
302302
ssl_close();
303303
return 1;
304304
}
305305
}
306
-
306
+
307307
if( BIO_do_handshake(iBio)<=0 ) {
308
- ssl_set_errmsg("Error establishing SSL connection %s:%d (%s)",
308
+ ssl_set_errmsg("Error establishing SSL connection %s:%d (%s)",
309309
pUrlData->useProxy?pUrlData->hostname:pUrlData->name,
310310
pUrlData->useProxy?pUrlData->proxyOrigPort:pUrlData->port,
311311
ERR_reason_error_string(ERR_get_error()));
312312
ssl_close();
313313
return 1;
@@ -321,17 +321,17 @@
321321
return 1;
322322
}
323323
324324
if( trusted<=0 && (e = SSL_get_verify_result(ssl)) != X509_V_OK ){
325325
char *desc, *prompt;
326
- char *warning = "";
326
+ const char *warning = "";
327327
Blob ans;
328328
char cReply;
329329
BIO *mem;
330330
unsigned char md[32];
331331
unsigned int mdLength = 31;
332
-
332
+
333333
mem = BIO_new(BIO_s_mem());
334334
X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE);
335335
BIO_puts(mem, "\n\nIssued By:\n\n");
336336
X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE);
337337
BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n ");
@@ -341,11 +341,11 @@
341341
BIO_printf(mem, " %02x", md[j]);
342342
}
343343
}
344344
BIO_write(mem, "", 1); /* nul-terminate mem buffer */
345345
BIO_get_mem_data(mem, &desc);
346
-
346
+
347347
if( hasSavedCertificate ){
348348
warning = "WARNING: Certificate doesn't match the "
349349
"saved certificate for this host!";
350350
}
351351
prompt = mprintf("\nSSL verification failed: %s\n"
@@ -413,11 +413,11 @@
413413
db_set(zHost, zCert, 1);
414414
free(zHost);
415415
zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name);
416416
db_set_int(zHost, trusted, 1);
417417
free(zHost);
418
- BIO_free(mem);
418
+ BIO_free(mem);
419419
}
420420
421421
/*
422422
** Get certificate for pUrlData->urlName from global config.
423423
** Return NULL if no certificate found.
@@ -443,11 +443,11 @@
443443
444444
mem = BIO_new(BIO_s_mem());
445445
BIO_puts(mem, zCert);
446446
cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
447447
free(zCert);
448
- BIO_free(mem);
448
+ BIO_free(mem);
449449
return cert;
450450
}
451451
452452
/*
453453
** Send content out over the SSL connection.
454454
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -58,11 +58,11 @@
58 }
59
60 /*
61 ** Set the SSL error message.
62 */
63 void ssl_set_errmsg(char *zFormat, ...){
64 va_list ap;
65 ssl_clear_errmsg();
66 va_start(ap, zFormat);
67 sslErrMsg = vmprintf(zFormat, ap);
68 va_end(ap);
@@ -82,30 +82,30 @@
82 static int ssl_client_cert_callback(SSL *ssl, X509 **x509, EVP_PKEY **pkey){
83 fossil_warning("The remote server requested a client certificate for "
84 "authentication. Specify the pathname to a file containing the PEM "
85 "encoded certificate and private key with the --ssl-identity option "
86 "or the ssl-identity setting.");
87 return 0; /* no cert available */
88 }
89
90 /*
91 ** Call this routine once before any other use of the SSL interface.
92 ** This routine does initial configuration of the SSL module.
93 */
94 void ssl_global_init(void){
95 const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
96 const char *identityFile;
97
98 if( sslIsInit==0 ){
99 SSL_library_init();
100 SSL_load_error_strings();
101 ERR_load_BIO_strings();
102 OpenSSL_add_all_algorithms();
103 sslCtx = SSL_CTX_new(SSLv23_client_method());
104 /* Disable SSLv2 */
105 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2);
106
107 /* Set up acceptable CA root certificates */
108 zCaSetting = db_get("ssl-ca-location", 0);
109 if( zCaSetting==0 || zCaSetting[0]=='\0' ){
110 /* CA location not specified, use platform's default certificate store */
111 X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
@@ -129,11 +129,11 @@
129 if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
130 fossil_fatal("Failed to use CA root certificates from "
131 "ssl-ca-location '%s'", zCaSetting);
132 }
133 }
134
135 /* Load client SSL identity, preferring the filename specified on the
136 ** command line */
137 if( g.zSSLIdentity!=0 ){
138 identityFile = g.zSSLIdentity;
139 }else{
@@ -164,11 +164,11 @@
164 sslIsInit = 0;
165 }
166 }
167
168 /*
169 ** Close the currently open SSL connection. If no connection is open,
170 ** this routine is a no-op.
171 */
172 void ssl_close(void){
173 if( iBio!=NULL ){
174 (void)BIO_reset(iBio);
@@ -276,11 +276,11 @@
276 BIO_push(iBio, sBio);
277 }else{
278 iBio = BIO_new_ssl_connect(sslCtx);
279 }
280 if( iBio==NULL ) {
281 ssl_set_errmsg("SSL: cannot open SSL (%s)",
282 ERR_reason_error_string(ERR_get_error()));
283 return 1;
284 }
285 BIO_get_ssl(iBio, &ssl);
286
@@ -295,19 +295,19 @@
295
296 if( !pUrlData->useProxy ){
297 BIO_set_conn_hostname(iBio, pUrlData->name);
298 BIO_set_conn_int_port(iBio, &pUrlData->port);
299 if( BIO_do_connect(iBio)<=0 ){
300 ssl_set_errmsg("SSL: cannot connect to host %s:%d (%s)",
301 pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error()));
302 ssl_close();
303 return 1;
304 }
305 }
306
307 if( BIO_do_handshake(iBio)<=0 ) {
308 ssl_set_errmsg("Error establishing SSL connection %s:%d (%s)",
309 pUrlData->useProxy?pUrlData->hostname:pUrlData->name,
310 pUrlData->useProxy?pUrlData->proxyOrigPort:pUrlData->port,
311 ERR_reason_error_string(ERR_get_error()));
312 ssl_close();
313 return 1;
@@ -321,17 +321,17 @@
321 return 1;
322 }
323
324 if( trusted<=0 && (e = SSL_get_verify_result(ssl)) != X509_V_OK ){
325 char *desc, *prompt;
326 char *warning = "";
327 Blob ans;
328 char cReply;
329 BIO *mem;
330 unsigned char md[32];
331 unsigned int mdLength = 31;
332
333 mem = BIO_new(BIO_s_mem());
334 X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE);
335 BIO_puts(mem, "\n\nIssued By:\n\n");
336 X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE);
337 BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n ");
@@ -341,11 +341,11 @@
341 BIO_printf(mem, " %02x", md[j]);
342 }
343 }
344 BIO_write(mem, "", 1); /* nul-terminate mem buffer */
345 BIO_get_mem_data(mem, &desc);
346
347 if( hasSavedCertificate ){
348 warning = "WARNING: Certificate doesn't match the "
349 "saved certificate for this host!";
350 }
351 prompt = mprintf("\nSSL verification failed: %s\n"
@@ -413,11 +413,11 @@
413 db_set(zHost, zCert, 1);
414 free(zHost);
415 zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name);
416 db_set_int(zHost, trusted, 1);
417 free(zHost);
418 BIO_free(mem);
419 }
420
421 /*
422 ** Get certificate for pUrlData->urlName from global config.
423 ** Return NULL if no certificate found.
@@ -443,11 +443,11 @@
443
444 mem = BIO_new(BIO_s_mem());
445 BIO_puts(mem, zCert);
446 cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
447 free(zCert);
448 BIO_free(mem);
449 return cert;
450 }
451
452 /*
453 ** Send content out over the SSL connection.
454
--- src/http_ssl.c
+++ src/http_ssl.c
@@ -58,11 +58,11 @@
58 }
59
60 /*
61 ** Set the SSL error message.
62 */
63 void ssl_set_errmsg(const char *zFormat, ...){
64 va_list ap;
65 ssl_clear_errmsg();
66 va_start(ap, zFormat);
67 sslErrMsg = vmprintf(zFormat, ap);
68 va_end(ap);
@@ -82,30 +82,30 @@
82 static int ssl_client_cert_callback(SSL *ssl, X509 **x509, EVP_PKEY **pkey){
83 fossil_warning("The remote server requested a client certificate for "
84 "authentication. Specify the pathname to a file containing the PEM "
85 "encoded certificate and private key with the --ssl-identity option "
86 "or the ssl-identity setting.");
87 return 0; /* no cert available */
88 }
89
90 /*
91 ** Call this routine once before any other use of the SSL interface.
92 ** This routine does initial configuration of the SSL module.
93 */
94 void ssl_global_init(void){
95 const char *zCaSetting = 0, *zCaFile = 0, *zCaDirectory = 0;
96 const char *identityFile;
97
98 if( sslIsInit==0 ){
99 SSL_library_init();
100 SSL_load_error_strings();
101 ERR_load_BIO_strings();
102 OpenSSL_add_all_algorithms();
103 sslCtx = SSL_CTX_new(SSLv23_client_method());
104 /* Disable SSLv2 */
105 SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2);
106
107 /* Set up acceptable CA root certificates */
108 zCaSetting = db_get("ssl-ca-location", 0);
109 if( zCaSetting==0 || zCaSetting[0]=='\0' ){
110 /* CA location not specified, use platform's default certificate store */
111 X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
@@ -129,11 +129,11 @@
129 if( SSL_CTX_load_verify_locations(sslCtx, zCaFile, zCaDirectory)==0 ){
130 fossil_fatal("Failed to use CA root certificates from "
131 "ssl-ca-location '%s'", zCaSetting);
132 }
133 }
134
135 /* Load client SSL identity, preferring the filename specified on the
136 ** command line */
137 if( g.zSSLIdentity!=0 ){
138 identityFile = g.zSSLIdentity;
139 }else{
@@ -164,11 +164,11 @@
164 sslIsInit = 0;
165 }
166 }
167
168 /*
169 ** Close the currently open SSL connection. If no connection is open,
170 ** this routine is a no-op.
171 */
172 void ssl_close(void){
173 if( iBio!=NULL ){
174 (void)BIO_reset(iBio);
@@ -276,11 +276,11 @@
276 BIO_push(iBio, sBio);
277 }else{
278 iBio = BIO_new_ssl_connect(sslCtx);
279 }
280 if( iBio==NULL ) {
281 ssl_set_errmsg("SSL: cannot open SSL (%s)",
282 ERR_reason_error_string(ERR_get_error()));
283 return 1;
284 }
285 BIO_get_ssl(iBio, &ssl);
286
@@ -295,19 +295,19 @@
295
296 if( !pUrlData->useProxy ){
297 BIO_set_conn_hostname(iBio, pUrlData->name);
298 BIO_set_conn_int_port(iBio, &pUrlData->port);
299 if( BIO_do_connect(iBio)<=0 ){
300 ssl_set_errmsg("SSL: cannot connect to host %s:%d (%s)",
301 pUrlData->name, pUrlData->port, ERR_reason_error_string(ERR_get_error()));
302 ssl_close();
303 return 1;
304 }
305 }
306
307 if( BIO_do_handshake(iBio)<=0 ) {
308 ssl_set_errmsg("Error establishing SSL connection %s:%d (%s)",
309 pUrlData->useProxy?pUrlData->hostname:pUrlData->name,
310 pUrlData->useProxy?pUrlData->proxyOrigPort:pUrlData->port,
311 ERR_reason_error_string(ERR_get_error()));
312 ssl_close();
313 return 1;
@@ -321,17 +321,17 @@
321 return 1;
322 }
323
324 if( trusted<=0 && (e = SSL_get_verify_result(ssl)) != X509_V_OK ){
325 char *desc, *prompt;
326 const char *warning = "";
327 Blob ans;
328 char cReply;
329 BIO *mem;
330 unsigned char md[32];
331 unsigned int mdLength = 31;
332
333 mem = BIO_new(BIO_s_mem());
334 X509_NAME_print_ex(mem, X509_get_subject_name(cert), 2, XN_FLAG_MULTILINE);
335 BIO_puts(mem, "\n\nIssued By:\n\n");
336 X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_MULTILINE);
337 BIO_puts(mem, "\n\nSHA1 Fingerprint:\n\n ");
@@ -341,11 +341,11 @@
341 BIO_printf(mem, " %02x", md[j]);
342 }
343 }
344 BIO_write(mem, "", 1); /* nul-terminate mem buffer */
345 BIO_get_mem_data(mem, &desc);
346
347 if( hasSavedCertificate ){
348 warning = "WARNING: Certificate doesn't match the "
349 "saved certificate for this host!";
350 }
351 prompt = mprintf("\nSSL verification failed: %s\n"
@@ -413,11 +413,11 @@
413 db_set(zHost, zCert, 1);
414 free(zHost);
415 zHost = mprintf("trusted:%s", pUrlData->useProxy?pUrlData->hostname:pUrlData->name);
416 db_set_int(zHost, trusted, 1);
417 free(zHost);
418 BIO_free(mem);
419 }
420
421 /*
422 ** Get certificate for pUrlData->urlName from global config.
423 ** Return NULL if no certificate found.
@@ -443,11 +443,11 @@
443
444 mem = BIO_new(BIO_s_mem());
445 BIO_puts(mem, zCert);
446 cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
447 free(zCert);
448 BIO_free(mem);
449 return cert;
450 }
451
452 /*
453 ** Send content out over the SSL connection.
454
--- src/http_transport.c
+++ src/http_transport.c
@@ -77,12 +77,12 @@
7777
}
7878
7979
/*
8080
** Default SSH command
8181
*/
82
-#ifdef __MINGW32__
83
-static char zDefaultSshCmd[] = "ssh -T";
82
+#ifdef _WIN32
83
+static char zDefaultSshCmd[] = "plink -ssh -T";
8484
#else
8585
static char zDefaultSshCmd[] = "ssh -e none -T";
8686
#endif
8787
8888
/*
@@ -99,11 +99,11 @@
9999
100100
socket_ssh_resolve_addr(pUrlData);
101101
zSsh = db_get("ssh-command", zDefaultSshCmd);
102102
blob_init(&zCmd, zSsh, -1);
103103
if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){
104
-#ifdef __MINGW32__
104
+#ifdef _WIN32
105105
blob_appendf(&zCmd, " -P %d", pUrlData->port);
106106
#else
107107
blob_appendf(&zCmd, " -p %d", pUrlData->port);
108108
#endif
109109
}
110110
--- src/http_transport.c
+++ src/http_transport.c
@@ -77,12 +77,12 @@
77 }
78
79 /*
80 ** Default SSH command
81 */
82 #ifdef __MINGW32__
83 static char zDefaultSshCmd[] = "ssh -T";
84 #else
85 static char zDefaultSshCmd[] = "ssh -e none -T";
86 #endif
87
88 /*
@@ -99,11 +99,11 @@
99
100 socket_ssh_resolve_addr(pUrlData);
101 zSsh = db_get("ssh-command", zDefaultSshCmd);
102 blob_init(&zCmd, zSsh, -1);
103 if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){
104 #ifdef __MINGW32__
105 blob_appendf(&zCmd, " -P %d", pUrlData->port);
106 #else
107 blob_appendf(&zCmd, " -p %d", pUrlData->port);
108 #endif
109 }
110
--- src/http_transport.c
+++ src/http_transport.c
@@ -77,12 +77,12 @@
77 }
78
79 /*
80 ** Default SSH command
81 */
82 #ifdef _WIN32
83 static char zDefaultSshCmd[] = "plink -ssh -T";
84 #else
85 static char zDefaultSshCmd[] = "ssh -e none -T";
86 #endif
87
88 /*
@@ -99,11 +99,11 @@
99
100 socket_ssh_resolve_addr(pUrlData);
101 zSsh = db_get("ssh-command", zDefaultSshCmd);
102 blob_init(&zCmd, zSsh, -1);
103 if( pUrlData->port!=pUrlData->dfltPort && pUrlData->port ){
104 #ifdef _WIN32
105 blob_appendf(&zCmd, " -P %d", pUrlData->port);
106 #else
107 blob_appendf(&zCmd, " -p %d", pUrlData->port);
108 #endif
109 }
110
--- src/manifest.c
+++ src/manifest.c
@@ -1261,10 +1261,11 @@
12611261
p->iFile = i;
12621262
return &p->aFile[i];
12631263
}
12641264
}
12651265
if( bBest ){
1266
+ if( lwr>=p->nFile ) lwr = p->nFile-1;
12661267
i = (int)strlen(zName);
12671268
if( strncmp(zName, p->aFile[lwr].zName, i)==0 ) return &p->aFile[lwr];
12681269
}
12691270
return 0;
12701271
}
12711272
--- src/manifest.c
+++ src/manifest.c
@@ -1261,10 +1261,11 @@
1261 p->iFile = i;
1262 return &p->aFile[i];
1263 }
1264 }
1265 if( bBest ){
 
1266 i = (int)strlen(zName);
1267 if( strncmp(zName, p->aFile[lwr].zName, i)==0 ) return &p->aFile[lwr];
1268 }
1269 return 0;
1270 }
1271
--- src/manifest.c
+++ src/manifest.c
@@ -1261,10 +1261,11 @@
1261 p->iFile = i;
1262 return &p->aFile[i];
1263 }
1264 }
1265 if( bBest ){
1266 if( lwr>=p->nFile ) lwr = p->nFile-1;
1267 i = (int)strlen(zName);
1268 if( strncmp(zName, p->aFile[lwr].zName, i)==0 ) return &p->aFile[lwr];
1269 }
1270 return 0;
1271 }
1272
+39
--- src/shell.c
+++ src/shell.c
@@ -1581,10 +1581,11 @@
15811581
".echo on|off Turn command echo on or off\n"
15821582
".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
15831583
".exit Exit this program\n"
15841584
".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
15851585
" With no args, it turns EXPLAIN on.\n"
1586
+ ".fullschema Show schema and the content of sqlite_stat tables\n"
15861587
".headers on|off Turn display of headers on or off\n"
15871588
".help Show this message\n"
15881589
".import FILE TABLE Import data from FILE into TABLE\n"
15891590
".indices ?TABLE? Show names of all indices\n"
15901591
" If TABLE specified, only show indices for tables\n"
@@ -2409,10 +2410,48 @@
24092410
p->mode = p->explainPrev.mode;
24102411
p->showHeader = p->explainPrev.showHeader;
24112412
memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
24122413
}
24132414
}else
2415
+
2416
+ if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
2417
+ struct callback_data data;
2418
+ char *zErrMsg = 0;
2419
+ if( nArg!=1 ){
2420
+ fprintf(stderr, "Usage: .fullschema\n");
2421
+ rc = 1;
2422
+ goto meta_command_exit;
2423
+ }
2424
+ open_db(p, 0);
2425
+ memcpy(&data, p, sizeof(data));
2426
+ data.showHeader = 0;
2427
+ data.mode = MODE_Semi;
2428
+ rc = sqlite3_exec(p->db,
2429
+ "SELECT sql FROM"
2430
+ " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2431
+ " FROM sqlite_master UNION ALL"
2432
+ " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
2433
+ "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
2434
+ "ORDER BY rowid",
2435
+ callback, &data, &zErrMsg
2436
+ );
2437
+ sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master;'",
2438
+ callback, &data, &zErrMsg);
2439
+ data.mode = MODE_Insert;
2440
+ data.zDestTable = "sqlite_stat1";
2441
+ shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2442
+ shell_callback, &data,&zErrMsg);
2443
+ data.zDestTable = "sqlite_stat3";
2444
+ shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2445
+ shell_callback, &data,&zErrMsg);
2446
+ data.zDestTable = "sqlite_stat4";
2447
+ shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2448
+ shell_callback, &data, &zErrMsg);
2449
+ data.mode = MODE_Semi;
2450
+ shell_exec(p->db, "SELECT 'ANALYZE sqlite_master;'",
2451
+ shell_callback, &data, &zErrMsg);
2452
+ }else
24142453
24152454
if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
24162455
if( nArg==2 ){
24172456
p->showHeader = booleanValue(azArg[1]);
24182457
}else{
24192458
--- src/shell.c
+++ src/shell.c
@@ -1581,10 +1581,11 @@
1581 ".echo on|off Turn command echo on or off\n"
1582 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
1583 ".exit Exit this program\n"
1584 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
1585 " With no args, it turns EXPLAIN on.\n"
 
1586 ".headers on|off Turn display of headers on or off\n"
1587 ".help Show this message\n"
1588 ".import FILE TABLE Import data from FILE into TABLE\n"
1589 ".indices ?TABLE? Show names of all indices\n"
1590 " If TABLE specified, only show indices for tables\n"
@@ -2409,10 +2410,48 @@
2409 p->mode = p->explainPrev.mode;
2410 p->showHeader = p->explainPrev.showHeader;
2411 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2412 }
2413 }else
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2414
2415 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2416 if( nArg==2 ){
2417 p->showHeader = booleanValue(azArg[1]);
2418 }else{
2419
--- src/shell.c
+++ src/shell.c
@@ -1581,10 +1581,11 @@
1581 ".echo on|off Turn command echo on or off\n"
1582 ".eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN\n"
1583 ".exit Exit this program\n"
1584 ".explain ?on|off? Turn output mode suitable for EXPLAIN on or off.\n"
1585 " With no args, it turns EXPLAIN on.\n"
1586 ".fullschema Show schema and the content of sqlite_stat tables\n"
1587 ".headers on|off Turn display of headers on or off\n"
1588 ".help Show this message\n"
1589 ".import FILE TABLE Import data from FILE into TABLE\n"
1590 ".indices ?TABLE? Show names of all indices\n"
1591 " If TABLE specified, only show indices for tables\n"
@@ -2409,10 +2410,48 @@
2410 p->mode = p->explainPrev.mode;
2411 p->showHeader = p->explainPrev.showHeader;
2412 memcpy(p->colWidth,p->explainPrev.colWidth,sizeof(p->colWidth));
2413 }
2414 }else
2415
2416 if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
2417 struct callback_data data;
2418 char *zErrMsg = 0;
2419 if( nArg!=1 ){
2420 fprintf(stderr, "Usage: .fullschema\n");
2421 rc = 1;
2422 goto meta_command_exit;
2423 }
2424 open_db(p, 0);
2425 memcpy(&data, p, sizeof(data));
2426 data.showHeader = 0;
2427 data.mode = MODE_Semi;
2428 rc = sqlite3_exec(p->db,
2429 "SELECT sql FROM"
2430 " (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
2431 " FROM sqlite_master UNION ALL"
2432 " SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
2433 "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%'"
2434 "ORDER BY rowid",
2435 callback, &data, &zErrMsg
2436 );
2437 sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master;'",
2438 callback, &data, &zErrMsg);
2439 data.mode = MODE_Insert;
2440 data.zDestTable = "sqlite_stat1";
2441 shell_exec(p->db, "SELECT * FROM sqlite_stat1",
2442 shell_callback, &data,&zErrMsg);
2443 data.zDestTable = "sqlite_stat3";
2444 shell_exec(p->db, "SELECT * FROM sqlite_stat3",
2445 shell_callback, &data,&zErrMsg);
2446 data.zDestTable = "sqlite_stat4";
2447 shell_exec(p->db, "SELECT * FROM sqlite_stat4",
2448 shell_callback, &data, &zErrMsg);
2449 data.mode = MODE_Semi;
2450 shell_exec(p->db, "SELECT 'ANALYZE sqlite_master;'",
2451 shell_callback, &data, &zErrMsg);
2452 }else
2453
2454 if( c=='h' && strncmp(azArg[0], "headers", n)==0 ){
2455 if( nArg==2 ){
2456 p->showHeader = booleanValue(azArg[1]);
2457 }else{
2458
+505 -237
--- 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.8.5. By combining all the individual C code files into this
3
+** version 3.8.6. 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.
@@ -220,13 +220,13 @@
220220
**
221221
** See also: [sqlite3_libversion()],
222222
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
223223
** [sqlite_version()] and [sqlite_source_id()].
224224
*/
225
-#define SQLITE_VERSION "3.8.5"
226
-#define SQLITE_VERSION_NUMBER 3008005
227
-#define SQLITE_SOURCE_ID "2014-06-04 14:06:34 b1ed4f2a34ba66c29b130f8d13e9092758019212"
225
+#define SQLITE_VERSION "3.8.6"
226
+#define SQLITE_VERSION_NUMBER 3008006
227
+#define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41"
228228
229229
/*
230230
** CAPI3REF: Run-Time Library Version Numbers
231231
** KEYWORDS: sqlite3_version, sqlite3_sourceid
232232
**
@@ -9479,10 +9479,11 @@
94799479
SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
94809480
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
94819481
#ifndef SQLITE_OMIT_TRACE
94829482
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
94839483
#endif
9484
+SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
94849485
94859486
SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
94869487
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
94879488
SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
94889489
@@ -12885,11 +12886,13 @@
1288512886
SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
1288612887
1288712888
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
1288812889
SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
1288912890
SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
12891
+SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
1289012892
SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
12893
+SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
1289112894
#endif
1289212895
1289312896
/*
1289412897
** The interface to the LEMON-generated parser
1289512898
*/
@@ -14199,11 +14202,10 @@
1419914202
SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
1420014203
1420114204
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
1420214205
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
1420314206
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
14204
-SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
1420514207
SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
1420614208
SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
1420714209
SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
1420814210
SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
1420914211
SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21562,12 +21564,12 @@
2156221564
** * Bytes in the range of 0x80 through 0xbf which occur as the first
2156321565
** byte of a character are interpreted as single-byte characters
2156421566
** and rendered as themselves even though they are technically
2156521567
** invalid characters.
2156621568
**
21567
-** * This routine accepts an infinite number of different UTF8 encodings
21568
-** for unicode values 0x80 and greater. It do not change over-length
21569
+** * This routine accepts over-length UTF8 encodings
21570
+** for unicode values 0x80 and greater. It does not change over-length
2156921571
** encodings to 0xfffd as some systems recommend.
2157021572
*/
2157121573
#define READ_UTF8(zIn, zTerm, c) \
2157221574
c = *(zIn++); \
2157321575
if( c>=0xc0 ){ \
@@ -24371,14 +24373,14 @@
2437124373
{ "mremap", (sqlite3_syscall_ptr)mremap, 0 },
2437224374
#else
2437324375
{ "mremap", (sqlite3_syscall_ptr)0, 0 },
2437424376
#endif
2437524377
#define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
24376
-#endif
24377
-
2437824378
{ "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
2437924379
#define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
24380
+
24381
+#endif
2438024382
2438124383
}; /* End of the overrideable system calls */
2438224384
2438324385
/*
2438424386
** This is the xSetSystemCall() method of sqlite3_vfs for all of the
@@ -25844,10 +25846,17 @@
2584425846
osUnlink(pFile->pId->zCanonicalName);
2584525847
}
2584625848
vxworksReleaseFileId(pFile->pId);
2584725849
pFile->pId = 0;
2584825850
}
25851
+#endif
25852
+#ifdef SQLITE_UNLINK_AFTER_CLOSE
25853
+ if( pFile->ctrlFlags & UNIXFILE_DELETE ){
25854
+ osUnlink(pFile->zPath);
25855
+ sqlite3_free(*(char**)&pFile->zPath);
25856
+ pFile->zPath = 0;
25857
+ }
2584925858
#endif
2585025859
OSTRACE(("CLOSE %-3d\n", pFile->h));
2585125860
OpenCounter(-1);
2585225861
sqlite3_free(pFile->pUnused);
2585325862
memset(pFile, 0, sizeof(unixFile));
@@ -27883,12 +27892,29 @@
2788327892
rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
2788427893
}
2788527894
return rc;
2788627895
}
2788727896
27897
+#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
27898
+
27899
+/*
27900
+** Return the system page size.
27901
+**
27902
+** This function should not be called directly by other code in this file.
27903
+** Instead, it should be called via macro osGetpagesize().
27904
+*/
27905
+static int unixGetpagesize(void){
27906
+#if defined(_BSD_SOURCE)
27907
+ return getpagesize();
27908
+#else
27909
+ return (int)sysconf(_SC_PAGESIZE);
27910
+#endif
27911
+}
27912
+
27913
+#endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */
27914
+
2788827915
#ifndef SQLITE_OMIT_WAL
27889
-
2789027916
2789127917
/*
2789227918
** Object used to represent an shared memory buffer.
2789327919
**
2789427920
** When multiple threads all reference the same wal-index, each thread
@@ -28035,24 +28061,10 @@
2803528061
#endif
2803628062
2803728063
return rc;
2803828064
}
2803928065
28040
-/*
28041
-** Return the system page size.
28042
-**
28043
-** This function should not be called directly by other code in this file.
28044
-** Instead, it should be called via macro osGetpagesize().
28045
-*/
28046
-static int unixGetpagesize(void){
28047
-#if defined(_BSD_SOURCE)
28048
- return getpagesize();
28049
-#else
28050
- return (int)sysconf(_SC_PAGESIZE);
28051
-#endif
28052
-}
28053
-
2805428066
/*
2805528067
** Return the minimum number of 32KB shm regions that should be mapped at
2805628068
** a time, assuming that each mapping must be an integer multiple of the
2805728069
** current system page-size.
2805828070
**
@@ -29698,10 +29710,16 @@
2969829710
}
2969929711
2970029712
if( isDelete ){
2970129713
#if OS_VXWORKS
2970229714
zPath = zName;
29715
+#elif defined(SQLITE_UNLINK_AFTER_CLOSE)
29716
+ zPath = sqlite3_mprintf("%s", zName);
29717
+ if( zPath==0 ){
29718
+ robust_close(p, fd, __LINE__);
29719
+ return SQLITE_NOMEM;
29720
+ }
2970329721
#else
2970429722
osUnlink(zName);
2970529723
#endif
2970629724
}
2970729725
#if SQLITE_ENABLE_LOCKING_STYLE
@@ -49189,20 +49207,20 @@
4918949207
**
4919049208
** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few
4919149209
** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this
4919249210
** is more of a scheduler yield than an actual delay. But on the 10th
4919349211
** an subsequent retries, the delays start becoming longer and longer,
49194
- ** so that on the 100th (and last) RETRY we delay for 21 milliseconds.
49195
- ** The total delay time before giving up is less than 1 second.
49212
+ ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
49213
+ ** The total delay time before giving up is less than 10 seconds.
4919649214
*/
4919749215
if( cnt>5 ){
4919849216
int nDelay = 1; /* Pause time in microseconds */
4919949217
if( cnt>100 ){
4920049218
VVA_ONLY( pWal->lockError = 1; )
4920149219
return SQLITE_PROTOCOL;
4920249220
}
49203
- if( cnt>=10 ) nDelay = (cnt-9)*238; /* Max delay 21ms. Total delay 996ms */
49221
+ if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
4920449222
sqlite3OsSleep(pWal->pVfs, nDelay);
4920549223
}
4920649224
4920749225
if( !useWal ){
4920849226
rc = walIndexReadHdr(pWal, pChanged);
@@ -61582,10 +61600,72 @@
6158261600
FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
6158361601
for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
6158461602
sqlite3FuncDefInsert(pHash, &aFunc[i]);
6158561603
}
6158661604
}
61605
+
61606
+/*
61607
+** Attempt to extract a value from pExpr and use it to construct *ppVal.
61608
+**
61609
+** If pAlloc is not NULL, then an UnpackedRecord object is created for
61610
+** pAlloc if one does not exist and the new value is added to the
61611
+** UnpackedRecord object.
61612
+**
61613
+** A value is extracted in the following cases:
61614
+**
61615
+** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
61616
+**
61617
+** * The expression is a bound variable, and this is a reprepare, or
61618
+**
61619
+** * The expression is a literal value.
61620
+**
61621
+** On success, *ppVal is made to point to the extracted value. The caller
61622
+** is responsible for ensuring that the value is eventually freed.
61623
+*/
61624
+static int stat4ValueFromExpr(
61625
+ Parse *pParse, /* Parse context */
61626
+ Expr *pExpr, /* The expression to extract a value from */
61627
+ u8 affinity, /* Affinity to use */
61628
+ struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */
61629
+ sqlite3_value **ppVal /* OUT: New value object (or NULL) */
61630
+){
61631
+ int rc = SQLITE_OK;
61632
+ sqlite3_value *pVal = 0;
61633
+ sqlite3 *db = pParse->db;
61634
+
61635
+ /* Skip over any TK_COLLATE nodes */
61636
+ pExpr = sqlite3ExprSkipCollate(pExpr);
61637
+
61638
+ if( !pExpr ){
61639
+ pVal = valueNew(db, pAlloc);
61640
+ if( pVal ){
61641
+ sqlite3VdbeMemSetNull((Mem*)pVal);
61642
+ }
61643
+ }else if( pExpr->op==TK_VARIABLE
61644
+ || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
61645
+ ){
61646
+ Vdbe *v;
61647
+ int iBindVar = pExpr->iColumn;
61648
+ sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
61649
+ if( (v = pParse->pReprepare)!=0 ){
61650
+ pVal = valueNew(db, pAlloc);
61651
+ if( pVal ){
61652
+ rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
61653
+ if( rc==SQLITE_OK ){
61654
+ sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
61655
+ }
61656
+ pVal->db = pParse->db;
61657
+ }
61658
+ }
61659
+ }else{
61660
+ rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc);
61661
+ }
61662
+
61663
+ assert( pVal==0 || pVal->db==db );
61664
+ *ppVal = pVal;
61665
+ return rc;
61666
+}
6158761667
6158861668
/*
6158961669
** This function is used to allocate and populate UnpackedRecord
6159061670
** structures intended to be compared against sample index keys stored
6159161671
** in the sqlite_stat4 table.
@@ -61622,52 +61702,90 @@
6162261702
Expr *pExpr, /* The expression to extract a value from */
6162361703
u8 affinity, /* Affinity to use */
6162461704
int iVal, /* Array element to populate */
6162561705
int *pbOk /* OUT: True if value was extracted */
6162661706
){
61627
- int rc = SQLITE_OK;
61707
+ int rc;
6162861708
sqlite3_value *pVal = 0;
61629
- sqlite3 *db = pParse->db;
61630
-
61631
-
6163261709
struct ValueNewStat4Ctx alloc;
61710
+
6163361711
alloc.pParse = pParse;
6163461712
alloc.pIdx = pIdx;
6163561713
alloc.ppRec = ppRec;
6163661714
alloc.iVal = iVal;
6163761715
61638
- /* Skip over any TK_COLLATE nodes */
61639
- pExpr = sqlite3ExprSkipCollate(pExpr);
61640
-
61641
- if( !pExpr ){
61642
- pVal = valueNew(db, &alloc);
61643
- if( pVal ){
61644
- sqlite3VdbeMemSetNull((Mem*)pVal);
61645
- }
61646
- }else if( pExpr->op==TK_VARIABLE
61647
- || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
61648
- ){
61649
- Vdbe *v;
61650
- int iBindVar = pExpr->iColumn;
61651
- sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
61652
- if( (v = pParse->pReprepare)!=0 ){
61653
- pVal = valueNew(db, &alloc);
61654
- if( pVal ){
61655
- rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
61656
- if( rc==SQLITE_OK ){
61657
- sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
61658
- }
61659
- pVal->db = pParse->db;
61660
- }
61661
- }
61662
- }else{
61663
- rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc);
61664
- }
61716
+ rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal);
61717
+ assert( pVal==0 || pVal->db==pParse->db );
6166561718
*pbOk = (pVal!=0);
61719
+ return rc;
61720
+}
6166661721
61667
- assert( pVal==0 || pVal->db==db );
61668
- return rc;
61722
+/*
61723
+** Attempt to extract a value from expression pExpr using the methods
61724
+** as described for sqlite3Stat4ProbeSetValue() above.
61725
+**
61726
+** If successful, set *ppVal to point to a new value object and return
61727
+** SQLITE_OK. If no value can be extracted, but no other error occurs
61728
+** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error
61729
+** does occur, return an SQLite error code. The final value of *ppVal
61730
+** is undefined in this case.
61731
+*/
61732
+SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(
61733
+ Parse *pParse, /* Parse context */
61734
+ Expr *pExpr, /* The expression to extract a value from */
61735
+ u8 affinity, /* Affinity to use */
61736
+ sqlite3_value **ppVal /* OUT: New value object (or NULL) */
61737
+){
61738
+ return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal);
61739
+}
61740
+
61741
+/*
61742
+** Extract the iCol-th column from the nRec-byte record in pRec. Write
61743
+** the column value into *ppVal. If *ppVal is initially NULL then a new
61744
+** sqlite3_value object is allocated.
61745
+**
61746
+** If *ppVal is initially NULL then the caller is responsible for
61747
+** ensuring that the value written into *ppVal is eventually freed.
61748
+*/
61749
+SQLITE_PRIVATE int sqlite3Stat4Column(
61750
+ sqlite3 *db, /* Database handle */
61751
+ const void *pRec, /* Pointer to buffer containing record */
61752
+ int nRec, /* Size of buffer pRec in bytes */
61753
+ int iCol, /* Column to extract */
61754
+ sqlite3_value **ppVal /* OUT: Extracted value */
61755
+){
61756
+ u32 t; /* a column type code */
61757
+ int nHdr; /* Size of the header in the record */
61758
+ int iHdr; /* Next unread header byte */
61759
+ int iField; /* Next unread data byte */
61760
+ int szField; /* Size of the current data field */
61761
+ int i; /* Column index */
61762
+ u8 *a = (u8*)pRec; /* Typecast byte array */
61763
+ Mem *pMem = *ppVal; /* Write result into this Mem object */
61764
+
61765
+ assert( iCol>0 );
61766
+ iHdr = getVarint32(a, nHdr);
61767
+ if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
61768
+ iField = nHdr;
61769
+ for(i=0; i<=iCol; i++){
61770
+ iHdr += getVarint32(&a[iHdr], t);
61771
+ testcase( iHdr==nHdr );
61772
+ testcase( iHdr==nHdr+1 );
61773
+ if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT;
61774
+ szField = sqlite3VdbeSerialTypeLen(t);
61775
+ iField += szField;
61776
+ }
61777
+ testcase( iField==nRec );
61778
+ testcase( iField==nRec+1 );
61779
+ if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
61780
+ if( pMem==0 ){
61781
+ pMem = *ppVal = sqlite3ValueNew(db);
61782
+ if( pMem==0 ) return SQLITE_NOMEM;
61783
+ }
61784
+ sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
61785
+ pMem->enc = ENC(db);
61786
+ return SQLITE_OK;
6166961787
}
6167061788
6167161789
/*
6167261790
** Unless it is NULL, the argument must be an UnpackedRecord object returned
6167361791
** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
@@ -65315,10 +65433,11 @@
6531565433
/* rc==0 here means that one or both of the keys ran out of fields and
6531665434
** all the fields up to that point were equal. Return the the default_rc
6531765435
** value. */
6531865436
assert( CORRUPT_DB
6531965437
|| pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)
65438
+ || pKeyInfo->db->mallocFailed
6532065439
);
6532165440
return pPKey2->default_rc;
6532265441
}
6532365442
6532465443
/*
@@ -65480,10 +65599,11 @@
6548065599
6548165600
assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
6548265601
|| (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
6548365602
|| (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
6548465603
|| CORRUPT_DB
65604
+ || pPKey2->pKeyInfo->db->mallocFailed
6548565605
);
6548665606
return res;
6548765607
}
6548865608
6548965609
/*
@@ -76853,11 +76973,12 @@
7685376973
}else{
7685476974
/* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
7685576975
** likelihood(X, 0.0625).
7685676976
** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
7685776977
** likelihood(X,0.0625). */
76858
- pExpr->iTable = 62; /* TUNING: Default 2nd arg to unlikely() is 0.0625 */
76978
+ /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
76979
+ pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
7685976980
}
7686076981
}
7686176982
}
7686276983
#ifndef SQLITE_OMIT_AUTHORIZATION
7686376984
if( pDef ){
@@ -77629,11 +77750,11 @@
7762977750
** SELECT * FROM t1 WHERE (select a from t1);
7763077751
*/
7763177752
SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
7763277753
int op;
7763377754
pExpr = sqlite3ExprSkipCollate(pExpr);
77634
- if( pExpr->flags & EP_Generic ) return SQLITE_AFF_NONE;
77755
+ if( pExpr->flags & EP_Generic ) return 0;
7763577756
op = pExpr->op;
7763677757
if( op==TK_SELECT ){
7763777758
assert( pExpr->flags&EP_xIsSelect );
7763877759
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
7763977760
}
@@ -82929,10 +83050,11 @@
8292983050
/* Open the sqlite_stat[134] tables for writing. */
8293083051
for(i=0; aTable[i].zCols; i++){
8293183052
assert( i<ArraySize(aTable) );
8293283053
sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
8293383054
sqlite3VdbeChangeP5(v, aCreateTbl[i]);
83055
+ VdbeComment((v, aTable[i].zName));
8293483056
}
8293583057
}
8293683058
8293783059
/*
8293883060
** Recommended number of samples for sqlite_stat4
@@ -82964,11 +83086,12 @@
8296483086
#endif
8296583087
};
8296683088
struct Stat4Accum {
8296783089
tRowcnt nRow; /* Number of rows in the entire table */
8296883090
tRowcnt nPSample; /* How often to do a periodic sample */
82969
- int nCol; /* Number of columns in index + rowid */
83091
+ int nCol; /* Number of columns in index + pk/rowid */
83092
+ int nKeyCol; /* Number of index columns w/o the pk/rowid */
8297083093
int mxSample; /* Maximum number of samples to accumulate */
8297183094
Stat4Sample current; /* Current row as a Stat4Sample */
8297283095
u32 iPrn; /* Pseudo-random number used for sampling */
8297383096
Stat4Sample *aBest; /* Array of nCol best samples */
8297483097
int iMin; /* Index in a[] of entry with minimum score */
@@ -83050,13 +83173,21 @@
8305083173
#endif
8305183174
sqlite3DbFree(p->db, p);
8305283175
}
8305383176
8305483177
/*
83055
-** Implementation of the stat_init(N,C) SQL function. The two parameters
83056
-** are the number of rows in the table or index (C) and the number of columns
83057
-** in the index (N). The second argument (C) is only used for STAT3 and STAT4.
83178
+** Implementation of the stat_init(N,K,C) SQL function. The three parameters
83179
+** are:
83180
+** N: The number of columns in the index including the rowid/pk
83181
+** K: The number of columns in the index excluding the rowid/pk
83182
+** C: The number of rows in the index
83183
+**
83184
+** C is only used for STAT3 and STAT4.
83185
+**
83186
+** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables,
83187
+** N=K+P where P is the number of columns in the primary key. For the
83188
+** covering index that implements the original WITHOUT ROWID table, N==K.
8305883189
**
8305983190
** This routine allocates the Stat4Accum object in heap memory. The return
8306083191
** value is a pointer to the the Stat4Accum object encoded as a blob (i.e.
8306183192
** the size of the blob is sizeof(void*) bytes).
8306283193
*/
@@ -83065,10 +83196,11 @@
8306583196
int argc,
8306683197
sqlite3_value **argv
8306783198
){
8306883199
Stat4Accum *p;
8306983200
int nCol; /* Number of columns in index being sampled */
83201
+ int nKeyCol; /* Number of key columns */
8307083202
int nColUp; /* nCol rounded up for alignment */
8307183203
int n; /* Bytes of space to allocate */
8307283204
sqlite3 *db; /* Database connection */
8307383205
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
8307483206
int mxSample = SQLITE_STAT4_SAMPLES;
@@ -83075,12 +83207,15 @@
8307583207
#endif
8307683208
8307783209
/* Decode the three function arguments */
8307883210
UNUSED_PARAMETER(argc);
8307983211
nCol = sqlite3_value_int(argv[0]);
83080
- assert( nCol>1 ); /* >1 because it includes the rowid column */
83212
+ assert( nCol>0 );
8308183213
nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
83214
+ nKeyCol = sqlite3_value_int(argv[1]);
83215
+ assert( nKeyCol<=nCol );
83216
+ assert( nKeyCol>0 );
8308283217
8308383218
/* Allocate the space required for the Stat4Accum object */
8308483219
n = sizeof(*p)
8308583220
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
8308683221
+ sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
@@ -83098,10 +83233,11 @@
8309883233
}
8309983234
8310083235
p->db = db;
8310183236
p->nRow = 0;
8310283237
p->nCol = nCol;
83238
+ p->nKeyCol = nKeyCol;
8310383239
p->current.anDLt = (tRowcnt*)&p[1];
8310483240
p->current.anEq = &p->current.anDLt[nColUp];
8310583241
8310683242
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
8310783243
{
@@ -83108,13 +83244,13 @@
8310883244
u8 *pSpace; /* Allocated space not yet assigned */
8310983245
int i; /* Used to iterate through p->aSample[] */
8311083246
8311183247
p->iGet = -1;
8311283248
p->mxSample = mxSample;
83113
- p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1);
83249
+ p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
8311483250
p->current.anLt = &p->current.anEq[nColUp];
83115
- p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[1])*0xd0944565;
83251
+ p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565;
8311683252
8311783253
/* Set up the Stat4Accum.a[] and aBest[] arrays */
8311883254
p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
8311983255
p->aBest = &p->a[mxSample];
8312083256
pSpace = (u8*)(&p->a[mxSample+nCol]);
@@ -83133,11 +83269,11 @@
8313383269
8313483270
/* Return a pointer to the allocated object to the caller */
8313583271
sqlite3_result_blob(context, p, sizeof(p), stat4Destructor);
8313683272
}
8313783273
static const FuncDef statInitFuncdef = {
83138
- 1+IsStat34, /* nArg */
83274
+ 2+IsStat34, /* nArg */
8313983275
SQLITE_UTF8, /* funcFlags */
8314083276
0, /* pUserData */
8314183277
0, /* pNext */
8314283278
statInit, /* xFunc */
8314383279
0, /* xStep */
@@ -83374,11 +83510,11 @@
8337483510
Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
8337583511
int iChng = sqlite3_value_int(argv[1]);
8337683512
8337783513
UNUSED_PARAMETER( argc );
8337883514
UNUSED_PARAMETER( context );
83379
- assert( p->nCol>1 ); /* Includes rowid field */
83515
+ assert( p->nCol>0 );
8338083516
assert( iChng<p->nCol );
8338183517
8338283518
if( p->nRow==0 ){
8338383519
/* This is the first call to this function. Do initialization. */
8338483520
for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
@@ -83502,19 +83638,19 @@
8350283638
** I = (K+D-1)/D
8350383639
*/
8350483640
char *z;
8350583641
int i;
8350683642
83507
- char *zRet = sqlite3MallocZero(p->nCol * 25);
83643
+ char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
8350883644
if( zRet==0 ){
8350983645
sqlite3_result_error_nomem(context);
8351083646
return;
8351183647
}
8351283648
8351383649
sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
8351483650
z = zRet + sqlite3Strlen30(zRet);
83515
- for(i=0; i<(p->nCol-1); i++){
83651
+ for(i=0; i<p->nKeyCol; i++){
8351683652
u64 nDistinct = p->current.anDLt[i] + 1;
8351783653
u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
8351883654
sqlite3_snprintf(24, z, " %llu", iVal);
8351983655
z += sqlite3Strlen30(z);
8352083656
assert( p->current.anEq[i] );
@@ -83679,22 +83815,23 @@
8367983815
int addrNextRow; /* Address of "next_row:" */
8368083816
const char *zIdxName; /* Name of the index */
8368183817
8368283818
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
8368383819
if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
83684
- VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
83685
- nCol = pIdx->nKeyCol;
83820
+ if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){
83821
+ nCol = pIdx->nKeyCol;
83822
+ zIdxName = pTab->zName;
83823
+ }else{
83824
+ nCol = pIdx->nColumn;
83825
+ zIdxName = pIdx->zName;
83826
+ }
8368683827
aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
8368783828
if( aGotoChng==0 ) continue;
8368883829
8368983830
/* Populate the register containing the index name. */
83690
- if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
83691
- zIdxName = pTab->zName;
83692
- }else{
83693
- zIdxName = pIdx->zName;
83694
- }
8369583831
sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
83832
+ VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
8369683833
8369783834
/*
8369883835
** Pseudo-code for loop that calls stat_push():
8369983836
**
8370083837
** Rewind csr
@@ -83744,16 +83881,17 @@
8374483881
** (2) the number of rows in the index,
8374583882
**
8374683883
** The second argument is only used for STAT3 and STAT4
8374783884
*/
8374883885
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83749
- sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
83886
+ sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
8375083887
#endif
83751
- sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
83888
+ sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
83889
+ sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
8375283890
sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
8375383891
sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
83754
- sqlite3VdbeChangeP5(v, 1+IsStat34);
83892
+ sqlite3VdbeChangeP5(v, 2+IsStat34);
8375583893
8375683894
/* Implementation of the following:
8375783895
**
8375883896
** Rewind csr
8375983897
** if eof(csr) goto end_of_scan;
@@ -83851,11 +83989,11 @@
8385183989
int regSampleRowid = regCol + nCol;
8385283990
int addrNext;
8385383991
int addrIsNull;
8385483992
u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
8385583993
83856
- pParse->nMem = MAX(pParse->nMem, regCol+nCol+1);
83994
+ pParse->nMem = MAX(pParse->nMem, regCol+nCol);
8385783995
8385883996
addrNext = sqlite3VdbeCurrentAddr(v);
8385983997
callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
8386083998
addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
8386183999
VdbeCoverage(v);
@@ -83873,11 +84011,11 @@
8387384011
#else
8387484012
for(i=0; i<nCol; i++){
8387584013
i16 iCol = pIdx->aiColumn[i];
8387684014
sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
8387784015
}
83878
- sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
84016
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
8387984017
#endif
8388084018
sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
8388184019
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
8388284020
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
8388384021
sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
@@ -84185,11 +84323,20 @@
8418584323
static void initAvgEq(Index *pIdx){
8418684324
if( pIdx ){
8418784325
IndexSample *aSample = pIdx->aSample;
8418884326
IndexSample *pFinal = &aSample[pIdx->nSample-1];
8418984327
int iCol;
84190
- for(iCol=0; iCol<pIdx->nKeyCol; iCol++){
84328
+ int nCol = 1;
84329
+ if( pIdx->nSampleCol>1 ){
84330
+ /* If this is stat4 data, then calculate aAvgEq[] values for all
84331
+ ** sample columns except the last. The last is always set to 1, as
84332
+ ** once the trailing PK fields are considered all index keys are
84333
+ ** unique. */
84334
+ nCol = pIdx->nSampleCol-1;
84335
+ pIdx->aAvgEq[nCol] = 1;
84336
+ }
84337
+ for(iCol=0; iCol<nCol; iCol++){
8419184338
int i; /* Used to iterate through samples */
8419284339
tRowcnt sumEq = 0; /* Sum of the nEq values */
8419384340
tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
8419484341
tRowcnt avgEq = 0;
8419584342
tRowcnt nDLt = pFinal->anDLt[iCol];
@@ -84208,11 +84355,10 @@
8420884355
if( nDLt>nSum ){
8420984356
avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
8421084357
}
8421184358
if( avgEq==0 ) avgEq = 1;
8421284359
pIdx->aAvgEq[iCol] = avgEq;
84213
- if( pIdx->nSampleCol==1 ) break;
8421484360
}
8421584361
}
8421684362
}
8421784363
8421884364
/*
@@ -84267,11 +84413,10 @@
8426784413
sqlite3DbFree(db, zSql);
8426884414
if( rc ) return rc;
8426984415
8427084416
while( sqlite3_step(pStmt)==SQLITE_ROW ){
8427184417
int nIdxCol = 1; /* Number of columns in stat4 records */
84272
- int nAvgCol = 1; /* Number of entries in Index.aAvgEq */
8427384418
8427484419
char *zIndex; /* Index name */
8427584420
Index *pIdx; /* Pointer to the index object */
8427684421
int nSample; /* Number of samples */
8427784422
int nByte; /* Bytes of space required */
@@ -84285,25 +84430,29 @@
8428584430
assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
8428684431
/* Index.nSample is non-zero at this point if data has already been
8428784432
** loaded from the stat4 table. In this case ignore stat3 data. */
8428884433
if( pIdx==0 || pIdx->nSample ) continue;
8428984434
if( bStat3==0 ){
84290
- nIdxCol = pIdx->nKeyCol+1;
84291
- nAvgCol = pIdx->nKeyCol;
84435
+ assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
84436
+ if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
84437
+ nIdxCol = pIdx->nKeyCol;
84438
+ }else{
84439
+ nIdxCol = pIdx->nColumn;
84440
+ }
8429284441
}
8429384442
pIdx->nSampleCol = nIdxCol;
8429484443
nByte = sizeof(IndexSample) * nSample;
8429584444
nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
84296
- nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
84445
+ nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
8429784446
8429884447
pIdx->aSample = sqlite3DbMallocZero(db, nByte);
8429984448
if( pIdx->aSample==0 ){
8430084449
sqlite3_finalize(pStmt);
8430184450
return SQLITE_NOMEM;
8430284451
}
8430384452
pSpace = (tRowcnt*)&pIdx->aSample[nSample];
84304
- pIdx->aAvgEq = pSpace; pSpace += nAvgCol;
84453
+ pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
8430584454
for(i=0; i<nSample; i++){
8430684455
pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
8430784456
pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
8430884457
pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
8430984458
}
@@ -92553,10 +92702,11 @@
9255392702
FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
9255492703
FUNCTION(hex, 1, 0, 0, hexFunc ),
9255592704
FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
9255692705
FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
9255792706
FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
92707
+ FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
9255892708
VFUNCTION(random, 0, 0, 0, randomFunc ),
9255992709
VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
9256092710
FUNCTION(nullif, 2, 0, 1, nullifFunc ),
9256192711
FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
9256292712
FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
@@ -110581,11 +110731,11 @@
110581110731
pScan->pOrigWC = pWC;
110582110732
pScan->pWC = pWC;
110583110733
if( pIdx && iColumn>=0 ){
110584110734
pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
110585110735
for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
110586
- if( NEVER(j>=pIdx->nKeyCol) ) return 0;
110736
+ if( NEVER(j>pIdx->nColumn) ) return 0;
110587110737
}
110588110738
pScan->zCollName = pIdx->azColl[j];
110589110739
}else{
110590110740
pScan->idxaff = 0;
110591110741
pScan->zCollName = 0;
@@ -111531,12 +111681,11 @@
111531111681
111532111682
/*
111533111683
** Estimate the logarithm of the input value to base 2.
111534111684
*/
111535111685
static LogEst estLog(LogEst N){
111536
- LogEst x = sqlite3LogEst(N);
111537
- return x>33 ? x - 33 : 0;
111686
+ return N<=10 ? 0 : sqlite3LogEst(N) - 33;
111538111687
}
111539111688
111540111689
/*
111541111690
** Two routines for printing the content of an sqlite3_index_info
111542111691
** structure. Used for testing and debugging only. If neither
@@ -111997,11 +112146,11 @@
111997112146
}else{
111998112147
i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
111999112148
iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
112000112149
iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
112001112150
}
112002
- aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
112151
+ aStat[1] = pIdx->aAvgEq[iCol];
112003112152
if( iLower>=iUpper ){
112004112153
iGap = 0;
112005112154
}else{
112006112155
iGap = iUpper - iLower;
112007112156
}
@@ -112036,10 +112185,118 @@
112036112185
}
112037112186
}
112038112187
return nRet;
112039112188
}
112040112189
112190
+#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
112191
+/*
112192
+** This function is called to estimate the number of rows visited by a
112193
+** range-scan on a skip-scan index. For example:
112194
+**
112195
+** CREATE INDEX i1 ON t1(a, b, c);
112196
+** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?;
112197
+**
112198
+** Value pLoop->nOut is currently set to the estimated number of rows
112199
+** visited for scanning (a=? AND b=?). This function reduces that estimate
112200
+** by some factor to account for the (c BETWEEN ? AND ?) expression based
112201
+** on the stat4 data for the index. this scan will be peformed multiple
112202
+** times (once for each (a,b) combination that matches a=?) is dealt with
112203
+** by the caller.
112204
+**
112205
+** It does this by scanning through all stat4 samples, comparing values
112206
+** extracted from pLower and pUpper with the corresponding column in each
112207
+** sample. If L and U are the number of samples found to be less than or
112208
+** equal to the values extracted from pLower and pUpper respectively, and
112209
+** N is the total number of samples, the pLoop->nOut value is adjusted
112210
+** as follows:
112211
+**
112212
+** nOut = nOut * ( min(U - L, 1) / N )
112213
+**
112214
+** If pLower is NULL, or a value cannot be extracted from the term, L is
112215
+** set to zero. If pUpper is NULL, or a value cannot be extracted from it,
112216
+** U is set to N.
112217
+**
112218
+** Normally, this function sets *pbDone to 1 before returning. However,
112219
+** if no value can be extracted from either pLower or pUpper (and so the
112220
+** estimate of the number of rows delivered remains unchanged), *pbDone
112221
+** is left as is.
112222
+**
112223
+** If an error occurs, an SQLite error code is returned. Otherwise,
112224
+** SQLITE_OK.
112225
+*/
112226
+static int whereRangeSkipScanEst(
112227
+ Parse *pParse, /* Parsing & code generating context */
112228
+ WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
112229
+ WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
112230
+ WhereLoop *pLoop, /* Update the .nOut value of this loop */
112231
+ int *pbDone /* Set to true if at least one expr. value extracted */
112232
+){
112233
+ Index *p = pLoop->u.btree.pIndex;
112234
+ int nEq = pLoop->u.btree.nEq;
112235
+ sqlite3 *db = pParse->db;
112236
+ int nLower = -1;
112237
+ int nUpper = p->nSample+1;
112238
+ int rc = SQLITE_OK;
112239
+ u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity;
112240
+ CollSeq *pColl;
112241
+
112242
+ sqlite3_value *p1 = 0; /* Value extracted from pLower */
112243
+ sqlite3_value *p2 = 0; /* Value extracted from pUpper */
112244
+ sqlite3_value *pVal = 0; /* Value extracted from record */
112245
+
112246
+ pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]);
112247
+ if( pLower ){
112248
+ rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1);
112249
+ nLower = 0;
112250
+ }
112251
+ if( pUpper && rc==SQLITE_OK ){
112252
+ rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2);
112253
+ nUpper = p2 ? 0 : p->nSample;
112254
+ }
112255
+
112256
+ if( p1 || p2 ){
112257
+ int i;
112258
+ int nDiff;
112259
+ for(i=0; rc==SQLITE_OK && i<p->nSample; i++){
112260
+ rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal);
112261
+ if( rc==SQLITE_OK && p1 ){
112262
+ int res = sqlite3MemCompare(p1, pVal, pColl);
112263
+ if( res>=0 ) nLower++;
112264
+ }
112265
+ if( rc==SQLITE_OK && p2 ){
112266
+ int res = sqlite3MemCompare(p2, pVal, pColl);
112267
+ if( res>=0 ) nUpper++;
112268
+ }
112269
+ }
112270
+ nDiff = (nUpper - nLower);
112271
+ if( nDiff<=0 ) nDiff = 1;
112272
+
112273
+ /* If there is both an upper and lower bound specified, and the
112274
+ ** comparisons indicate that they are close together, use the fallback
112275
+ ** method (assume that the scan visits 1/64 of the rows) for estimating
112276
+ ** the number of rows visited. Otherwise, estimate the number of rows
112277
+ ** using the method described in the header comment for this function. */
112278
+ if( nDiff!=1 || pUpper==0 || pLower==0 ){
112279
+ int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff));
112280
+ pLoop->nOut -= nAdjust;
112281
+ *pbDone = 1;
112282
+ WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n",
112283
+ nLower, nUpper, nAdjust*-1, pLoop->nOut));
112284
+ }
112285
+
112286
+ }else{
112287
+ assert( *pbDone==0 );
112288
+ }
112289
+
112290
+ sqlite3ValueFree(p1);
112291
+ sqlite3ValueFree(p2);
112292
+ sqlite3ValueFree(pVal);
112293
+
112294
+ return rc;
112295
+}
112296
+#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
112297
+
112041112298
/*
112042112299
** This function is used to estimate the number of rows that will be visited
112043112300
** by scanning an index for a range of values. The range may have an upper
112044112301
** bound, a lower bound, or both. The WHERE clause terms that set the upper
112045112302
** and lower bounds are represented by pLower and pUpper respectively. For
@@ -112072,13 +112329,13 @@
112072112329
** considering the range constraints. If nEq is 0, this is the number of
112073112330
** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
112074112331
** to account for the range contraints pLower and pUpper.
112075112332
**
112076112333
** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
112077
-** used, each range inequality reduces the search space by a factor of 4.
112078
-** Hence a pair of constraints (x>? AND x<?) reduces the expected number of
112079
-** rows visited by a factor of 16.
112334
+** used, a single range inequality reduces the search space by a factor of 4.
112335
+** and a pair of constraints (x>? AND x<?) reduces the expected number of
112336
+** rows visited by a factor of 64.
112080112337
*/
112081112338
static int whereRangeScanEst(
112082112339
Parse *pParse, /* Parsing & code generating context */
112083112340
WhereLoopBuilder *pBuilder,
112084112341
WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
@@ -112092,99 +112349,104 @@
112092112349
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
112093112350
Index *p = pLoop->u.btree.pIndex;
112094112351
int nEq = pLoop->u.btree.nEq;
112095112352
112096112353
if( p->nSample>0
112097
- && nEq==pBuilder->nRecValid
112098112354
&& nEq<p->nSampleCol
112099112355
&& OptimizationEnabled(pParse->db, SQLITE_Stat3)
112100112356
){
112101
- UnpackedRecord *pRec = pBuilder->pRec;
112102
- tRowcnt a[2];
112103
- u8 aff;
112104
-
112105
- /* Variable iLower will be set to the estimate of the number of rows in
112106
- ** the index that are less than the lower bound of the range query. The
112107
- ** lower bound being the concatenation of $P and $L, where $P is the
112108
- ** key-prefix formed by the nEq values matched against the nEq left-most
112109
- ** columns of the index, and $L is the value in pLower.
112110
- **
112111
- ** Or, if pLower is NULL or $L cannot be extracted from it (because it
112112
- ** is not a simple variable or literal value), the lower bound of the
112113
- ** range is $P. Due to a quirk in the way whereKeyStats() works, even
112114
- ** if $L is available, whereKeyStats() is called for both ($P) and
112115
- ** ($P:$L) and the larger of the two returned values used.
112116
- **
112117
- ** Similarly, iUpper is to be set to the estimate of the number of rows
112118
- ** less than the upper bound of the range query. Where the upper bound
112119
- ** is either ($P) or ($P:$U). Again, even if $U is available, both values
112120
- ** of iUpper are requested of whereKeyStats() and the smaller used.
112121
- */
112122
- tRowcnt iLower;
112123
- tRowcnt iUpper;
112124
-
112125
- if( nEq==p->nKeyCol ){
112126
- aff = SQLITE_AFF_INTEGER;
112127
- }else{
112128
- aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
112129
- }
112130
- /* Determine iLower and iUpper using ($P) only. */
112131
- if( nEq==0 ){
112132
- iLower = 0;
112133
- iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
112134
- }else{
112135
- /* Note: this call could be optimized away - since the same values must
112136
- ** have been requested when testing key $P in whereEqualScanEst(). */
112137
- whereKeyStats(pParse, p, pRec, 0, a);
112138
- iLower = a[0];
112139
- iUpper = a[0] + a[1];
112140
- }
112141
-
112142
- /* If possible, improve on the iLower estimate using ($P:$L). */
112143
- if( pLower ){
112144
- int bOk; /* True if value is extracted from pExpr */
112145
- Expr *pExpr = pLower->pExpr->pRight;
112146
- assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
112147
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112148
- if( rc==SQLITE_OK && bOk ){
112149
- tRowcnt iNew;
112150
- whereKeyStats(pParse, p, pRec, 0, a);
112151
- iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
112152
- if( iNew>iLower ) iLower = iNew;
112153
- nOut--;
112154
- }
112155
- }
112156
-
112157
- /* If possible, improve on the iUpper estimate using ($P:$U). */
112158
- if( pUpper ){
112159
- int bOk; /* True if value is extracted from pExpr */
112160
- Expr *pExpr = pUpper->pExpr->pRight;
112161
- assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
112162
- rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112163
- if( rc==SQLITE_OK && bOk ){
112164
- tRowcnt iNew;
112165
- whereKeyStats(pParse, p, pRec, 1, a);
112166
- iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
112167
- if( iNew<iUpper ) iUpper = iNew;
112168
- nOut--;
112169
- }
112170
- }
112171
-
112172
- pBuilder->pRec = pRec;
112173
- if( rc==SQLITE_OK ){
112174
- if( iUpper>iLower ){
112175
- nNew = sqlite3LogEst(iUpper - iLower);
112176
- }else{
112177
- nNew = 10; assert( 10==sqlite3LogEst(2) );
112178
- }
112179
- if( nNew<nOut ){
112180
- nOut = nNew;
112181
- }
112182
- pLoop->nOut = (LogEst)nOut;
112183
- WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n",
112184
- (u32)iLower, (u32)iUpper, nOut));
112185
- return SQLITE_OK;
112357
+ if( nEq==pBuilder->nRecValid ){
112358
+ UnpackedRecord *pRec = pBuilder->pRec;
112359
+ tRowcnt a[2];
112360
+ u8 aff;
112361
+
112362
+ /* Variable iLower will be set to the estimate of the number of rows in
112363
+ ** the index that are less than the lower bound of the range query. The
112364
+ ** lower bound being the concatenation of $P and $L, where $P is the
112365
+ ** key-prefix formed by the nEq values matched against the nEq left-most
112366
+ ** columns of the index, and $L is the value in pLower.
112367
+ **
112368
+ ** Or, if pLower is NULL or $L cannot be extracted from it (because it
112369
+ ** is not a simple variable or literal value), the lower bound of the
112370
+ ** range is $P. Due to a quirk in the way whereKeyStats() works, even
112371
+ ** if $L is available, whereKeyStats() is called for both ($P) and
112372
+ ** ($P:$L) and the larger of the two returned values used.
112373
+ **
112374
+ ** Similarly, iUpper is to be set to the estimate of the number of rows
112375
+ ** less than the upper bound of the range query. Where the upper bound
112376
+ ** is either ($P) or ($P:$U). Again, even if $U is available, both values
112377
+ ** of iUpper are requested of whereKeyStats() and the smaller used.
112378
+ */
112379
+ tRowcnt iLower;
112380
+ tRowcnt iUpper;
112381
+
112382
+ if( nEq==p->nKeyCol ){
112383
+ aff = SQLITE_AFF_INTEGER;
112384
+ }else{
112385
+ aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
112386
+ }
112387
+ /* Determine iLower and iUpper using ($P) only. */
112388
+ if( nEq==0 ){
112389
+ iLower = 0;
112390
+ iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
112391
+ }else{
112392
+ /* Note: this call could be optimized away - since the same values must
112393
+ ** have been requested when testing key $P in whereEqualScanEst(). */
112394
+ whereKeyStats(pParse, p, pRec, 0, a);
112395
+ iLower = a[0];
112396
+ iUpper = a[0] + a[1];
112397
+ }
112398
+
112399
+ /* If possible, improve on the iLower estimate using ($P:$L). */
112400
+ if( pLower ){
112401
+ int bOk; /* True if value is extracted from pExpr */
112402
+ Expr *pExpr = pLower->pExpr->pRight;
112403
+ assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
112404
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112405
+ if( rc==SQLITE_OK && bOk ){
112406
+ tRowcnt iNew;
112407
+ whereKeyStats(pParse, p, pRec, 0, a);
112408
+ iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
112409
+ if( iNew>iLower ) iLower = iNew;
112410
+ nOut--;
112411
+ }
112412
+ }
112413
+
112414
+ /* If possible, improve on the iUpper estimate using ($P:$U). */
112415
+ if( pUpper ){
112416
+ int bOk; /* True if value is extracted from pExpr */
112417
+ Expr *pExpr = pUpper->pExpr->pRight;
112418
+ assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
112419
+ rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112420
+ if( rc==SQLITE_OK && bOk ){
112421
+ tRowcnt iNew;
112422
+ whereKeyStats(pParse, p, pRec, 1, a);
112423
+ iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
112424
+ if( iNew<iUpper ) iUpper = iNew;
112425
+ nOut--;
112426
+ }
112427
+ }
112428
+
112429
+ pBuilder->pRec = pRec;
112430
+ if( rc==SQLITE_OK ){
112431
+ if( iUpper>iLower ){
112432
+ nNew = sqlite3LogEst(iUpper - iLower);
112433
+ }else{
112434
+ nNew = 10; assert( 10==sqlite3LogEst(2) );
112435
+ }
112436
+ if( nNew<nOut ){
112437
+ nOut = nNew;
112438
+ }
112439
+ pLoop->nOut = (LogEst)nOut;
112440
+ WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n",
112441
+ (u32)iLower, (u32)iUpper, nOut));
112442
+ return SQLITE_OK;
112443
+ }
112444
+ }else{
112445
+ int bDone = 0;
112446
+ rc = whereRangeSkipScanEst(pParse, pLower, pUpper, pLoop, &bDone);
112447
+ if( bDone ) return rc;
112186112448
}
112187112449
}
112188112450
#else
112189112451
UNUSED_PARAMETER(pParse);
112190112452
UNUSED_PARAMETER(pBuilder);
@@ -112239,11 +112501,11 @@
112239112501
int rc; /* Subfunction return code */
112240112502
tRowcnt a[2]; /* Statistics */
112241112503
int bOk;
112242112504
112243112505
assert( nEq>=1 );
112244
- assert( nEq<=(p->nKeyCol+1) );
112506
+ assert( nEq<=p->nColumn );
112245112507
assert( p->aSample!=0 );
112246112508
assert( p->nSample>0 );
112247112509
assert( pBuilder->nRecValid<nEq );
112248112510
112249112511
/* If values are not available for all fields of the index to the left
@@ -112252,11 +112514,11 @@
112252112514
return SQLITE_NOTFOUND;
112253112515
}
112254112516
112255112517
/* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
112256112518
** below would return the same value. */
112257
- if( nEq>p->nKeyCol ){
112519
+ if( nEq>=p->nColumn ){
112258112520
*pnRow = 1;
112259112521
return SQLITE_OK;
112260112522
}
112261112523
112262112524
aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
@@ -112683,11 +112945,11 @@
112683112945
}
112684112946
sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
112685112947
txt.db = db;
112686112948
sqlite3StrAccumAppend(&txt, " (", 2);
112687112949
for(i=0; i<nEq; i++){
112688
- char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName;
112950
+ char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
112689112951
if( i>=nSkip ){
112690112952
explainAppendTerm(&txt, i, z, "=");
112691112953
}else{
112692112954
if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
112693112955
sqlite3StrAccumAppend(&txt, "ANY(", 4);
@@ -112696,15 +112958,15 @@
112696112958
}
112697112959
}
112698112960
112699112961
j = i;
112700112962
if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
112701
- char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
112963
+ char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
112702112964
explainAppendTerm(&txt, i++, z, ">");
112703112965
}
112704112966
if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
112705
- char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
112967
+ char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
112706112968
explainAppendTerm(&txt, i, z, "<");
112707112969
}
112708112970
sqlite3StrAccumAppend(&txt, ")", 1);
112709112971
return sqlite3StrAccumFinish(&txt);
112710112972
}
@@ -113724,11 +113986,11 @@
113724113986
z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
113725113987
}
113726113988
sqlite3DebugPrintf(" %-19s", z);
113727113989
sqlite3_free(z);
113728113990
}
113729
- sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm);
113991
+ sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
113730113992
sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
113731113993
#ifdef SQLITE_ENABLE_TREE_EXPLAIN
113732113994
/* If the 0x100 bit of wheretracing is set, then show all of the constraint
113733113995
** expressions in the WhereLoop.aLTerm[] array.
113734113996
*/
@@ -113960,10 +114222,21 @@
113960114222
113961114223
/* whereLoopAddBtree() always generates and inserts the automatic index
113962114224
** case first. Hence compatible candidate WhereLoops never have a larger
113963114225
** rSetup. Call this SETUP-INVARIANT */
113964114226
assert( p->rSetup>=pTemplate->rSetup );
114227
+
114228
+ /* Any loop using an appliation-defined index (or PRIMARY KEY or
114229
+ ** UNIQUE constraint) with one or more == constraints is better
114230
+ ** than an automatic index. */
114231
+ if( (p->wsFlags & WHERE_AUTO_INDEX)!=0
114232
+ && (pTemplate->wsFlags & WHERE_INDEXED)!=0
114233
+ && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
114234
+ && (p->prereq & pTemplate->prereq)==pTemplate->prereq
114235
+ ){
114236
+ break;
114237
+ }
113965114238
113966114239
/* If existing WhereLoop p is better than pTemplate, pTemplate can be
113967114240
** discarded. WhereLoop p is better if:
113968114241
** (1) p has no more dependencies than pTemplate, and
113969114242
** (2) p has an equal or lower cost than pTemplate
@@ -114085,17 +114358,17 @@
114085114358
** p[] that are also supplated by pTemplate */
114086114359
WhereLoop **ppTail = &p->pNextLoop;
114087114360
WhereLoop *pToDel;
114088114361
while( *ppTail ){
114089114362
ppTail = whereLoopFindLesser(ppTail, pTemplate);
114090
- if( NEVER(ppTail==0) ) break;
114363
+ if( ppTail==0 ) break;
114091114364
pToDel = *ppTail;
114092114365
if( pToDel==0 ) break;
114093114366
*ppTail = pToDel->pNextLoop;
114094114367
#if WHERETRACE_ENABLED /* 0x8 */
114095114368
if( sqlite3WhereTrace & 0x8 ){
114096
- sqlite3DebugPrintf("ins-del: ");
114369
+ sqlite3DebugPrintf("ins-del: ");
114097114370
whereLoopPrint(pToDel, pBuilder->pWC);
114098114371
}
114099114372
#endif
114100114373
whereLoopDelete(db, pToDel);
114101114374
}
@@ -114191,16 +114464,13 @@
114191114464
}else{
114192114465
opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
114193114466
}
114194114467
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
114195114468
114196
- assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
114197
- if( pNew->u.btree.nEq < pProbe->nKeyCol ){
114198
- iCol = pProbe->aiColumn[pNew->u.btree.nEq];
114199
- }else{
114200
- iCol = -1;
114201
- }
114469
+ assert( pNew->u.btree.nEq<pProbe->nColumn );
114470
+ iCol = pProbe->aiColumn[pNew->u.btree.nEq];
114471
+
114202114472
pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
114203114473
opMask, pProbe);
114204114474
saved_nEq = pNew->u.btree.nEq;
114205114475
saved_nSkip = pNew->u.btree.nSkip;
114206114476
saved_nLTerm = pNew->nLTerm;
@@ -114386,11 +114656,11 @@
114386114656
}else{
114387114657
pNew->nOut = nOutUnadjusted;
114388114658
}
114389114659
114390114660
if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
114391
- && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0))
114661
+ && pNew->u.btree.nEq<pProbe->nColumn
114392114662
){
114393114663
whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
114394114664
}
114395114665
pNew->nOut = saved_nOut;
114396114666
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -114533,10 +114803,11 @@
114533114803
** fake index the first in a chain of Index objects with all of the real
114534114804
** indices to follow */
114535114805
Index *pFirst; /* First of real indices on the table */
114536114806
memset(&sPk, 0, sizeof(Index));
114537114807
sPk.nKeyCol = 1;
114808
+ sPk.nColumn = 1;
114538114809
sPk.aiColumn = &aiColumnPk;
114539114810
sPk.aiRowLogEst = aiRowEstPk;
114540114811
sPk.onError = OE_Replace;
114541114812
sPk.pTable = pTab;
114542114813
sPk.szIdxRow = pTab->szTabRow;
@@ -115316,11 +115587,10 @@
115316115587
int mxI = 0; /* Index of next entry to replace */
115317115588
int nOrderBy; /* Number of ORDER BY clause terms */
115318115589
LogEst rCost; /* Cost of a path */
115319115590
LogEst nOut; /* Number of outputs */
115320115591
LogEst mxCost = 0; /* Maximum cost of a set of paths */
115321
- LogEst mxOut = 0; /* Maximum nOut value on the set of paths */
115322115592
int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
115323115593
WherePath *aFrom; /* All nFrom paths at the previous level */
115324115594
WherePath *aTo; /* The nTo best paths at the current level */
115325115595
WherePath *pFrom; /* An element of aFrom[] that we are working on */
115326115596
WherePath *pTo; /* An element of aTo[] that we are working on */
@@ -115426,12 +115696,10 @@
115426115696
}
115427115697
/* Check to see if pWLoop should be added to the mxChoice best so far */
115428115698
for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
115429115699
if( pTo->maskLoop==maskNew
115430115700
&& ((pTo->isOrdered^isOrdered)&80)==0
115431
- && ((pTo->rCost<=rCost && pTo->nRow<=nOut) ||
115432
- (pTo->rCost>=rCost && pTo->nRow>=nOut))
115433115701
){
115434115702
testcase( jj==nTo-1 );
115435115703
break;
115436115704
}
115437115705
}
@@ -115461,11 +115729,11 @@
115461115729
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
115462115730
isOrdered>=0 ? isOrdered+'0' : '?');
115463115731
}
115464115732
#endif
115465115733
}else{
115466
- if( pTo->rCost<=rCost && pTo->nRow<=nOut ){
115734
+ if( pTo->rCost<=rCost ){
115467115735
#ifdef WHERETRACE_ENABLED /* 0x4 */
115468115736
if( sqlite3WhereTrace&0x4 ){
115469115737
sqlite3DebugPrintf(
115470115738
"Skip %s cost=%-3d,%3d order=%c",
115471115739
wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
@@ -115501,15 +115769,13 @@
115501115769
memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
115502115770
pTo->aLoop[iLoop] = pWLoop;
115503115771
if( nTo>=mxChoice ){
115504115772
mxI = 0;
115505115773
mxCost = aTo[0].rCost;
115506
- mxOut = aTo[0].nRow;
115507115774
for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
115508
- if( pTo->rCost>mxCost || (pTo->rCost==mxCost && pTo->nRow>mxOut) ){
115775
+ if( pTo->rCost>mxCost ){
115509115776
mxCost = pTo->rCost;
115510
- mxOut = pTo->nRow;
115511115777
mxI = jj;
115512115778
}
115513115779
}
115514115780
}
115515115781
}
@@ -124205,14 +124471,14 @@
124205124471
** sqlite3_test_control().
124206124472
*/
124207124473
case SQLITE_TESTCTRL_FAULT_INSTALL: {
124208124474
/* MSVC is picky about pulling func ptrs from va lists.
124209124475
** http://support.microsoft.com/kb/47961
124210
- ** sqlite3Config.xTestCallback = va_arg(ap, int(*)(int));
124476
+ ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
124211124477
*/
124212124478
typedef int(*TESTCALLBACKFUNC_t)(int);
124213
- sqlite3Config.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
124479
+ sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
124214124480
rc = sqlite3FaultSim(0);
124215124481
break;
124216124482
}
124217124483
124218124484
/*
@@ -140777,38 +141043,40 @@
140777141043
i64 iDocid = sqlite3_column_int64(pStmt, 0);
140778141044
int iLang = langidFromSelect(p, pStmt);
140779141045
int iCol;
140780141046
140781141047
for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
140782
- const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
140783
- int nText = sqlite3_column_bytes(pStmt, iCol+1);
140784
- sqlite3_tokenizer_cursor *pT = 0;
140785
-
140786
- rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
140787
- while( rc==SQLITE_OK ){
140788
- char const *zToken; /* Buffer containing token */
140789
- int nToken = 0; /* Number of bytes in token */
140790
- int iDum1 = 0, iDum2 = 0; /* Dummy variables */
140791
- int iPos = 0; /* Position of token in zText */
140792
-
140793
- rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
140794
- if( rc==SQLITE_OK ){
140795
- int i;
140796
- cksum2 = cksum2 ^ fts3ChecksumEntry(
140797
- zToken, nToken, iLang, 0, iDocid, iCol, iPos
140798
- );
140799
- for(i=1; i<p->nIndex; i++){
140800
- if( p->aIndex[i].nPrefix<=nToken ){
140801
- cksum2 = cksum2 ^ fts3ChecksumEntry(
140802
- zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos
140803
- );
140804
- }
140805
- }
140806
- }
140807
- }
140808
- if( pT ) pModule->xClose(pT);
140809
- if( rc==SQLITE_DONE ) rc = SQLITE_OK;
141048
+ if( p->abNotindexed[iCol]==0 ){
141049
+ const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
141050
+ int nText = sqlite3_column_bytes(pStmt, iCol+1);
141051
+ sqlite3_tokenizer_cursor *pT = 0;
141052
+
141053
+ rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText,&pT);
141054
+ while( rc==SQLITE_OK ){
141055
+ char const *zToken; /* Buffer containing token */
141056
+ int nToken = 0; /* Number of bytes in token */
141057
+ int iDum1 = 0, iDum2 = 0; /* Dummy variables */
141058
+ int iPos = 0; /* Position of token in zText */
141059
+
141060
+ rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
141061
+ if( rc==SQLITE_OK ){
141062
+ int i;
141063
+ cksum2 = cksum2 ^ fts3ChecksumEntry(
141064
+ zToken, nToken, iLang, 0, iDocid, iCol, iPos
141065
+ );
141066
+ for(i=1; i<p->nIndex; i++){
141067
+ if( p->aIndex[i].nPrefix<=nToken ){
141068
+ cksum2 = cksum2 ^ fts3ChecksumEntry(
141069
+ zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos
141070
+ );
141071
+ }
141072
+ }
141073
+ }
141074
+ }
141075
+ if( pT ) pModule->xClose(pT);
141076
+ if( rc==SQLITE_DONE ) rc = SQLITE_OK;
141077
+ }
140810141078
}
140811141079
}
140812141080
140813141081
sqlite3_finalize(pStmt);
140814141082
}
140815141083
--- 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.8.5. 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.
@@ -220,13 +220,13 @@
220 **
221 ** See also: [sqlite3_libversion()],
222 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
223 ** [sqlite_version()] and [sqlite_source_id()].
224 */
225 #define SQLITE_VERSION "3.8.5"
226 #define SQLITE_VERSION_NUMBER 3008005
227 #define SQLITE_SOURCE_ID "2014-06-04 14:06:34 b1ed4f2a34ba66c29b130f8d13e9092758019212"
228
229 /*
230 ** CAPI3REF: Run-Time Library Version Numbers
231 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
232 **
@@ -9479,10 +9479,11 @@
9479 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
9480 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
9481 #ifndef SQLITE_OMIT_TRACE
9482 SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
9483 #endif
 
9484
9485 SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
9486 SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
9487 SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
9488
@@ -12885,11 +12886,13 @@
12885 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
12886
12887 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
12888 SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
12889 SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
 
12890 SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
 
12891 #endif
12892
12893 /*
12894 ** The interface to the LEMON-generated parser
12895 */
@@ -14199,11 +14202,10 @@
14199 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
14200
14201 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
14202 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
14203 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
14204 SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
14205 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
14206 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
14207 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
14208 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
14209 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21562,12 +21564,12 @@
21562 ** * Bytes in the range of 0x80 through 0xbf which occur as the first
21563 ** byte of a character are interpreted as single-byte characters
21564 ** and rendered as themselves even though they are technically
21565 ** invalid characters.
21566 **
21567 ** * This routine accepts an infinite number of different UTF8 encodings
21568 ** for unicode values 0x80 and greater. It do not change over-length
21569 ** encodings to 0xfffd as some systems recommend.
21570 */
21571 #define READ_UTF8(zIn, zTerm, c) \
21572 c = *(zIn++); \
21573 if( c>=0xc0 ){ \
@@ -24371,14 +24373,14 @@
24371 { "mremap", (sqlite3_syscall_ptr)mremap, 0 },
24372 #else
24373 { "mremap", (sqlite3_syscall_ptr)0, 0 },
24374 #endif
24375 #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
24376 #endif
24377
24378 { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
24379 #define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
 
 
24380
24381 }; /* End of the overrideable system calls */
24382
24383 /*
24384 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
@@ -25844,10 +25846,17 @@
25844 osUnlink(pFile->pId->zCanonicalName);
25845 }
25846 vxworksReleaseFileId(pFile->pId);
25847 pFile->pId = 0;
25848 }
 
 
 
 
 
 
 
25849 #endif
25850 OSTRACE(("CLOSE %-3d\n", pFile->h));
25851 OpenCounter(-1);
25852 sqlite3_free(pFile->pUnused);
25853 memset(pFile, 0, sizeof(unixFile));
@@ -27883,12 +27892,29 @@
27883 rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
27884 }
27885 return rc;
27886 }
27887
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27888 #ifndef SQLITE_OMIT_WAL
27889
27890
27891 /*
27892 ** Object used to represent an shared memory buffer.
27893 **
27894 ** When multiple threads all reference the same wal-index, each thread
@@ -28035,24 +28061,10 @@
28035 #endif
28036
28037 return rc;
28038 }
28039
28040 /*
28041 ** Return the system page size.
28042 **
28043 ** This function should not be called directly by other code in this file.
28044 ** Instead, it should be called via macro osGetpagesize().
28045 */
28046 static int unixGetpagesize(void){
28047 #if defined(_BSD_SOURCE)
28048 return getpagesize();
28049 #else
28050 return (int)sysconf(_SC_PAGESIZE);
28051 #endif
28052 }
28053
28054 /*
28055 ** Return the minimum number of 32KB shm regions that should be mapped at
28056 ** a time, assuming that each mapping must be an integer multiple of the
28057 ** current system page-size.
28058 **
@@ -29698,10 +29710,16 @@
29698 }
29699
29700 if( isDelete ){
29701 #if OS_VXWORKS
29702 zPath = zName;
 
 
 
 
 
 
29703 #else
29704 osUnlink(zName);
29705 #endif
29706 }
29707 #if SQLITE_ENABLE_LOCKING_STYLE
@@ -49189,20 +49207,20 @@
49189 **
49190 ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few
49191 ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this
49192 ** is more of a scheduler yield than an actual delay. But on the 10th
49193 ** an subsequent retries, the delays start becoming longer and longer,
49194 ** so that on the 100th (and last) RETRY we delay for 21 milliseconds.
49195 ** The total delay time before giving up is less than 1 second.
49196 */
49197 if( cnt>5 ){
49198 int nDelay = 1; /* Pause time in microseconds */
49199 if( cnt>100 ){
49200 VVA_ONLY( pWal->lockError = 1; )
49201 return SQLITE_PROTOCOL;
49202 }
49203 if( cnt>=10 ) nDelay = (cnt-9)*238; /* Max delay 21ms. Total delay 996ms */
49204 sqlite3OsSleep(pWal->pVfs, nDelay);
49205 }
49206
49207 if( !useWal ){
49208 rc = walIndexReadHdr(pWal, pChanged);
@@ -61582,10 +61600,72 @@
61582 FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
61583 for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
61584 sqlite3FuncDefInsert(pHash, &aFunc[i]);
61585 }
61586 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61587
61588 /*
61589 ** This function is used to allocate and populate UnpackedRecord
61590 ** structures intended to be compared against sample index keys stored
61591 ** in the sqlite_stat4 table.
@@ -61622,52 +61702,90 @@
61622 Expr *pExpr, /* The expression to extract a value from */
61623 u8 affinity, /* Affinity to use */
61624 int iVal, /* Array element to populate */
61625 int *pbOk /* OUT: True if value was extracted */
61626 ){
61627 int rc = SQLITE_OK;
61628 sqlite3_value *pVal = 0;
61629 sqlite3 *db = pParse->db;
61630
61631
61632 struct ValueNewStat4Ctx alloc;
 
61633 alloc.pParse = pParse;
61634 alloc.pIdx = pIdx;
61635 alloc.ppRec = ppRec;
61636 alloc.iVal = iVal;
61637
61638 /* Skip over any TK_COLLATE nodes */
61639 pExpr = sqlite3ExprSkipCollate(pExpr);
61640
61641 if( !pExpr ){
61642 pVal = valueNew(db, &alloc);
61643 if( pVal ){
61644 sqlite3VdbeMemSetNull((Mem*)pVal);
61645 }
61646 }else if( pExpr->op==TK_VARIABLE
61647 || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
61648 ){
61649 Vdbe *v;
61650 int iBindVar = pExpr->iColumn;
61651 sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
61652 if( (v = pParse->pReprepare)!=0 ){
61653 pVal = valueNew(db, &alloc);
61654 if( pVal ){
61655 rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
61656 if( rc==SQLITE_OK ){
61657 sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
61658 }
61659 pVal->db = pParse->db;
61660 }
61661 }
61662 }else{
61663 rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc);
61664 }
61665 *pbOk = (pVal!=0);
 
 
61666
61667 assert( pVal==0 || pVal->db==db );
61668 return rc;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61669 }
61670
61671 /*
61672 ** Unless it is NULL, the argument must be an UnpackedRecord object returned
61673 ** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
@@ -65315,10 +65433,11 @@
65315 /* rc==0 here means that one or both of the keys ran out of fields and
65316 ** all the fields up to that point were equal. Return the the default_rc
65317 ** value. */
65318 assert( CORRUPT_DB
65319 || pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)
 
65320 );
65321 return pPKey2->default_rc;
65322 }
65323
65324 /*
@@ -65480,10 +65599,11 @@
65480
65481 assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
65482 || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
65483 || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
65484 || CORRUPT_DB
 
65485 );
65486 return res;
65487 }
65488
65489 /*
@@ -76853,11 +76973,12 @@
76853 }else{
76854 /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
76855 ** likelihood(X, 0.0625).
76856 ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
76857 ** likelihood(X,0.0625). */
76858 pExpr->iTable = 62; /* TUNING: Default 2nd arg to unlikely() is 0.0625 */
 
76859 }
76860 }
76861 }
76862 #ifndef SQLITE_OMIT_AUTHORIZATION
76863 if( pDef ){
@@ -77629,11 +77750,11 @@
77629 ** SELECT * FROM t1 WHERE (select a from t1);
77630 */
77631 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
77632 int op;
77633 pExpr = sqlite3ExprSkipCollate(pExpr);
77634 if( pExpr->flags & EP_Generic ) return SQLITE_AFF_NONE;
77635 op = pExpr->op;
77636 if( op==TK_SELECT ){
77637 assert( pExpr->flags&EP_xIsSelect );
77638 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
77639 }
@@ -82929,10 +83050,11 @@
82929 /* Open the sqlite_stat[134] tables for writing. */
82930 for(i=0; aTable[i].zCols; i++){
82931 assert( i<ArraySize(aTable) );
82932 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
82933 sqlite3VdbeChangeP5(v, aCreateTbl[i]);
 
82934 }
82935 }
82936
82937 /*
82938 ** Recommended number of samples for sqlite_stat4
@@ -82964,11 +83086,12 @@
82964 #endif
82965 };
82966 struct Stat4Accum {
82967 tRowcnt nRow; /* Number of rows in the entire table */
82968 tRowcnt nPSample; /* How often to do a periodic sample */
82969 int nCol; /* Number of columns in index + rowid */
 
82970 int mxSample; /* Maximum number of samples to accumulate */
82971 Stat4Sample current; /* Current row as a Stat4Sample */
82972 u32 iPrn; /* Pseudo-random number used for sampling */
82973 Stat4Sample *aBest; /* Array of nCol best samples */
82974 int iMin; /* Index in a[] of entry with minimum score */
@@ -83050,13 +83173,21 @@
83050 #endif
83051 sqlite3DbFree(p->db, p);
83052 }
83053
83054 /*
83055 ** Implementation of the stat_init(N,C) SQL function. The two parameters
83056 ** are the number of rows in the table or index (C) and the number of columns
83057 ** in the index (N). The second argument (C) is only used for STAT3 and STAT4.
 
 
 
 
 
 
 
 
83058 **
83059 ** This routine allocates the Stat4Accum object in heap memory. The return
83060 ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e.
83061 ** the size of the blob is sizeof(void*) bytes).
83062 */
@@ -83065,10 +83196,11 @@
83065 int argc,
83066 sqlite3_value **argv
83067 ){
83068 Stat4Accum *p;
83069 int nCol; /* Number of columns in index being sampled */
 
83070 int nColUp; /* nCol rounded up for alignment */
83071 int n; /* Bytes of space to allocate */
83072 sqlite3 *db; /* Database connection */
83073 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83074 int mxSample = SQLITE_STAT4_SAMPLES;
@@ -83075,12 +83207,15 @@
83075 #endif
83076
83077 /* Decode the three function arguments */
83078 UNUSED_PARAMETER(argc);
83079 nCol = sqlite3_value_int(argv[0]);
83080 assert( nCol>1 ); /* >1 because it includes the rowid column */
83081 nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
 
 
 
83082
83083 /* Allocate the space required for the Stat4Accum object */
83084 n = sizeof(*p)
83085 + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
83086 + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
@@ -83098,10 +83233,11 @@
83098 }
83099
83100 p->db = db;
83101 p->nRow = 0;
83102 p->nCol = nCol;
 
83103 p->current.anDLt = (tRowcnt*)&p[1];
83104 p->current.anEq = &p->current.anDLt[nColUp];
83105
83106 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83107 {
@@ -83108,13 +83244,13 @@
83108 u8 *pSpace; /* Allocated space not yet assigned */
83109 int i; /* Used to iterate through p->aSample[] */
83110
83111 p->iGet = -1;
83112 p->mxSample = mxSample;
83113 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1);
83114 p->current.anLt = &p->current.anEq[nColUp];
83115 p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[1])*0xd0944565;
83116
83117 /* Set up the Stat4Accum.a[] and aBest[] arrays */
83118 p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
83119 p->aBest = &p->a[mxSample];
83120 pSpace = (u8*)(&p->a[mxSample+nCol]);
@@ -83133,11 +83269,11 @@
83133
83134 /* Return a pointer to the allocated object to the caller */
83135 sqlite3_result_blob(context, p, sizeof(p), stat4Destructor);
83136 }
83137 static const FuncDef statInitFuncdef = {
83138 1+IsStat34, /* nArg */
83139 SQLITE_UTF8, /* funcFlags */
83140 0, /* pUserData */
83141 0, /* pNext */
83142 statInit, /* xFunc */
83143 0, /* xStep */
@@ -83374,11 +83510,11 @@
83374 Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
83375 int iChng = sqlite3_value_int(argv[1]);
83376
83377 UNUSED_PARAMETER( argc );
83378 UNUSED_PARAMETER( context );
83379 assert( p->nCol>1 ); /* Includes rowid field */
83380 assert( iChng<p->nCol );
83381
83382 if( p->nRow==0 ){
83383 /* This is the first call to this function. Do initialization. */
83384 for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
@@ -83502,19 +83638,19 @@
83502 ** I = (K+D-1)/D
83503 */
83504 char *z;
83505 int i;
83506
83507 char *zRet = sqlite3MallocZero(p->nCol * 25);
83508 if( zRet==0 ){
83509 sqlite3_result_error_nomem(context);
83510 return;
83511 }
83512
83513 sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
83514 z = zRet + sqlite3Strlen30(zRet);
83515 for(i=0; i<(p->nCol-1); i++){
83516 u64 nDistinct = p->current.anDLt[i] + 1;
83517 u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
83518 sqlite3_snprintf(24, z, " %llu", iVal);
83519 z += sqlite3Strlen30(z);
83520 assert( p->current.anEq[i] );
@@ -83679,22 +83815,23 @@
83679 int addrNextRow; /* Address of "next_row:" */
83680 const char *zIdxName; /* Name of the index */
83681
83682 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
83683 if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
83684 VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
83685 nCol = pIdx->nKeyCol;
 
 
 
 
 
83686 aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
83687 if( aGotoChng==0 ) continue;
83688
83689 /* Populate the register containing the index name. */
83690 if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
83691 zIdxName = pTab->zName;
83692 }else{
83693 zIdxName = pIdx->zName;
83694 }
83695 sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
 
83696
83697 /*
83698 ** Pseudo-code for loop that calls stat_push():
83699 **
83700 ** Rewind csr
@@ -83744,16 +83881,17 @@
83744 ** (2) the number of rows in the index,
83745 **
83746 ** The second argument is only used for STAT3 and STAT4
83747 */
83748 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83749 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2);
83750 #endif
83751 sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1);
 
83752 sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
83753 sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
83754 sqlite3VdbeChangeP5(v, 1+IsStat34);
83755
83756 /* Implementation of the following:
83757 **
83758 ** Rewind csr
83759 ** if eof(csr) goto end_of_scan;
@@ -83851,11 +83989,11 @@
83851 int regSampleRowid = regCol + nCol;
83852 int addrNext;
83853 int addrIsNull;
83854 u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
83855
83856 pParse->nMem = MAX(pParse->nMem, regCol+nCol+1);
83857
83858 addrNext = sqlite3VdbeCurrentAddr(v);
83859 callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
83860 addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
83861 VdbeCoverage(v);
@@ -83873,11 +84011,11 @@
83873 #else
83874 for(i=0; i<nCol; i++){
83875 i16 iCol = pIdx->aiColumn[i];
83876 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
83877 }
83878 sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample);
83879 #endif
83880 sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
83881 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
83882 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
83883 sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
@@ -84185,11 +84323,20 @@
84185 static void initAvgEq(Index *pIdx){
84186 if( pIdx ){
84187 IndexSample *aSample = pIdx->aSample;
84188 IndexSample *pFinal = &aSample[pIdx->nSample-1];
84189 int iCol;
84190 for(iCol=0; iCol<pIdx->nKeyCol; iCol++){
 
 
 
 
 
 
 
 
 
84191 int i; /* Used to iterate through samples */
84192 tRowcnt sumEq = 0; /* Sum of the nEq values */
84193 tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
84194 tRowcnt avgEq = 0;
84195 tRowcnt nDLt = pFinal->anDLt[iCol];
@@ -84208,11 +84355,10 @@
84208 if( nDLt>nSum ){
84209 avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
84210 }
84211 if( avgEq==0 ) avgEq = 1;
84212 pIdx->aAvgEq[iCol] = avgEq;
84213 if( pIdx->nSampleCol==1 ) break;
84214 }
84215 }
84216 }
84217
84218 /*
@@ -84267,11 +84413,10 @@
84267 sqlite3DbFree(db, zSql);
84268 if( rc ) return rc;
84269
84270 while( sqlite3_step(pStmt)==SQLITE_ROW ){
84271 int nIdxCol = 1; /* Number of columns in stat4 records */
84272 int nAvgCol = 1; /* Number of entries in Index.aAvgEq */
84273
84274 char *zIndex; /* Index name */
84275 Index *pIdx; /* Pointer to the index object */
84276 int nSample; /* Number of samples */
84277 int nByte; /* Bytes of space required */
@@ -84285,25 +84430,29 @@
84285 assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
84286 /* Index.nSample is non-zero at this point if data has already been
84287 ** loaded from the stat4 table. In this case ignore stat3 data. */
84288 if( pIdx==0 || pIdx->nSample ) continue;
84289 if( bStat3==0 ){
84290 nIdxCol = pIdx->nKeyCol+1;
84291 nAvgCol = pIdx->nKeyCol;
 
 
 
 
84292 }
84293 pIdx->nSampleCol = nIdxCol;
84294 nByte = sizeof(IndexSample) * nSample;
84295 nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
84296 nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
84297
84298 pIdx->aSample = sqlite3DbMallocZero(db, nByte);
84299 if( pIdx->aSample==0 ){
84300 sqlite3_finalize(pStmt);
84301 return SQLITE_NOMEM;
84302 }
84303 pSpace = (tRowcnt*)&pIdx->aSample[nSample];
84304 pIdx->aAvgEq = pSpace; pSpace += nAvgCol;
84305 for(i=0; i<nSample; i++){
84306 pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
84307 pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
84308 pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
84309 }
@@ -92553,10 +92702,11 @@
92553 FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
92554 FUNCTION(hex, 1, 0, 0, hexFunc ),
92555 FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
92556 FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
92557 FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
 
92558 VFUNCTION(random, 0, 0, 0, randomFunc ),
92559 VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
92560 FUNCTION(nullif, 2, 0, 1, nullifFunc ),
92561 FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
92562 FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
@@ -110581,11 +110731,11 @@
110581 pScan->pOrigWC = pWC;
110582 pScan->pWC = pWC;
110583 if( pIdx && iColumn>=0 ){
110584 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
110585 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
110586 if( NEVER(j>=pIdx->nKeyCol) ) return 0;
110587 }
110588 pScan->zCollName = pIdx->azColl[j];
110589 }else{
110590 pScan->idxaff = 0;
110591 pScan->zCollName = 0;
@@ -111531,12 +111681,11 @@
111531
111532 /*
111533 ** Estimate the logarithm of the input value to base 2.
111534 */
111535 static LogEst estLog(LogEst N){
111536 LogEst x = sqlite3LogEst(N);
111537 return x>33 ? x - 33 : 0;
111538 }
111539
111540 /*
111541 ** Two routines for printing the content of an sqlite3_index_info
111542 ** structure. Used for testing and debugging only. If neither
@@ -111997,11 +112146,11 @@
111997 }else{
111998 i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
111999 iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
112000 iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
112001 }
112002 aStat[1] = (pIdx->nKeyCol>iCol ? pIdx->aAvgEq[iCol] : 1);
112003 if( iLower>=iUpper ){
112004 iGap = 0;
112005 }else{
112006 iGap = iUpper - iLower;
112007 }
@@ -112036,10 +112185,118 @@
112036 }
112037 }
112038 return nRet;
112039 }
112040
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112041 /*
112042 ** This function is used to estimate the number of rows that will be visited
112043 ** by scanning an index for a range of values. The range may have an upper
112044 ** bound, a lower bound, or both. The WHERE clause terms that set the upper
112045 ** and lower bounds are represented by pLower and pUpper respectively. For
@@ -112072,13 +112329,13 @@
112072 ** considering the range constraints. If nEq is 0, this is the number of
112073 ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
112074 ** to account for the range contraints pLower and pUpper.
112075 **
112076 ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
112077 ** used, each range inequality reduces the search space by a factor of 4.
112078 ** Hence a pair of constraints (x>? AND x<?) reduces the expected number of
112079 ** rows visited by a factor of 16.
112080 */
112081 static int whereRangeScanEst(
112082 Parse *pParse, /* Parsing & code generating context */
112083 WhereLoopBuilder *pBuilder,
112084 WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
@@ -112092,99 +112349,104 @@
112092 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
112093 Index *p = pLoop->u.btree.pIndex;
112094 int nEq = pLoop->u.btree.nEq;
112095
112096 if( p->nSample>0
112097 && nEq==pBuilder->nRecValid
112098 && nEq<p->nSampleCol
112099 && OptimizationEnabled(pParse->db, SQLITE_Stat3)
112100 ){
112101 UnpackedRecord *pRec = pBuilder->pRec;
112102 tRowcnt a[2];
112103 u8 aff;
112104
112105 /* Variable iLower will be set to the estimate of the number of rows in
112106 ** the index that are less than the lower bound of the range query. The
112107 ** lower bound being the concatenation of $P and $L, where $P is the
112108 ** key-prefix formed by the nEq values matched against the nEq left-most
112109 ** columns of the index, and $L is the value in pLower.
112110 **
112111 ** Or, if pLower is NULL or $L cannot be extracted from it (because it
112112 ** is not a simple variable or literal value), the lower bound of the
112113 ** range is $P. Due to a quirk in the way whereKeyStats() works, even
112114 ** if $L is available, whereKeyStats() is called for both ($P) and
112115 ** ($P:$L) and the larger of the two returned values used.
112116 **
112117 ** Similarly, iUpper is to be set to the estimate of the number of rows
112118 ** less than the upper bound of the range query. Where the upper bound
112119 ** is either ($P) or ($P:$U). Again, even if $U is available, both values
112120 ** of iUpper are requested of whereKeyStats() and the smaller used.
112121 */
112122 tRowcnt iLower;
112123 tRowcnt iUpper;
112124
112125 if( nEq==p->nKeyCol ){
112126 aff = SQLITE_AFF_INTEGER;
112127 }else{
112128 aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
112129 }
112130 /* Determine iLower and iUpper using ($P) only. */
112131 if( nEq==0 ){
112132 iLower = 0;
112133 iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
112134 }else{
112135 /* Note: this call could be optimized away - since the same values must
112136 ** have been requested when testing key $P in whereEqualScanEst(). */
112137 whereKeyStats(pParse, p, pRec, 0, a);
112138 iLower = a[0];
112139 iUpper = a[0] + a[1];
112140 }
112141
112142 /* If possible, improve on the iLower estimate using ($P:$L). */
112143 if( pLower ){
112144 int bOk; /* True if value is extracted from pExpr */
112145 Expr *pExpr = pLower->pExpr->pRight;
112146 assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
112147 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112148 if( rc==SQLITE_OK && bOk ){
112149 tRowcnt iNew;
112150 whereKeyStats(pParse, p, pRec, 0, a);
112151 iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
112152 if( iNew>iLower ) iLower = iNew;
112153 nOut--;
112154 }
112155 }
112156
112157 /* If possible, improve on the iUpper estimate using ($P:$U). */
112158 if( pUpper ){
112159 int bOk; /* True if value is extracted from pExpr */
112160 Expr *pExpr = pUpper->pExpr->pRight;
112161 assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
112162 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112163 if( rc==SQLITE_OK && bOk ){
112164 tRowcnt iNew;
112165 whereKeyStats(pParse, p, pRec, 1, a);
112166 iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
112167 if( iNew<iUpper ) iUpper = iNew;
112168 nOut--;
112169 }
112170 }
112171
112172 pBuilder->pRec = pRec;
112173 if( rc==SQLITE_OK ){
112174 if( iUpper>iLower ){
112175 nNew = sqlite3LogEst(iUpper - iLower);
112176 }else{
112177 nNew = 10; assert( 10==sqlite3LogEst(2) );
112178 }
112179 if( nNew<nOut ){
112180 nOut = nNew;
112181 }
112182 pLoop->nOut = (LogEst)nOut;
112183 WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n",
112184 (u32)iLower, (u32)iUpper, nOut));
112185 return SQLITE_OK;
 
 
 
 
 
 
112186 }
112187 }
112188 #else
112189 UNUSED_PARAMETER(pParse);
112190 UNUSED_PARAMETER(pBuilder);
@@ -112239,11 +112501,11 @@
112239 int rc; /* Subfunction return code */
112240 tRowcnt a[2]; /* Statistics */
112241 int bOk;
112242
112243 assert( nEq>=1 );
112244 assert( nEq<=(p->nKeyCol+1) );
112245 assert( p->aSample!=0 );
112246 assert( p->nSample>0 );
112247 assert( pBuilder->nRecValid<nEq );
112248
112249 /* If values are not available for all fields of the index to the left
@@ -112252,11 +112514,11 @@
112252 return SQLITE_NOTFOUND;
112253 }
112254
112255 /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
112256 ** below would return the same value. */
112257 if( nEq>p->nKeyCol ){
112258 *pnRow = 1;
112259 return SQLITE_OK;
112260 }
112261
112262 aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
@@ -112683,11 +112945,11 @@
112683 }
112684 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
112685 txt.db = db;
112686 sqlite3StrAccumAppend(&txt, " (", 2);
112687 for(i=0; i<nEq; i++){
112688 char *z = (i==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[i]].zName;
112689 if( i>=nSkip ){
112690 explainAppendTerm(&txt, i, z, "=");
112691 }else{
112692 if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
112693 sqlite3StrAccumAppend(&txt, "ANY(", 4);
@@ -112696,15 +112958,15 @@
112696 }
112697 }
112698
112699 j = i;
112700 if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
112701 char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
112702 explainAppendTerm(&txt, i++, z, ">");
112703 }
112704 if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
112705 char *z = (j==pIndex->nKeyCol ) ? "rowid" : aCol[aiColumn[j]].zName;
112706 explainAppendTerm(&txt, i, z, "<");
112707 }
112708 sqlite3StrAccumAppend(&txt, ")", 1);
112709 return sqlite3StrAccumFinish(&txt);
112710 }
@@ -113724,11 +113986,11 @@
113724 z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
113725 }
113726 sqlite3DebugPrintf(" %-19s", z);
113727 sqlite3_free(z);
113728 }
113729 sqlite3DebugPrintf(" f %04x N %d", p->wsFlags, p->nLTerm);
113730 sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
113731 #ifdef SQLITE_ENABLE_TREE_EXPLAIN
113732 /* If the 0x100 bit of wheretracing is set, then show all of the constraint
113733 ** expressions in the WhereLoop.aLTerm[] array.
113734 */
@@ -113960,10 +114222,21 @@
113960
113961 /* whereLoopAddBtree() always generates and inserts the automatic index
113962 ** case first. Hence compatible candidate WhereLoops never have a larger
113963 ** rSetup. Call this SETUP-INVARIANT */
113964 assert( p->rSetup>=pTemplate->rSetup );
 
 
 
 
 
 
 
 
 
 
 
113965
113966 /* If existing WhereLoop p is better than pTemplate, pTemplate can be
113967 ** discarded. WhereLoop p is better if:
113968 ** (1) p has no more dependencies than pTemplate, and
113969 ** (2) p has an equal or lower cost than pTemplate
@@ -114085,17 +114358,17 @@
114085 ** p[] that are also supplated by pTemplate */
114086 WhereLoop **ppTail = &p->pNextLoop;
114087 WhereLoop *pToDel;
114088 while( *ppTail ){
114089 ppTail = whereLoopFindLesser(ppTail, pTemplate);
114090 if( NEVER(ppTail==0) ) break;
114091 pToDel = *ppTail;
114092 if( pToDel==0 ) break;
114093 *ppTail = pToDel->pNextLoop;
114094 #if WHERETRACE_ENABLED /* 0x8 */
114095 if( sqlite3WhereTrace & 0x8 ){
114096 sqlite3DebugPrintf("ins-del: ");
114097 whereLoopPrint(pToDel, pBuilder->pWC);
114098 }
114099 #endif
114100 whereLoopDelete(db, pToDel);
114101 }
@@ -114191,16 +114464,13 @@
114191 }else{
114192 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
114193 }
114194 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
114195
114196 assert( pNew->u.btree.nEq<=pProbe->nKeyCol );
114197 if( pNew->u.btree.nEq < pProbe->nKeyCol ){
114198 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
114199 }else{
114200 iCol = -1;
114201 }
114202 pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
114203 opMask, pProbe);
114204 saved_nEq = pNew->u.btree.nEq;
114205 saved_nSkip = pNew->u.btree.nSkip;
114206 saved_nLTerm = pNew->nLTerm;
@@ -114386,11 +114656,11 @@
114386 }else{
114387 pNew->nOut = nOutUnadjusted;
114388 }
114389
114390 if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
114391 && pNew->u.btree.nEq<(pProbe->nKeyCol + (pProbe->zName!=0))
114392 ){
114393 whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
114394 }
114395 pNew->nOut = saved_nOut;
114396 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -114533,10 +114803,11 @@
114533 ** fake index the first in a chain of Index objects with all of the real
114534 ** indices to follow */
114535 Index *pFirst; /* First of real indices on the table */
114536 memset(&sPk, 0, sizeof(Index));
114537 sPk.nKeyCol = 1;
 
114538 sPk.aiColumn = &aiColumnPk;
114539 sPk.aiRowLogEst = aiRowEstPk;
114540 sPk.onError = OE_Replace;
114541 sPk.pTable = pTab;
114542 sPk.szIdxRow = pTab->szTabRow;
@@ -115316,11 +115587,10 @@
115316 int mxI = 0; /* Index of next entry to replace */
115317 int nOrderBy; /* Number of ORDER BY clause terms */
115318 LogEst rCost; /* Cost of a path */
115319 LogEst nOut; /* Number of outputs */
115320 LogEst mxCost = 0; /* Maximum cost of a set of paths */
115321 LogEst mxOut = 0; /* Maximum nOut value on the set of paths */
115322 int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
115323 WherePath *aFrom; /* All nFrom paths at the previous level */
115324 WherePath *aTo; /* The nTo best paths at the current level */
115325 WherePath *pFrom; /* An element of aFrom[] that we are working on */
115326 WherePath *pTo; /* An element of aTo[] that we are working on */
@@ -115426,12 +115696,10 @@
115426 }
115427 /* Check to see if pWLoop should be added to the mxChoice best so far */
115428 for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
115429 if( pTo->maskLoop==maskNew
115430 && ((pTo->isOrdered^isOrdered)&80)==0
115431 && ((pTo->rCost<=rCost && pTo->nRow<=nOut) ||
115432 (pTo->rCost>=rCost && pTo->nRow>=nOut))
115433 ){
115434 testcase( jj==nTo-1 );
115435 break;
115436 }
115437 }
@@ -115461,11 +115729,11 @@
115461 wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
115462 isOrdered>=0 ? isOrdered+'0' : '?');
115463 }
115464 #endif
115465 }else{
115466 if( pTo->rCost<=rCost && pTo->nRow<=nOut ){
115467 #ifdef WHERETRACE_ENABLED /* 0x4 */
115468 if( sqlite3WhereTrace&0x4 ){
115469 sqlite3DebugPrintf(
115470 "Skip %s cost=%-3d,%3d order=%c",
115471 wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
@@ -115501,15 +115769,13 @@
115501 memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
115502 pTo->aLoop[iLoop] = pWLoop;
115503 if( nTo>=mxChoice ){
115504 mxI = 0;
115505 mxCost = aTo[0].rCost;
115506 mxOut = aTo[0].nRow;
115507 for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
115508 if( pTo->rCost>mxCost || (pTo->rCost==mxCost && pTo->nRow>mxOut) ){
115509 mxCost = pTo->rCost;
115510 mxOut = pTo->nRow;
115511 mxI = jj;
115512 }
115513 }
115514 }
115515 }
@@ -124205,14 +124471,14 @@
124205 ** sqlite3_test_control().
124206 */
124207 case SQLITE_TESTCTRL_FAULT_INSTALL: {
124208 /* MSVC is picky about pulling func ptrs from va lists.
124209 ** http://support.microsoft.com/kb/47961
124210 ** sqlite3Config.xTestCallback = va_arg(ap, int(*)(int));
124211 */
124212 typedef int(*TESTCALLBACKFUNC_t)(int);
124213 sqlite3Config.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
124214 rc = sqlite3FaultSim(0);
124215 break;
124216 }
124217
124218 /*
@@ -140777,38 +141043,40 @@
140777 i64 iDocid = sqlite3_column_int64(pStmt, 0);
140778 int iLang = langidFromSelect(p, pStmt);
140779 int iCol;
140780
140781 for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
140782 const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
140783 int nText = sqlite3_column_bytes(pStmt, iCol+1);
140784 sqlite3_tokenizer_cursor *pT = 0;
140785
140786 rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText, &pT);
140787 while( rc==SQLITE_OK ){
140788 char const *zToken; /* Buffer containing token */
140789 int nToken = 0; /* Number of bytes in token */
140790 int iDum1 = 0, iDum2 = 0; /* Dummy variables */
140791 int iPos = 0; /* Position of token in zText */
140792
140793 rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
140794 if( rc==SQLITE_OK ){
140795 int i;
140796 cksum2 = cksum2 ^ fts3ChecksumEntry(
140797 zToken, nToken, iLang, 0, iDocid, iCol, iPos
140798 );
140799 for(i=1; i<p->nIndex; i++){
140800 if( p->aIndex[i].nPrefix<=nToken ){
140801 cksum2 = cksum2 ^ fts3ChecksumEntry(
140802 zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos
140803 );
140804 }
140805 }
140806 }
140807 }
140808 if( pT ) pModule->xClose(pT);
140809 if( rc==SQLITE_DONE ) rc = SQLITE_OK;
 
 
140810 }
140811 }
140812
140813 sqlite3_finalize(pStmt);
140814 }
140815
--- 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.8.6. 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.
@@ -220,13 +220,13 @@
220 **
221 ** See also: [sqlite3_libversion()],
222 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
223 ** [sqlite_version()] and [sqlite_source_id()].
224 */
225 #define SQLITE_VERSION "3.8.6"
226 #define SQLITE_VERSION_NUMBER 3008006
227 #define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41"
228
229 /*
230 ** CAPI3REF: Run-Time Library Version Numbers
231 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
232 **
@@ -9479,10 +9479,11 @@
9479 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
9480 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
9481 #ifndef SQLITE_OMIT_TRACE
9482 SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
9483 #endif
9484 SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
9485
9486 SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*);
9487 SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*,int);
9488 SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo *, char *, int, char **);
9489
@@ -12885,11 +12886,13 @@
12886 SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);
12887
12888 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
12889 SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void);
12890 SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*);
12891 SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**);
12892 SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*);
12893 SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**);
12894 #endif
12895
12896 /*
12897 ** The interface to the LEMON-generated parser
12898 */
@@ -14199,11 +14202,10 @@
14202 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
14203
14204 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
14205 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
14206 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
 
14207 SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*);
14208 SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*);
14209 SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*);
14210 SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int);
14211 SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*);
@@ -21562,12 +21564,12 @@
21564 ** * Bytes in the range of 0x80 through 0xbf which occur as the first
21565 ** byte of a character are interpreted as single-byte characters
21566 ** and rendered as themselves even though they are technically
21567 ** invalid characters.
21568 **
21569 ** * This routine accepts over-length UTF8 encodings
21570 ** for unicode values 0x80 and greater. It does not change over-length
21571 ** encodings to 0xfffd as some systems recommend.
21572 */
21573 #define READ_UTF8(zIn, zTerm, c) \
21574 c = *(zIn++); \
21575 if( c>=0xc0 ){ \
@@ -24371,14 +24373,14 @@
24373 { "mremap", (sqlite3_syscall_ptr)mremap, 0 },
24374 #else
24375 { "mremap", (sqlite3_syscall_ptr)0, 0 },
24376 #endif
24377 #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent)
 
 
24378 { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 },
24379 #define osGetpagesize ((int(*)(void))aSyscall[24].pCurrent)
24380
24381 #endif
24382
24383 }; /* End of the overrideable system calls */
24384
24385 /*
24386 ** This is the xSetSystemCall() method of sqlite3_vfs for all of the
@@ -25844,10 +25846,17 @@
25846 osUnlink(pFile->pId->zCanonicalName);
25847 }
25848 vxworksReleaseFileId(pFile->pId);
25849 pFile->pId = 0;
25850 }
25851 #endif
25852 #ifdef SQLITE_UNLINK_AFTER_CLOSE
25853 if( pFile->ctrlFlags & UNIXFILE_DELETE ){
25854 osUnlink(pFile->zPath);
25855 sqlite3_free(*(char**)&pFile->zPath);
25856 pFile->zPath = 0;
25857 }
25858 #endif
25859 OSTRACE(("CLOSE %-3d\n", pFile->h));
25860 OpenCounter(-1);
25861 sqlite3_free(pFile->pUnused);
25862 memset(pFile, 0, sizeof(unixFile));
@@ -27883,12 +27892,29 @@
27892 rc |= SQLITE_IOCAP_POWERSAFE_OVERWRITE;
27893 }
27894 return rc;
27895 }
27896
27897 #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
27898
27899 /*
27900 ** Return the system page size.
27901 **
27902 ** This function should not be called directly by other code in this file.
27903 ** Instead, it should be called via macro osGetpagesize().
27904 */
27905 static int unixGetpagesize(void){
27906 #if defined(_BSD_SOURCE)
27907 return getpagesize();
27908 #else
27909 return (int)sysconf(_SC_PAGESIZE);
27910 #endif
27911 }
27912
27913 #endif /* !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 */
27914
27915 #ifndef SQLITE_OMIT_WAL
 
27916
27917 /*
27918 ** Object used to represent an shared memory buffer.
27919 **
27920 ** When multiple threads all reference the same wal-index, each thread
@@ -28035,24 +28061,10 @@
28061 #endif
28062
28063 return rc;
28064 }
28065
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28066 /*
28067 ** Return the minimum number of 32KB shm regions that should be mapped at
28068 ** a time, assuming that each mapping must be an integer multiple of the
28069 ** current system page-size.
28070 **
@@ -29698,10 +29710,16 @@
29710 }
29711
29712 if( isDelete ){
29713 #if OS_VXWORKS
29714 zPath = zName;
29715 #elif defined(SQLITE_UNLINK_AFTER_CLOSE)
29716 zPath = sqlite3_mprintf("%s", zName);
29717 if( zPath==0 ){
29718 robust_close(p, fd, __LINE__);
29719 return SQLITE_NOMEM;
29720 }
29721 #else
29722 osUnlink(zName);
29723 #endif
29724 }
29725 #if SQLITE_ENABLE_LOCKING_STYLE
@@ -49189,20 +49207,20 @@
49207 **
49208 ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few
49209 ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this
49210 ** is more of a scheduler yield than an actual delay. But on the 10th
49211 ** an subsequent retries, the delays start becoming longer and longer,
49212 ** so that on the 100th (and last) RETRY we delay for 323 milliseconds.
49213 ** The total delay time before giving up is less than 10 seconds.
49214 */
49215 if( cnt>5 ){
49216 int nDelay = 1; /* Pause time in microseconds */
49217 if( cnt>100 ){
49218 VVA_ONLY( pWal->lockError = 1; )
49219 return SQLITE_PROTOCOL;
49220 }
49221 if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39;
49222 sqlite3OsSleep(pWal->pVfs, nDelay);
49223 }
49224
49225 if( !useWal ){
49226 rc = walIndexReadHdr(pWal, pChanged);
@@ -61582,10 +61600,72 @@
61600 FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs);
61601 for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){
61602 sqlite3FuncDefInsert(pHash, &aFunc[i]);
61603 }
61604 }
61605
61606 /*
61607 ** Attempt to extract a value from pExpr and use it to construct *ppVal.
61608 **
61609 ** If pAlloc is not NULL, then an UnpackedRecord object is created for
61610 ** pAlloc if one does not exist and the new value is added to the
61611 ** UnpackedRecord object.
61612 **
61613 ** A value is extracted in the following cases:
61614 **
61615 ** * (pExpr==0). In this case the value is assumed to be an SQL NULL,
61616 **
61617 ** * The expression is a bound variable, and this is a reprepare, or
61618 **
61619 ** * The expression is a literal value.
61620 **
61621 ** On success, *ppVal is made to point to the extracted value. The caller
61622 ** is responsible for ensuring that the value is eventually freed.
61623 */
61624 static int stat4ValueFromExpr(
61625 Parse *pParse, /* Parse context */
61626 Expr *pExpr, /* The expression to extract a value from */
61627 u8 affinity, /* Affinity to use */
61628 struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */
61629 sqlite3_value **ppVal /* OUT: New value object (or NULL) */
61630 ){
61631 int rc = SQLITE_OK;
61632 sqlite3_value *pVal = 0;
61633 sqlite3 *db = pParse->db;
61634
61635 /* Skip over any TK_COLLATE nodes */
61636 pExpr = sqlite3ExprSkipCollate(pExpr);
61637
61638 if( !pExpr ){
61639 pVal = valueNew(db, pAlloc);
61640 if( pVal ){
61641 sqlite3VdbeMemSetNull((Mem*)pVal);
61642 }
61643 }else if( pExpr->op==TK_VARIABLE
61644 || NEVER(pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
61645 ){
61646 Vdbe *v;
61647 int iBindVar = pExpr->iColumn;
61648 sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar);
61649 if( (v = pParse->pReprepare)!=0 ){
61650 pVal = valueNew(db, pAlloc);
61651 if( pVal ){
61652 rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]);
61653 if( rc==SQLITE_OK ){
61654 sqlite3ValueApplyAffinity(pVal, affinity, ENC(db));
61655 }
61656 pVal->db = pParse->db;
61657 }
61658 }
61659 }else{
61660 rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, pAlloc);
61661 }
61662
61663 assert( pVal==0 || pVal->db==db );
61664 *ppVal = pVal;
61665 return rc;
61666 }
61667
61668 /*
61669 ** This function is used to allocate and populate UnpackedRecord
61670 ** structures intended to be compared against sample index keys stored
61671 ** in the sqlite_stat4 table.
@@ -61622,52 +61702,90 @@
61702 Expr *pExpr, /* The expression to extract a value from */
61703 u8 affinity, /* Affinity to use */
61704 int iVal, /* Array element to populate */
61705 int *pbOk /* OUT: True if value was extracted */
61706 ){
61707 int rc;
61708 sqlite3_value *pVal = 0;
 
 
 
61709 struct ValueNewStat4Ctx alloc;
61710
61711 alloc.pParse = pParse;
61712 alloc.pIdx = pIdx;
61713 alloc.ppRec = ppRec;
61714 alloc.iVal = iVal;
61715
61716 rc = stat4ValueFromExpr(pParse, pExpr, affinity, &alloc, &pVal);
61717 assert( pVal==0 || pVal->db==pParse->db );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61718 *pbOk = (pVal!=0);
61719 return rc;
61720 }
61721
61722 /*
61723 ** Attempt to extract a value from expression pExpr using the methods
61724 ** as described for sqlite3Stat4ProbeSetValue() above.
61725 **
61726 ** If successful, set *ppVal to point to a new value object and return
61727 ** SQLITE_OK. If no value can be extracted, but no other error occurs
61728 ** (e.g. OOM), return SQLITE_OK and set *ppVal to NULL. Or, if an error
61729 ** does occur, return an SQLite error code. The final value of *ppVal
61730 ** is undefined in this case.
61731 */
61732 SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(
61733 Parse *pParse, /* Parse context */
61734 Expr *pExpr, /* The expression to extract a value from */
61735 u8 affinity, /* Affinity to use */
61736 sqlite3_value **ppVal /* OUT: New value object (or NULL) */
61737 ){
61738 return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal);
61739 }
61740
61741 /*
61742 ** Extract the iCol-th column from the nRec-byte record in pRec. Write
61743 ** the column value into *ppVal. If *ppVal is initially NULL then a new
61744 ** sqlite3_value object is allocated.
61745 **
61746 ** If *ppVal is initially NULL then the caller is responsible for
61747 ** ensuring that the value written into *ppVal is eventually freed.
61748 */
61749 SQLITE_PRIVATE int sqlite3Stat4Column(
61750 sqlite3 *db, /* Database handle */
61751 const void *pRec, /* Pointer to buffer containing record */
61752 int nRec, /* Size of buffer pRec in bytes */
61753 int iCol, /* Column to extract */
61754 sqlite3_value **ppVal /* OUT: Extracted value */
61755 ){
61756 u32 t; /* a column type code */
61757 int nHdr; /* Size of the header in the record */
61758 int iHdr; /* Next unread header byte */
61759 int iField; /* Next unread data byte */
61760 int szField; /* Size of the current data field */
61761 int i; /* Column index */
61762 u8 *a = (u8*)pRec; /* Typecast byte array */
61763 Mem *pMem = *ppVal; /* Write result into this Mem object */
61764
61765 assert( iCol>0 );
61766 iHdr = getVarint32(a, nHdr);
61767 if( nHdr>nRec || iHdr>=nHdr ) return SQLITE_CORRUPT_BKPT;
61768 iField = nHdr;
61769 for(i=0; i<=iCol; i++){
61770 iHdr += getVarint32(&a[iHdr], t);
61771 testcase( iHdr==nHdr );
61772 testcase( iHdr==nHdr+1 );
61773 if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT;
61774 szField = sqlite3VdbeSerialTypeLen(t);
61775 iField += szField;
61776 }
61777 testcase( iField==nRec );
61778 testcase( iField==nRec+1 );
61779 if( iField>nRec ) return SQLITE_CORRUPT_BKPT;
61780 if( pMem==0 ){
61781 pMem = *ppVal = sqlite3ValueNew(db);
61782 if( pMem==0 ) return SQLITE_NOMEM;
61783 }
61784 sqlite3VdbeSerialGet(&a[iField-szField], t, pMem);
61785 pMem->enc = ENC(db);
61786 return SQLITE_OK;
61787 }
61788
61789 /*
61790 ** Unless it is NULL, the argument must be an UnpackedRecord object returned
61791 ** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes
@@ -65315,10 +65433,11 @@
65433 /* rc==0 here means that one or both of the keys ran out of fields and
65434 ** all the fields up to that point were equal. Return the the default_rc
65435 ** value. */
65436 assert( CORRUPT_DB
65437 || pPKey2->default_rc==vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)
65438 || pKeyInfo->db->mallocFailed
65439 );
65440 return pPKey2->default_rc;
65441 }
65442
65443 /*
@@ -65480,10 +65599,11 @@
65599
65600 assert( (res==0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)==0)
65601 || (res<0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)<0)
65602 || (res>0 && vdbeRecordCompareDebug(nKey1, pKey1, pPKey2)>0)
65603 || CORRUPT_DB
65604 || pPKey2->pKeyInfo->db->mallocFailed
65605 );
65606 return res;
65607 }
65608
65609 /*
@@ -76853,11 +76973,12 @@
76973 }else{
76974 /* EVIDENCE-OF: R-61304-29449 The unlikely(X) function is equivalent to
76975 ** likelihood(X, 0.0625).
76976 ** EVIDENCE-OF: R-01283-11636 The unlikely(X) function is short-hand for
76977 ** likelihood(X,0.0625). */
76978 /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */
76979 pExpr->iTable = pDef->zName[0]=='u' ? 62 : 938;
76980 }
76981 }
76982 }
76983 #ifndef SQLITE_OMIT_AUTHORIZATION
76984 if( pDef ){
@@ -77629,11 +77750,11 @@
77750 ** SELECT * FROM t1 WHERE (select a from t1);
77751 */
77752 SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){
77753 int op;
77754 pExpr = sqlite3ExprSkipCollate(pExpr);
77755 if( pExpr->flags & EP_Generic ) return 0;
77756 op = pExpr->op;
77757 if( op==TK_SELECT ){
77758 assert( pExpr->flags&EP_xIsSelect );
77759 return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
77760 }
@@ -82929,10 +83050,11 @@
83050 /* Open the sqlite_stat[134] tables for writing. */
83051 for(i=0; aTable[i].zCols; i++){
83052 assert( i<ArraySize(aTable) );
83053 sqlite3VdbeAddOp4Int(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb, 3);
83054 sqlite3VdbeChangeP5(v, aCreateTbl[i]);
83055 VdbeComment((v, aTable[i].zName));
83056 }
83057 }
83058
83059 /*
83060 ** Recommended number of samples for sqlite_stat4
@@ -82964,11 +83086,12 @@
83086 #endif
83087 };
83088 struct Stat4Accum {
83089 tRowcnt nRow; /* Number of rows in the entire table */
83090 tRowcnt nPSample; /* How often to do a periodic sample */
83091 int nCol; /* Number of columns in index + pk/rowid */
83092 int nKeyCol; /* Number of index columns w/o the pk/rowid */
83093 int mxSample; /* Maximum number of samples to accumulate */
83094 Stat4Sample current; /* Current row as a Stat4Sample */
83095 u32 iPrn; /* Pseudo-random number used for sampling */
83096 Stat4Sample *aBest; /* Array of nCol best samples */
83097 int iMin; /* Index in a[] of entry with minimum score */
@@ -83050,13 +83173,21 @@
83173 #endif
83174 sqlite3DbFree(p->db, p);
83175 }
83176
83177 /*
83178 ** Implementation of the stat_init(N,K,C) SQL function. The three parameters
83179 ** are:
83180 ** N: The number of columns in the index including the rowid/pk
83181 ** K: The number of columns in the index excluding the rowid/pk
83182 ** C: The number of rows in the index
83183 **
83184 ** C is only used for STAT3 and STAT4.
83185 **
83186 ** For ordinary rowid tables, N==K+1. But for WITHOUT ROWID tables,
83187 ** N=K+P where P is the number of columns in the primary key. For the
83188 ** covering index that implements the original WITHOUT ROWID table, N==K.
83189 **
83190 ** This routine allocates the Stat4Accum object in heap memory. The return
83191 ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e.
83192 ** the size of the blob is sizeof(void*) bytes).
83193 */
@@ -83065,10 +83196,11 @@
83196 int argc,
83197 sqlite3_value **argv
83198 ){
83199 Stat4Accum *p;
83200 int nCol; /* Number of columns in index being sampled */
83201 int nKeyCol; /* Number of key columns */
83202 int nColUp; /* nCol rounded up for alignment */
83203 int n; /* Bytes of space to allocate */
83204 sqlite3 *db; /* Database connection */
83205 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83206 int mxSample = SQLITE_STAT4_SAMPLES;
@@ -83075,12 +83207,15 @@
83207 #endif
83208
83209 /* Decode the three function arguments */
83210 UNUSED_PARAMETER(argc);
83211 nCol = sqlite3_value_int(argv[0]);
83212 assert( nCol>0 );
83213 nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol;
83214 nKeyCol = sqlite3_value_int(argv[1]);
83215 assert( nKeyCol<=nCol );
83216 assert( nKeyCol>0 );
83217
83218 /* Allocate the space required for the Stat4Accum object */
83219 n = sizeof(*p)
83220 + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */
83221 + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */
@@ -83098,10 +83233,11 @@
83233 }
83234
83235 p->db = db;
83236 p->nRow = 0;
83237 p->nCol = nCol;
83238 p->nKeyCol = nKeyCol;
83239 p->current.anDLt = (tRowcnt*)&p[1];
83240 p->current.anEq = &p->current.anDLt[nColUp];
83241
83242 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83243 {
@@ -83108,13 +83244,13 @@
83244 u8 *pSpace; /* Allocated space not yet assigned */
83245 int i; /* Used to iterate through p->aSample[] */
83246
83247 p->iGet = -1;
83248 p->mxSample = mxSample;
83249 p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1);
83250 p->current.anLt = &p->current.anEq[nColUp];
83251 p->iPrn = nCol*0x689e962d ^ sqlite3_value_int(argv[2])*0xd0944565;
83252
83253 /* Set up the Stat4Accum.a[] and aBest[] arrays */
83254 p->a = (struct Stat4Sample*)&p->current.anLt[nColUp];
83255 p->aBest = &p->a[mxSample];
83256 pSpace = (u8*)(&p->a[mxSample+nCol]);
@@ -83133,11 +83269,11 @@
83269
83270 /* Return a pointer to the allocated object to the caller */
83271 sqlite3_result_blob(context, p, sizeof(p), stat4Destructor);
83272 }
83273 static const FuncDef statInitFuncdef = {
83274 2+IsStat34, /* nArg */
83275 SQLITE_UTF8, /* funcFlags */
83276 0, /* pUserData */
83277 0, /* pNext */
83278 statInit, /* xFunc */
83279 0, /* xStep */
@@ -83374,11 +83510,11 @@
83510 Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]);
83511 int iChng = sqlite3_value_int(argv[1]);
83512
83513 UNUSED_PARAMETER( argc );
83514 UNUSED_PARAMETER( context );
83515 assert( p->nCol>0 );
83516 assert( iChng<p->nCol );
83517
83518 if( p->nRow==0 ){
83519 /* This is the first call to this function. Do initialization. */
83520 for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1;
@@ -83502,19 +83638,19 @@
83638 ** I = (K+D-1)/D
83639 */
83640 char *z;
83641 int i;
83642
83643 char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
83644 if( zRet==0 ){
83645 sqlite3_result_error_nomem(context);
83646 return;
83647 }
83648
83649 sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow);
83650 z = zRet + sqlite3Strlen30(zRet);
83651 for(i=0; i<p->nKeyCol; i++){
83652 u64 nDistinct = p->current.anDLt[i] + 1;
83653 u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
83654 sqlite3_snprintf(24, z, " %llu", iVal);
83655 z += sqlite3Strlen30(z);
83656 assert( p->current.anEq[i] );
@@ -83679,22 +83815,23 @@
83815 int addrNextRow; /* Address of "next_row:" */
83816 const char *zIdxName; /* Name of the index */
83817
83818 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
83819 if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
83820 if( !HasRowid(pTab) && IsPrimaryKeyIndex(pIdx) ){
83821 nCol = pIdx->nKeyCol;
83822 zIdxName = pTab->zName;
83823 }else{
83824 nCol = pIdx->nColumn;
83825 zIdxName = pIdx->zName;
83826 }
83827 aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1));
83828 if( aGotoChng==0 ) continue;
83829
83830 /* Populate the register containing the index name. */
 
 
 
 
 
83831 sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, zIdxName, 0);
83832 VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName));
83833
83834 /*
83835 ** Pseudo-code for loop that calls stat_push():
83836 **
83837 ** Rewind csr
@@ -83744,16 +83881,17 @@
83881 ** (2) the number of rows in the index,
83882 **
83883 ** The second argument is only used for STAT3 and STAT4
83884 */
83885 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
83886 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3);
83887 #endif
83888 sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1);
83889 sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2);
83890 sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4);
83891 sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF);
83892 sqlite3VdbeChangeP5(v, 2+IsStat34);
83893
83894 /* Implementation of the following:
83895 **
83896 ** Rewind csr
83897 ** if eof(csr) goto end_of_scan;
@@ -83851,11 +83989,11 @@
83989 int regSampleRowid = regCol + nCol;
83990 int addrNext;
83991 int addrIsNull;
83992 u8 seekOp = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
83993
83994 pParse->nMem = MAX(pParse->nMem, regCol+nCol);
83995
83996 addrNext = sqlite3VdbeCurrentAddr(v);
83997 callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid);
83998 addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid);
83999 VdbeCoverage(v);
@@ -83873,11 +84011,11 @@
84011 #else
84012 for(i=0; i<nCol; i++){
84013 i16 iCol = pIdx->aiColumn[i];
84014 sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i);
84015 }
84016 sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol, regSample);
84017 #endif
84018 sqlite3VdbeAddOp3(v, OP_MakeRecord, regTabname, 6, regTemp);
84019 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid);
84020 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid);
84021 sqlite3VdbeAddOp2(v, OP_Goto, 1, addrNext); /* P1==1 for end-of-loop */
@@ -84185,11 +84323,20 @@
84323 static void initAvgEq(Index *pIdx){
84324 if( pIdx ){
84325 IndexSample *aSample = pIdx->aSample;
84326 IndexSample *pFinal = &aSample[pIdx->nSample-1];
84327 int iCol;
84328 int nCol = 1;
84329 if( pIdx->nSampleCol>1 ){
84330 /* If this is stat4 data, then calculate aAvgEq[] values for all
84331 ** sample columns except the last. The last is always set to 1, as
84332 ** once the trailing PK fields are considered all index keys are
84333 ** unique. */
84334 nCol = pIdx->nSampleCol-1;
84335 pIdx->aAvgEq[nCol] = 1;
84336 }
84337 for(iCol=0; iCol<nCol; iCol++){
84338 int i; /* Used to iterate through samples */
84339 tRowcnt sumEq = 0; /* Sum of the nEq values */
84340 tRowcnt nSum = 0; /* Number of terms contributing to sumEq */
84341 tRowcnt avgEq = 0;
84342 tRowcnt nDLt = pFinal->anDLt[iCol];
@@ -84208,11 +84355,10 @@
84355 if( nDLt>nSum ){
84356 avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum);
84357 }
84358 if( avgEq==0 ) avgEq = 1;
84359 pIdx->aAvgEq[iCol] = avgEq;
 
84360 }
84361 }
84362 }
84363
84364 /*
@@ -84267,11 +84413,10 @@
84413 sqlite3DbFree(db, zSql);
84414 if( rc ) return rc;
84415
84416 while( sqlite3_step(pStmt)==SQLITE_ROW ){
84417 int nIdxCol = 1; /* Number of columns in stat4 records */
 
84418
84419 char *zIndex; /* Index name */
84420 Index *pIdx; /* Pointer to the index object */
84421 int nSample; /* Number of samples */
84422 int nByte; /* Bytes of space required */
@@ -84285,25 +84430,29 @@
84430 assert( pIdx==0 || bStat3 || pIdx->nSample==0 );
84431 /* Index.nSample is non-zero at this point if data has already been
84432 ** loaded from the stat4 table. In this case ignore stat3 data. */
84433 if( pIdx==0 || pIdx->nSample ) continue;
84434 if( bStat3==0 ){
84435 assert( !HasRowid(pIdx->pTable) || pIdx->nColumn==pIdx->nKeyCol+1 );
84436 if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){
84437 nIdxCol = pIdx->nKeyCol;
84438 }else{
84439 nIdxCol = pIdx->nColumn;
84440 }
84441 }
84442 pIdx->nSampleCol = nIdxCol;
84443 nByte = sizeof(IndexSample) * nSample;
84444 nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample;
84445 nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */
84446
84447 pIdx->aSample = sqlite3DbMallocZero(db, nByte);
84448 if( pIdx->aSample==0 ){
84449 sqlite3_finalize(pStmt);
84450 return SQLITE_NOMEM;
84451 }
84452 pSpace = (tRowcnt*)&pIdx->aSample[nSample];
84453 pIdx->aAvgEq = pSpace; pSpace += nIdxCol;
84454 for(i=0; i<nSample; i++){
84455 pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol;
84456 pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol;
84457 pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol;
84458 }
@@ -92553,10 +92702,11 @@
92702 FUNCTION2(coalesce, -1, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
92703 FUNCTION(hex, 1, 0, 0, hexFunc ),
92704 FUNCTION2(ifnull, 2, 0, 0, noopFunc, SQLITE_FUNC_COALESCE),
92705 FUNCTION2(unlikely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
92706 FUNCTION2(likelihood, 2, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
92707 FUNCTION2(likely, 1, 0, 0, noopFunc, SQLITE_FUNC_UNLIKELY),
92708 VFUNCTION(random, 0, 0, 0, randomFunc ),
92709 VFUNCTION(randomblob, 1, 0, 0, randomBlob ),
92710 FUNCTION(nullif, 2, 0, 1, nullifFunc ),
92711 FUNCTION(sqlite_version, 0, 0, 0, versionFunc ),
92712 FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ),
@@ -110581,11 +110731,11 @@
110731 pScan->pOrigWC = pWC;
110732 pScan->pWC = pWC;
110733 if( pIdx && iColumn>=0 ){
110734 pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
110735 for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
110736 if( NEVER(j>pIdx->nColumn) ) return 0;
110737 }
110738 pScan->zCollName = pIdx->azColl[j];
110739 }else{
110740 pScan->idxaff = 0;
110741 pScan->zCollName = 0;
@@ -111531,12 +111681,11 @@
111681
111682 /*
111683 ** Estimate the logarithm of the input value to base 2.
111684 */
111685 static LogEst estLog(LogEst N){
111686 return N<=10 ? 0 : sqlite3LogEst(N) - 33;
 
111687 }
111688
111689 /*
111690 ** Two routines for printing the content of an sqlite3_index_info
111691 ** structure. Used for testing and debugging only. If neither
@@ -111997,11 +112146,11 @@
112146 }else{
112147 i64 nRow0 = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]);
112148 iUpper = i>=pIdx->nSample ? nRow0 : aSample[i].anLt[iCol];
112149 iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol];
112150 }
112151 aStat[1] = pIdx->aAvgEq[iCol];
112152 if( iLower>=iUpper ){
112153 iGap = 0;
112154 }else{
112155 iGap = iUpper - iLower;
112156 }
@@ -112036,10 +112185,118 @@
112185 }
112186 }
112187 return nRet;
112188 }
112189
112190 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
112191 /*
112192 ** This function is called to estimate the number of rows visited by a
112193 ** range-scan on a skip-scan index. For example:
112194 **
112195 ** CREATE INDEX i1 ON t1(a, b, c);
112196 ** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?;
112197 **
112198 ** Value pLoop->nOut is currently set to the estimated number of rows
112199 ** visited for scanning (a=? AND b=?). This function reduces that estimate
112200 ** by some factor to account for the (c BETWEEN ? AND ?) expression based
112201 ** on the stat4 data for the index. this scan will be peformed multiple
112202 ** times (once for each (a,b) combination that matches a=?) is dealt with
112203 ** by the caller.
112204 **
112205 ** It does this by scanning through all stat4 samples, comparing values
112206 ** extracted from pLower and pUpper with the corresponding column in each
112207 ** sample. If L and U are the number of samples found to be less than or
112208 ** equal to the values extracted from pLower and pUpper respectively, and
112209 ** N is the total number of samples, the pLoop->nOut value is adjusted
112210 ** as follows:
112211 **
112212 ** nOut = nOut * ( min(U - L, 1) / N )
112213 **
112214 ** If pLower is NULL, or a value cannot be extracted from the term, L is
112215 ** set to zero. If pUpper is NULL, or a value cannot be extracted from it,
112216 ** U is set to N.
112217 **
112218 ** Normally, this function sets *pbDone to 1 before returning. However,
112219 ** if no value can be extracted from either pLower or pUpper (and so the
112220 ** estimate of the number of rows delivered remains unchanged), *pbDone
112221 ** is left as is.
112222 **
112223 ** If an error occurs, an SQLite error code is returned. Otherwise,
112224 ** SQLITE_OK.
112225 */
112226 static int whereRangeSkipScanEst(
112227 Parse *pParse, /* Parsing & code generating context */
112228 WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
112229 WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */
112230 WhereLoop *pLoop, /* Update the .nOut value of this loop */
112231 int *pbDone /* Set to true if at least one expr. value extracted */
112232 ){
112233 Index *p = pLoop->u.btree.pIndex;
112234 int nEq = pLoop->u.btree.nEq;
112235 sqlite3 *db = pParse->db;
112236 int nLower = -1;
112237 int nUpper = p->nSample+1;
112238 int rc = SQLITE_OK;
112239 u8 aff = p->pTable->aCol[ p->aiColumn[nEq] ].affinity;
112240 CollSeq *pColl;
112241
112242 sqlite3_value *p1 = 0; /* Value extracted from pLower */
112243 sqlite3_value *p2 = 0; /* Value extracted from pUpper */
112244 sqlite3_value *pVal = 0; /* Value extracted from record */
112245
112246 pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]);
112247 if( pLower ){
112248 rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1);
112249 nLower = 0;
112250 }
112251 if( pUpper && rc==SQLITE_OK ){
112252 rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2);
112253 nUpper = p2 ? 0 : p->nSample;
112254 }
112255
112256 if( p1 || p2 ){
112257 int i;
112258 int nDiff;
112259 for(i=0; rc==SQLITE_OK && i<p->nSample; i++){
112260 rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal);
112261 if( rc==SQLITE_OK && p1 ){
112262 int res = sqlite3MemCompare(p1, pVal, pColl);
112263 if( res>=0 ) nLower++;
112264 }
112265 if( rc==SQLITE_OK && p2 ){
112266 int res = sqlite3MemCompare(p2, pVal, pColl);
112267 if( res>=0 ) nUpper++;
112268 }
112269 }
112270 nDiff = (nUpper - nLower);
112271 if( nDiff<=0 ) nDiff = 1;
112272
112273 /* If there is both an upper and lower bound specified, and the
112274 ** comparisons indicate that they are close together, use the fallback
112275 ** method (assume that the scan visits 1/64 of the rows) for estimating
112276 ** the number of rows visited. Otherwise, estimate the number of rows
112277 ** using the method described in the header comment for this function. */
112278 if( nDiff!=1 || pUpper==0 || pLower==0 ){
112279 int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff));
112280 pLoop->nOut -= nAdjust;
112281 *pbDone = 1;
112282 WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n",
112283 nLower, nUpper, nAdjust*-1, pLoop->nOut));
112284 }
112285
112286 }else{
112287 assert( *pbDone==0 );
112288 }
112289
112290 sqlite3ValueFree(p1);
112291 sqlite3ValueFree(p2);
112292 sqlite3ValueFree(pVal);
112293
112294 return rc;
112295 }
112296 #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
112297
112298 /*
112299 ** This function is used to estimate the number of rows that will be visited
112300 ** by scanning an index for a range of values. The range may have an upper
112301 ** bound, a lower bound, or both. The WHERE clause terms that set the upper
112302 ** and lower bounds are represented by pLower and pUpper respectively. For
@@ -112072,13 +112329,13 @@
112329 ** considering the range constraints. If nEq is 0, this is the number of
112330 ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced)
112331 ** to account for the range contraints pLower and pUpper.
112332 **
112333 ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be
112334 ** used, a single range inequality reduces the search space by a factor of 4.
112335 ** and a pair of constraints (x>? AND x<?) reduces the expected number of
112336 ** rows visited by a factor of 64.
112337 */
112338 static int whereRangeScanEst(
112339 Parse *pParse, /* Parsing & code generating context */
112340 WhereLoopBuilder *pBuilder,
112341 WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */
@@ -112092,99 +112349,104 @@
112349 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
112350 Index *p = pLoop->u.btree.pIndex;
112351 int nEq = pLoop->u.btree.nEq;
112352
112353 if( p->nSample>0
 
112354 && nEq<p->nSampleCol
112355 && OptimizationEnabled(pParse->db, SQLITE_Stat3)
112356 ){
112357 if( nEq==pBuilder->nRecValid ){
112358 UnpackedRecord *pRec = pBuilder->pRec;
112359 tRowcnt a[2];
112360 u8 aff;
112361
112362 /* Variable iLower will be set to the estimate of the number of rows in
112363 ** the index that are less than the lower bound of the range query. The
112364 ** lower bound being the concatenation of $P and $L, where $P is the
112365 ** key-prefix formed by the nEq values matched against the nEq left-most
112366 ** columns of the index, and $L is the value in pLower.
112367 **
112368 ** Or, if pLower is NULL or $L cannot be extracted from it (because it
112369 ** is not a simple variable or literal value), the lower bound of the
112370 ** range is $P. Due to a quirk in the way whereKeyStats() works, even
112371 ** if $L is available, whereKeyStats() is called for both ($P) and
112372 ** ($P:$L) and the larger of the two returned values used.
112373 **
112374 ** Similarly, iUpper is to be set to the estimate of the number of rows
112375 ** less than the upper bound of the range query. Where the upper bound
112376 ** is either ($P) or ($P:$U). Again, even if $U is available, both values
112377 ** of iUpper are requested of whereKeyStats() and the smaller used.
112378 */
112379 tRowcnt iLower;
112380 tRowcnt iUpper;
112381
112382 if( nEq==p->nKeyCol ){
112383 aff = SQLITE_AFF_INTEGER;
112384 }else{
112385 aff = p->pTable->aCol[p->aiColumn[nEq]].affinity;
112386 }
112387 /* Determine iLower and iUpper using ($P) only. */
112388 if( nEq==0 ){
112389 iLower = 0;
112390 iUpper = sqlite3LogEstToInt(p->aiRowLogEst[0]);
112391 }else{
112392 /* Note: this call could be optimized away - since the same values must
112393 ** have been requested when testing key $P in whereEqualScanEst(). */
112394 whereKeyStats(pParse, p, pRec, 0, a);
112395 iLower = a[0];
112396 iUpper = a[0] + a[1];
112397 }
112398
112399 /* If possible, improve on the iLower estimate using ($P:$L). */
112400 if( pLower ){
112401 int bOk; /* True if value is extracted from pExpr */
112402 Expr *pExpr = pLower->pExpr->pRight;
112403 assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 );
112404 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112405 if( rc==SQLITE_OK && bOk ){
112406 tRowcnt iNew;
112407 whereKeyStats(pParse, p, pRec, 0, a);
112408 iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0);
112409 if( iNew>iLower ) iLower = iNew;
112410 nOut--;
112411 }
112412 }
112413
112414 /* If possible, improve on the iUpper estimate using ($P:$U). */
112415 if( pUpper ){
112416 int bOk; /* True if value is extracted from pExpr */
112417 Expr *pExpr = pUpper->pExpr->pRight;
112418 assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 );
112419 rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk);
112420 if( rc==SQLITE_OK && bOk ){
112421 tRowcnt iNew;
112422 whereKeyStats(pParse, p, pRec, 1, a);
112423 iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0);
112424 if( iNew<iUpper ) iUpper = iNew;
112425 nOut--;
112426 }
112427 }
112428
112429 pBuilder->pRec = pRec;
112430 if( rc==SQLITE_OK ){
112431 if( iUpper>iLower ){
112432 nNew = sqlite3LogEst(iUpper - iLower);
112433 }else{
112434 nNew = 10; assert( 10==sqlite3LogEst(2) );
112435 }
112436 if( nNew<nOut ){
112437 nOut = nNew;
112438 }
112439 pLoop->nOut = (LogEst)nOut;
112440 WHERETRACE(0x10, ("range scan regions: %u..%u est=%d\n",
112441 (u32)iLower, (u32)iUpper, nOut));
112442 return SQLITE_OK;
112443 }
112444 }else{
112445 int bDone = 0;
112446 rc = whereRangeSkipScanEst(pParse, pLower, pUpper, pLoop, &bDone);
112447 if( bDone ) return rc;
112448 }
112449 }
112450 #else
112451 UNUSED_PARAMETER(pParse);
112452 UNUSED_PARAMETER(pBuilder);
@@ -112239,11 +112501,11 @@
112501 int rc; /* Subfunction return code */
112502 tRowcnt a[2]; /* Statistics */
112503 int bOk;
112504
112505 assert( nEq>=1 );
112506 assert( nEq<=p->nColumn );
112507 assert( p->aSample!=0 );
112508 assert( p->nSample>0 );
112509 assert( pBuilder->nRecValid<nEq );
112510
112511 /* If values are not available for all fields of the index to the left
@@ -112252,11 +112514,11 @@
112514 return SQLITE_NOTFOUND;
112515 }
112516
112517 /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue()
112518 ** below would return the same value. */
112519 if( nEq>=p->nColumn ){
112520 *pnRow = 1;
112521 return SQLITE_OK;
112522 }
112523
112524 aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity;
@@ -112683,11 +112945,11 @@
112945 }
112946 sqlite3StrAccumInit(&txt, 0, 0, SQLITE_MAX_LENGTH);
112947 txt.db = db;
112948 sqlite3StrAccumAppend(&txt, " (", 2);
112949 for(i=0; i<nEq; i++){
112950 char *z = aiColumn[i] < 0 ? "rowid" : aCol[aiColumn[i]].zName;
112951 if( i>=nSkip ){
112952 explainAppendTerm(&txt, i, z, "=");
112953 }else{
112954 if( i ) sqlite3StrAccumAppend(&txt, " AND ", 5);
112955 sqlite3StrAccumAppend(&txt, "ANY(", 4);
@@ -112696,15 +112958,15 @@
112958 }
112959 }
112960
112961 j = i;
112962 if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
112963 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
112964 explainAppendTerm(&txt, i++, z, ">");
112965 }
112966 if( pLoop->wsFlags&WHERE_TOP_LIMIT ){
112967 char *z = aiColumn[j] < 0 ? "rowid" : aCol[aiColumn[j]].zName;
112968 explainAppendTerm(&txt, i, z, "<");
112969 }
112970 sqlite3StrAccumAppend(&txt, ")", 1);
112971 return sqlite3StrAccumFinish(&txt);
112972 }
@@ -113724,11 +113986,11 @@
113986 z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask);
113987 }
113988 sqlite3DebugPrintf(" %-19s", z);
113989 sqlite3_free(z);
113990 }
113991 sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm);
113992 sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut);
113993 #ifdef SQLITE_ENABLE_TREE_EXPLAIN
113994 /* If the 0x100 bit of wheretracing is set, then show all of the constraint
113995 ** expressions in the WhereLoop.aLTerm[] array.
113996 */
@@ -113960,10 +114222,21 @@
114222
114223 /* whereLoopAddBtree() always generates and inserts the automatic index
114224 ** case first. Hence compatible candidate WhereLoops never have a larger
114225 ** rSetup. Call this SETUP-INVARIANT */
114226 assert( p->rSetup>=pTemplate->rSetup );
114227
114228 /* Any loop using an appliation-defined index (or PRIMARY KEY or
114229 ** UNIQUE constraint) with one or more == constraints is better
114230 ** than an automatic index. */
114231 if( (p->wsFlags & WHERE_AUTO_INDEX)!=0
114232 && (pTemplate->wsFlags & WHERE_INDEXED)!=0
114233 && (pTemplate->wsFlags & WHERE_COLUMN_EQ)!=0
114234 && (p->prereq & pTemplate->prereq)==pTemplate->prereq
114235 ){
114236 break;
114237 }
114238
114239 /* If existing WhereLoop p is better than pTemplate, pTemplate can be
114240 ** discarded. WhereLoop p is better if:
114241 ** (1) p has no more dependencies than pTemplate, and
114242 ** (2) p has an equal or lower cost than pTemplate
@@ -114085,17 +114358,17 @@
114358 ** p[] that are also supplated by pTemplate */
114359 WhereLoop **ppTail = &p->pNextLoop;
114360 WhereLoop *pToDel;
114361 while( *ppTail ){
114362 ppTail = whereLoopFindLesser(ppTail, pTemplate);
114363 if( ppTail==0 ) break;
114364 pToDel = *ppTail;
114365 if( pToDel==0 ) break;
114366 *ppTail = pToDel->pNextLoop;
114367 #if WHERETRACE_ENABLED /* 0x8 */
114368 if( sqlite3WhereTrace & 0x8 ){
114369 sqlite3DebugPrintf("ins-del: ");
114370 whereLoopPrint(pToDel, pBuilder->pWC);
114371 }
114372 #endif
114373 whereLoopDelete(db, pToDel);
114374 }
@@ -114191,16 +114464,13 @@
114464 }else{
114465 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
114466 }
114467 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
114468
114469 assert( pNew->u.btree.nEq<pProbe->nColumn );
114470 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
114471
 
 
 
114472 pTerm = whereScanInit(&scan, pBuilder->pWC, pSrc->iCursor, iCol,
114473 opMask, pProbe);
114474 saved_nEq = pNew->u.btree.nEq;
114475 saved_nSkip = pNew->u.btree.nSkip;
114476 saved_nLTerm = pNew->nLTerm;
@@ -114386,11 +114656,11 @@
114656 }else{
114657 pNew->nOut = nOutUnadjusted;
114658 }
114659
114660 if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0
114661 && pNew->u.btree.nEq<pProbe->nColumn
114662 ){
114663 whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn);
114664 }
114665 pNew->nOut = saved_nOut;
114666 #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
@@ -114533,10 +114803,11 @@
114803 ** fake index the first in a chain of Index objects with all of the real
114804 ** indices to follow */
114805 Index *pFirst; /* First of real indices on the table */
114806 memset(&sPk, 0, sizeof(Index));
114807 sPk.nKeyCol = 1;
114808 sPk.nColumn = 1;
114809 sPk.aiColumn = &aiColumnPk;
114810 sPk.aiRowLogEst = aiRowEstPk;
114811 sPk.onError = OE_Replace;
114812 sPk.pTable = pTab;
114813 sPk.szIdxRow = pTab->szTabRow;
@@ -115316,11 +115587,10 @@
115587 int mxI = 0; /* Index of next entry to replace */
115588 int nOrderBy; /* Number of ORDER BY clause terms */
115589 LogEst rCost; /* Cost of a path */
115590 LogEst nOut; /* Number of outputs */
115591 LogEst mxCost = 0; /* Maximum cost of a set of paths */
 
115592 int nTo, nFrom; /* Number of valid entries in aTo[] and aFrom[] */
115593 WherePath *aFrom; /* All nFrom paths at the previous level */
115594 WherePath *aTo; /* The nTo best paths at the current level */
115595 WherePath *pFrom; /* An element of aFrom[] that we are working on */
115596 WherePath *pTo; /* An element of aTo[] that we are working on */
@@ -115426,12 +115696,10 @@
115696 }
115697 /* Check to see if pWLoop should be added to the mxChoice best so far */
115698 for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
115699 if( pTo->maskLoop==maskNew
115700 && ((pTo->isOrdered^isOrdered)&80)==0
 
 
115701 ){
115702 testcase( jj==nTo-1 );
115703 break;
115704 }
115705 }
@@ -115461,11 +115729,11 @@
115729 wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
115730 isOrdered>=0 ? isOrdered+'0' : '?');
115731 }
115732 #endif
115733 }else{
115734 if( pTo->rCost<=rCost ){
115735 #ifdef WHERETRACE_ENABLED /* 0x4 */
115736 if( sqlite3WhereTrace&0x4 ){
115737 sqlite3DebugPrintf(
115738 "Skip %s cost=%-3d,%3d order=%c",
115739 wherePathName(pFrom, iLoop, pWLoop), rCost, nOut,
@@ -115501,15 +115769,13 @@
115769 memcpy(pTo->aLoop, pFrom->aLoop, sizeof(WhereLoop*)*iLoop);
115770 pTo->aLoop[iLoop] = pWLoop;
115771 if( nTo>=mxChoice ){
115772 mxI = 0;
115773 mxCost = aTo[0].rCost;
 
115774 for(jj=1, pTo=&aTo[1]; jj<mxChoice; jj++, pTo++){
115775 if( pTo->rCost>mxCost ){
115776 mxCost = pTo->rCost;
 
115777 mxI = jj;
115778 }
115779 }
115780 }
115781 }
@@ -124205,14 +124471,14 @@
124471 ** sqlite3_test_control().
124472 */
124473 case SQLITE_TESTCTRL_FAULT_INSTALL: {
124474 /* MSVC is picky about pulling func ptrs from va lists.
124475 ** http://support.microsoft.com/kb/47961
124476 ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int));
124477 */
124478 typedef int(*TESTCALLBACKFUNC_t)(int);
124479 sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t);
124480 rc = sqlite3FaultSim(0);
124481 break;
124482 }
124483
124484 /*
@@ -140777,38 +141043,40 @@
141043 i64 iDocid = sqlite3_column_int64(pStmt, 0);
141044 int iLang = langidFromSelect(p, pStmt);
141045 int iCol;
141046
141047 for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
141048 if( p->abNotindexed[iCol]==0 ){
141049 const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1);
141050 int nText = sqlite3_column_bytes(pStmt, iCol+1);
141051 sqlite3_tokenizer_cursor *pT = 0;
141052
141053 rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, nText,&pT);
141054 while( rc==SQLITE_OK ){
141055 char const *zToken; /* Buffer containing token */
141056 int nToken = 0; /* Number of bytes in token */
141057 int iDum1 = 0, iDum2 = 0; /* Dummy variables */
141058 int iPos = 0; /* Position of token in zText */
141059
141060 rc = pModule->xNext(pT, &zToken, &nToken, &iDum1, &iDum2, &iPos);
141061 if( rc==SQLITE_OK ){
141062 int i;
141063 cksum2 = cksum2 ^ fts3ChecksumEntry(
141064 zToken, nToken, iLang, 0, iDocid, iCol, iPos
141065 );
141066 for(i=1; i<p->nIndex; i++){
141067 if( p->aIndex[i].nPrefix<=nToken ){
141068 cksum2 = cksum2 ^ fts3ChecksumEntry(
141069 zToken, p->aIndex[i].nPrefix, iLang, i, iDocid, iCol, iPos
141070 );
141071 }
141072 }
141073 }
141074 }
141075 if( pT ) pModule->xClose(pT);
141076 if( rc==SQLITE_DONE ) rc = SQLITE_OK;
141077 }
141078 }
141079 }
141080
141081 sqlite3_finalize(pStmt);
141082 }
141083
+3 -3
--- 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.8.5"
111
-#define SQLITE_VERSION_NUMBER 3008005
112
-#define SQLITE_SOURCE_ID "2014-06-04 14:06:34 b1ed4f2a34ba66c29b130f8d13e9092758019212"
110
+#define SQLITE_VERSION "3.8.6"
111
+#define SQLITE_VERSION_NUMBER 3008006
112
+#define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
118118
--- 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.8.5"
111 #define SQLITE_VERSION_NUMBER 3008005
112 #define SQLITE_SOURCE_ID "2014-06-04 14:06:34 b1ed4f2a34ba66c29b130f8d13e9092758019212"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
--- 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.8.6"
111 #define SQLITE_VERSION_NUMBER 3008006
112 #define SQLITE_SOURCE_ID "2014-07-01 11:54:02 21981e35062cc6b30e9576786cbf55265a7a4d41"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
118
+13 -2
--- src/stat.c
+++ src/stat.c
@@ -49,10 +49,11 @@
4949
int n, m;
5050
int szMax, szAvg;
5151
const char *zDb;
5252
int brief;
5353
char zBuf[100];
54
+ const char *p;
5455
5556
login_check_credentials();
5657
if( !g.perm.Read ){ login_needed(); return; }
5758
brief = P("brief")!=0;
5859
style_header("Repository Statistics");
@@ -120,11 +121,15 @@
120121
@ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
121122
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
122123
" + 0.99");
123124
@ %d(n) days or approximately %.2f(n/365.2425) years.
124125
@ </td></tr>
125
- @ <tr><th>Project&nbsp;ID:</th><td>%h(db_get("project-code",""))</td></tr>
126
+ p = db_get("project-code", 0);
127
+ if( p ){
128
+ @ <tr><th>Project&nbsp;ID:</th><td>%h(p)</td></tr>
129
+ }
130
+ @ <tr><th>Server&nbsp;ID:</th><td>%h(db_get("server-code",""))</td></tr>
126131
@ <tr><th>Fossil&nbsp;Version:</th><td>
127132
@ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
128133
@ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)]
129134
@ </td></tr>
130135
@ <tr><th>SQLite&nbsp;Version:</th><td>%.19s(sqlite3_sourceid())
@@ -163,10 +168,12 @@
163168
int szMax, szAvg;
164169
const char *zDb;
165170
int brief;
166171
char zBuf[100];
167172
const int colWidth = -19 /* printf alignment/width for left column */;
173
+ const char *p;
174
+
168175
brief = find_option("brief", "b",0)!=0;
169176
db_find_and_open_repository(0,0);
170177
fsize = file_size(g.zRepositoryName);
171178
bigSizeName(sizeof(zBuf), zBuf, fsize);
172179
fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
@@ -219,11 +226,15 @@
219226
}
220227
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
221228
" + 0.99");
222229
fossil_print("%*s%d days or approximately %.2f years.\n",
223230
colWidth, "project-age:", n, n/365.2425);
224
- fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
231
+ p = db_get("project-code", 0);
232
+ if( p ){
233
+ fossil_print("%*s%s\n", colWidth, "project-id:", p);
234
+ }
235
+ fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
225236
fossil_print("%*s%s %s [%s] (%s)\n",
226237
colWidth, "fossil-version:",
227238
MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
228239
COMPILER_NAME);
229240
fossil_print("%*s%.19s [%.10s] (%s)\n",
230241
--- src/stat.c
+++ src/stat.c
@@ -49,10 +49,11 @@
49 int n, m;
50 int szMax, szAvg;
51 const char *zDb;
52 int brief;
53 char zBuf[100];
 
54
55 login_check_credentials();
56 if( !g.perm.Read ){ login_needed(); return; }
57 brief = P("brief")!=0;
58 style_header("Repository Statistics");
@@ -120,11 +121,15 @@
120 @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
121 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
122 " + 0.99");
123 @ %d(n) days or approximately %.2f(n/365.2425) years.
124 @ </td></tr>
125 @ <tr><th>Project&nbsp;ID:</th><td>%h(db_get("project-code",""))</td></tr>
 
 
 
 
126 @ <tr><th>Fossil&nbsp;Version:</th><td>
127 @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
128 @ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)]
129 @ </td></tr>
130 @ <tr><th>SQLite&nbsp;Version:</th><td>%.19s(sqlite3_sourceid())
@@ -163,10 +168,12 @@
163 int szMax, szAvg;
164 const char *zDb;
165 int brief;
166 char zBuf[100];
167 const int colWidth = -19 /* printf alignment/width for left column */;
 
 
168 brief = find_option("brief", "b",0)!=0;
169 db_find_and_open_repository(0,0);
170 fsize = file_size(g.zRepositoryName);
171 bigSizeName(sizeof(zBuf), zBuf, fsize);
172 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
@@ -219,11 +226,15 @@
219 }
220 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
221 " + 0.99");
222 fossil_print("%*s%d days or approximately %.2f years.\n",
223 colWidth, "project-age:", n, n/365.2425);
224 fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
 
 
 
 
225 fossil_print("%*s%s %s [%s] (%s)\n",
226 colWidth, "fossil-version:",
227 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
228 COMPILER_NAME);
229 fossil_print("%*s%.19s [%.10s] (%s)\n",
230
--- src/stat.c
+++ src/stat.c
@@ -49,10 +49,11 @@
49 int n, m;
50 int szMax, szAvg;
51 const char *zDb;
52 int brief;
53 char zBuf[100];
54 const char *p;
55
56 login_check_credentials();
57 if( !g.perm.Read ){ login_needed(); return; }
58 brief = P("brief")!=0;
59 style_header("Repository Statistics");
@@ -120,11 +121,15 @@
121 @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
122 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
123 " + 0.99");
124 @ %d(n) days or approximately %.2f(n/365.2425) years.
125 @ </td></tr>
126 p = db_get("project-code", 0);
127 if( p ){
128 @ <tr><th>Project&nbsp;ID:</th><td>%h(p)</td></tr>
129 }
130 @ <tr><th>Server&nbsp;ID:</th><td>%h(db_get("server-code",""))</td></tr>
131 @ <tr><th>Fossil&nbsp;Version:</th><td>
132 @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
133 @ (%h(RELEASE_VERSION)) [compiled using %h(COMPILER_NAME)]
134 @ </td></tr>
135 @ <tr><th>SQLite&nbsp;Version:</th><td>%.19s(sqlite3_sourceid())
@@ -163,10 +168,12 @@
168 int szMax, szAvg;
169 const char *zDb;
170 int brief;
171 char zBuf[100];
172 const int colWidth = -19 /* printf alignment/width for left column */;
173 const char *p;
174
175 brief = find_option("brief", "b",0)!=0;
176 db_find_and_open_repository(0,0);
177 fsize = file_size(g.zRepositoryName);
178 bigSizeName(sizeof(zBuf), zBuf, fsize);
179 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
@@ -219,11 +226,15 @@
226 }
227 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
228 " + 0.99");
229 fossil_print("%*s%d days or approximately %.2f years.\n",
230 colWidth, "project-age:", n, n/365.2425);
231 p = db_get("project-code", 0);
232 if( p ){
233 fossil_print("%*s%s\n", colWidth, "project-id:", p);
234 }
235 fossil_print("%*s%s\n", colWidth, "server-id:", db_get("server-code", 0));
236 fossil_print("%*s%s %s [%s] (%s)\n",
237 colWidth, "fossil-version:",
238 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
239 COMPILER_NAME);
240 fossil_print("%*s%.19s [%.10s] (%s)\n",
241
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -1,9 +1,9 @@
11
<title>Graph Test One</title>
22
33
This page contains examples a list of URLs of timelines with
4
-interesting graphs. Click on all URLs, one by one, to verify
4
+interesting graphs. Click on all URLs, one by one, to verify
55
the correct operation of the graph drawing logic.
66
77
* <a href="../../../timeline?n=20&y=ci&b=2010-11-08" target="testwindow">
88
20-element timeline, check-ins only, before 2010-11-08</a>
99
* <a href="../../../timeline?n=20&y=ci&b=2010-11-08&ng" target="testwindow">
@@ -12,13 +12,13 @@
1212
20-element timeline, check-ins only, file changes, before 2010-11-08</a>
1313
* <a href="../../../timeline?n=40&y=ci&b=2010-11-08" target="testwindow">
1414
40-element timeline, check-ins only, before 2010-11-08</a>
1515
* <a href="../../../timeline?n=1000&y=ci&b=2010-11-08" target="testwindow">
1616
1000-element timeline, check-ins only, before 2010-11-08</a>
17
- * <a href="../../../timeline?n=10&c=2010-11-07+10:23:00" target="testwindow">
17
+ * <a href="../../../timeline?n=10&c=2010-11-07T10:23:00" target="testwindow">
1818
10-elements circa 2010-11-07 10:23:00, with dividers</a>
19
- * <a href="../../../timeline?n=10&c=2010-11-07+10:23:00&nd"
19
+ * <a href="../../../timeline?n=10&c=2010-11-07T10:23:00&nd"
2020
target="testwindow">
2121
10-elements circa 2010-11-07 10:23:00, without dividers</a>
2222
* <a href="../../../timeline?f=3ea66260b5555" target="testwindow">
2323
Parents and children of check-in 3ea66260b5555</a>
2424
* <a href="../../../timeline?d=e5fe4164f74a7576&p=e5fe4164f74a7576&n=3"
@@ -49,11 +49,11 @@
4949
* <a href="../../../timeline?a=1970-01-01" target="testwindow">
5050
20 elements after 1970-01-01.</a>
5151
* <a href="../../../timeline?n=100000000&y=ci" target="testwindow">
5252
All check-ins - a huge graph.</a>
5353
* <a href="../../../timeline?f=8dfed953f7530442" target="testwindow">
54
- This malformed commit has a
54
+ This malformed commit has a
5555
merge parent which is not a valid checkin.</a>
5656
* <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9"
5757
target="testwindow">
5858
From e663bac6f7 to a298a0e2f9 by shortest path.</a>
5959
* <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&nomerge"
6060
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -1,9 +1,9 @@
1 <title>Graph Test One</title>
2
3 This page contains examples a list of URLs of timelines with
4 interesting graphs. Click on all URLs, one by one, to verify
5 the correct operation of the graph drawing logic.
6
7 * <a href="../../../timeline?n=20&y=ci&b=2010-11-08" target="testwindow">
8 20-element timeline, check-ins only, before 2010-11-08</a>
9 * <a href="../../../timeline?n=20&y=ci&b=2010-11-08&ng" target="testwindow">
@@ -12,13 +12,13 @@
12 20-element timeline, check-ins only, file changes, before 2010-11-08</a>
13 * <a href="../../../timeline?n=40&y=ci&b=2010-11-08" target="testwindow">
14 40-element timeline, check-ins only, before 2010-11-08</a>
15 * <a href="../../../timeline?n=1000&y=ci&b=2010-11-08" target="testwindow">
16 1000-element timeline, check-ins only, before 2010-11-08</a>
17 * <a href="../../../timeline?n=10&c=2010-11-07+10:23:00" target="testwindow">
18 10-elements circa 2010-11-07 10:23:00, with dividers</a>
19 * <a href="../../../timeline?n=10&c=2010-11-07+10:23:00&nd"
20 target="testwindow">
21 10-elements circa 2010-11-07 10:23:00, without dividers</a>
22 * <a href="../../../timeline?f=3ea66260b5555" target="testwindow">
23 Parents and children of check-in 3ea66260b5555</a>
24 * <a href="../../../timeline?d=e5fe4164f74a7576&p=e5fe4164f74a7576&n=3"
@@ -49,11 +49,11 @@
49 * <a href="../../../timeline?a=1970-01-01" target="testwindow">
50 20 elements after 1970-01-01.</a>
51 * <a href="../../../timeline?n=100000000&y=ci" target="testwindow">
52 All check-ins - a huge graph.</a>
53 * <a href="../../../timeline?f=8dfed953f7530442" target="testwindow">
54 This malformed commit has a
55 merge parent which is not a valid checkin.</a>
56 * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9"
57 target="testwindow">
58 From e663bac6f7 to a298a0e2f9 by shortest path.</a>
59 * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&nomerge"
60
--- test/graph-test-1.wiki
+++ test/graph-test-1.wiki
@@ -1,9 +1,9 @@
1 <title>Graph Test One</title>
2
3 This page contains examples a list of URLs of timelines with
4 interesting graphs. Click on all URLs, one by one, to verify
5 the correct operation of the graph drawing logic.
6
7 * <a href="../../../timeline?n=20&y=ci&b=2010-11-08" target="testwindow">
8 20-element timeline, check-ins only, before 2010-11-08</a>
9 * <a href="../../../timeline?n=20&y=ci&b=2010-11-08&ng" target="testwindow">
@@ -12,13 +12,13 @@
12 20-element timeline, check-ins only, file changes, before 2010-11-08</a>
13 * <a href="../../../timeline?n=40&y=ci&b=2010-11-08" target="testwindow">
14 40-element timeline, check-ins only, before 2010-11-08</a>
15 * <a href="../../../timeline?n=1000&y=ci&b=2010-11-08" target="testwindow">
16 1000-element timeline, check-ins only, before 2010-11-08</a>
17 * <a href="../../../timeline?n=10&c=2010-11-07T10:23:00" target="testwindow">
18 10-elements circa 2010-11-07 10:23:00, with dividers</a>
19 * <a href="../../../timeline?n=10&c=2010-11-07T10:23:00&nd"
20 target="testwindow">
21 10-elements circa 2010-11-07 10:23:00, without dividers</a>
22 * <a href="../../../timeline?f=3ea66260b5555" target="testwindow">
23 Parents and children of check-in 3ea66260b5555</a>
24 * <a href="../../../timeline?d=e5fe4164f74a7576&p=e5fe4164f74a7576&n=3"
@@ -49,11 +49,11 @@
49 * <a href="../../../timeline?a=1970-01-01" target="testwindow">
50 20 elements after 1970-01-01.</a>
51 * <a href="../../../timeline?n=100000000&y=ci" target="testwindow">
52 All check-ins - a huge graph.</a>
53 * <a href="../../../timeline?f=8dfed953f7530442" target="testwindow">
54 This malformed commit has a
55 merge parent which is not a valid checkin.</a>
56 * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9"
57 target="testwindow">
58 From e663bac6f7 to a298a0e2f9 by shortest path.</a>
59 * <a href="../../../timeline?from=e663bac6f7&to=a298a0e2f9&nomerge"
60
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,13 +1,14 @@
11
<title>Change Log</title>
22
33
<h2>Changes For Version 1.30 (as yet unreleased)</h2>
44
* Add setting to control the number of times autosync will be tried before
55
returning an error.
6
- * Add the "fossil fusefs DIRECTORY" command that mounts a Fuse Filesystem
7
- at the given DIRECTORY and populates it with read-only copies of all
8
- historical check-ins. This only works on systems that support FuseFS.
6
+ * Add the [/help/fusefs|fossil fusefs DIRECTORY] command that mounts a
7
+ Fuse Filesystem at the given DIRECTORY and populates it with read-only
8
+ copies of all historical check-ins. This only works on systems that
9
+ support FuseFS.
910
* Support customization of commands and webpages, including the ability to
1011
add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled
1112
via a compile-time option.
1213
* Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter],
1314
[trace], [getParameter], [setParameter], and [artifact]</nowiki> commands
1415
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,13 +1,14 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.30 (as yet unreleased)</h2>
4 * Add setting to control the number of times autosync will be tried before
5 returning an error.
6 * Add the "fossil fusefs DIRECTORY" command that mounts a Fuse Filesystem
7 at the given DIRECTORY and populates it with read-only copies of all
8 historical check-ins. This only works on systems that support FuseFS.
 
9 * Support customization of commands and webpages, including the ability to
10 add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled
11 via a compile-time option.
12 * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter],
13 [trace], [getParameter], [setParameter], and [artifact]</nowiki> commands
14
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,13 +1,14 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.30 (as yet unreleased)</h2>
4 * Add setting to control the number of times autosync will be tried before
5 returning an error.
6 * Add the [/help/fusefs|fossil fusefs DIRECTORY] command that mounts a
7 Fuse Filesystem at the given DIRECTORY and populates it with read-only
8 copies of all historical check-ins. This only works on systems that
9 support FuseFS.
10 * Support customization of commands and webpages, including the ability to
11 add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled
12 via a compile-time option.
13 * Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter],
14 [trace], [getParameter], [setParameter], and [artifact]</nowiki> commands
15
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -3,15 +3,15 @@
33
<h2>1.0 Don't Stress!</h2>
44
55
If you start out using one DVCS and later decide you like the other better,
66
it is [./inout.wiki | easy to change].
77
8
-But it also helps to be informed about the differences between
8
+But it also helps to be informed about the differences between
99
[http://git-scm.com | Git] and Fossil. See the table below for
1010
a high-level summary and the text that follows for more details.
1111
12
-Keep in mind that you are reading this on a Fossil website,
12
+Keep in mind that you are reading this on a Fossil website,
1313
so the information here
1414
might be biased in favor of Fossil. Ask around with people who have
1515
used both Fossil and Git for other opinions.
1616
1717
<h2>2.0 Executive Summary:</h2>
@@ -47,21 +47,21 @@
4747
<h3>3.2 Sharding versus Replicating</h3>
4848
4949
Git makes it easy for each repository in a project to hold a subset of
5050
the branches for that project. In fact, it is entirely possible and not
5151
uncommon for no repository in the project to hold all the different code
52
-versions for a project. Instead the information is distributed.
52
+versions for a project. Instead the information is distributed.
5353
Individual developers have one or more private branches. A hierarchy
5454
of integrators merge changes from individual developers into collaborative
5555
branches, until all the changes are merged together at the top-level master
5656
branch. And all of this can be accomplished without having to have all the
5757
code in any one repository. Developers or groups of developers can share
5858
only those branches that they want to share and keep other branchs of the
5959
project private. This is analogous to sharding an a distributed database.
6060
6161
Fossil allows private branches, but its default mode is to share everything.
62
-And so in a Fossil project, all respositories tend to contain all of the
62
+And so in a Fossil project, all repositories tend to contain all of the
6363
content at all times. This is analogous to replication in a
6464
distributed database.
6565
6666
The Git model works best for large projects, like the
6767
Linux kernel for which Git was designed.
@@ -73,35 +73,35 @@
7373
works in his or her own branch and then merges changes up the hierarchy
7474
until they reach the master branch.
7575
7676
Fossil is designed for smaller and non-hierarchical teams where all
7777
developers are operating directly on the master branch, or at most
78
-a small number of well defined branches.
78
+a small number of well defined branches.
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
8484
<h3>3.3 Branches</h3>
8585
86
-Git (and especially GitHub) encourages a workflow where each developer
86
+Git (and especially GitHub) encourages a workflow where each developer
8787
has his or her own branch or branches. Developers then send "pull requests"
8888
to have their changes be merged into "official" branches by integrators.
8989
For example, the Linux kernel team has a hierarchy of integrators with
9090
Linus Torvalds at the root. Individual developers each have their own
9191
private branches of the source tree into which they make their own changes.
9292
They then encourage first-tier integrators to pull those changes. The
9393
first-tier integrators merge together changes from multiple contributors
9494
then try to get second-tier integrators to pull their branches. The
95
-changes merge up the hierarchy until (hopefully) they are pulled into
95
+changes merge up the hierarchy until (hopefully) they are pulled into
9696
"Linus's branch", at which time they become part of the "official" Linux.
9797
9898
In Git, each branch is "owned" by the person who creates it and works
9999
on it. The owner might pull changes from others, but the owner is always
100100
in control of the branch. Branches are developer-centric.
101101
102
-Fossil, on the other hand, encourages a workflow where branches are
102
+Fossil, on the other hand, encourages a workflow where branches are
103103
associated with features or releases, not individual developers.
104104
All developers share all branches in common, and two
105105
or more developers can and often do intersperse commits onto the same branch.
106106
Branches do not belong to individuals. All branches are read/write
107107
accessible to all developers at all times. There is no need
@@ -113,11 +113,11 @@
113113
branches in Fossil are feature-centric.
114114
115115
The Git approach scales much better for large projects like the Linux
116116
kernel with thousands of contributors who in many cases don't even know
117117
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,
118
+undesirable code out of the official Linux source tree. On the other hand,
119119
not many projects are as big or as loosely organized as the Linux kernel.
120120
Most projects have a small team of developers who all know each other
121121
well and trust each other, and who enjoy working together collaboratively
122122
without the overhead and hierarchy of integrators.
123123
@@ -141,14 +141,14 @@
141141
to think about version control to some extent. But one wants to minimize
142142
the thinking about version control.
143143
144144
Git requires the developer to maintain a more complex mental model than
145145
most other DVCSes. Git takes longer to learn. And you have to spend
146
-more time thinking about what you are doing with Git.
146
+more time thinking about what you are doing with Git.
147147
148148
Fossil strives for simplicity. Fossil wants to be easy to learn and to
149
-require little thinking about how to operating it.
149
+require little thinking about how to operating it.
150150
[./quotes.wiki | Reports from the field]
151151
indicate that Fossil is mostly successful at this effort.
152152
153153
<h3>3.5 Web Interface</h3>
154154
@@ -195,17 +195,17 @@
195195
196196
Git features the "rebase" command which can be used to change the
197197
sequence of check-ins in the repository. Rebase can be used to "clean up"
198198
a complex sequence of check-ins to make their intent easier for others
199199
to understand. This is important if you view the history of a project
200
-as part of the documentation for the project.
200
+as part of the documentation for the project.
201201
202202
Fossil takes an opposing view. Fossil views history as sacrosanct and
203203
stubornly refuses to change it.
204204
Fossil allows mistakes to be corrected (for example, check-in comments
205205
can be revised, and check-ins can be moved onto new branches even after
206
-the check-in has occurred) but the correction is an addition to the respository
206
+the check-in has occurred) but the correction is an addition to the repository
207207
and the original actions are preserved and displayed alongside
208208
the corrections, thus preserving an historically accurate audit trail.
209209
This is analogous to an accountant marking through an incorrect
210210
entry in a ledger and writing in a correction beside it, rather than
211211
erasing and incorrect entry.
@@ -216,12 +216,12 @@
216216
The lack of a "rebase" command and the inability to rewrite history
217217
is considered a feature of Fossil, not an omission or bug.
218218
219219
<h3>3.9 License</h3>
220220
221
-Both Git and Fossil are open-source. Git is under
221
+Both Git and Fossil are open-source. Git is under
222222
[http://www.gnu.org/licenses/gpl.html | GPL] whereas Fossil is
223
-under the
223
+under the
224224
[http://en.wikipedia.org/wiki/BSD_licenses | two-clause BSD license].
225225
The difference should not be of a concern to most users. However,
226226
some corporate lawyers have objections to using GPL products and
227227
are more comfortable with a BSD-style license.
228228
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -3,15 +3,15 @@
3 <h2>1.0 Don't Stress!</h2>
4
5 If you start out using one DVCS and later decide you like the other better,
6 it is [./inout.wiki | easy to change].
7
8 But it also helps to be informed about the differences between
9 [http://git-scm.com | Git] and Fossil. See the table below for
10 a high-level summary and the text that follows for more details.
11
12 Keep in mind that you are reading this on a Fossil website,
13 so the information here
14 might be biased in favor of Fossil. Ask around with people who have
15 used both Fossil and Git for other opinions.
16
17 <h2>2.0 Executive Summary:</h2>
@@ -47,21 +47,21 @@
47 <h3>3.2 Sharding versus Replicating</h3>
48
49 Git makes it easy for each repository in a project to hold a subset of
50 the branches for that project. In fact, it is entirely possible and not
51 uncommon for no repository in the project to hold all the different code
52 versions for a project. Instead the information is distributed.
53 Individual developers have one or more private branches. A hierarchy
54 of integrators merge changes from individual developers into collaborative
55 branches, until all the changes are merged together at the top-level master
56 branch. And all of this can be accomplished without having to have all the
57 code in any one repository. Developers or groups of developers can share
58 only those branches that they want to share and keep other branchs of the
59 project private. This is analogous to sharding an a distributed database.
60
61 Fossil allows private branches, but its default mode is to share everything.
62 And so in a Fossil project, all respositories tend to contain all of the
63 content at all times. This is analogous to replication in a
64 distributed database.
65
66 The Git model works best for large projects, like the
67 Linux kernel for which Git was designed.
@@ -73,35 +73,35 @@
73 works in his or her own branch and then merges changes up the hierarchy
74 until they reach the master branch.
75
76 Fossil is designed for smaller and non-hierarchical teams where all
77 developers are operating directly on the master branch, or at most
78 a small number of well defined branches.
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 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
@@ -113,11 +113,11 @@
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 projects 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
@@ -141,14 +141,14 @@
141 to think about version control to some extent. But one wants to minimize
142 the thinking about version control.
143
144 Git requires the developer to maintain a more complex mental model than
145 most other DVCSes. Git takes longer to learn. And you have to spend
146 more time thinking about what you are doing with Git.
147
148 Fossil strives for simplicity. Fossil wants to be easy to learn and to
149 require little thinking about how to operating it.
150 [./quotes.wiki | Reports from the field]
151 indicate that Fossil is mostly successful at this effort.
152
153 <h3>3.5 Web Interface</h3>
154
@@ -195,17 +195,17 @@
195
196 Git features the "rebase" command which can be used to change the
197 sequence of check-ins in the repository. Rebase can be used to "clean up"
198 a complex sequence of check-ins to make their intent easier for others
199 to understand. This is important if you view the history of a project
200 as part of the documentation for the project.
201
202 Fossil takes an opposing view. Fossil views history as sacrosanct and
203 stubornly refuses to change it.
204 Fossil allows mistakes to be corrected (for example, check-in comments
205 can be revised, and check-ins can be moved onto new branches even after
206 the check-in has occurred) but the correction is an addition to the respository
207 and the original actions are preserved and displayed alongside
208 the corrections, thus preserving an historically accurate audit trail.
209 This is analogous to an accountant marking through an incorrect
210 entry in a ledger and writing in a correction beside it, rather than
211 erasing and incorrect entry.
@@ -216,12 +216,12 @@
216 The lack of a "rebase" command and the inability to rewrite history
217 is considered a feature of Fossil, not an omission or bug.
218
219 <h3>3.9 License</h3>
220
221 Both Git and Fossil are open-source. Git is under
222 [http://www.gnu.org/licenses/gpl.html | GPL] whereas Fossil is
223 under the
224 [http://en.wikipedia.org/wiki/BSD_licenses | two-clause BSD license].
225 The difference should not be of a concern to most users. However,
226 some corporate lawyers have objections to using GPL products and
227 are more comfortable with a BSD-style license.
228
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -3,15 +3,15 @@
3 <h2>1.0 Don't Stress!</h2>
4
5 If you start out using one DVCS and later decide you like the other better,
6 it is [./inout.wiki | easy to change].
7
8 But it also helps to be informed about the differences between
9 [http://git-scm.com | Git] and Fossil. See the table below for
10 a high-level summary and the text that follows for more details.
11
12 Keep in mind that you are reading this on a Fossil website,
13 so the information here
14 might be biased in favor of Fossil. Ask around with people who have
15 used both Fossil and Git for other opinions.
16
17 <h2>2.0 Executive Summary:</h2>
@@ -47,21 +47,21 @@
47 <h3>3.2 Sharding versus Replicating</h3>
48
49 Git makes it easy for each repository in a project to hold a subset of
50 the branches for that project. In fact, it is entirely possible and not
51 uncommon for no repository in the project to hold all the different code
52 versions for a project. Instead the information is distributed.
53 Individual developers have one or more private branches. A hierarchy
54 of integrators merge changes from individual developers into collaborative
55 branches, until all the changes are merged together at the top-level master
56 branch. And all of this can be accomplished without having to have all the
57 code in any one repository. Developers or groups of developers can share
58 only those branches that they want to share and keep other branchs of the
59 project private. This is analogous to sharding an a distributed database.
60
61 Fossil allows private branches, but its default mode is to share everything.
62 And so in a Fossil project, all repositories tend to contain all of the
63 content at all times. This is analogous to replication in a
64 distributed database.
65
66 The Git model works best for large projects, like the
67 Linux kernel for which Git was designed.
@@ -73,35 +73,35 @@
73 works in his or her own branch and then merges changes up the hierarchy
74 until they reach the master branch.
75
76 Fossil is designed for smaller and non-hierarchical teams where all
77 developers are operating directly on the master branch, or at most
78 a small number of well defined branches.
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 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
@@ -113,11 +113,11 @@
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 projects 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
@@ -141,14 +141,14 @@
141 to think about version control to some extent. But one wants to minimize
142 the thinking about version control.
143
144 Git requires the developer to maintain a more complex mental model than
145 most other DVCSes. Git takes longer to learn. And you have to spend
146 more time thinking about what you are doing with Git.
147
148 Fossil strives for simplicity. Fossil wants to be easy to learn and to
149 require little thinking about how to operating it.
150 [./quotes.wiki | Reports from the field]
151 indicate that Fossil is mostly successful at this effort.
152
153 <h3>3.5 Web Interface</h3>
154
@@ -195,17 +195,17 @@
195
196 Git features the "rebase" command which can be used to change the
197 sequence of check-ins in the repository. Rebase can be used to "clean up"
198 a complex sequence of check-ins to make their intent easier for others
199 to understand. This is important if you view the history of a project
200 as part of the documentation for the project.
201
202 Fossil takes an opposing view. Fossil views history as sacrosanct and
203 stubornly refuses to change it.
204 Fossil allows mistakes to be corrected (for example, check-in comments
205 can be revised, and check-ins can be moved onto new branches even after
206 the check-in has occurred) but the correction is an addition to the repository
207 and the original actions are preserved and displayed alongside
208 the corrections, thus preserving an historically accurate audit trail.
209 This is analogous to an accountant marking through an incorrect
210 entry in a ledger and writing in a correction beside it, rather than
211 erasing and incorrect entry.
@@ -216,12 +216,12 @@
216 The lack of a "rebase" command and the inability to rewrite history
217 is considered a feature of Fossil, not an omission or bug.
218
219 <h3>3.9 License</h3>
220
221 Both Git and Fossil are open-source. Git is under
222 [http://www.gnu.org/licenses/gpl.html | GPL] whereas Fossil is
223 under the
224 [http://en.wikipedia.org/wiki/BSD_licenses | two-clause BSD license].
225 The difference should not be of a concern to most users. However,
226 some corporate lawyers have objections to using GPL products and
227 are more comfortable with a BSD-style license.
228
--- www/password.wiki
+++ www/password.wiki
@@ -7,12 +7,12 @@
77
are not transmitted from one repository to another during a sync.
88
Passwords are local configuration information that can (and usually does)
99
vary from one repository to the next within the same project.
1010
1111
Passwords are stored in the PW field of the USER table.
12
-In older versions of Fossil (prior to
13
-[/timeline?c=2010-01-10+20:56:30 | 2010-01-11]) the password
12
+In older versions of Fossil (prior to
13
+[/timeline?c=2010-01-10T20:56:30 | 2010-01-11]) the password
1414
is stored as cleartext. In newer versions of Fossil, the password
1515
can be either cleartext or an SHA1 hash (written as a 40-character
1616
lower-case hexadecimal number). If the USER.PW field contains
1717
a 40-character string, that string is assumed to be a SHA1 hash.
1818
If the size of USER.PW is anything other than 40 characters, then
@@ -71,14 +71,14 @@
7171
hashes the password and compares it against the value stored in USER.PW.
7272
If they match, the server sets a cookie on the client to record the
7373
login. This cookie contains a large amount of high-quality randomness
7474
and is thus intractable to guess. The value of the cookie and the IP
7575
address of the client is stored in the USER.COOKIE and USER.IPADDR fields
76
-of the USER table on the server.
76
+of the USER table on the server.
7777
The USER.CEXPIRE field holds an expiration date
7878
for the cookie, encoded as a julian day number. On all subsequent
79
-HTTP requests, the cookie value is matched against the USER table to
79
+HTTP requests, the cookie value is matched against the USER table to
8080
enable access to the repository.
8181
8282
A login cookie will only work if the IP address matches. This feature
8383
is designed to make it more difficult for an attacker to sniff the cookie
8484
and take over the connection. A cookie-sniffing attack will only work
@@ -103,12 +103,12 @@
103103
over the wire, but that plan has not yet been set in code.
104104
105105
<h2>Sync Protocol Authentication</h2>
106106
107107
A different authentication mechanism is used when one repository wants
108
-to sync (or push or pull or clone) another respository. When two
109
-respositories are syncing, the one that initiates the transaction is
108
+to sync (or push or pull or clone) another repository. When two
109
+repositories are syncing, the one that initiates the transaction is
110110
the client and the repository that responds is the server. The client
111111
works by sending HTTP requests to the server with a method of "xfer"
112112
and a content-type of "application/x-fossil". The content is Zlib-compressed
113113
text consisting of "cards" of instructions. The first card of this content
114114
is a "login" card responsible for authentication. The login card contains
@@ -137,12 +137,12 @@
137137
<blockquote><pre>
138138
http://<font color="blue">login:password</font>@servername.org/path
139139
</pre></blockquote>
140140
141141
For older clients, the password is used for the shared secret as stated
142
-in the URL and with no encoding.
143
-For newer clients, the shared secret is derived from the password
142
+in the URL and with no encoding.
143
+For newer clients, the shared secret is derived from the password
144144
by transformed the password using the SHA1 hash encoding
145145
described above. However, if the first character of the password is
146146
"*" (ASCII 0x2a) then the "*" is skipped and the rest of the password
147147
is used directly as the share secret without the SHA1 encoding.
148148
149149
--- www/password.wiki
+++ www/password.wiki
@@ -7,12 +7,12 @@
7 are not transmitted from one repository to another during a sync.
8 Passwords are local configuration information that can (and usually does)
9 vary from one repository to the next within the same project.
10
11 Passwords are stored in the PW field of the USER table.
12 In older versions of Fossil (prior to
13 [/timeline?c=2010-01-10+20:56:30 | 2010-01-11]) the password
14 is stored as cleartext. In newer versions of Fossil, the password
15 can be either cleartext or an SHA1 hash (written as a 40-character
16 lower-case hexadecimal number). If the USER.PW field contains
17 a 40-character string, that string is assumed to be a SHA1 hash.
18 If the size of USER.PW is anything other than 40 characters, then
@@ -71,14 +71,14 @@
71 hashes the password and compares it against the value stored in USER.PW.
72 If they match, the server sets a cookie on the client to record the
73 login. This cookie contains a large amount of high-quality randomness
74 and is thus intractable to guess. The value of the cookie and the IP
75 address of the client is stored in the USER.COOKIE and USER.IPADDR fields
76 of the USER table on the server.
77 The USER.CEXPIRE field holds an expiration date
78 for the cookie, encoded as a julian day number. On all subsequent
79 HTTP requests, the cookie value is matched against the USER table to
80 enable access to the repository.
81
82 A login cookie will only work if the IP address matches. This feature
83 is designed to make it more difficult for an attacker to sniff the cookie
84 and take over the connection. A cookie-sniffing attack will only work
@@ -103,12 +103,12 @@
103 over the wire, but that plan has not yet been set in code.
104
105 <h2>Sync Protocol Authentication</h2>
106
107 A different authentication mechanism is used when one repository wants
108 to sync (or push or pull or clone) another respository. When two
109 respositories are syncing, the one that initiates the transaction is
110 the client and the repository that responds is the server. The client
111 works by sending HTTP requests to the server with a method of "xfer"
112 and a content-type of "application/x-fossil". The content is Zlib-compressed
113 text consisting of "cards" of instructions. The first card of this content
114 is a "login" card responsible for authentication. The login card contains
@@ -137,12 +137,12 @@
137 <blockquote><pre>
138 http://<font color="blue">login:password</font>@servername.org/path
139 </pre></blockquote>
140
141 For older clients, the password is used for the shared secret as stated
142 in the URL and with no encoding.
143 For newer clients, the shared secret is derived from the password
144 by transformed the password using the SHA1 hash encoding
145 described above. However, if the first character of the password is
146 "*" (ASCII 0x2a) then the "*" is skipped and the rest of the password
147 is used directly as the share secret without the SHA1 encoding.
148
149
--- www/password.wiki
+++ www/password.wiki
@@ -7,12 +7,12 @@
7 are not transmitted from one repository to another during a sync.
8 Passwords are local configuration information that can (and usually does)
9 vary from one repository to the next within the same project.
10
11 Passwords are stored in the PW field of the USER table.
12 In older versions of Fossil (prior to
13 [/timeline?c=2010-01-10T20:56:30 | 2010-01-11]) the password
14 is stored as cleartext. In newer versions of Fossil, the password
15 can be either cleartext or an SHA1 hash (written as a 40-character
16 lower-case hexadecimal number). If the USER.PW field contains
17 a 40-character string, that string is assumed to be a SHA1 hash.
18 If the size of USER.PW is anything other than 40 characters, then
@@ -71,14 +71,14 @@
71 hashes the password and compares it against the value stored in USER.PW.
72 If they match, the server sets a cookie on the client to record the
73 login. This cookie contains a large amount of high-quality randomness
74 and is thus intractable to guess. The value of the cookie and the IP
75 address of the client is stored in the USER.COOKIE and USER.IPADDR fields
76 of the USER table on the server.
77 The USER.CEXPIRE field holds an expiration date
78 for the cookie, encoded as a julian day number. On all subsequent
79 HTTP requests, the cookie value is matched against the USER table to
80 enable access to the repository.
81
82 A login cookie will only work if the IP address matches. This feature
83 is designed to make it more difficult for an attacker to sniff the cookie
84 and take over the connection. A cookie-sniffing attack will only work
@@ -103,12 +103,12 @@
103 over the wire, but that plan has not yet been set in code.
104
105 <h2>Sync Protocol Authentication</h2>
106
107 A different authentication mechanism is used when one repository wants
108 to sync (or push or pull or clone) another repository. When two
109 repositories are syncing, the one that initiates the transaction is
110 the client and the repository that responds is the server. The client
111 works by sending HTTP requests to the server with a method of "xfer"
112 and a content-type of "application/x-fossil". The content is Zlib-compressed
113 text consisting of "cards" of instructions. The first card of this content
114 is a "login" card responsible for authentication. The login card contains
@@ -137,12 +137,12 @@
137 <blockquote><pre>
138 http://<font color="blue">login:password</font>@servername.org/path
139 </pre></blockquote>
140
141 For older clients, the password is used for the shared secret as stated
142 in the URL and with no encoding.
143 For newer clients, the shared secret is derived from the password
144 by transformed the password using the SHA1 hash encoding
145 described above. However, if the first character of the password is
146 "*" (ASCII 0x2a) then the "*" is skipped and the rest of the password
147 is used directly as the share secret without the SHA1 encoding.
148
149
--- www/tickets.wiki
+++ www/tickets.wiki
@@ -101,20 +101,20 @@
101101
used to uniquely identify the ticket to which the row belongs. These
102102
keys are for internal use only and may change when doing a "fossil rebuild".
103103
104104
The <b>tkt_uuid</b> field is the unique hexadecimal identifier for the ticket.
105105
Ticket identifiers appear to be SHA1 hash strings, but they
106
-are not really the hash of any identifible artifact. They are
106
+are not really the hash of any identifiable artifact. They are
107107
just random hexadecimal numbers. When creating a new ticket, Fossil uses
108
-a (high-quality) pseudo-random number generator to create the ticket
108
+a (high-quality) pseudo-random number generator to create the ticket
109109
number. The ticket numbers are large so that the chance of collision
110110
between any two tickets is vanishingly small.
111111
112112
The <b>tkt_mtime</b> field of TICKET shows the time (as a Julian day number)
113113
of the most recent ticket change artifact for that ticket. The
114114
<b>tkt_mtime</b> field of TICKETCHNG shows the timestamp on the ticket
115
-change artifact that the TICKETCHNG row refers to. The
115
+change artifact that the TICKETCHNG row refers to. The
116116
<b>tkt_ctime</b> field of TICKET is the time of the oldest ticket change
117117
artifact for that ticket, thus holding the time that the ticket was
118118
created.
119119
120120
The <b>tkt_rid</b> field of TICKETCHNG is the integer primary key in the
@@ -160,11 +160,11 @@
160160
visited, its key/value pairs are examined. For any key/value pair in
161161
which the key is the same as a field in the TICKET table, the value
162162
of that pair either replaces or is appended to the previous value
163163
of the corresponding field in the TICKET table. Whether a value is
164164
replaced or appended is determined by markings in the ticket change
165
-artifact itself. Most fields are usually replaced. (For example, to change
165
+artifact itself. Most fields are usually replaced. (For example, to change
166166
the status from "Open" to "Fixed" would involve a key value pair
167167
"status/Fixed" with the replace attribute set). The main exception
168168
is the "comment" field, which is usually appended with new comment
169169
text.
170170
@@ -174,26 +174,26 @@
174174
difference there.
175175
176176
<h3>2.3 Old-Style versus New-Style Tickets</h3>
177177
178178
Older versions of Fossil
179
-(before [/timeline?c=2012-11-27+16:26:29 | 2012-11-27])
179
+(before [/timeline?c=2012-11-27T16:26:29 | 2012-11-27])
180180
only supported the TICKET table.
181181
In this older style, new comments were added to tickets by using
182182
the append-value feature on the comment field. Thus the TICKET.COMMENT
183183
field contains the complete text of all user comments already appended
184184
together and ready for display.
185185
186186
A problem with the old approach is that all comment text had to
187187
be in the same format. In other words, the all comment text had to be
188188
either plaintext or wiki or HTML. It was not possible for some comments
189
-to be in HTML and others to be plaintext. Some site adminstrators wanted the
190
-ability to mix plaintext, wiki, and HTML comments and display each
189
+to be in HTML and others to be plaintext. Some site administrators wanted the
190
+ability to mix plaintext, wiki, and HTML comments and display each
191191
comment according to its chosen format. Hence, Fossil was enhanced to
192192
support the "new-style" tickets.
193193
194194
The TICKETCHNG table was added to support new-style tickets. In the new
195195
style, comment text is stored with the "icomment" (for "Incremental Comment")
196196
key and appears separately, and with its on mimetype, in multiple rows
197197
of the TICKETCHNG table. It then falls to the TH1 script code on the
198198
View Ticket Page to query the TICKETCHNG table and extract and format
199199
the various comments in timestamp order.
200200
--- www/tickets.wiki
+++ www/tickets.wiki
@@ -101,20 +101,20 @@
101 used to uniquely identify the ticket to which the row belongs. These
102 keys are for internal use only and may change when doing a "fossil rebuild".
103
104 The <b>tkt_uuid</b> field is the unique hexadecimal identifier for the ticket.
105 Ticket identifiers appear to be SHA1 hash strings, but they
106 are not really the hash of any identifible artifact. They are
107 just random hexadecimal numbers. When creating a new ticket, Fossil uses
108 a (high-quality) pseudo-random number generator to create the ticket
109 number. The ticket numbers are large so that the chance of collision
110 between any two tickets is vanishingly small.
111
112 The <b>tkt_mtime</b> field of TICKET shows the time (as a Julian day number)
113 of the most recent ticket change artifact for that ticket. The
114 <b>tkt_mtime</b> field of TICKETCHNG shows the timestamp on the ticket
115 change artifact that the TICKETCHNG row refers to. The
116 <b>tkt_ctime</b> field of TICKET is the time of the oldest ticket change
117 artifact for that ticket, thus holding the time that the ticket was
118 created.
119
120 The <b>tkt_rid</b> field of TICKETCHNG is the integer primary key in the
@@ -160,11 +160,11 @@
160 visited, its key/value pairs are examined. For any key/value pair in
161 which the key is the same as a field in the TICKET table, the value
162 of that pair either replaces or is appended to the previous value
163 of the corresponding field in the TICKET table. Whether a value is
164 replaced or appended is determined by markings in the ticket change
165 artifact itself. Most fields are usually replaced. (For example, to change
166 the status from "Open" to "Fixed" would involve a key value pair
167 "status/Fixed" with the replace attribute set). The main exception
168 is the "comment" field, which is usually appended with new comment
169 text.
170
@@ -174,26 +174,26 @@
174 difference there.
175
176 <h3>2.3 Old-Style versus New-Style Tickets</h3>
177
178 Older versions of Fossil
179 (before [/timeline?c=2012-11-27+16:26:29 | 2012-11-27])
180 only supported the TICKET table.
181 In this older style, new comments were added to tickets by using
182 the append-value feature on the comment field. Thus the TICKET.COMMENT
183 field contains the complete text of all user comments already appended
184 together and ready for display.
185
186 A problem with the old approach is that all comment text had to
187 be in the same format. In other words, the all comment text had to be
188 either plaintext or wiki or HTML. It was not possible for some comments
189 to be in HTML and others to be plaintext. Some site adminstrators wanted the
190 ability to mix plaintext, wiki, and HTML comments and display each
191 comment according to its chosen format. Hence, Fossil was enhanced to
192 support the "new-style" tickets.
193
194 The TICKETCHNG table was added to support new-style tickets. In the new
195 style, comment text is stored with the "icomment" (for "Incremental Comment")
196 key and appears separately, and with its on mimetype, in multiple rows
197 of the TICKETCHNG table. It then falls to the TH1 script code on the
198 View Ticket Page to query the TICKETCHNG table and extract and format
199 the various comments in timestamp order.
200
--- www/tickets.wiki
+++ www/tickets.wiki
@@ -101,20 +101,20 @@
101 used to uniquely identify the ticket to which the row belongs. These
102 keys are for internal use only and may change when doing a "fossil rebuild".
103
104 The <b>tkt_uuid</b> field is the unique hexadecimal identifier for the ticket.
105 Ticket identifiers appear to be SHA1 hash strings, but they
106 are not really the hash of any identifiable artifact. They are
107 just random hexadecimal numbers. When creating a new ticket, Fossil uses
108 a (high-quality) pseudo-random number generator to create the ticket
109 number. The ticket numbers are large so that the chance of collision
110 between any two tickets is vanishingly small.
111
112 The <b>tkt_mtime</b> field of TICKET shows the time (as a Julian day number)
113 of the most recent ticket change artifact for that ticket. The
114 <b>tkt_mtime</b> field of TICKETCHNG shows the timestamp on the ticket
115 change artifact that the TICKETCHNG row refers to. The
116 <b>tkt_ctime</b> field of TICKET is the time of the oldest ticket change
117 artifact for that ticket, thus holding the time that the ticket was
118 created.
119
120 The <b>tkt_rid</b> field of TICKETCHNG is the integer primary key in the
@@ -160,11 +160,11 @@
160 visited, its key/value pairs are examined. For any key/value pair in
161 which the key is the same as a field in the TICKET table, the value
162 of that pair either replaces or is appended to the previous value
163 of the corresponding field in the TICKET table. Whether a value is
164 replaced or appended is determined by markings in the ticket change
165 artifact itself. Most fields are usually replaced. (For example, to change
166 the status from "Open" to "Fixed" would involve a key value pair
167 "status/Fixed" with the replace attribute set). The main exception
168 is the "comment" field, which is usually appended with new comment
169 text.
170
@@ -174,26 +174,26 @@
174 difference there.
175
176 <h3>2.3 Old-Style versus New-Style Tickets</h3>
177
178 Older versions of Fossil
179 (before [/timeline?c=2012-11-27T16:26:29 | 2012-11-27])
180 only supported the TICKET table.
181 In this older style, new comments were added to tickets by using
182 the append-value feature on the comment field. Thus the TICKET.COMMENT
183 field contains the complete text of all user comments already appended
184 together and ready for display.
185
186 A problem with the old approach is that all comment text had to
187 be in the same format. In other words, the all comment text had to be
188 either plaintext or wiki or HTML. It was not possible for some comments
189 to be in HTML and others to be plaintext. Some site administrators wanted the
190 ability to mix plaintext, wiki, and HTML comments and display each
191 comment according to its chosen format. Hence, Fossil was enhanced to
192 support the "new-style" tickets.
193
194 The TICKETCHNG table was added to support new-style tickets. In the new
195 style, comment text is stored with the "icomment" (for "Incremental Comment")
196 key and appears separately, and with its on mimetype, in multiple rows
197 of the TICKETCHNG table. It then falls to the TH1 script code on the
198 View Ticket Page to query the TICKETCHNG table and extract and format
199 the various comments in timestamp order.
200

Keyboard Shortcuts

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