Fossil SCM

Merge trunk.

andygoth 2015-06-19 15:44 andygoth-brackets-outside-link merge
Commit 21220b21b7fc2d6a635ec7804d8f39c9af3b0783
-15
--- auto.def
+++ auto.def
@@ -14,11 +14,10 @@
1414
with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism}
1515
with-tcl-private-stubs=0
1616
=> {Enable Tcl integration via private stubs mechanism}
1717
internal-sqlite=1 => {Don't use the internal SQLite, use the system one}
1818
static=0 => {Link a static executable}
19
- lineedit=1 => {Disable line editing}
2019
fusefs=1 => {Disable the Fuse Filesystem}
2120
fossil-debug=0 => {Build with fossil debugging enabled}
2221
json=0 => {Build with fossil JSON API enabled}
2322
}
2423
@@ -260,24 +259,10 @@
260259
if {![cc-check-includes zlib.h] || ![cc-check-function-in-lib inflateEnd z]} {
261260
user-error "zlib not found please install it or specify the location with --with-zlib"
262261
}
263262
}
264263
265
-if {[opt-bool lineedit]} {
266
- # Need readline-compatible line editing
267
- cc-with {-includes stdio.h} {
268
- if {[cc-check-includes readline/readline.h] && [cc-check-function-in-lib readline readline]} {
269
- define-append EXTRA_CFLAGS -DHAVE_READLINE
270
- msg-result "Using readline for line editing"
271
- } elseif {[cc-check-includes editline/readline.h] && [cc-check-function-in-lib readline edit]} {
272
- define-feature editline
273
- define-append EXTRA_CFLAGS -DHAVE_EDITLINE
274
- msg-result "Using editline for line editing"
275
- }
276
- }
277
-}
278
-
279264
# Network functions require libraries on some systems
280265
cc-check-function-in-lib gethostbyname nsl
281266
if {![cc-check-function-in-lib socket {socket network}]} {
282267
# Last resort, may be Windows
283268
if {[string match *mingw* [get-define host]]} {
284269
--- auto.def
+++ auto.def
@@ -14,11 +14,10 @@
14 with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism}
15 with-tcl-private-stubs=0
16 => {Enable Tcl integration via private stubs mechanism}
17 internal-sqlite=1 => {Don't use the internal SQLite, use the system one}
18 static=0 => {Link a static executable}
19 lineedit=1 => {Disable line editing}
20 fusefs=1 => {Disable the Fuse Filesystem}
21 fossil-debug=0 => {Build with fossil debugging enabled}
22 json=0 => {Build with fossil JSON API enabled}
23 }
24
@@ -260,24 +259,10 @@
260 if {![cc-check-includes zlib.h] || ![cc-check-function-in-lib inflateEnd z]} {
261 user-error "zlib not found please install it or specify the location with --with-zlib"
262 }
263 }
264
265 if {[opt-bool lineedit]} {
266 # Need readline-compatible line editing
267 cc-with {-includes stdio.h} {
268 if {[cc-check-includes readline/readline.h] && [cc-check-function-in-lib readline readline]} {
269 define-append EXTRA_CFLAGS -DHAVE_READLINE
270 msg-result "Using readline for line editing"
271 } elseif {[cc-check-includes editline/readline.h] && [cc-check-function-in-lib readline edit]} {
272 define-feature editline
273 define-append EXTRA_CFLAGS -DHAVE_EDITLINE
274 msg-result "Using editline for line editing"
275 }
276 }
277 }
278
279 # Network functions require libraries on some systems
280 cc-check-function-in-lib gethostbyname nsl
281 if {![cc-check-function-in-lib socket {socket network}]} {
282 # Last resort, may be Windows
283 if {[string match *mingw* [get-define host]]} {
284
--- auto.def
+++ auto.def
@@ -14,11 +14,10 @@
14 with-tcl-stubs=0 => {Enable Tcl integration via stubs library mechanism}
15 with-tcl-private-stubs=0
16 => {Enable Tcl integration via private stubs mechanism}
17 internal-sqlite=1 => {Don't use the internal SQLite, use the system one}
18 static=0 => {Link a static executable}
 
19 fusefs=1 => {Disable the Fuse Filesystem}
20 fossil-debug=0 => {Build with fossil debugging enabled}
21 json=0 => {Build with fossil JSON API enabled}
22 }
23
@@ -260,24 +259,10 @@
259 if {![cc-check-includes zlib.h] || ![cc-check-function-in-lib inflateEnd z]} {
260 user-error "zlib not found please install it or specify the location with --with-zlib"
261 }
262 }
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264 # Network functions require libraries on some systems
265 cc-check-function-in-lib gethostbyname nsl
266 if {![cc-check-function-in-lib socket {socket network}]} {
267 # Last resort, may be Windows
268 if {[string match *mingw* [get-define host]]} {
269
+41 -37
--- src/add.c
+++ src/add.c
@@ -91,11 +91,11 @@
9191
9292
if( cachedManifest == -1 ){
9393
Blob repo;
9494
cachedManifest = db_get_boolean("manifest",0);
9595
blob_zero(&repo);
96
- if( file_tree_name(g.zRepositoryName, &repo, 0) ){
96
+ if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
9797
const char *zRepo = blob_str(&repo);
9898
azRepo[0] = zRepo;
9999
azRepo[1] = mprintf("%s-journal", zRepo);
100100
azRepo[2] = mprintf("%s-wal", zRepo);
101101
azRepo[3] = mprintf("%s-shm", zRepo);
@@ -201,11 +201,11 @@
201201
const char *zReserved; /* Name of a reserved file */
202202
Blob repoName; /* Treename of the repository */
203203
Stmt loop; /* SQL to loop over all files to add */
204204
int (*xCmp)(const char*,const char*);
205205
206
- if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){
206
+ if( !file_tree_name(g.zRepositoryName, &repoName, 0, 0) ){
207207
blob_zero(&repoName);
208208
zRepo = "";
209209
}else{
210210
zRepo = blob_str(&repoName);
211211
}
@@ -307,11 +307,11 @@
307307
int isDir;
308308
Blob fullName;
309309
310310
/* file_tree_name() throws a fatal error if g.argv[i] is outside of the
311311
** checkout. */
312
- file_tree_name(g.argv[i], &fullName, 1);
312
+ file_tree_name(g.argv[i], &fullName, 0, 1);
313313
blob_reset(&fullName);
314314
315315
file_canonical_name(g.argv[i], &fullName, 0);
316316
zName = blob_str(&fullName);
317317
isDir = file_wd_isdir(zName);
@@ -365,11 +365,11 @@
365365
if( !tableCreated ){
366366
db_multi_exec("CREATE TEMP TABLE fremove(x TEXT PRIMARY KEY %s)",
367367
filename_collation());
368368
tableCreated = 1;
369369
}
370
- file_canonical_name(zOldName, &fullOldName, 0);
370
+ file_tree_name(zOldName, &fullOldName, 1, 1);
371371
db_multi_exec("INSERT INTO fremove VALUES('%q');", blob_str(&fullOldName));
372372
blob_reset(&fullOldName);
373373
}
374374
375375
/*
@@ -384,20 +384,22 @@
384384
*/
385385
static void process_files_to_remove(
386386
int dryRunFlag /* Zero to actually operate on the file-system. */
387387
){
388388
Stmt remove;
389
- db_prepare(&remove, "SELECT x FROM fremove ORDER BY x;");
390
- while( db_step(&remove)==SQLITE_ROW ){
391
- const char *zOldName = db_column_text(&remove, 0);
392
- if( !dryRunFlag ){
393
- file_delete(zOldName);
394
- }
395
- fossil_print("DELETED_FILE %s\n", zOldName);
396
- }
397
- db_finalize(&remove);
398
- db_multi_exec("DROP TABLE fremove;");
389
+ if( db_table_exists(db_name("temp"), "fremove") ){
390
+ db_prepare(&remove, "SELECT x FROM fremove ORDER BY x;");
391
+ while( db_step(&remove)==SQLITE_ROW ){
392
+ const char *zOldName = db_column_text(&remove, 0);
393
+ if( !dryRunFlag ){
394
+ file_delete(zOldName);
395
+ }
396
+ fossil_print("DELETED_FILE %s\n", zOldName);
397
+ }
398
+ db_finalize(&remove);
399
+ db_multi_exec("DROP TABLE fremove;");
400
+ }
399401
}
400402
401403
/*
402404
** COMMAND: rm
403405
** COMMAND: delete
@@ -464,11 +466,11 @@
464466
filename_collation());
465467
for(i=2; i<g.argc; i++){
466468
Blob treeName;
467469
char *zTreeName;
468470
469
- file_tree_name(g.argv[i], &treeName, 1);
471
+ file_tree_name(g.argv[i], &treeName, 0, 1);
470472
zTreeName = blob_str(&treeName);
471473
db_multi_exec(
472474
"INSERT OR IGNORE INTO sfile"
473475
" SELECT pathname FROM vfile"
474476
" WHERE (pathname=%Q %s"
@@ -631,11 +633,11 @@
631633
632634
/* We should be done with options.. */
633635
verify_all_options();
634636
635637
/* Fail if unprocessed arguments are present, in case user expect the
636
- ** addremove command to accept a list of file or directory.
638
+ ** addremove command to accept a list of file or directory.
637639
*/
638640
if( g.argc>2 ){
639641
fossil_fatal(
640642
"%s: Can only work on the entire checkout, no arguments supported.",
641643
g.argv[1]);
@@ -746,12 +748,12 @@
746748
if( !tableCreated ){
747749
db_multi_exec("CREATE TEMP TABLE fmove(x TEXT PRIMARY KEY %s, y TEXT %s)",
748750
filename_collation(), filename_collation());
749751
tableCreated = 1;
750752
}
751
- file_canonical_name(zOldName, &fullOldName, 0);
752
- file_canonical_name(zNewName, &fullNewName, 0);
753
+ file_tree_name(zOldName, &fullOldName, 1, 1);
754
+ file_tree_name(zNewName, &fullNewName, 1, 1);
753755
db_multi_exec("INSERT INTO fmove VALUES('%q','%q');",
754756
blob_str(&fullOldName), blob_str(&fullNewName));
755757
blob_reset(&fullNewName);
756758
blob_reset(&fullOldName);
757759
}
@@ -768,26 +770,28 @@
768770
*/
769771
static void process_files_to_move(
770772
int dryRunFlag /* Zero to actually operate on the file-system. */
771773
){
772774
Stmt move;
773
- db_prepare(&move, "SELECT x, y FROM fmove ORDER BY x;");
774
- while( db_step(&move)==SQLITE_ROW ){
775
- const char *zOldName = db_column_text(&move, 0);
776
- const char *zNewName = db_column_text(&move, 1);
777
- if( !dryRunFlag ){
778
- if( file_wd_islink(zOldName) ){
779
- symlink_copy(zOldName, zNewName);
780
- }else{
781
- file_copy(zOldName, zNewName);
782
- }
783
- file_delete(zOldName);
784
- }
785
- fossil_print("MOVED_FILE %s\n", zOldName);
786
- }
787
- db_finalize(&move);
788
- db_multi_exec("DROP TABLE fmove;");
775
+ if( db_table_exists(db_name("temp"), "fmove") ){
776
+ db_prepare(&move, "SELECT x, y FROM fmove ORDER BY x;");
777
+ while( db_step(&move)==SQLITE_ROW ){
778
+ const char *zOldName = db_column_text(&move, 0);
779
+ const char *zNewName = db_column_text(&move, 1);
780
+ if( !dryRunFlag ){
781
+ if( file_wd_islink(zOldName) ){
782
+ symlink_copy(zOldName, zNewName);
783
+ }else{
784
+ file_copy(zOldName, zNewName);
785
+ }
786
+ file_delete(zOldName);
787
+ }
788
+ fossil_print("MOVED_FILE %s\n", zOldName);
789
+ }
790
+ db_finalize(&move);
791
+ db_multi_exec("DROP TABLE fmove;");
792
+ }
789793
}
790794
791795
/*
792796
** COMMAND: mv
793797
** COMMAND: rename*
@@ -860,11 +864,11 @@
860864
moveFiles = db_get_boolean("mv-rm-files",0);
861865
#else
862866
moveFiles = FOSSIL_MV_RM_FILE;
863867
#endif
864868
}
865
- file_tree_name(zDest, &dest, 1);
869
+ file_tree_name(zDest, &dest, 0, 1);
866870
db_multi_exec(
867871
"UPDATE vfile SET origname=pathname WHERE origname IS NULL;"
868872
);
869873
db_multi_exec(
870874
"CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);"
@@ -872,11 +876,11 @@
872876
if( file_wd_isdir(zDest)!=1 ){
873877
Blob orig;
874878
if( g.argc!=4 ){
875879
usage("OLDNAME NEWNAME");
876880
}
877
- file_tree_name(g.argv[2], &orig, 1);
881
+ file_tree_name(g.argv[2], &orig, 0, 1);
878882
db_multi_exec(
879883
"INSERT INTO mv VALUES(%B,%B)", &orig, &dest
880884
);
881885
}else{
882886
if( blob_eq(&dest, ".") ){
@@ -886,11 +890,11 @@
886890
}
887891
for(i=2; i<g.argc-1; i++){
888892
Blob orig;
889893
char *zOrig;
890894
int nOrig;
891
- file_tree_name(g.argv[i], &orig, 1);
895
+ file_tree_name(g.argv[i], &orig, 0, 1);
892896
zOrig = blob_str(&orig);
893897
nOrig = blob_size(&orig);
894898
db_prepare(&q,
895899
"SELECT pathname FROM vfile"
896900
" WHERE vid=%d"
897901
--- src/add.c
+++ src/add.c
@@ -91,11 +91,11 @@
91
92 if( cachedManifest == -1 ){
93 Blob repo;
94 cachedManifest = db_get_boolean("manifest",0);
95 blob_zero(&repo);
96 if( file_tree_name(g.zRepositoryName, &repo, 0) ){
97 const char *zRepo = blob_str(&repo);
98 azRepo[0] = zRepo;
99 azRepo[1] = mprintf("%s-journal", zRepo);
100 azRepo[2] = mprintf("%s-wal", zRepo);
101 azRepo[3] = mprintf("%s-shm", zRepo);
@@ -201,11 +201,11 @@
201 const char *zReserved; /* Name of a reserved file */
202 Blob repoName; /* Treename of the repository */
203 Stmt loop; /* SQL to loop over all files to add */
204 int (*xCmp)(const char*,const char*);
205
206 if( !file_tree_name(g.zRepositoryName, &repoName, 0) ){
207 blob_zero(&repoName);
208 zRepo = "";
209 }else{
210 zRepo = blob_str(&repoName);
211 }
@@ -307,11 +307,11 @@
307 int isDir;
308 Blob fullName;
309
310 /* file_tree_name() throws a fatal error if g.argv[i] is outside of the
311 ** checkout. */
312 file_tree_name(g.argv[i], &fullName, 1);
313 blob_reset(&fullName);
314
315 file_canonical_name(g.argv[i], &fullName, 0);
316 zName = blob_str(&fullName);
317 isDir = file_wd_isdir(zName);
@@ -365,11 +365,11 @@
365 if( !tableCreated ){
366 db_multi_exec("CREATE TEMP TABLE fremove(x TEXT PRIMARY KEY %s)",
367 filename_collation());
368 tableCreated = 1;
369 }
370 file_canonical_name(zOldName, &fullOldName, 0);
371 db_multi_exec("INSERT INTO fremove VALUES('%q');", blob_str(&fullOldName));
372 blob_reset(&fullOldName);
373 }
374
375 /*
@@ -384,20 +384,22 @@
384 */
385 static void process_files_to_remove(
386 int dryRunFlag /* Zero to actually operate on the file-system. */
387 ){
388 Stmt remove;
389 db_prepare(&remove, "SELECT x FROM fremove ORDER BY x;");
390 while( db_step(&remove)==SQLITE_ROW ){
391 const char *zOldName = db_column_text(&remove, 0);
392 if( !dryRunFlag ){
393 file_delete(zOldName);
394 }
395 fossil_print("DELETED_FILE %s\n", zOldName);
396 }
397 db_finalize(&remove);
398 db_multi_exec("DROP TABLE fremove;");
 
 
399 }
400
401 /*
402 ** COMMAND: rm
403 ** COMMAND: delete
@@ -464,11 +466,11 @@
464 filename_collation());
465 for(i=2; i<g.argc; i++){
466 Blob treeName;
467 char *zTreeName;
468
469 file_tree_name(g.argv[i], &treeName, 1);
470 zTreeName = blob_str(&treeName);
471 db_multi_exec(
472 "INSERT OR IGNORE INTO sfile"
473 " SELECT pathname FROM vfile"
474 " WHERE (pathname=%Q %s"
@@ -631,11 +633,11 @@
631
632 /* We should be done with options.. */
633 verify_all_options();
634
635 /* Fail if unprocessed arguments are present, in case user expect the
636 ** addremove command to accept a list of file or directory.
637 */
638 if( g.argc>2 ){
639 fossil_fatal(
640 "%s: Can only work on the entire checkout, no arguments supported.",
641 g.argv[1]);
@@ -746,12 +748,12 @@
746 if( !tableCreated ){
747 db_multi_exec("CREATE TEMP TABLE fmove(x TEXT PRIMARY KEY %s, y TEXT %s)",
748 filename_collation(), filename_collation());
749 tableCreated = 1;
750 }
751 file_canonical_name(zOldName, &fullOldName, 0);
752 file_canonical_name(zNewName, &fullNewName, 0);
753 db_multi_exec("INSERT INTO fmove VALUES('%q','%q');",
754 blob_str(&fullOldName), blob_str(&fullNewName));
755 blob_reset(&fullNewName);
756 blob_reset(&fullOldName);
757 }
@@ -768,26 +770,28 @@
768 */
769 static void process_files_to_move(
770 int dryRunFlag /* Zero to actually operate on the file-system. */
771 ){
772 Stmt move;
773 db_prepare(&move, "SELECT x, y FROM fmove ORDER BY x;");
774 while( db_step(&move)==SQLITE_ROW ){
775 const char *zOldName = db_column_text(&move, 0);
776 const char *zNewName = db_column_text(&move, 1);
777 if( !dryRunFlag ){
778 if( file_wd_islink(zOldName) ){
779 symlink_copy(zOldName, zNewName);
780 }else{
781 file_copy(zOldName, zNewName);
782 }
783 file_delete(zOldName);
784 }
785 fossil_print("MOVED_FILE %s\n", zOldName);
786 }
787 db_finalize(&move);
788 db_multi_exec("DROP TABLE fmove;");
 
 
789 }
790
791 /*
792 ** COMMAND: mv
793 ** COMMAND: rename*
@@ -860,11 +864,11 @@
860 moveFiles = db_get_boolean("mv-rm-files",0);
861 #else
862 moveFiles = FOSSIL_MV_RM_FILE;
863 #endif
864 }
865 file_tree_name(zDest, &dest, 1);
866 db_multi_exec(
867 "UPDATE vfile SET origname=pathname WHERE origname IS NULL;"
868 );
869 db_multi_exec(
870 "CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);"
@@ -872,11 +876,11 @@
872 if( file_wd_isdir(zDest)!=1 ){
873 Blob orig;
874 if( g.argc!=4 ){
875 usage("OLDNAME NEWNAME");
876 }
877 file_tree_name(g.argv[2], &orig, 1);
878 db_multi_exec(
879 "INSERT INTO mv VALUES(%B,%B)", &orig, &dest
880 );
881 }else{
882 if( blob_eq(&dest, ".") ){
@@ -886,11 +890,11 @@
886 }
887 for(i=2; i<g.argc-1; i++){
888 Blob orig;
889 char *zOrig;
890 int nOrig;
891 file_tree_name(g.argv[i], &orig, 1);
892 zOrig = blob_str(&orig);
893 nOrig = blob_size(&orig);
894 db_prepare(&q,
895 "SELECT pathname FROM vfile"
896 " WHERE vid=%d"
897
--- src/add.c
+++ src/add.c
@@ -91,11 +91,11 @@
91
92 if( cachedManifest == -1 ){
93 Blob repo;
94 cachedManifest = db_get_boolean("manifest",0);
95 blob_zero(&repo);
96 if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
97 const char *zRepo = blob_str(&repo);
98 azRepo[0] = zRepo;
99 azRepo[1] = mprintf("%s-journal", zRepo);
100 azRepo[2] = mprintf("%s-wal", zRepo);
101 azRepo[3] = mprintf("%s-shm", zRepo);
@@ -201,11 +201,11 @@
201 const char *zReserved; /* Name of a reserved file */
202 Blob repoName; /* Treename of the repository */
203 Stmt loop; /* SQL to loop over all files to add */
204 int (*xCmp)(const char*,const char*);
205
206 if( !file_tree_name(g.zRepositoryName, &repoName, 0, 0) ){
207 blob_zero(&repoName);
208 zRepo = "";
209 }else{
210 zRepo = blob_str(&repoName);
211 }
@@ -307,11 +307,11 @@
307 int isDir;
308 Blob fullName;
309
310 /* file_tree_name() throws a fatal error if g.argv[i] is outside of the
311 ** checkout. */
312 file_tree_name(g.argv[i], &fullName, 0, 1);
313 blob_reset(&fullName);
314
315 file_canonical_name(g.argv[i], &fullName, 0);
316 zName = blob_str(&fullName);
317 isDir = file_wd_isdir(zName);
@@ -365,11 +365,11 @@
365 if( !tableCreated ){
366 db_multi_exec("CREATE TEMP TABLE fremove(x TEXT PRIMARY KEY %s)",
367 filename_collation());
368 tableCreated = 1;
369 }
370 file_tree_name(zOldName, &fullOldName, 1, 1);
371 db_multi_exec("INSERT INTO fremove VALUES('%q');", blob_str(&fullOldName));
372 blob_reset(&fullOldName);
373 }
374
375 /*
@@ -384,20 +384,22 @@
384 */
385 static void process_files_to_remove(
386 int dryRunFlag /* Zero to actually operate on the file-system. */
387 ){
388 Stmt remove;
389 if( db_table_exists(db_name("temp"), "fremove") ){
390 db_prepare(&remove, "SELECT x FROM fremove ORDER BY x;");
391 while( db_step(&remove)==SQLITE_ROW ){
392 const char *zOldName = db_column_text(&remove, 0);
393 if( !dryRunFlag ){
394 file_delete(zOldName);
395 }
396 fossil_print("DELETED_FILE %s\n", zOldName);
397 }
398 db_finalize(&remove);
399 db_multi_exec("DROP TABLE fremove;");
400 }
401 }
402
403 /*
404 ** COMMAND: rm
405 ** COMMAND: delete
@@ -464,11 +466,11 @@
466 filename_collation());
467 for(i=2; i<g.argc; i++){
468 Blob treeName;
469 char *zTreeName;
470
471 file_tree_name(g.argv[i], &treeName, 0, 1);
472 zTreeName = blob_str(&treeName);
473 db_multi_exec(
474 "INSERT OR IGNORE INTO sfile"
475 " SELECT pathname FROM vfile"
476 " WHERE (pathname=%Q %s"
@@ -631,11 +633,11 @@
633
634 /* We should be done with options.. */
635 verify_all_options();
636
637 /* Fail if unprocessed arguments are present, in case user expect the
638 ** addremove command to accept a list of file or directory.
639 */
640 if( g.argc>2 ){
641 fossil_fatal(
642 "%s: Can only work on the entire checkout, no arguments supported.",
643 g.argv[1]);
@@ -746,12 +748,12 @@
748 if( !tableCreated ){
749 db_multi_exec("CREATE TEMP TABLE fmove(x TEXT PRIMARY KEY %s, y TEXT %s)",
750 filename_collation(), filename_collation());
751 tableCreated = 1;
752 }
753 file_tree_name(zOldName, &fullOldName, 1, 1);
754 file_tree_name(zNewName, &fullNewName, 1, 1);
755 db_multi_exec("INSERT INTO fmove VALUES('%q','%q');",
756 blob_str(&fullOldName), blob_str(&fullNewName));
757 blob_reset(&fullNewName);
758 blob_reset(&fullOldName);
759 }
@@ -768,26 +770,28 @@
770 */
771 static void process_files_to_move(
772 int dryRunFlag /* Zero to actually operate on the file-system. */
773 ){
774 Stmt move;
775 if( db_table_exists(db_name("temp"), "fmove") ){
776 db_prepare(&move, "SELECT x, y FROM fmove ORDER BY x;");
777 while( db_step(&move)==SQLITE_ROW ){
778 const char *zOldName = db_column_text(&move, 0);
779 const char *zNewName = db_column_text(&move, 1);
780 if( !dryRunFlag ){
781 if( file_wd_islink(zOldName) ){
782 symlink_copy(zOldName, zNewName);
783 }else{
784 file_copy(zOldName, zNewName);
785 }
786 file_delete(zOldName);
787 }
788 fossil_print("MOVED_FILE %s\n", zOldName);
789 }
790 db_finalize(&move);
791 db_multi_exec("DROP TABLE fmove;");
792 }
793 }
794
795 /*
796 ** COMMAND: mv
797 ** COMMAND: rename*
@@ -860,11 +864,11 @@
864 moveFiles = db_get_boolean("mv-rm-files",0);
865 #else
866 moveFiles = FOSSIL_MV_RM_FILE;
867 #endif
868 }
869 file_tree_name(zDest, &dest, 0, 1);
870 db_multi_exec(
871 "UPDATE vfile SET origname=pathname WHERE origname IS NULL;"
872 );
873 db_multi_exec(
874 "CREATE TEMP TABLE mv(f TEXT UNIQUE ON CONFLICT IGNORE, t TEXT);"
@@ -872,11 +876,11 @@
876 if( file_wd_isdir(zDest)!=1 ){
877 Blob orig;
878 if( g.argc!=4 ){
879 usage("OLDNAME NEWNAME");
880 }
881 file_tree_name(g.argv[2], &orig, 0, 1);
882 db_multi_exec(
883 "INSERT INTO mv VALUES(%B,%B)", &orig, &dest
884 );
885 }else{
886 if( blob_eq(&dest, ".") ){
@@ -886,11 +890,11 @@
890 }
891 for(i=2; i<g.argc-1; i++){
892 Blob orig;
893 char *zOrig;
894 int nOrig;
895 file_tree_name(g.argv[i], &orig, 0, 1);
896 zOrig = blob_str(&orig);
897 nOrig = blob_size(&orig);
898 db_prepare(&q,
899 "SELECT pathname FROM vfile"
900 " WHERE vid=%d"
901
+2 -2
--- src/blob.c
+++ src/blob.c
@@ -300,11 +300,11 @@
300300
** Return a pointer to a null-terminated string for a blob.
301301
*/
302302
char *blob_str(Blob *p){
303303
blob_is_init(p);
304304
if( p->nUsed==0 ){
305
- blob_append(p, "", 1);
305
+ blob_append(p, "", 1); /* NOTE: Changes nUsed. */
306306
p->nUsed = 0;
307307
}
308308
if( p->aData[p->nUsed]!=0 ){
309309
blob_materialize(p);
310310
}
@@ -839,11 +839,11 @@
839839
#if defined(_WIN32)
840840
fflush(stdout);
841841
_setmode(_fileno(stdout), _O_TEXT);
842842
#endif
843843
}else{
844
- file_mkfolder(zFilename, 1);
844
+ file_mkfolder(zFilename, 1, 0);
845845
out = fossil_fopen(zFilename, "wb");
846846
if( out==0 ){
847847
fossil_fatal_recursive("unable to open file \"%s\" for writing",
848848
zFilename);
849849
return 0;
850850
--- src/blob.c
+++ src/blob.c
@@ -300,11 +300,11 @@
300 ** Return a pointer to a null-terminated string for a blob.
301 */
302 char *blob_str(Blob *p){
303 blob_is_init(p);
304 if( p->nUsed==0 ){
305 blob_append(p, "", 1);
306 p->nUsed = 0;
307 }
308 if( p->aData[p->nUsed]!=0 ){
309 blob_materialize(p);
310 }
@@ -839,11 +839,11 @@
839 #if defined(_WIN32)
840 fflush(stdout);
841 _setmode(_fileno(stdout), _O_TEXT);
842 #endif
843 }else{
844 file_mkfolder(zFilename, 1);
845 out = fossil_fopen(zFilename, "wb");
846 if( out==0 ){
847 fossil_fatal_recursive("unable to open file \"%s\" for writing",
848 zFilename);
849 return 0;
850
--- src/blob.c
+++ src/blob.c
@@ -300,11 +300,11 @@
300 ** Return a pointer to a null-terminated string for a blob.
301 */
302 char *blob_str(Blob *p){
303 blob_is_init(p);
304 if( p->nUsed==0 ){
305 blob_append(p, "", 1); /* NOTE: Changes nUsed. */
306 p->nUsed = 0;
307 }
308 if( p->aData[p->nUsed]!=0 ){
309 blob_materialize(p);
310 }
@@ -839,11 +839,11 @@
839 #if defined(_WIN32)
840 fflush(stdout);
841 _setmode(_fileno(stdout), _O_TEXT);
842 #endif
843 }else{
844 file_mkfolder(zFilename, 1, 0);
845 out = fossil_fopen(zFilename, "wb");
846 if( out==0 ){
847 fossil_fatal_recursive("unable to open file \"%s\" for writing",
848 zFilename);
849 return 0;
850
+5 -5
--- src/checkin.c
+++ src/checkin.c
@@ -46,11 +46,11 @@
4646
int i;
4747
4848
blob_zero(&where);
4949
for(i=2; i<g.argc; i++){
5050
Blob fname;
51
- file_tree_name(g.argv[i], &fname, 1);
51
+ file_tree_name(g.argv[i], &fname, 0, 1);
5252
zName = blob_str(&fname);
5353
if( fossil_strcmp(zName, ".")==0 ){
5454
blob_reset(&where);
5555
break;
5656
}
@@ -296,11 +296,11 @@
296296
297297
/* Handle given file names */
298298
blob_zero(&where);
299299
for(i=2; i<g.argc; i++){
300300
Blob fname;
301
- file_tree_name(g.argv[i], &fname, 1);
301
+ file_tree_name(g.argv[i], &fname, 0, 1);
302302
zName = blob_str(&fname);
303303
if( fossil_strcmp(zName, ".")==0 ){
304304
blob_reset(&where);
305305
break;
306306
}
@@ -409,11 +409,11 @@
409409
}
410410
verify_all_options();
411411
blob_zero(&where);
412412
for(i=2; i<g.argc; i++){
413413
Blob fname;
414
- file_tree_name(g.argv[i], &fname, 1);
414
+ file_tree_name(g.argv[i], &fname, 0, 1);
415415
zName = blob_str(&fname);
416416
if( fossil_strcmp(zName, ".")==0 ){
417417
blob_reset(&where);
418418
break;
419419
}
@@ -741,11 +741,11 @@
741741
"SELECT %Q || x FROM sfile"
742742
" WHERE x NOT IN (%s)"
743743
" ORDER BY 1",
744744
g.zLocalRoot, fossil_all_reserved_names(0)
745745
);
746
- if( file_tree_name(g.zRepositoryName, &repo, 0) ){
746
+ if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
747747
db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
748748
}
749749
db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
750750
while( db_step(&q)==SQLITE_ROW ){
751751
const char *zName = db_column_text(&q, 0);
@@ -1037,11 +1037,11 @@
10371037
10381038
blob_zero(&fname);
10391039
bag_init(&toCommit);
10401040
for(ii=2; ii<g.argc; ii++){
10411041
int cnt = 0;
1042
- file_tree_name(g.argv[ii], &fname, 1);
1042
+ file_tree_name(g.argv[ii], &fname, 0, 1);
10431043
if( fossil_strcmp(blob_str(&fname),".")==0 ){
10441044
bag_clear(&toCommit);
10451045
return result;
10461046
}
10471047
db_prepare(&q,
10481048
--- src/checkin.c
+++ src/checkin.c
@@ -46,11 +46,11 @@
46 int i;
47
48 blob_zero(&where);
49 for(i=2; i<g.argc; i++){
50 Blob fname;
51 file_tree_name(g.argv[i], &fname, 1);
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ){
54 blob_reset(&where);
55 break;
56 }
@@ -296,11 +296,11 @@
296
297 /* Handle given file names */
298 blob_zero(&where);
299 for(i=2; i<g.argc; i++){
300 Blob fname;
301 file_tree_name(g.argv[i], &fname, 1);
302 zName = blob_str(&fname);
303 if( fossil_strcmp(zName, ".")==0 ){
304 blob_reset(&where);
305 break;
306 }
@@ -409,11 +409,11 @@
409 }
410 verify_all_options();
411 blob_zero(&where);
412 for(i=2; i<g.argc; i++){
413 Blob fname;
414 file_tree_name(g.argv[i], &fname, 1);
415 zName = blob_str(&fname);
416 if( fossil_strcmp(zName, ".")==0 ){
417 blob_reset(&where);
418 break;
419 }
@@ -741,11 +741,11 @@
741 "SELECT %Q || x FROM sfile"
742 " WHERE x NOT IN (%s)"
743 " ORDER BY 1",
744 g.zLocalRoot, fossil_all_reserved_names(0)
745 );
746 if( file_tree_name(g.zRepositoryName, &repo, 0) ){
747 db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
748 }
749 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
750 while( db_step(&q)==SQLITE_ROW ){
751 const char *zName = db_column_text(&q, 0);
@@ -1037,11 +1037,11 @@
1037
1038 blob_zero(&fname);
1039 bag_init(&toCommit);
1040 for(ii=2; ii<g.argc; ii++){
1041 int cnt = 0;
1042 file_tree_name(g.argv[ii], &fname, 1);
1043 if( fossil_strcmp(blob_str(&fname),".")==0 ){
1044 bag_clear(&toCommit);
1045 return result;
1046 }
1047 db_prepare(&q,
1048
--- src/checkin.c
+++ src/checkin.c
@@ -46,11 +46,11 @@
46 int i;
47
48 blob_zero(&where);
49 for(i=2; i<g.argc; i++){
50 Blob fname;
51 file_tree_name(g.argv[i], &fname, 0, 1);
52 zName = blob_str(&fname);
53 if( fossil_strcmp(zName, ".")==0 ){
54 blob_reset(&where);
55 break;
56 }
@@ -296,11 +296,11 @@
296
297 /* Handle given file names */
298 blob_zero(&where);
299 for(i=2; i<g.argc; i++){
300 Blob fname;
301 file_tree_name(g.argv[i], &fname, 0, 1);
302 zName = blob_str(&fname);
303 if( fossil_strcmp(zName, ".")==0 ){
304 blob_reset(&where);
305 break;
306 }
@@ -409,11 +409,11 @@
409 }
410 verify_all_options();
411 blob_zero(&where);
412 for(i=2; i<g.argc; i++){
413 Blob fname;
414 file_tree_name(g.argv[i], &fname, 0, 1);
415 zName = blob_str(&fname);
416 if( fossil_strcmp(zName, ".")==0 ){
417 blob_reset(&where);
418 break;
419 }
@@ -741,11 +741,11 @@
741 "SELECT %Q || x FROM sfile"
742 " WHERE x NOT IN (%s)"
743 " ORDER BY 1",
744 g.zLocalRoot, fossil_all_reserved_names(0)
745 );
746 if( file_tree_name(g.zRepositoryName, &repo, 0, 0) ){
747 db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
748 }
749 db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
750 while( db_step(&q)==SQLITE_ROW ){
751 const char *zName = db_column_text(&q, 0);
@@ -1037,11 +1037,11 @@
1037
1038 blob_zero(&fname);
1039 bag_init(&toCommit);
1040 for(ii=2; ii<g.argc; ii++){
1041 int cnt = 0;
1042 file_tree_name(g.argv[ii], &fname, 0, 1);
1043 if( fossil_strcmp(blob_str(&fname),".")==0 ){
1044 bag_clear(&toCommit);
1045 return result;
1046 }
1047 db_prepare(&q,
1048
+2 -5
--- src/db.c
+++ src/db.c
@@ -1258,11 +1258,12 @@
12581258
** Return the name of the database "localdb", "configdb", or "repository".
12591259
*/
12601260
const char *db_name(const char *zDb){
12611261
assert( fossil_strcmp(zDb,"localdb")==0
12621262
|| fossil_strcmp(zDb,"configdb")==0
1263
- || fossil_strcmp(zDb,"repository")==0 );
1263
+ || fossil_strcmp(zDb,"repository")==0
1264
+ || fossil_strcmp(zDb,"temp")==0 );
12641265
if( fossil_strcmp(zDb, g.zMainDbType)==0 ) zDb = "main";
12651266
return zDb;
12661267
}
12671268
12681269
/*
@@ -2217,12 +2218,10 @@
22172218
void cmd_open(void){
22182219
int emptyFlag;
22192220
int keepFlag;
22202221
int forceMissingFlag;
22212222
int allowNested;
2222
- char **oldArgv;
2223
- int oldArgc;
22242223
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
22252224
22262225
url_proxy_options();
22272226
emptyFlag = find_option("empty",0,0)!=0;
22282227
keepFlag = find_option("keep",0,0)!=0;
@@ -2268,12 +2267,10 @@
22682267
db_delete_on_failure(LOCALDB_NAME);
22692268
db_open_local(0);
22702269
db_lset("repository", g.argv[2]);
22712270
db_record_repository_filename(g.argv[2]);
22722271
db_lset_int("checkout", 0);
2273
- oldArgv = g.argv;
2274
- oldArgc = g.argc;
22752272
azNewArgv[0] = g.argv[0];
22762273
g.argv = azNewArgv;
22772274
if( !emptyFlag ){
22782275
g.argc = 3;
22792276
if( g.zOpenRevision ){
22802277
--- src/db.c
+++ src/db.c
@@ -1258,11 +1258,12 @@
1258 ** Return the name of the database "localdb", "configdb", or "repository".
1259 */
1260 const char *db_name(const char *zDb){
1261 assert( fossil_strcmp(zDb,"localdb")==0
1262 || fossil_strcmp(zDb,"configdb")==0
1263 || fossil_strcmp(zDb,"repository")==0 );
 
1264 if( fossil_strcmp(zDb, g.zMainDbType)==0 ) zDb = "main";
1265 return zDb;
1266 }
1267
1268 /*
@@ -2217,12 +2218,10 @@
2217 void cmd_open(void){
2218 int emptyFlag;
2219 int keepFlag;
2220 int forceMissingFlag;
2221 int allowNested;
2222 char **oldArgv;
2223 int oldArgc;
2224 static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
2225
2226 url_proxy_options();
2227 emptyFlag = find_option("empty",0,0)!=0;
2228 keepFlag = find_option("keep",0,0)!=0;
@@ -2268,12 +2267,10 @@
2268 db_delete_on_failure(LOCALDB_NAME);
2269 db_open_local(0);
2270 db_lset("repository", g.argv[2]);
2271 db_record_repository_filename(g.argv[2]);
2272 db_lset_int("checkout", 0);
2273 oldArgv = g.argv;
2274 oldArgc = g.argc;
2275 azNewArgv[0] = g.argv[0];
2276 g.argv = azNewArgv;
2277 if( !emptyFlag ){
2278 g.argc = 3;
2279 if( g.zOpenRevision ){
2280
--- src/db.c
+++ src/db.c
@@ -1258,11 +1258,12 @@
1258 ** Return the name of the database "localdb", "configdb", or "repository".
1259 */
1260 const char *db_name(const char *zDb){
1261 assert( fossil_strcmp(zDb,"localdb")==0
1262 || fossil_strcmp(zDb,"configdb")==0
1263 || fossil_strcmp(zDb,"repository")==0
1264 || fossil_strcmp(zDb,"temp")==0 );
1265 if( fossil_strcmp(zDb, g.zMainDbType)==0 ) zDb = "main";
1266 return zDb;
1267 }
1268
1269 /*
@@ -2217,12 +2218,10 @@
2218 void cmd_open(void){
2219 int emptyFlag;
2220 int keepFlag;
2221 int forceMissingFlag;
2222 int allowNested;
 
 
2223 static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
2224
2225 url_proxy_options();
2226 emptyFlag = find_option("empty",0,0)!=0;
2227 keepFlag = find_option("keep",0,0)!=0;
@@ -2268,12 +2267,10 @@
2267 db_delete_on_failure(LOCALDB_NAME);
2268 db_open_local(0);
2269 db_lset("repository", g.argv[2]);
2270 db_record_repository_filename(g.argv[2]);
2271 db_lset_int("checkout", 0);
 
 
2272 azNewArgv[0] = g.argv[0];
2273 g.argv = azNewArgv;
2274 if( !emptyFlag ){
2275 g.argc = 3;
2276 if( g.zOpenRevision ){
2277
+12 -29
--- src/descendants.c
+++ src/descendants.c
@@ -255,39 +255,22 @@
255255
/*
256256
** Load the record ID rid and up to N-1 closest descendants into
257257
** the "ok" table.
258258
*/
259259
void compute_descendants(int rid, int N){
260
- Bag seen;
261
- PQueue queue;
262
- Stmt ins;
263
- Stmt q;
264
-
265
- bag_init(&seen);
266
- pqueuex_init(&queue);
267
- bag_insert(&seen, rid);
268
- pqueuex_insert(&queue, rid, 0.0, 0);
269
- db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
270
- db_prepare(&q, "SELECT cid, mtime FROM plink WHERE pid=:rid");
271
- while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
272
- db_bind_int(&ins, ":rid", rid);
273
- db_step(&ins);
274
- db_reset(&ins);
275
- db_bind_int(&q, ":rid", rid);
276
- while( db_step(&q)==SQLITE_ROW ){
277
- int pid = db_column_int(&q, 0);
278
- double mtime = db_column_double(&q, 1);
279
- if( bag_insert(&seen, pid) ){
280
- pqueuex_insert(&queue, pid, mtime, 0);
281
- }
282
- }
283
- db_reset(&q);
284
- }
285
- bag_clear(&seen);
286
- pqueuex_clear(&queue);
287
- db_finalize(&ins);
288
- db_finalize(&q);
260
+ db_multi_exec(
261
+ "WITH RECURSIVE"
262
+ " dx(rid,mtime) AS ("
263
+ " SELECT %d, 0"
264
+ " UNION"
265
+ " SELECT plink.cid, plink.mtime FROM dx, plink"
266
+ " WHERE plink.pid=dx.rid"
267
+ " ORDER BY 2"
268
+ " )"
269
+ "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
270
+ rid, N
271
+ );
289272
}
290273
291274
/*
292275
** COMMAND: descendants*
293276
**
294277
--- src/descendants.c
+++ src/descendants.c
@@ -255,39 +255,22 @@
255 /*
256 ** Load the record ID rid and up to N-1 closest descendants into
257 ** the "ok" table.
258 */
259 void compute_descendants(int rid, int N){
260 Bag seen;
261 PQueue queue;
262 Stmt ins;
263 Stmt q;
264
265 bag_init(&seen);
266 pqueuex_init(&queue);
267 bag_insert(&seen, rid);
268 pqueuex_insert(&queue, rid, 0.0, 0);
269 db_prepare(&ins, "INSERT OR IGNORE INTO ok VALUES(:rid)");
270 db_prepare(&q, "SELECT cid, mtime FROM plink WHERE pid=:rid");
271 while( (N--)>0 && (rid = pqueuex_extract(&queue, 0))!=0 ){
272 db_bind_int(&ins, ":rid", rid);
273 db_step(&ins);
274 db_reset(&ins);
275 db_bind_int(&q, ":rid", rid);
276 while( db_step(&q)==SQLITE_ROW ){
277 int pid = db_column_int(&q, 0);
278 double mtime = db_column_double(&q, 1);
279 if( bag_insert(&seen, pid) ){
280 pqueuex_insert(&queue, pid, mtime, 0);
281 }
282 }
283 db_reset(&q);
284 }
285 bag_clear(&seen);
286 pqueuex_clear(&queue);
287 db_finalize(&ins);
288 db_finalize(&q);
289 }
290
291 /*
292 ** COMMAND: descendants*
293 **
294
--- src/descendants.c
+++ src/descendants.c
@@ -255,39 +255,22 @@
255 /*
256 ** Load the record ID rid and up to N-1 closest descendants into
257 ** the "ok" table.
258 */
259 void compute_descendants(int rid, int N){
260 db_multi_exec(
261 "WITH RECURSIVE"
262 " dx(rid,mtime) AS ("
263 " SELECT %d, 0"
264 " UNION"
265 " SELECT plink.cid, plink.mtime FROM dx, plink"
266 " WHERE plink.pid=dx.rid"
267 " ORDER BY 2"
268 " )"
269 "INSERT OR IGNORE INTO ok SELECT rid FROM dx LIMIT %d",
270 rid, N
271 );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272 }
273
274 /*
275 ** COMMAND: descendants*
276 **
277
+1 -1
--- src/diff.c
+++ src/diff.c
@@ -2457,11 +2457,11 @@
24572457
verify_all_options();
24582458
24592459
if( g.argc<3 ) {
24602460
usage("FILENAME");
24612461
}
2462
- file_tree_name(g.argv[2], &treename, 1);
2462
+ file_tree_name(g.argv[2], &treename, 0, 1);
24632463
zFilename = blob_str(&treename);
24642464
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
24652465
if( fnid==0 ){
24662466
fossil_fatal("no such file: %s", zFilename);
24672467
}
24682468
--- src/diff.c
+++ src/diff.c
@@ -2457,11 +2457,11 @@
2457 verify_all_options();
2458
2459 if( g.argc<3 ) {
2460 usage("FILENAME");
2461 }
2462 file_tree_name(g.argv[2], &treename, 1);
2463 zFilename = blob_str(&treename);
2464 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2465 if( fnid==0 ){
2466 fossil_fatal("no such file: %s", zFilename);
2467 }
2468
--- src/diff.c
+++ src/diff.c
@@ -2457,11 +2457,11 @@
2457 verify_all_options();
2458
2459 if( g.argc<3 ) {
2460 usage("FILENAME");
2461 }
2462 file_tree_name(g.argv[2], &treename, 0, 1);
2463 zFilename = blob_str(&treename);
2464 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2465 if( fnid==0 ){
2466 fossil_fatal("no such file: %s", zFilename);
2467 }
2468
+1 -1
--- src/diff.c
+++ src/diff.c
@@ -2457,11 +2457,11 @@
24572457
verify_all_options();
24582458
24592459
if( g.argc<3 ) {
24602460
usage("FILENAME");
24612461
}
2462
- file_tree_name(g.argv[2], &treename, 1);
2462
+ file_tree_name(g.argv[2], &treename, 0, 1);
24632463
zFilename = blob_str(&treename);
24642464
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
24652465
if( fnid==0 ){
24662466
fossil_fatal("no such file: %s", zFilename);
24672467
}
24682468
--- src/diff.c
+++ src/diff.c
@@ -2457,11 +2457,11 @@
2457 verify_all_options();
2458
2459 if( g.argc<3 ) {
2460 usage("FILENAME");
2461 }
2462 file_tree_name(g.argv[2], &treename, 1);
2463 zFilename = blob_str(&treename);
2464 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2465 if( fnid==0 ){
2466 fossil_fatal("no such file: %s", zFilename);
2467 }
2468
--- src/diff.c
+++ src/diff.c
@@ -2457,11 +2457,11 @@
2457 verify_all_options();
2458
2459 if( g.argc<3 ) {
2460 usage("FILENAME");
2461 }
2462 file_tree_name(g.argv[2], &treename, 0, 1);
2463 zFilename = blob_str(&treename);
2464 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
2465 if( fnid==0 ){
2466 fossil_fatal("no such file: %s", zFilename);
2467 }
2468
+3 -3
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -298,11 +298,11 @@
298298
){
299299
Blob fname;
300300
Blob content;
301301
int isLink;
302302
int isBin;
303
- file_tree_name(zFileTreeName, &fname, 1);
303
+ file_tree_name(zFileTreeName, &fname, 0, 1);
304304
historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305305
fIncludeBinary ? 0 : &isBin, 0);
306306
if( !isLink != !file_wd_islink(zFrom) ){
307307
fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308308
}else{
@@ -454,11 +454,11 @@
454454
Blob fname;
455455
Blob v1, v2;
456456
int isLink1, isLink2;
457457
int isBin1, isBin2;
458458
if( diffFlags & DIFF_BRIEF ) return;
459
- file_tree_name(zFileTreeName, &fname, 1);
459
+ file_tree_name(zFileTreeName, &fname, 0, 1);
460460
zName = blob_str(&fname);
461461
historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
462462
fIncludeBinary ? 0 : &isBin1, 0);
463463
historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464464
fIncludeBinary ? 0 : &isBin2, 0);
@@ -662,11 +662,11 @@
662662
fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
663663
}else{
664664
#if defined(FOSSIL_ENABLE_TCL)
665665
Th_FossilInit(TH_INIT_DEFAULT);
666666
if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
667
- blob_size(&script), 1, 0)==TCL_OK ){
667
+ blob_size(&script), 1, 1, 0)==TCL_OK ){
668668
blob_reset(&script);
669669
return;
670670
}
671671
/*
672672
* If evaluation of the Tcl script fails, the reason may be that Tk
673673
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -298,11 +298,11 @@
298 ){
299 Blob fname;
300 Blob content;
301 int isLink;
302 int isBin;
303 file_tree_name(zFileTreeName, &fname, 1);
304 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305 fIncludeBinary ? 0 : &isBin, 0);
306 if( !isLink != !file_wd_islink(zFrom) ){
307 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308 }else{
@@ -454,11 +454,11 @@
454 Blob fname;
455 Blob v1, v2;
456 int isLink1, isLink2;
457 int isBin1, isBin2;
458 if( diffFlags & DIFF_BRIEF ) return;
459 file_tree_name(zFileTreeName, &fname, 1);
460 zName = blob_str(&fname);
461 historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
462 fIncludeBinary ? 0 : &isBin1, 0);
463 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464 fIncludeBinary ? 0 : &isBin2, 0);
@@ -662,11 +662,11 @@
662 fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
663 }else{
664 #if defined(FOSSIL_ENABLE_TCL)
665 Th_FossilInit(TH_INIT_DEFAULT);
666 if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
667 blob_size(&script), 1, 0)==TCL_OK ){
668 blob_reset(&script);
669 return;
670 }
671 /*
672 * If evaluation of the Tcl script fails, the reason may be that Tk
673
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -298,11 +298,11 @@
298 ){
299 Blob fname;
300 Blob content;
301 int isLink;
302 int isBin;
303 file_tree_name(zFileTreeName, &fname, 0, 1);
304 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0,
305 fIncludeBinary ? 0 : &isBin, 0);
306 if( !isLink != !file_wd_islink(zFrom) ){
307 fossil_print("%s",DIFF_CANNOT_COMPUTE_SYMLINK);
308 }else{
@@ -454,11 +454,11 @@
454 Blob fname;
455 Blob v1, v2;
456 int isLink1, isLink2;
457 int isBin1, isBin2;
458 if( diffFlags & DIFF_BRIEF ) return;
459 file_tree_name(zFileTreeName, &fname, 0, 1);
460 zName = blob_str(&fname);
461 historical_version_of_file(zFrom, zName, &v1, &isLink1, 0,
462 fIncludeBinary ? 0 : &isBin1, 0);
463 historical_version_of_file(zTo, zName, &v2, &isLink2, 0,
464 fIncludeBinary ? 0 : &isBin2, 0);
@@ -662,11 +662,11 @@
662 fossil_print("To see diff, run: tclsh \"%s\"\n", zTempFile);
663 }else{
664 #if defined(FOSSIL_ENABLE_TCL)
665 Th_FossilInit(TH_INIT_DEFAULT);
666 if( evaluateTclWithEvents(g.interp, &g.tcl, blob_str(&script),
667 blob_size(&script), 1, 1, 0)==TCL_OK ){
668 blob_reset(&script);
669 return;
670 }
671 /*
672 * If evaluation of the Tcl script fails, the reason may be that Tk
673
+90 -21
--- src/file.c
+++ src/file.c
@@ -57,10 +57,16 @@
5757
i64 st_size;
5858
i64 st_mtime;
5959
int st_mode;
6060
};
6161
#endif
62
+
63
+#if defined(_WIN32) || defined(__CYGWIN__)
64
+# define fossil_isdirsep(a) (((a) == '/') || ((a) == '\\'))
65
+#else
66
+# define fossil_isdirsep(a) ((a) == '/')
67
+#endif
6268
6369
#endif /* INTERFACE */
6470
6571
#if !defined(_WIN32) || !(defined(__MSVCRT__) || defined(_MSC_VER))
6672
# define fossilStat stat
@@ -370,16 +376,32 @@
370376
** Return the tail of a file pathname. The tail is the last component
371377
** of the path. For example, the tail of "/a/b/c.d" is "c.d".
372378
*/
373379
const char *file_tail(const char *z){
374380
const char *zTail = z;
381
+ if( !zTail ) return 0;
375382
while( z[0] ){
376
- if( z[0]=='/' ) zTail = &z[1];
383
+ if( fossil_isdirsep(z[0]) ) zTail = &z[1];
377384
z++;
378385
}
379386
return zTail;
380387
}
388
+
389
+/*
390
+** Return the directory of a file path name. The directory is all components
391
+** except the last one. For example, the directory of "/a/b/c.d" is "/a/b".
392
+** If there is no directory, NULL is returned; otherwise, the returned memory
393
+** should be freed via fossil_free().
394
+*/
395
+char *file_dirname(const char *z){
396
+ const char *zTail = file_tail(z);
397
+ if( zTail && zTail!=z ){
398
+ return mprintf("%.*s", (int)(zTail-z-1), z);
399
+ }else{
400
+ return 0;
401
+ }
402
+}
381403
382404
/*
383405
** Copy the content of a file from one place to another.
384406
*/
385407
void file_copy(const char *zFrom, const char *zTo){
@@ -386,11 +408,11 @@
386408
FILE *in, *out;
387409
int got;
388410
char zBuf[8192];
389411
in = fossil_fopen(zFrom, "rb");
390412
if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
391
- file_mkfolder(zTo, 0);
413
+ file_mkfolder(zTo, 0, 0);
392414
out = fossil_fopen(zTo, "wb");
393415
if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
394416
while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
395417
fwrite(zBuf, 1, got, out);
396418
}
@@ -530,13 +552,16 @@
530552
}
531553
532554
/*
533555
** Create the tree of directories in which zFilename belongs, if that sequence
534556
** of directories does not already exist.
557
+**
558
+** On success, return zero. On error, return errorReturn if positive, otherwise
559
+** print an error message and abort.
535560
*/
536
-void file_mkfolder(const char *zFilename, int forceFlag){
537
- int i, nName;
561
+int file_mkfolder(const char *zFilename, int forceFlag, int errorReturn){
562
+ int i, nName, rc = 0;
538563
char *zName;
539564
540565
nName = strlen(zFilename);
541566
zName = mprintf("%s", zFilename);
542567
nName = file_simplify_name(zName, nName, 0);
@@ -550,20 +575,24 @@
550575
** C: in this example.
551576
*/
552577
if( !(i==2 && zName[1]==':') ){
553578
#endif
554579
if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
555
- fossil_fatal_recursive("unable to create directory %s", zName);
556
- return;
580
+ if (errorReturn <= 0) {
581
+ fossil_fatal_recursive("unable to create directory %s", zName);
582
+ }
583
+ rc = errorReturn;
584
+ break;
557585
}
558586
#if defined(_WIN32) || defined(__CYGWIN__)
559587
}
560588
#endif
561589
zName[i] = '/';
562590
}
563591
}
564592
free(zName);
593
+ return rc;
565594
}
566595
567596
/*
568597
** Removes the directory named in the argument, if it exists. The directory
569598
** must be empty and cannot be the current directory or the root directory.
@@ -810,15 +839,14 @@
810839
/*
811840
** Return true if zPath is an absolute pathname. Return false
812841
** if it is relative.
813842
*/
814843
int file_is_absolute_path(const char *zPath){
815
- if( zPath[0]=='/'
844
+ if( fossil_isdirsep(zPath[0])
816845
#if defined(_WIN32) || defined(__CYGWIN__)
817
- || zPath[0]=='\\'
818846
|| (fossil_isalpha(zPath[0]) && zPath[1]==':'
819
- && (zPath[2]=='\\' || zPath[2]=='/' || zPath[2]=='\0'))
847
+ && (fossil_isdirsep(zPath[2]) || zPath[2]=='\0'))
820848
#endif
821849
){
822850
return 1;
823851
}else{
824852
return 0;
@@ -1022,18 +1050,25 @@
10221050
blob_reset(&x);
10231051
}
10241052
}
10251053
10261054
/*
1027
-** Compute a pathname for a file relative to the root of the local
1028
-** tree. Return TRUE on success. On failure, print and error
1029
-** message and quit if the errFatal flag is true. If errFatal is
1030
-** false, then simply return 0.
1031
-**
1032
-** The root of the tree is defined by the g.zLocalRoot variable.
1055
+** Compute a full path name for a file in the local tree. If
1056
+** the absolute flag is non-zero, the computed path will be
1057
+** absolute, starting with the root path of the local tree;
1058
+** otherwise, it will be relative to the root of the local
1059
+** tree. In both cases, the root of the local tree is defined
1060
+** by the g.zLocalRoot variable. Return TRUE on success. On
1061
+** failure, print and error message and quit if the errFatal
1062
+** flag is true. If errFatal is false, then simply return 0.
10331063
*/
1034
-int file_tree_name(const char *zOrigName, Blob *pOut, int errFatal){
1064
+int file_tree_name(
1065
+ const char *zOrigName,
1066
+ Blob *pOut,
1067
+ int absolute,
1068
+ int errFatal
1069
+){
10351070
Blob localRoot;
10361071
int nLocalRoot;
10371072
char *zLocalRoot;
10381073
Blob full;
10391074
int nFull;
@@ -1040,12 +1075,31 @@
10401075
char *zFull;
10411076
int (*xCmp)(const char*,const char*,int);
10421077
10431078
blob_zero(pOut);
10441079
if( !g.localOpen ){
1045
- blob_appendf(pOut, "%s", zOrigName);
1046
- return 1;
1080
+ if( absolute && !file_is_absolute_path(zOrigName) ){
1081
+ if( errFatal ){
1082
+ fossil_fatal("relative to absolute needs open checkout tree: %s",
1083
+ zOrigName);
1084
+ }
1085
+ return 0;
1086
+ }else{
1087
+ /*
1088
+ ** The original path may be relative or absolute; however, without
1089
+ ** an open checkout tree, the only things we can do at this point
1090
+ ** is return it verbatim or generate a fatal error. The caller is
1091
+ ** probably expecting a tree-relative path name will be returned;
1092
+ ** however, most places where this function is called already check
1093
+ ** if the local checkout tree is open, either directly or indirectly,
1094
+ ** which would make this situation impossible. Alternatively, they
1095
+ ** could check the returned path using the file_is_absolute_path()
1096
+ ** function.
1097
+ */
1098
+ blob_appendf(pOut, "%s", zOrigName);
1099
+ return 1;
1100
+ }
10471101
}
10481102
file_canonical_name(g.zLocalRoot, &localRoot, 1);
10491103
nLocalRoot = blob_size(&localRoot);
10501104
zLocalRoot = blob_buffer(&localRoot);
10511105
assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' );
@@ -1059,11 +1113,15 @@
10591113
}
10601114
10611115
/* Special case. zOrigName refers to g.zLocalRoot directory. */
10621116
if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
10631117
|| (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
1064
- blob_append(pOut, ".", 1);
1118
+ if( absolute ){
1119
+ blob_append(pOut, zLocalRoot, nLocalRoot);
1120
+ }else{
1121
+ blob_append(pOut, ".", 1);
1122
+ }
10651123
blob_reset(&localRoot);
10661124
blob_reset(&full);
10671125
return 1;
10681126
}
10691127
@@ -1073,11 +1131,20 @@
10731131
if( errFatal ){
10741132
fossil_fatal("file outside of checkout tree: %s", zOrigName);
10751133
}
10761134
return 0;
10771135
}
1078
- blob_append(pOut, &zFull[nLocalRoot], nFull-nLocalRoot);
1136
+ if( absolute ){
1137
+ if( !file_is_absolute_path(zOrigName) ){
1138
+ blob_append(pOut, zLocalRoot, nLocalRoot);
1139
+ }
1140
+ blob_append(pOut, zOrigName, -1);
1141
+ blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
1142
+ blob_size(pOut), 0));
1143
+ }else{
1144
+ blob_append(pOut, &zFull[nLocalRoot], nFull-nLocalRoot);
1145
+ }
10791146
blob_reset(&localRoot);
10801147
blob_reset(&full);
10811148
return 1;
10821149
}
10831150
@@ -1085,20 +1152,22 @@
10851152
** COMMAND: test-tree-name
10861153
**
10871154
** Test the operation of the tree name generator.
10881155
**
10891156
** Options:
1157
+** --absolute Return an absolute path instead of a relative one.
10901158
** --case-sensitive B Enable or disable case-sensitive filenames. B is
10911159
** a boolean: "yes", "no", "true", "false", etc.
10921160
*/
10931161
void cmd_test_tree_name(void){
10941162
int i;
10951163
Blob x;
1164
+ int absoluteFlag = find_option("absolute",0,0)!=0;
10961165
db_find_and_open_repository(0,0);
10971166
blob_zero(&x);
10981167
for(i=2; i<g.argc; i++){
1099
- if( file_tree_name(g.argv[i], &x, 1) ){
1168
+ if( file_tree_name(g.argv[i], &x, absoluteFlag, 1) ){
11001169
fossil_print("%s\n", blob_buffer(&x));
11011170
blob_reset(&x);
11021171
}
11031172
}
11041173
}
11051174
--- src/file.c
+++ src/file.c
@@ -57,10 +57,16 @@
57 i64 st_size;
58 i64 st_mtime;
59 int st_mode;
60 };
61 #endif
 
 
 
 
 
 
62
63 #endif /* INTERFACE */
64
65 #if !defined(_WIN32) || !(defined(__MSVCRT__) || defined(_MSC_VER))
66 # define fossilStat stat
@@ -370,16 +376,32 @@
370 ** Return the tail of a file pathname. The tail is the last component
371 ** of the path. For example, the tail of "/a/b/c.d" is "c.d".
372 */
373 const char *file_tail(const char *z){
374 const char *zTail = z;
 
375 while( z[0] ){
376 if( z[0]=='/' ) zTail = &z[1];
377 z++;
378 }
379 return zTail;
380 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
382 /*
383 ** Copy the content of a file from one place to another.
384 */
385 void file_copy(const char *zFrom, const char *zTo){
@@ -386,11 +408,11 @@
386 FILE *in, *out;
387 int got;
388 char zBuf[8192];
389 in = fossil_fopen(zFrom, "rb");
390 if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
391 file_mkfolder(zTo, 0);
392 out = fossil_fopen(zTo, "wb");
393 if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
394 while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
395 fwrite(zBuf, 1, got, out);
396 }
@@ -530,13 +552,16 @@
530 }
531
532 /*
533 ** Create the tree of directories in which zFilename belongs, if that sequence
534 ** of directories does not already exist.
 
 
 
535 */
536 void file_mkfolder(const char *zFilename, int forceFlag){
537 int i, nName;
538 char *zName;
539
540 nName = strlen(zFilename);
541 zName = mprintf("%s", zFilename);
542 nName = file_simplify_name(zName, nName, 0);
@@ -550,20 +575,24 @@
550 ** C: in this example.
551 */
552 if( !(i==2 && zName[1]==':') ){
553 #endif
554 if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
555 fossil_fatal_recursive("unable to create directory %s", zName);
556 return;
 
 
 
557 }
558 #if defined(_WIN32) || defined(__CYGWIN__)
559 }
560 #endif
561 zName[i] = '/';
562 }
563 }
564 free(zName);
 
565 }
566
567 /*
568 ** Removes the directory named in the argument, if it exists. The directory
569 ** must be empty and cannot be the current directory or the root directory.
@@ -810,15 +839,14 @@
810 /*
811 ** Return true if zPath is an absolute pathname. Return false
812 ** if it is relative.
813 */
814 int file_is_absolute_path(const char *zPath){
815 if( zPath[0]=='/'
816 #if defined(_WIN32) || defined(__CYGWIN__)
817 || zPath[0]=='\\'
818 || (fossil_isalpha(zPath[0]) && zPath[1]==':'
819 && (zPath[2]=='\\' || zPath[2]=='/' || zPath[2]=='\0'))
820 #endif
821 ){
822 return 1;
823 }else{
824 return 0;
@@ -1022,18 +1050,25 @@
1022 blob_reset(&x);
1023 }
1024 }
1025
1026 /*
1027 ** Compute a pathname for a file relative to the root of the local
1028 ** tree. Return TRUE on success. On failure, print and error
1029 ** message and quit if the errFatal flag is true. If errFatal is
1030 ** false, then simply return 0.
1031 **
1032 ** The root of the tree is defined by the g.zLocalRoot variable.
 
 
1033 */
1034 int file_tree_name(const char *zOrigName, Blob *pOut, int errFatal){
 
 
 
 
 
1035 Blob localRoot;
1036 int nLocalRoot;
1037 char *zLocalRoot;
1038 Blob full;
1039 int nFull;
@@ -1040,12 +1075,31 @@
1040 char *zFull;
1041 int (*xCmp)(const char*,const char*,int);
1042
1043 blob_zero(pOut);
1044 if( !g.localOpen ){
1045 blob_appendf(pOut, "%s", zOrigName);
1046 return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1047 }
1048 file_canonical_name(g.zLocalRoot, &localRoot, 1);
1049 nLocalRoot = blob_size(&localRoot);
1050 zLocalRoot = blob_buffer(&localRoot);
1051 assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' );
@@ -1059,11 +1113,15 @@
1059 }
1060
1061 /* Special case. zOrigName refers to g.zLocalRoot directory. */
1062 if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
1063 || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
1064 blob_append(pOut, ".", 1);
 
 
 
 
1065 blob_reset(&localRoot);
1066 blob_reset(&full);
1067 return 1;
1068 }
1069
@@ -1073,11 +1131,20 @@
1073 if( errFatal ){
1074 fossil_fatal("file outside of checkout tree: %s", zOrigName);
1075 }
1076 return 0;
1077 }
1078 blob_append(pOut, &zFull[nLocalRoot], nFull-nLocalRoot);
 
 
 
 
 
 
 
 
 
1079 blob_reset(&localRoot);
1080 blob_reset(&full);
1081 return 1;
1082 }
1083
@@ -1085,20 +1152,22 @@
1085 ** COMMAND: test-tree-name
1086 **
1087 ** Test the operation of the tree name generator.
1088 **
1089 ** Options:
 
1090 ** --case-sensitive B Enable or disable case-sensitive filenames. B is
1091 ** a boolean: "yes", "no", "true", "false", etc.
1092 */
1093 void cmd_test_tree_name(void){
1094 int i;
1095 Blob x;
 
1096 db_find_and_open_repository(0,0);
1097 blob_zero(&x);
1098 for(i=2; i<g.argc; i++){
1099 if( file_tree_name(g.argv[i], &x, 1) ){
1100 fossil_print("%s\n", blob_buffer(&x));
1101 blob_reset(&x);
1102 }
1103 }
1104 }
1105
--- src/file.c
+++ src/file.c
@@ -57,10 +57,16 @@
57 i64 st_size;
58 i64 st_mtime;
59 int st_mode;
60 };
61 #endif
62
63 #if defined(_WIN32) || defined(__CYGWIN__)
64 # define fossil_isdirsep(a) (((a) == '/') || ((a) == '\\'))
65 #else
66 # define fossil_isdirsep(a) ((a) == '/')
67 #endif
68
69 #endif /* INTERFACE */
70
71 #if !defined(_WIN32) || !(defined(__MSVCRT__) || defined(_MSC_VER))
72 # define fossilStat stat
@@ -370,16 +376,32 @@
376 ** Return the tail of a file pathname. The tail is the last component
377 ** of the path. For example, the tail of "/a/b/c.d" is "c.d".
378 */
379 const char *file_tail(const char *z){
380 const char *zTail = z;
381 if( !zTail ) return 0;
382 while( z[0] ){
383 if( fossil_isdirsep(z[0]) ) zTail = &z[1];
384 z++;
385 }
386 return zTail;
387 }
388
389 /*
390 ** Return the directory of a file path name. The directory is all components
391 ** except the last one. For example, the directory of "/a/b/c.d" is "/a/b".
392 ** If there is no directory, NULL is returned; otherwise, the returned memory
393 ** should be freed via fossil_free().
394 */
395 char *file_dirname(const char *z){
396 const char *zTail = file_tail(z);
397 if( zTail && zTail!=z ){
398 return mprintf("%.*s", (int)(zTail-z-1), z);
399 }else{
400 return 0;
401 }
402 }
403
404 /*
405 ** Copy the content of a file from one place to another.
406 */
407 void file_copy(const char *zFrom, const char *zTo){
@@ -386,11 +408,11 @@
408 FILE *in, *out;
409 int got;
410 char zBuf[8192];
411 in = fossil_fopen(zFrom, "rb");
412 if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom);
413 file_mkfolder(zTo, 0, 0);
414 out = fossil_fopen(zTo, "wb");
415 if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo);
416 while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){
417 fwrite(zBuf, 1, got, out);
418 }
@@ -530,13 +552,16 @@
552 }
553
554 /*
555 ** Create the tree of directories in which zFilename belongs, if that sequence
556 ** of directories does not already exist.
557 **
558 ** On success, return zero. On error, return errorReturn if positive, otherwise
559 ** print an error message and abort.
560 */
561 int file_mkfolder(const char *zFilename, int forceFlag, int errorReturn){
562 int i, nName, rc = 0;
563 char *zName;
564
565 nName = strlen(zFilename);
566 zName = mprintf("%s", zFilename);
567 nName = file_simplify_name(zName, nName, 0);
@@ -550,20 +575,24 @@
575 ** C: in this example.
576 */
577 if( !(i==2 && zName[1]==':') ){
578 #endif
579 if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){
580 if (errorReturn <= 0) {
581 fossil_fatal_recursive("unable to create directory %s", zName);
582 }
583 rc = errorReturn;
584 break;
585 }
586 #if defined(_WIN32) || defined(__CYGWIN__)
587 }
588 #endif
589 zName[i] = '/';
590 }
591 }
592 free(zName);
593 return rc;
594 }
595
596 /*
597 ** Removes the directory named in the argument, if it exists. The directory
598 ** must be empty and cannot be the current directory or the root directory.
@@ -810,15 +839,14 @@
839 /*
840 ** Return true if zPath is an absolute pathname. Return false
841 ** if it is relative.
842 */
843 int file_is_absolute_path(const char *zPath){
844 if( fossil_isdirsep(zPath[0])
845 #if defined(_WIN32) || defined(__CYGWIN__)
 
846 || (fossil_isalpha(zPath[0]) && zPath[1]==':'
847 && (fossil_isdirsep(zPath[2]) || zPath[2]=='\0'))
848 #endif
849 ){
850 return 1;
851 }else{
852 return 0;
@@ -1022,18 +1050,25 @@
1050 blob_reset(&x);
1051 }
1052 }
1053
1054 /*
1055 ** Compute a full path name for a file in the local tree. If
1056 ** the absolute flag is non-zero, the computed path will be
1057 ** absolute, starting with the root path of the local tree;
1058 ** otherwise, it will be relative to the root of the local
1059 ** tree. In both cases, the root of the local tree is defined
1060 ** by the g.zLocalRoot variable. Return TRUE on success. On
1061 ** failure, print and error message and quit if the errFatal
1062 ** flag is true. If errFatal is false, then simply return 0.
1063 */
1064 int file_tree_name(
1065 const char *zOrigName,
1066 Blob *pOut,
1067 int absolute,
1068 int errFatal
1069 ){
1070 Blob localRoot;
1071 int nLocalRoot;
1072 char *zLocalRoot;
1073 Blob full;
1074 int nFull;
@@ -1040,12 +1075,31 @@
1075 char *zFull;
1076 int (*xCmp)(const char*,const char*,int);
1077
1078 blob_zero(pOut);
1079 if( !g.localOpen ){
1080 if( absolute && !file_is_absolute_path(zOrigName) ){
1081 if( errFatal ){
1082 fossil_fatal("relative to absolute needs open checkout tree: %s",
1083 zOrigName);
1084 }
1085 return 0;
1086 }else{
1087 /*
1088 ** The original path may be relative or absolute; however, without
1089 ** an open checkout tree, the only things we can do at this point
1090 ** is return it verbatim or generate a fatal error. The caller is
1091 ** probably expecting a tree-relative path name will be returned;
1092 ** however, most places where this function is called already check
1093 ** if the local checkout tree is open, either directly or indirectly,
1094 ** which would make this situation impossible. Alternatively, they
1095 ** could check the returned path using the file_is_absolute_path()
1096 ** function.
1097 */
1098 blob_appendf(pOut, "%s", zOrigName);
1099 return 1;
1100 }
1101 }
1102 file_canonical_name(g.zLocalRoot, &localRoot, 1);
1103 nLocalRoot = blob_size(&localRoot);
1104 zLocalRoot = blob_buffer(&localRoot);
1105 assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' );
@@ -1059,11 +1113,15 @@
1113 }
1114
1115 /* Special case. zOrigName refers to g.zLocalRoot directory. */
1116 if( (nFull==nLocalRoot-1 && xCmp(zLocalRoot, zFull, nFull)==0)
1117 || (nFull==1 && zFull[0]=='/' && nLocalRoot==1 && zLocalRoot[0]=='/') ){
1118 if( absolute ){
1119 blob_append(pOut, zLocalRoot, nLocalRoot);
1120 }else{
1121 blob_append(pOut, ".", 1);
1122 }
1123 blob_reset(&localRoot);
1124 blob_reset(&full);
1125 return 1;
1126 }
1127
@@ -1073,11 +1131,20 @@
1131 if( errFatal ){
1132 fossil_fatal("file outside of checkout tree: %s", zOrigName);
1133 }
1134 return 0;
1135 }
1136 if( absolute ){
1137 if( !file_is_absolute_path(zOrigName) ){
1138 blob_append(pOut, zLocalRoot, nLocalRoot);
1139 }
1140 blob_append(pOut, zOrigName, -1);
1141 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
1142 blob_size(pOut), 0));
1143 }else{
1144 blob_append(pOut, &zFull[nLocalRoot], nFull-nLocalRoot);
1145 }
1146 blob_reset(&localRoot);
1147 blob_reset(&full);
1148 return 1;
1149 }
1150
@@ -1085,20 +1152,22 @@
1152 ** COMMAND: test-tree-name
1153 **
1154 ** Test the operation of the tree name generator.
1155 **
1156 ** Options:
1157 ** --absolute Return an absolute path instead of a relative one.
1158 ** --case-sensitive B Enable or disable case-sensitive filenames. B is
1159 ** a boolean: "yes", "no", "true", "false", etc.
1160 */
1161 void cmd_test_tree_name(void){
1162 int i;
1163 Blob x;
1164 int absoluteFlag = find_option("absolute",0,0)!=0;
1165 db_find_and_open_repository(0,0);
1166 blob_zero(&x);
1167 for(i=2; i<g.argc; i++){
1168 if( file_tree_name(g.argv[i], &x, absoluteFlag, 1) ){
1169 fossil_print("%s\n", blob_buffer(&x));
1170 blob_reset(&x);
1171 }
1172 }
1173 }
1174
+4 -4
--- src/finfo.c
+++ src/finfo.c
@@ -73,11 +73,11 @@
7373
vid = db_lget_int("checkout", 0);
7474
if( vid==0 ){
7575
fossil_fatal("no checkout to finfo files in");
7676
}
7777
vfile_check_signature(vid, CKSIG_ENOTFILE);
78
- file_tree_name(g.argv[2], &fname, 1);
78
+ file_tree_name(g.argv[2], &fname, 0, 1);
7979
db_prepare(&q,
8080
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
8181
" FROM vfile WHERE vfile.pathname=%B %s",
8282
&fname, filename_collation());
8383
blob_zero(&line);
@@ -122,11 +122,11 @@
122122
const char *zRevision = find_option("revision", "r", 1);
123123
124124
/* We should be done with options.. */
125125
verify_all_options();
126126
127
- file_tree_name(g.argv[2], &fname, 1);
127
+ file_tree_name(g.argv[2], &fname, 0, 1);
128128
if( zRevision ){
129129
historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0);
130130
}else{
131131
int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
132132
&fname, filename_collation());
@@ -174,11 +174,11 @@
174174
verify_all_options();
175175
176176
if( g.argc!=3 ){
177177
usage("?-l|--log? ?-b|--brief? FILENAME");
178178
}
179
- file_tree_name(g.argv[2], &fname, 1);
179
+ file_tree_name(g.argv[2], &fname, 0, 1);
180180
rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
181181
&fname, filename_collation());
182182
if( rid==0 ){
183183
fossil_fatal("no history for file: %b", &fname);
184184
}
@@ -259,11 +259,11 @@
259259
260260
/* We should be done with options.. */
261261
verify_all_options();
262262
263263
for(i=2; i<g.argc; i++){
264
- file_tree_name(g.argv[i], &fname, 1);
264
+ file_tree_name(g.argv[i], &fname, 0, 1);
265265
blob_zero(&content);
266266
rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
267267
if( rc==2 ){
268268
fossil_fatal("no such file: %s", g.argv[i]);
269269
}
270270
271271
ADDED src/linenoise.c
272272
ADDED src/linenoise.h
--- src/finfo.c
+++ src/finfo.c
@@ -73,11 +73,11 @@
73 vid = db_lget_int("checkout", 0);
74 if( vid==0 ){
75 fossil_fatal("no checkout to finfo files in");
76 }
77 vfile_check_signature(vid, CKSIG_ENOTFILE);
78 file_tree_name(g.argv[2], &fname, 1);
79 db_prepare(&q,
80 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
81 " FROM vfile WHERE vfile.pathname=%B %s",
82 &fname, filename_collation());
83 blob_zero(&line);
@@ -122,11 +122,11 @@
122 const char *zRevision = find_option("revision", "r", 1);
123
124 /* We should be done with options.. */
125 verify_all_options();
126
127 file_tree_name(g.argv[2], &fname, 1);
128 if( zRevision ){
129 historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0);
130 }else{
131 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
132 &fname, filename_collation());
@@ -174,11 +174,11 @@
174 verify_all_options();
175
176 if( g.argc!=3 ){
177 usage("?-l|--log? ?-b|--brief? FILENAME");
178 }
179 file_tree_name(g.argv[2], &fname, 1);
180 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
181 &fname, filename_collation());
182 if( rid==0 ){
183 fossil_fatal("no history for file: %b", &fname);
184 }
@@ -259,11 +259,11 @@
259
260 /* We should be done with options.. */
261 verify_all_options();
262
263 for(i=2; i<g.argc; i++){
264 file_tree_name(g.argv[i], &fname, 1);
265 blob_zero(&content);
266 rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
267 if( rc==2 ){
268 fossil_fatal("no such file: %s", g.argv[i]);
269 }
270
271 DDED src/linenoise.c
272 DDED src/linenoise.h
--- src/finfo.c
+++ src/finfo.c
@@ -73,11 +73,11 @@
73 vid = db_lget_int("checkout", 0);
74 if( vid==0 ){
75 fossil_fatal("no checkout to finfo files in");
76 }
77 vfile_check_signature(vid, CKSIG_ENOTFILE);
78 file_tree_name(g.argv[2], &fname, 0, 1);
79 db_prepare(&q,
80 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
81 " FROM vfile WHERE vfile.pathname=%B %s",
82 &fname, filename_collation());
83 blob_zero(&line);
@@ -122,11 +122,11 @@
122 const char *zRevision = find_option("revision", "r", 1);
123
124 /* We should be done with options.. */
125 verify_all_options();
126
127 file_tree_name(g.argv[2], &fname, 0, 1);
128 if( zRevision ){
129 historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0);
130 }else{
131 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
132 &fname, filename_collation());
@@ -174,11 +174,11 @@
174 verify_all_options();
175
176 if( g.argc!=3 ){
177 usage("?-l|--log? ?-b|--brief? FILENAME");
178 }
179 file_tree_name(g.argv[2], &fname, 0, 1);
180 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
181 &fname, filename_collation());
182 if( rid==0 ){
183 fossil_fatal("no history for file: %b", &fname);
184 }
@@ -259,11 +259,11 @@
259
260 /* We should be done with options.. */
261 verify_all_options();
262
263 for(i=2; i<g.argc; i++){
264 file_tree_name(g.argv[i], &fname, 0, 1);
265 blob_zero(&content);
266 rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
267 if( rc==2 ){
268 fossil_fatal("no such file: %s", g.argv[i]);
269 }
270
271 DDED src/linenoise.c
272 DDED src/linenoise.h
+4 -4
--- src/finfo.c
+++ src/finfo.c
@@ -73,11 +73,11 @@
7373
vid = db_lget_int("checkout", 0);
7474
if( vid==0 ){
7575
fossil_fatal("no checkout to finfo files in");
7676
}
7777
vfile_check_signature(vid, CKSIG_ENOTFILE);
78
- file_tree_name(g.argv[2], &fname, 1);
78
+ file_tree_name(g.argv[2], &fname, 0, 1);
7979
db_prepare(&q,
8080
"SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
8181
" FROM vfile WHERE vfile.pathname=%B %s",
8282
&fname, filename_collation());
8383
blob_zero(&line);
@@ -122,11 +122,11 @@
122122
const char *zRevision = find_option("revision", "r", 1);
123123
124124
/* We should be done with options.. */
125125
verify_all_options();
126126
127
- file_tree_name(g.argv[2], &fname, 1);
127
+ file_tree_name(g.argv[2], &fname, 0, 1);
128128
if( zRevision ){
129129
historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0);
130130
}else{
131131
int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
132132
&fname, filename_collation());
@@ -174,11 +174,11 @@
174174
verify_all_options();
175175
176176
if( g.argc!=3 ){
177177
usage("?-l|--log? ?-b|--brief? FILENAME");
178178
}
179
- file_tree_name(g.argv[2], &fname, 1);
179
+ file_tree_name(g.argv[2], &fname, 0, 1);
180180
rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
181181
&fname, filename_collation());
182182
if( rid==0 ){
183183
fossil_fatal("no history for file: %b", &fname);
184184
}
@@ -259,11 +259,11 @@
259259
260260
/* We should be done with options.. */
261261
verify_all_options();
262262
263263
for(i=2; i<g.argc; i++){
264
- file_tree_name(g.argv[i], &fname, 1);
264
+ file_tree_name(g.argv[i], &fname, 0, 1);
265265
blob_zero(&content);
266266
rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
267267
if( rc==2 ){
268268
fossil_fatal("no such file: %s", g.argv[i]);
269269
}
270270
271271
ADDED src/linenoise.c
272272
ADDED src/linenoise.h
--- src/finfo.c
+++ src/finfo.c
@@ -73,11 +73,11 @@
73 vid = db_lget_int("checkout", 0);
74 if( vid==0 ){
75 fossil_fatal("no checkout to finfo files in");
76 }
77 vfile_check_signature(vid, CKSIG_ENOTFILE);
78 file_tree_name(g.argv[2], &fname, 1);
79 db_prepare(&q,
80 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
81 " FROM vfile WHERE vfile.pathname=%B %s",
82 &fname, filename_collation());
83 blob_zero(&line);
@@ -122,11 +122,11 @@
122 const char *zRevision = find_option("revision", "r", 1);
123
124 /* We should be done with options.. */
125 verify_all_options();
126
127 file_tree_name(g.argv[2], &fname, 1);
128 if( zRevision ){
129 historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0);
130 }else{
131 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
132 &fname, filename_collation());
@@ -174,11 +174,11 @@
174 verify_all_options();
175
176 if( g.argc!=3 ){
177 usage("?-l|--log? ?-b|--brief? FILENAME");
178 }
179 file_tree_name(g.argv[2], &fname, 1);
180 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
181 &fname, filename_collation());
182 if( rid==0 ){
183 fossil_fatal("no history for file: %b", &fname);
184 }
@@ -259,11 +259,11 @@
259
260 /* We should be done with options.. */
261 verify_all_options();
262
263 for(i=2; i<g.argc; i++){
264 file_tree_name(g.argv[i], &fname, 1);
265 blob_zero(&content);
266 rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
267 if( rc==2 ){
268 fossil_fatal("no such file: %s", g.argv[i]);
269 }
270
271 DDED src/linenoise.c
272 DDED src/linenoise.h
--- src/finfo.c
+++ src/finfo.c
@@ -73,11 +73,11 @@
73 vid = db_lget_int("checkout", 0);
74 if( vid==0 ){
75 fossil_fatal("no checkout to finfo files in");
76 }
77 vfile_check_signature(vid, CKSIG_ENOTFILE);
78 file_tree_name(g.argv[2], &fname, 0, 1);
79 db_prepare(&q,
80 "SELECT pathname, deleted, rid, chnged, coalesce(origname!=pathname,0)"
81 " FROM vfile WHERE vfile.pathname=%B %s",
82 &fname, filename_collation());
83 blob_zero(&line);
@@ -122,11 +122,11 @@
122 const char *zRevision = find_option("revision", "r", 1);
123
124 /* We should be done with options.. */
125 verify_all_options();
126
127 file_tree_name(g.argv[2], &fname, 0, 1);
128 if( zRevision ){
129 historical_version_of_file(zRevision, blob_str(&fname), &record, 0,0,0,0);
130 }else{
131 int rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
132 &fname, filename_collation());
@@ -174,11 +174,11 @@
174 verify_all_options();
175
176 if( g.argc!=3 ){
177 usage("?-l|--log? ?-b|--brief? FILENAME");
178 }
179 file_tree_name(g.argv[2], &fname, 0, 1);
180 rid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%B %s",
181 &fname, filename_collation());
182 if( rid==0 ){
183 fossil_fatal("no history for file: %b", &fname);
184 }
@@ -259,11 +259,11 @@
259
260 /* We should be done with options.. */
261 verify_all_options();
262
263 for(i=2; i<g.argc; i++){
264 file_tree_name(g.argv[i], &fname, 0, 1);
265 blob_zero(&content);
266 rc = historical_version_of_file(zRev, blob_str(&fname), &content, 0,0,0,2);
267 if( rc==2 ){
268 fossil_fatal("no such file: %s", g.argv[i]);
269 }
270
271 DDED src/linenoise.c
272 DDED src/linenoise.h
--- a/src/linenoise.c
+++ b/src/linenoise.c
@@ -0,0 +1,39 @@
1
+t->buf, oVERSION 1.0
2
+ *
3
+ * G line editing lib
4
+ *4argtypest->buf, o#include "sqlite3onst char *fmt, arg1fmt, arg1arg1==== C89 compatibility====== */
5
+
6
+/* snprintf() is not C89, but sqlite3_vsnprintf() can be adaptedSnprintf(char *str, size_t size, const char *format, ...) {
7
+ va_list ap;
8
+ int result;
9
+
10
+ va_start(ap,format);
11
+ result = (int)strlen(sqlite3_vsnprintf((int)size,str,format,ap));
12
+ va_end(ap);
13
+
14
+ return result;
15
+}
16
+#undef snprintf
17
+#define snprintf linenoiseSnprintf
18
+
19
+/* strdup() is technically not standard C89 despite being in POSIXStrdup(const char *s) {
20
+ size_t size = strlen(s)+1;
21
+ char *result = malloc(size);
22
+
23
+ if (result) memcpy(result,s,size);
24
+
25
+ return result;
26
+}
27
+#undef strdup
28
+#define strdup linenoiseStrdup
29
+
30
+/* strcasecmp() is not standard C89. SQLite offers a direct replacement. */
31
+#undef strcasecmp
32
+#define strcasecmp sqlite3_stricmp#if !defined(__sun__)#endift->buf, o, 0);, 0);
33
+t->buf, o, 0"\n",1);", 0) /* || mlmode */(int){
34
+*/ buflen, stdin)countif (count && buf[count-1]countt->bu}/* Interactive editingen printf("\n");
35
+ }FILE *int->buf, oVERSION ne editing lib
36
+ *4argtypest->buf, o#include "sqlite3onst char *fmt, arg1fmt, arg1arg1==== C89 compatibility====== */
37
+
38
+/* snprintf() is not C89, but s...__VA_ARGS__...););
39
+");
--- a/src/linenoise.c
+++ b/src/linenoise.c
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/linenoise.c
+++ b/src/linenoise.c
@@ -0,0 +1,39 @@
1 t->buf, oVERSION 1.0
2 *
3 * G line editing lib
4 *4argtypest->buf, o#include "sqlite3onst char *fmt, arg1fmt, arg1arg1==== C89 compatibility====== */
5
6 /* snprintf() is not C89, but sqlite3_vsnprintf() can be adaptedSnprintf(char *str, size_t size, const char *format, ...) {
7 va_list ap;
8 int result;
9
10 va_start(ap,format);
11 result = (int)strlen(sqlite3_vsnprintf((int)size,str,format,ap));
12 va_end(ap);
13
14 return result;
15 }
16 #undef snprintf
17 #define snprintf linenoiseSnprintf
18
19 /* strdup() is technically not standard C89 despite being in POSIXStrdup(const char *s) {
20 size_t size = strlen(s)+1;
21 char *result = malloc(size);
22
23 if (result) memcpy(result,s,size);
24
25 return result;
26 }
27 #undef strdup
28 #define strdup linenoiseStrdup
29
30 /* strcasecmp() is not standard C89. SQLite offers a direct replacement. */
31 #undef strcasecmp
32 #define strcasecmp sqlite3_stricmp#if !defined(__sun__)#endift->buf, o, 0);, 0);
33 t->buf, o, 0"\n",1);", 0) /* || mlmode */(int){
34 */ buflen, stdin)countif (count && buf[count-1]countt->bu}/* Interactive editingen printf("\n");
35 }FILE *int->buf, oVERSION ne editing lib
36 *4argtypest->buf, o#include "sqlite3onst char *fmt, arg1fmt, arg1arg1==== C89 compatibility====== */
37
38 /* snprintf() is not C89, but s...__VA_ARGS__...););
39 ");
--- a/src/linenoise.h
+++ b/src/linenoise.h
@@ -0,0 +1,21 @@
1
+/* linenoise.h -- VERSION 1.0
2
+ *
3
+ * Guerrilla line editing libr line editing lib
4
+ * needs to be 20,000 lines of C code.
5
+ *
6
+ * See linenoise.c for more information.
7
+ *
8
+ * -----------------------------------------------------------------------2014, Salvatore Sanfilippo <antirez at gmail dot com>
9
+ * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
10
+ *
11
+ * All rights reserved.
12
+ *
13
+ * Redistribution and use in source and binary forms, with or without
14
+ * modification, are permitted provided that the following conditions are
15
+ * met:
16
+ *
17
+ * * Redistributions of source code must retain the above copyright
18
+ * notice, this list of conditions and the following disclaimer.
19
+ *
20
+ * * Redistributions in binary form must reproduce the above copyright
21
+ * notice, thi
--- a/src/linenoise.h
+++ b/src/linenoise.h
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/linenoise.h
+++ b/src/linenoise.h
@@ -0,0 +1,21 @@
1 /* linenoise.h -- VERSION 1.0
2 *
3 * Guerrilla line editing libr line editing lib
4 * needs to be 20,000 lines of C code.
5 *
6 * See linenoise.c for more information.
7 *
8 * -----------------------------------------------------------------------2014, Salvatore Sanfilippo <antirez at gmail dot com>
9 * Copyright (c) 2010-2013, Pieter Noordhuis <pcnoordhuis at gmail dot com>
10 *
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions are
15 * met:
16 *
17 * * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * * Redistributions in binary form must reproduce the above copyright
21 * notice, thi
+2 -1
--- src/main.c
+++ src/main.c
@@ -102,17 +102,18 @@
102102
** "th_tcl.c".
103103
*/
104104
struct TclContext {
105105
int argc; /* Number of original (expanded) arguments. */
106106
char **argv; /* Full copy of the original (expanded) arguments. */
107
- void *library; /* The Tcl library module handle. */
107
+ void *hLibrary; /* The Tcl library module handle. */
108108
void *xFindExecutable; /* See tcl_FindExecutableProc in th_tcl.c. */
109109
void *xCreateInterp; /* See tcl_CreateInterpProc in th_tcl.c. */
110110
void *xDeleteInterp; /* See tcl_DeleteInterpProc in th_tcl.c. */
111111
void *xFinalize; /* See tcl_FinalizeProc in th_tcl.c. */
112112
Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
113113
int useObjProc; /* Non-zero if an objProc can be called directly. */
114
+ int useTip285; /* Non-zero if TIP #285 is available. */
114115
char *setup; /* The optional Tcl setup script. */
115116
void *xPreEval; /* Optional, called before Tcl_Eval*(). */
116117
void *pPreContext; /* Optional, provided to xPreEval(). */
117118
void *xPostEval; /* Optional, called after Tcl_Eval*(). */
118119
void *pPostContext; /* Optional, provided to xPostEval(). */
119120
--- src/main.c
+++ src/main.c
@@ -102,17 +102,18 @@
102 ** "th_tcl.c".
103 */
104 struct TclContext {
105 int argc; /* Number of original (expanded) arguments. */
106 char **argv; /* Full copy of the original (expanded) arguments. */
107 void *library; /* The Tcl library module handle. */
108 void *xFindExecutable; /* See tcl_FindExecutableProc in th_tcl.c. */
109 void *xCreateInterp; /* See tcl_CreateInterpProc in th_tcl.c. */
110 void *xDeleteInterp; /* See tcl_DeleteInterpProc in th_tcl.c. */
111 void *xFinalize; /* See tcl_FinalizeProc in th_tcl.c. */
112 Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
113 int useObjProc; /* Non-zero if an objProc can be called directly. */
 
114 char *setup; /* The optional Tcl setup script. */
115 void *xPreEval; /* Optional, called before Tcl_Eval*(). */
116 void *pPreContext; /* Optional, provided to xPreEval(). */
117 void *xPostEval; /* Optional, called after Tcl_Eval*(). */
118 void *pPostContext; /* Optional, provided to xPostEval(). */
119
--- src/main.c
+++ src/main.c
@@ -102,17 +102,18 @@
102 ** "th_tcl.c".
103 */
104 struct TclContext {
105 int argc; /* Number of original (expanded) arguments. */
106 char **argv; /* Full copy of the original (expanded) arguments. */
107 void *hLibrary; /* The Tcl library module handle. */
108 void *xFindExecutable; /* See tcl_FindExecutableProc in th_tcl.c. */
109 void *xCreateInterp; /* See tcl_CreateInterpProc in th_tcl.c. */
110 void *xDeleteInterp; /* See tcl_DeleteInterpProc in th_tcl.c. */
111 void *xFinalize; /* See tcl_FinalizeProc in th_tcl.c. */
112 Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
113 int useObjProc; /* Non-zero if an objProc can be called directly. */
114 int useTip285; /* Non-zero if TIP #285 is available. */
115 char *setup; /* The optional Tcl setup script. */
116 void *xPreEval; /* Optional, called before Tcl_Eval*(). */
117 void *pPreContext; /* Optional, provided to xPreEval(). */
118 void *xPostEval; /* Optional, called after Tcl_Eval*(). */
119 void *pPostContext; /* Optional, provided to xPostEval(). */
120
+5 -1
--- src/main.mk
+++ src/main.mk
@@ -510,10 +510,11 @@
510510
511511
512512
EXTRAOBJ = \
513513
$(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
514514
$(MINIZ_OBJ.$(FOSSIL_ENABLE_MINIZ)) \
515
+ $(OBJDIR)/linenoise.o \
515516
$(OBJDIR)/shell.o \
516517
$(OBJDIR)/th.o \
517518
$(OBJDIR)/th_lang.o \
518519
$(OBJDIR)/th_tcl.o \
519520
$(OBJDIR)/cson_amalgamation.o
@@ -1620,11 +1621,14 @@
16201621
16211622
$(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
16221623
$(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $@
16231624
16241625
$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1625
- $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $@
1626
+ $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -DHAVE_LINENOISE -c $(SRCDIR)/shell.c -o $@
1627
+
1628
+$(OBJDIR)/linenoise.o: $(SRCDIR)/linenoise.c $(SRCDIR)/linenoise.h
1629
+ $(XTCC) -c $(SRCDIR)/linenoise.c -o $@
16261630
16271631
$(OBJDIR)/th.o: $(SRCDIR)/th.c
16281632
$(XTCC) -c $(SRCDIR)/th.c -o $@
16291633
16301634
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
16311635
--- src/main.mk
+++ src/main.mk
@@ -510,10 +510,11 @@
510
511
512 EXTRAOBJ = \
513 $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
514 $(MINIZ_OBJ.$(FOSSIL_ENABLE_MINIZ)) \
 
515 $(OBJDIR)/shell.o \
516 $(OBJDIR)/th.o \
517 $(OBJDIR)/th_lang.o \
518 $(OBJDIR)/th_tcl.o \
519 $(OBJDIR)/cson_amalgamation.o
@@ -1620,11 +1621,14 @@
1620
1621 $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
1622 $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $@
1623
1624 $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1625 $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -c $(SRCDIR)/shell.c -o $@
 
 
 
1626
1627 $(OBJDIR)/th.o: $(SRCDIR)/th.c
1628 $(XTCC) -c $(SRCDIR)/th.c -o $@
1629
1630 $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
1631
--- src/main.mk
+++ src/main.mk
@@ -510,10 +510,11 @@
510
511
512 EXTRAOBJ = \
513 $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) \
514 $(MINIZ_OBJ.$(FOSSIL_ENABLE_MINIZ)) \
515 $(OBJDIR)/linenoise.o \
516 $(OBJDIR)/shell.o \
517 $(OBJDIR)/th.o \
518 $(OBJDIR)/th_lang.o \
519 $(OBJDIR)/th_tcl.o \
520 $(OBJDIR)/cson_amalgamation.o
@@ -1620,11 +1621,14 @@
1621
1622 $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
1623 $(XTCC) $(SQLITE_OPTIONS) $(SQLITE_CFLAGS) -c $(SRCDIR)/sqlite3.c -o $@
1624
1625 $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1626 $(XTCC) $(SHELL_OPTIONS) $(SHELL_CFLAGS) -DHAVE_LINENOISE -c $(SRCDIR)/shell.c -o $@
1627
1628 $(OBJDIR)/linenoise.o: $(SRCDIR)/linenoise.c $(SRCDIR)/linenoise.h
1629 $(XTCC) -c $(SRCDIR)/linenoise.c -o $@
1630
1631 $(OBJDIR)/th.o: $(SRCDIR)/th.c
1632 $(XTCC) -c $(SRCDIR)/th.c -o $@
1633
1634 $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
1635
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -341,10 +341,11 @@
341341
342342
writeln [string map [list <<<NEXT_LINE>>> \\] {
343343
EXTRAOBJ = <<<NEXT_LINE>>>
344344
$(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) <<<NEXT_LINE>>>
345345
$(MINIZ_OBJ.$(FOSSIL_ENABLE_MINIZ)) <<<NEXT_LINE>>>
346
+ $(OBJDIR)/linenoise.o <<<NEXT_LINE>>>
346347
$(OBJDIR)/shell.o <<<NEXT_LINE>>>
347348
$(OBJDIR)/th.o <<<NEXT_LINE>>>
348349
$(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
349350
$(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
350351
$(OBJDIR)/cson_amalgamation.o
@@ -401,11 +402,14 @@
401402
402403
writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
403404
writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$@\n"
404405
405406
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
406
-writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SRCDIR)/shell.c -o \$@\n"
407
+writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -DHAVE_LINENOISE -c \$(SRCDIR)/shell.c -o \$@\n"
408
+
409
+writeln "\$(OBJDIR)/linenoise.o:\t\$(SRCDIR)/linenoise.c \$(SRCDIR)/linenoise.h"
410
+writeln "\t\$(XTCC) -c \$(SRCDIR)/linenoise.c -o \$@\n"
407411
408412
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
409413
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"
410414
411415
writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
@@ -593,11 +597,11 @@
593597
#### The directories where the OpenSSL include and library files are located.
594598
# The recommended usage here is to use the Sysinternals junction tool
595599
# to create a hard link between an "openssl-1.x" sub-directory of the
596600
# Fossil source code directory and the target OpenSSL source directory.
597601
#
598
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2a
602
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2c
599603
OPENSSLINCDIR = $(OPENSSLDIR)/include
600604
OPENSSLLIBDIR = $(OPENSSLDIR)
601605
602606
#### Either the directory where the Tcl library is installed or the Tcl
603607
# source code directory resides (depending on the value of the macro
@@ -1335,11 +1339,11 @@
13351339
13361340
# Uncomment to enable Tcl support
13371341
# FOSSIL_ENABLE_TCL = 1
13381342
13391343
!ifdef FOSSIL_ENABLE_SSL
1340
-SSLDIR = $(B)\compat\openssl-1.0.2a
1344
+SSLDIR = $(B)\compat\openssl-1.0.2c
13411345
SSLINCDIR = $(SSLDIR)\inc32
13421346
SSLLIBDIR = $(SSLDIR)\out32
13431347
SSLLFLAGS = /nologo /opt:ref /debug
13441348
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
13451349
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
13461350
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -341,10 +341,11 @@
341
342 writeln [string map [list <<<NEXT_LINE>>> \\] {
343 EXTRAOBJ = <<<NEXT_LINE>>>
344 $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) <<<NEXT_LINE>>>
345 $(MINIZ_OBJ.$(FOSSIL_ENABLE_MINIZ)) <<<NEXT_LINE>>>
 
346 $(OBJDIR)/shell.o <<<NEXT_LINE>>>
347 $(OBJDIR)/th.o <<<NEXT_LINE>>>
348 $(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
349 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
350 $(OBJDIR)/cson_amalgamation.o
@@ -401,11 +402,14 @@
401
402 writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
403 writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$@\n"
404
405 writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
406 writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -c \$(SRCDIR)/shell.c -o \$@\n"
 
 
 
407
408 writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
409 writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"
410
411 writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
@@ -593,11 +597,11 @@
593 #### The directories where the OpenSSL include and library files are located.
594 # The recommended usage here is to use the Sysinternals junction tool
595 # to create a hard link between an "openssl-1.x" sub-directory of the
596 # Fossil source code directory and the target OpenSSL source directory.
597 #
598 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2a
599 OPENSSLINCDIR = $(OPENSSLDIR)/include
600 OPENSSLLIBDIR = $(OPENSSLDIR)
601
602 #### Either the directory where the Tcl library is installed or the Tcl
603 # source code directory resides (depending on the value of the macro
@@ -1335,11 +1339,11 @@
1335
1336 # Uncomment to enable Tcl support
1337 # FOSSIL_ENABLE_TCL = 1
1338
1339 !ifdef FOSSIL_ENABLE_SSL
1340 SSLDIR = $(B)\compat\openssl-1.0.2a
1341 SSLINCDIR = $(SSLDIR)\inc32
1342 SSLLIBDIR = $(SSLDIR)\out32
1343 SSLLFLAGS = /nologo /opt:ref /debug
1344 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1345 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1346
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -341,10 +341,11 @@
341
342 writeln [string map [list <<<NEXT_LINE>>> \\] {
343 EXTRAOBJ = <<<NEXT_LINE>>>
344 $(SQLITE3_OBJ.$(USE_SYSTEM_SQLITE)) <<<NEXT_LINE>>>
345 $(MINIZ_OBJ.$(FOSSIL_ENABLE_MINIZ)) <<<NEXT_LINE>>>
346 $(OBJDIR)/linenoise.o <<<NEXT_LINE>>>
347 $(OBJDIR)/shell.o <<<NEXT_LINE>>>
348 $(OBJDIR)/th.o <<<NEXT_LINE>>>
349 $(OBJDIR)/th_lang.o <<<NEXT_LINE>>>
350 $(OBJDIR)/th_tcl.o <<<NEXT_LINE>>>
351 $(OBJDIR)/cson_amalgamation.o
@@ -401,11 +402,14 @@
402
403 writeln "\$(OBJDIR)/sqlite3.o:\t\$(SRCDIR)/sqlite3.c"
404 writeln "\t\$(XTCC) \$(SQLITE_OPTIONS) \$(SQLITE_CFLAGS) -c \$(SRCDIR)/sqlite3.c -o \$@\n"
405
406 writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
407 writeln "\t\$(XTCC) \$(SHELL_OPTIONS) \$(SHELL_CFLAGS) -DHAVE_LINENOISE -c \$(SRCDIR)/shell.c -o \$@\n"
408
409 writeln "\$(OBJDIR)/linenoise.o:\t\$(SRCDIR)/linenoise.c \$(SRCDIR)/linenoise.h"
410 writeln "\t\$(XTCC) -c \$(SRCDIR)/linenoise.c -o \$@\n"
411
412 writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
413 writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$@\n"
414
415 writeln "\$(OBJDIR)/th_lang.o:\t\$(SRCDIR)/th_lang.c"
@@ -593,11 +597,11 @@
597 #### The directories where the OpenSSL include and library files are located.
598 # The recommended usage here is to use the Sysinternals junction tool
599 # to create a hard link between an "openssl-1.x" sub-directory of the
600 # Fossil source code directory and the target OpenSSL source directory.
601 #
602 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2c
603 OPENSSLINCDIR = $(OPENSSLDIR)/include
604 OPENSSLLIBDIR = $(OPENSSLDIR)
605
606 #### Either the directory where the Tcl library is installed or the Tcl
607 # source code directory resides (depending on the value of the macro
@@ -1335,11 +1339,11 @@
1339
1340 # Uncomment to enable Tcl support
1341 # FOSSIL_ENABLE_TCL = 1
1342
1343 !ifdef FOSSIL_ENABLE_SSL
1344 SSLDIR = $(B)\compat\openssl-1.0.2c
1345 SSLINCDIR = $(SSLDIR)\inc32
1346 SSLLIBDIR = $(SSLDIR)\out32
1347 SSLLFLAGS = /nologo /opt:ref /debug
1348 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
1349 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
1350
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -34,16 +34,16 @@
3434
3535
/* INTER_BLOCK -- skip a line between block level elements */
3636
#define INTER_BLOCK(ob) \
3737
do { if( blob_size(ob)>0 ) blob_append(ob, "\n", 1); } while (0)
3838
39
-/* BLOB_APPEND_LITTERAL -- append a string litteral to a blob */
40
-#define BLOB_APPEND_LITTERAL(blob, litteral) \
41
- blob_append((blob), "" litteral, (sizeof litteral)-1)
39
+/* BLOB_APPEND_LITERAL -- append a string literal to a blob */
40
+#define BLOB_APPEND_LITERAL(blob, literal) \
41
+ blob_append((blob), "" literal, (sizeof literal)-1)
4242
/*
4343
* The empty string in the second argument leads to a syntax error
44
- * when the macro is not used with a string litteral. Unfortunately
44
+ * when the macro is not used with a string literal. Unfortunately
4545
* the error is not overly explicit.
4646
*/
4747
4848
/* BLOB_APPEND_BLOB -- append blob contents to another */
4949
#define BLOB_APPEND_BLOB(dest, src) \
@@ -65,17 +65,17 @@
6565
i++;
6666
}
6767
blob_append(ob, data+beg, i-beg);
6868
while( i<size ){
6969
if( data[i]=='<' ){
70
- BLOB_APPEND_LITTERAL(ob, "&lt;");
70
+ BLOB_APPEND_LITERAL(ob, "&lt;");
7171
}else if( data[i]=='>' ){
72
- BLOB_APPEND_LITTERAL(ob, "&gt;");
72
+ BLOB_APPEND_LITERAL(ob, "&gt;");
7373
}else if( data[i]=='&' ){
74
- BLOB_APPEND_LITTERAL(ob, "&amp;");
74
+ BLOB_APPEND_LITERAL(ob, "&amp;");
7575
}else if( data[i]=='"' ){
76
- BLOB_APPEND_LITTERAL(ob, "&quot;");
76
+ BLOB_APPEND_LITERAL(ob, "&quot;");
7777
}else{
7878
break;
7979
}
8080
i++;
8181
}
@@ -88,41 +88,41 @@
8888
/* Size of the prolog: "<div class='markdown'>\n" */
8989
#define PROLOG_SIZE 23
9090
9191
static void html_prolog(struct Blob *ob, void *opaque){
9292
INTER_BLOCK(ob);
93
- BLOB_APPEND_LITTERAL(ob, "<div class=\"markdown\">\n");
93
+ BLOB_APPEND_LITERAL(ob, "<div class=\"markdown\">\n");
9494
assert( blob_size(ob)==PROLOG_SIZE );
9595
}
9696
9797
static void html_epilog(struct Blob *ob, void *opaque){
9898
INTER_BLOCK(ob);
99
- BLOB_APPEND_LITTERAL(ob, "</div>\n");
99
+ BLOB_APPEND_LITERAL(ob, "</div>\n");
100100
}
101101
102102
static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){
103103
char *data = blob_buffer(text);
104104
size_t first = 0, size = blob_size(text);
105105
INTER_BLOCK(ob);
106106
while( first<size && data[first]=='\n' ) first++;
107107
while( size>first && data[size-1]=='\n' ) size--;
108108
blob_append(ob, data+first, size-first);
109
- BLOB_APPEND_LITTERAL(ob, "\n");
109
+ BLOB_APPEND_LITERAL(ob, "\n");
110110
}
111111
112112
static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
113113
INTER_BLOCK(ob);
114
- BLOB_APPEND_LITTERAL(ob, "<pre><code>");
114
+ BLOB_APPEND_LITERAL(ob, "<pre><code>");
115115
html_escape(ob, blob_buffer(text), blob_size(text));
116
- BLOB_APPEND_LITTERAL(ob, "</code></pre>\n");
116
+ BLOB_APPEND_LITERAL(ob, "</code></pre>\n");
117117
}
118118
119119
static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
120120
INTER_BLOCK(ob);
121
- BLOB_APPEND_LITTERAL(ob, "<blockquote>\n");
121
+ BLOB_APPEND_LITERAL(ob, "<blockquote>\n");
122122
BLOB_APPEND_BLOB(ob, text);
123
- BLOB_APPEND_LITTERAL(ob, "</blockquote>\n");
123
+ BLOB_APPEND_LITERAL(ob, "</blockquote>\n");
124124
}
125125
126126
static void html_header(
127127
struct Blob *ob,
128128
struct Blob *text,
@@ -141,11 +141,11 @@
141141
blob_appendf(ob, "</h%d>", level);
142142
}
143143
144144
static void html_hrule(struct Blob *ob, void *opaque){
145145
INTER_BLOCK(ob);
146
- BLOB_APPEND_LITTERAL(ob, "<hr />\n");
146
+ BLOB_APPEND_LITERAL(ob, "<hr />\n");
147147
}
148148
149149
150150
static void html_list(
151151
struct Blob *ob,
@@ -169,20 +169,20 @@
169169
void *opaque
170170
){
171171
char *text_data = blob_buffer(text);
172172
size_t text_size = blob_size(text);
173173
while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
174
- BLOB_APPEND_LITTERAL(ob, "<li>");
174
+ BLOB_APPEND_LITERAL(ob, "<li>");
175175
blob_append(ob, text_data, text_size);
176
- BLOB_APPEND_LITTERAL(ob, "</li>\n");
176
+ BLOB_APPEND_LITERAL(ob, "</li>\n");
177177
}
178178
179179
static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
180180
INTER_BLOCK(ob);
181
- BLOB_APPEND_LITTERAL(ob, "<p>");
181
+ BLOB_APPEND_LITERAL(ob, "<p>");
182182
BLOB_APPEND_BLOB(ob, text);
183
- BLOB_APPEND_LITTERAL(ob, "</p>\n");
183
+ BLOB_APPEND_LITERAL(ob, "</p>\n");
184184
}
185185
186186
187187
static void html_table(
188188
struct Blob *ob,
@@ -189,68 +189,68 @@
189189
struct Blob *head_row,
190190
struct Blob *rows,
191191
void *opaque
192192
){
193193
INTER_BLOCK(ob);
194
- BLOB_APPEND_LITTERAL(ob, "<table>\n");
194
+ BLOB_APPEND_LITERAL(ob, "<table>\n");
195195
if( head_row && blob_size(head_row)>0 ){
196
- BLOB_APPEND_LITTERAL(ob, "<thead>\n");
196
+ BLOB_APPEND_LITERAL(ob, "<thead>\n");
197197
BLOB_APPEND_BLOB(ob, head_row);
198
- BLOB_APPEND_LITTERAL(ob, "</thead>\n<tbody>\n");
198
+ BLOB_APPEND_LITERAL(ob, "</thead>\n<tbody>\n");
199199
}
200200
if( rows ){
201201
BLOB_APPEND_BLOB(ob, rows);
202202
}
203203
if( head_row && blob_size(head_row)>0 ){
204
- BLOB_APPEND_LITTERAL(ob, "</tbody>\n");
204
+ BLOB_APPEND_LITERAL(ob, "</tbody>\n");
205205
}
206
- BLOB_APPEND_LITTERAL(ob, "</table>\n");
206
+ BLOB_APPEND_LITERAL(ob, "</table>\n");
207207
}
208208
209209
static void html_table_cell(
210210
struct Blob *ob,
211211
struct Blob *text,
212212
int flags,
213213
void *opaque
214214
){
215215
if( flags & MKD_CELL_HEAD ){
216
- BLOB_APPEND_LITTERAL(ob, " <th");
216
+ BLOB_APPEND_LITERAL(ob, " <th");
217217
}else{
218
- BLOB_APPEND_LITTERAL(ob, " <td");
218
+ BLOB_APPEND_LITERAL(ob, " <td");
219219
}
220220
switch( flags & MKD_CELL_ALIGN_MASK ){
221221
case MKD_CELL_ALIGN_LEFT: {
222
- BLOB_APPEND_LITTERAL(ob, " align=\"left\"");
222
+ BLOB_APPEND_LITERAL(ob, " align=\"left\"");
223223
break;
224224
}
225225
case MKD_CELL_ALIGN_RIGHT: {
226
- BLOB_APPEND_LITTERAL(ob, " align=\"right\"");
226
+ BLOB_APPEND_LITERAL(ob, " align=\"right\"");
227227
break;
228228
}
229229
case MKD_CELL_ALIGN_CENTER: {
230
- BLOB_APPEND_LITTERAL(ob, " align=\"center\"");
230
+ BLOB_APPEND_LITERAL(ob, " align=\"center\"");
231231
break;
232232
}
233233
}
234
- BLOB_APPEND_LITTERAL(ob, ">");
234
+ BLOB_APPEND_LITERAL(ob, ">");
235235
BLOB_APPEND_BLOB(ob, text);
236236
if( flags & MKD_CELL_HEAD ){
237
- BLOB_APPEND_LITTERAL(ob, "</th>\n");
237
+ BLOB_APPEND_LITERAL(ob, "</th>\n");
238238
}else{
239
- BLOB_APPEND_LITTERAL(ob, "</td>\n");
239
+ BLOB_APPEND_LITERAL(ob, "</td>\n");
240240
}
241241
}
242242
243243
static void html_table_row(
244244
struct Blob *ob,
245245
struct Blob *cells,
246246
int flags,
247247
void *opaque
248248
){
249
- BLOB_APPEND_LITTERAL(ob, " <tr>\n");
249
+ BLOB_APPEND_LITERAL(ob, " <tr>\n");
250250
BLOB_APPEND_BLOB(ob, cells);
251
- BLOB_APPEND_LITTERAL(ob, " </tr>\n");
251
+ BLOB_APPEND_LITERAL(ob, " </tr>\n");
252252
}
253253
254254
255255
256256
/* HTML span tags */
@@ -265,52 +265,52 @@
265265
struct Blob *link,
266266
enum mkd_autolink type,
267267
void *opaque
268268
){
269269
if( !link || blob_size(link)<=0 ) return 0;
270
- BLOB_APPEND_LITTERAL(ob, "<a href=\"");
271
- if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITTERAL(ob, "mailto:");
270
+ BLOB_APPEND_LITERAL(ob, "<a href=\"");
271
+ if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:");
272272
html_escape(ob, blob_buffer(link), blob_size(link));
273
- BLOB_APPEND_LITTERAL(ob, "\">");
273
+ BLOB_APPEND_LITERAL(ob, "\">");
274274
if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
275275
/* remove "mailto:" from displayed text */
276276
html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
277277
}else{
278278
html_escape(ob, blob_buffer(link), blob_size(link));
279279
}
280
- BLOB_APPEND_LITTERAL(ob, "</a>");
280
+ BLOB_APPEND_LITERAL(ob, "</a>");
281281
return 1;
282282
}
283283
284284
static int html_code_span(struct Blob *ob, struct Blob *text, void *opaque){
285
- BLOB_APPEND_LITTERAL(ob, "<code>");
285
+ BLOB_APPEND_LITERAL(ob, "<code>");
286286
html_escape(ob, blob_buffer(text), blob_size(text));
287
- BLOB_APPEND_LITTERAL(ob, "</code>");
287
+ BLOB_APPEND_LITERAL(ob, "</code>");
288288
return 1;
289289
}
290290
291291
static int html_double_emphasis(
292292
struct Blob *ob,
293293
struct Blob *text,
294294
char c,
295295
void *opaque
296296
){
297
- BLOB_APPEND_LITTERAL(ob, "<strong>");
297
+ BLOB_APPEND_LITERAL(ob, "<strong>");
298298
BLOB_APPEND_BLOB(ob, text);
299
- BLOB_APPEND_LITTERAL(ob, "</strong>");
299
+ BLOB_APPEND_LITERAL(ob, "</strong>");
300300
return 1;
301301
}
302302
303303
static int html_emphasis(
304304
struct Blob *ob,
305305
struct Blob *text,
306306
char c,
307307
void *opaque
308308
){
309
- BLOB_APPEND_LITTERAL(ob, "<em>");
309
+ BLOB_APPEND_LITERAL(ob, "<em>");
310310
BLOB_APPEND_BLOB(ob, text);
311
- BLOB_APPEND_LITTERAL(ob, "</em>");
311
+ BLOB_APPEND_LITERAL(ob, "</em>");
312312
return 1;
313313
}
314314
315315
static int html_image(
316316
struct Blob *ob,
@@ -317,24 +317,24 @@
317317
struct Blob *link,
318318
struct Blob *title,
319319
struct Blob *alt,
320320
void *opaque
321321
){
322
- BLOB_APPEND_LITTERAL(ob, "<img src=\"");
322
+ BLOB_APPEND_LITERAL(ob, "<img src=\"");
323323
html_escape(ob, blob_buffer(link), blob_size(link));
324
- BLOB_APPEND_LITTERAL(ob, "\" alt=\"");
324
+ BLOB_APPEND_LITERAL(ob, "\" alt=\"");
325325
html_escape(ob, blob_buffer(alt), blob_size(alt));
326326
if( title && blob_size(title)>0 ){
327
- BLOB_APPEND_LITTERAL(ob, "\" title=\"");
327
+ BLOB_APPEND_LITERAL(ob, "\" title=\"");
328328
html_escape(ob, blob_buffer(title), blob_size(title));
329329
}
330
- BLOB_APPEND_LITTERAL(ob, "\" />");
330
+ BLOB_APPEND_LITERAL(ob, "\" />");
331331
return 1;
332332
}
333333
334334
static int html_line_break(struct Blob *ob, void *opaque){
335
- BLOB_APPEND_LITTERAL(ob, "<br />\n");
335
+ BLOB_APPEND_LITERAL(ob, "<br />\n");
336336
return 1;
337337
}
338338
339339
static int html_link(
340340
struct Blob *ob,
@@ -341,31 +341,31 @@
341341
struct Blob *link,
342342
struct Blob *title,
343343
struct Blob *content,
344344
void *opaque
345345
){
346
- BLOB_APPEND_LITTERAL(ob, "<a href=\"");
346
+ BLOB_APPEND_LITERAL(ob, "<a href=\"");
347347
html_escape(ob, blob_buffer(link), blob_size(link));
348348
if( title && blob_size(title)>0 ){
349
- BLOB_APPEND_LITTERAL(ob, "\" title=\"");
349
+ BLOB_APPEND_LITERAL(ob, "\" title=\"");
350350
html_escape(ob, blob_buffer(title), blob_size(title));
351351
}
352
- BLOB_APPEND_LITTERAL(ob, "\">");
352
+ BLOB_APPEND_LITERAL(ob, "\">");
353353
BLOB_APPEND_BLOB(ob, content);
354
- BLOB_APPEND_LITTERAL(ob, "</a>");
354
+ BLOB_APPEND_LITERAL(ob, "</a>");
355355
return 1;
356356
}
357357
358358
static int html_triple_emphasis(
359359
struct Blob *ob,
360360
struct Blob *text,
361361
char c,
362362
void *opaque
363363
){
364
- BLOB_APPEND_LITTERAL(ob, "<strong><em>");
364
+ BLOB_APPEND_LITERAL(ob, "<strong><em>");
365365
BLOB_APPEND_BLOB(ob, text);
366
- BLOB_APPEND_LITTERAL(ob, "</em></strong>");
366
+ BLOB_APPEND_LITERAL(ob, "</em></strong>");
367367
return 1;
368368
}
369369
370370
371371
static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
372372
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -34,16 +34,16 @@
34
35 /* INTER_BLOCK -- skip a line between block level elements */
36 #define INTER_BLOCK(ob) \
37 do { if( blob_size(ob)>0 ) blob_append(ob, "\n", 1); } while (0)
38
39 /* BLOB_APPEND_LITTERAL -- append a string litteral to a blob */
40 #define BLOB_APPEND_LITTERAL(blob, litteral) \
41 blob_append((blob), "" litteral, (sizeof litteral)-1)
42 /*
43 * The empty string in the second argument leads to a syntax error
44 * when the macro is not used with a string litteral. Unfortunately
45 * the error is not overly explicit.
46 */
47
48 /* BLOB_APPEND_BLOB -- append blob contents to another */
49 #define BLOB_APPEND_BLOB(dest, src) \
@@ -65,17 +65,17 @@
65 i++;
66 }
67 blob_append(ob, data+beg, i-beg);
68 while( i<size ){
69 if( data[i]=='<' ){
70 BLOB_APPEND_LITTERAL(ob, "&lt;");
71 }else if( data[i]=='>' ){
72 BLOB_APPEND_LITTERAL(ob, "&gt;");
73 }else if( data[i]=='&' ){
74 BLOB_APPEND_LITTERAL(ob, "&amp;");
75 }else if( data[i]=='"' ){
76 BLOB_APPEND_LITTERAL(ob, "&quot;");
77 }else{
78 break;
79 }
80 i++;
81 }
@@ -88,41 +88,41 @@
88 /* Size of the prolog: "<div class='markdown'>\n" */
89 #define PROLOG_SIZE 23
90
91 static void html_prolog(struct Blob *ob, void *opaque){
92 INTER_BLOCK(ob);
93 BLOB_APPEND_LITTERAL(ob, "<div class=\"markdown\">\n");
94 assert( blob_size(ob)==PROLOG_SIZE );
95 }
96
97 static void html_epilog(struct Blob *ob, void *opaque){
98 INTER_BLOCK(ob);
99 BLOB_APPEND_LITTERAL(ob, "</div>\n");
100 }
101
102 static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){
103 char *data = blob_buffer(text);
104 size_t first = 0, size = blob_size(text);
105 INTER_BLOCK(ob);
106 while( first<size && data[first]=='\n' ) first++;
107 while( size>first && data[size-1]=='\n' ) size--;
108 blob_append(ob, data+first, size-first);
109 BLOB_APPEND_LITTERAL(ob, "\n");
110 }
111
112 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
113 INTER_BLOCK(ob);
114 BLOB_APPEND_LITTERAL(ob, "<pre><code>");
115 html_escape(ob, blob_buffer(text), blob_size(text));
116 BLOB_APPEND_LITTERAL(ob, "</code></pre>\n");
117 }
118
119 static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
120 INTER_BLOCK(ob);
121 BLOB_APPEND_LITTERAL(ob, "<blockquote>\n");
122 BLOB_APPEND_BLOB(ob, text);
123 BLOB_APPEND_LITTERAL(ob, "</blockquote>\n");
124 }
125
126 static void html_header(
127 struct Blob *ob,
128 struct Blob *text,
@@ -141,11 +141,11 @@
141 blob_appendf(ob, "</h%d>", level);
142 }
143
144 static void html_hrule(struct Blob *ob, void *opaque){
145 INTER_BLOCK(ob);
146 BLOB_APPEND_LITTERAL(ob, "<hr />\n");
147 }
148
149
150 static void html_list(
151 struct Blob *ob,
@@ -169,20 +169,20 @@
169 void *opaque
170 ){
171 char *text_data = blob_buffer(text);
172 size_t text_size = blob_size(text);
173 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
174 BLOB_APPEND_LITTERAL(ob, "<li>");
175 blob_append(ob, text_data, text_size);
176 BLOB_APPEND_LITTERAL(ob, "</li>\n");
177 }
178
179 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
180 INTER_BLOCK(ob);
181 BLOB_APPEND_LITTERAL(ob, "<p>");
182 BLOB_APPEND_BLOB(ob, text);
183 BLOB_APPEND_LITTERAL(ob, "</p>\n");
184 }
185
186
187 static void html_table(
188 struct Blob *ob,
@@ -189,68 +189,68 @@
189 struct Blob *head_row,
190 struct Blob *rows,
191 void *opaque
192 ){
193 INTER_BLOCK(ob);
194 BLOB_APPEND_LITTERAL(ob, "<table>\n");
195 if( head_row && blob_size(head_row)>0 ){
196 BLOB_APPEND_LITTERAL(ob, "<thead>\n");
197 BLOB_APPEND_BLOB(ob, head_row);
198 BLOB_APPEND_LITTERAL(ob, "</thead>\n<tbody>\n");
199 }
200 if( rows ){
201 BLOB_APPEND_BLOB(ob, rows);
202 }
203 if( head_row && blob_size(head_row)>0 ){
204 BLOB_APPEND_LITTERAL(ob, "</tbody>\n");
205 }
206 BLOB_APPEND_LITTERAL(ob, "</table>\n");
207 }
208
209 static void html_table_cell(
210 struct Blob *ob,
211 struct Blob *text,
212 int flags,
213 void *opaque
214 ){
215 if( flags & MKD_CELL_HEAD ){
216 BLOB_APPEND_LITTERAL(ob, " <th");
217 }else{
218 BLOB_APPEND_LITTERAL(ob, " <td");
219 }
220 switch( flags & MKD_CELL_ALIGN_MASK ){
221 case MKD_CELL_ALIGN_LEFT: {
222 BLOB_APPEND_LITTERAL(ob, " align=\"left\"");
223 break;
224 }
225 case MKD_CELL_ALIGN_RIGHT: {
226 BLOB_APPEND_LITTERAL(ob, " align=\"right\"");
227 break;
228 }
229 case MKD_CELL_ALIGN_CENTER: {
230 BLOB_APPEND_LITTERAL(ob, " align=\"center\"");
231 break;
232 }
233 }
234 BLOB_APPEND_LITTERAL(ob, ">");
235 BLOB_APPEND_BLOB(ob, text);
236 if( flags & MKD_CELL_HEAD ){
237 BLOB_APPEND_LITTERAL(ob, "</th>\n");
238 }else{
239 BLOB_APPEND_LITTERAL(ob, "</td>\n");
240 }
241 }
242
243 static void html_table_row(
244 struct Blob *ob,
245 struct Blob *cells,
246 int flags,
247 void *opaque
248 ){
249 BLOB_APPEND_LITTERAL(ob, " <tr>\n");
250 BLOB_APPEND_BLOB(ob, cells);
251 BLOB_APPEND_LITTERAL(ob, " </tr>\n");
252 }
253
254
255
256 /* HTML span tags */
@@ -265,52 +265,52 @@
265 struct Blob *link,
266 enum mkd_autolink type,
267 void *opaque
268 ){
269 if( !link || blob_size(link)<=0 ) return 0;
270 BLOB_APPEND_LITTERAL(ob, "<a href=\"");
271 if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITTERAL(ob, "mailto:");
272 html_escape(ob, blob_buffer(link), blob_size(link));
273 BLOB_APPEND_LITTERAL(ob, "\">");
274 if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
275 /* remove "mailto:" from displayed text */
276 html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
277 }else{
278 html_escape(ob, blob_buffer(link), blob_size(link));
279 }
280 BLOB_APPEND_LITTERAL(ob, "</a>");
281 return 1;
282 }
283
284 static int html_code_span(struct Blob *ob, struct Blob *text, void *opaque){
285 BLOB_APPEND_LITTERAL(ob, "<code>");
286 html_escape(ob, blob_buffer(text), blob_size(text));
287 BLOB_APPEND_LITTERAL(ob, "</code>");
288 return 1;
289 }
290
291 static int html_double_emphasis(
292 struct Blob *ob,
293 struct Blob *text,
294 char c,
295 void *opaque
296 ){
297 BLOB_APPEND_LITTERAL(ob, "<strong>");
298 BLOB_APPEND_BLOB(ob, text);
299 BLOB_APPEND_LITTERAL(ob, "</strong>");
300 return 1;
301 }
302
303 static int html_emphasis(
304 struct Blob *ob,
305 struct Blob *text,
306 char c,
307 void *opaque
308 ){
309 BLOB_APPEND_LITTERAL(ob, "<em>");
310 BLOB_APPEND_BLOB(ob, text);
311 BLOB_APPEND_LITTERAL(ob, "</em>");
312 return 1;
313 }
314
315 static int html_image(
316 struct Blob *ob,
@@ -317,24 +317,24 @@
317 struct Blob *link,
318 struct Blob *title,
319 struct Blob *alt,
320 void *opaque
321 ){
322 BLOB_APPEND_LITTERAL(ob, "<img src=\"");
323 html_escape(ob, blob_buffer(link), blob_size(link));
324 BLOB_APPEND_LITTERAL(ob, "\" alt=\"");
325 html_escape(ob, blob_buffer(alt), blob_size(alt));
326 if( title && blob_size(title)>0 ){
327 BLOB_APPEND_LITTERAL(ob, "\" title=\"");
328 html_escape(ob, blob_buffer(title), blob_size(title));
329 }
330 BLOB_APPEND_LITTERAL(ob, "\" />");
331 return 1;
332 }
333
334 static int html_line_break(struct Blob *ob, void *opaque){
335 BLOB_APPEND_LITTERAL(ob, "<br />\n");
336 return 1;
337 }
338
339 static int html_link(
340 struct Blob *ob,
@@ -341,31 +341,31 @@
341 struct Blob *link,
342 struct Blob *title,
343 struct Blob *content,
344 void *opaque
345 ){
346 BLOB_APPEND_LITTERAL(ob, "<a href=\"");
347 html_escape(ob, blob_buffer(link), blob_size(link));
348 if( title && blob_size(title)>0 ){
349 BLOB_APPEND_LITTERAL(ob, "\" title=\"");
350 html_escape(ob, blob_buffer(title), blob_size(title));
351 }
352 BLOB_APPEND_LITTERAL(ob, "\">");
353 BLOB_APPEND_BLOB(ob, content);
354 BLOB_APPEND_LITTERAL(ob, "</a>");
355 return 1;
356 }
357
358 static int html_triple_emphasis(
359 struct Blob *ob,
360 struct Blob *text,
361 char c,
362 void *opaque
363 ){
364 BLOB_APPEND_LITTERAL(ob, "<strong><em>");
365 BLOB_APPEND_BLOB(ob, text);
366 BLOB_APPEND_LITTERAL(ob, "</em></strong>");
367 return 1;
368 }
369
370
371 static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
372
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -34,16 +34,16 @@
34
35 /* INTER_BLOCK -- skip a line between block level elements */
36 #define INTER_BLOCK(ob) \
37 do { if( blob_size(ob)>0 ) blob_append(ob, "\n", 1); } while (0)
38
39 /* BLOB_APPEND_LITERAL -- append a string literal to a blob */
40 #define BLOB_APPEND_LITERAL(blob, literal) \
41 blob_append((blob), "" literal, (sizeof literal)-1)
42 /*
43 * The empty string in the second argument leads to a syntax error
44 * when the macro is not used with a string literal. Unfortunately
45 * the error is not overly explicit.
46 */
47
48 /* BLOB_APPEND_BLOB -- append blob contents to another */
49 #define BLOB_APPEND_BLOB(dest, src) \
@@ -65,17 +65,17 @@
65 i++;
66 }
67 blob_append(ob, data+beg, i-beg);
68 while( i<size ){
69 if( data[i]=='<' ){
70 BLOB_APPEND_LITERAL(ob, "&lt;");
71 }else if( data[i]=='>' ){
72 BLOB_APPEND_LITERAL(ob, "&gt;");
73 }else if( data[i]=='&' ){
74 BLOB_APPEND_LITERAL(ob, "&amp;");
75 }else if( data[i]=='"' ){
76 BLOB_APPEND_LITERAL(ob, "&quot;");
77 }else{
78 break;
79 }
80 i++;
81 }
@@ -88,41 +88,41 @@
88 /* Size of the prolog: "<div class='markdown'>\n" */
89 #define PROLOG_SIZE 23
90
91 static void html_prolog(struct Blob *ob, void *opaque){
92 INTER_BLOCK(ob);
93 BLOB_APPEND_LITERAL(ob, "<div class=\"markdown\">\n");
94 assert( blob_size(ob)==PROLOG_SIZE );
95 }
96
97 static void html_epilog(struct Blob *ob, void *opaque){
98 INTER_BLOCK(ob);
99 BLOB_APPEND_LITERAL(ob, "</div>\n");
100 }
101
102 static void html_raw_block(struct Blob *ob, struct Blob *text, void *opaque){
103 char *data = blob_buffer(text);
104 size_t first = 0, size = blob_size(text);
105 INTER_BLOCK(ob);
106 while( first<size && data[first]=='\n' ) first++;
107 while( size>first && data[size-1]=='\n' ) size--;
108 blob_append(ob, data+first, size-first);
109 BLOB_APPEND_LITERAL(ob, "\n");
110 }
111
112 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
113 INTER_BLOCK(ob);
114 BLOB_APPEND_LITERAL(ob, "<pre><code>");
115 html_escape(ob, blob_buffer(text), blob_size(text));
116 BLOB_APPEND_LITERAL(ob, "</code></pre>\n");
117 }
118
119 static void html_blockquote(struct Blob *ob, struct Blob *text, void *opaque){
120 INTER_BLOCK(ob);
121 BLOB_APPEND_LITERAL(ob, "<blockquote>\n");
122 BLOB_APPEND_BLOB(ob, text);
123 BLOB_APPEND_LITERAL(ob, "</blockquote>\n");
124 }
125
126 static void html_header(
127 struct Blob *ob,
128 struct Blob *text,
@@ -141,11 +141,11 @@
141 blob_appendf(ob, "</h%d>", level);
142 }
143
144 static void html_hrule(struct Blob *ob, void *opaque){
145 INTER_BLOCK(ob);
146 BLOB_APPEND_LITERAL(ob, "<hr />\n");
147 }
148
149
150 static void html_list(
151 struct Blob *ob,
@@ -169,20 +169,20 @@
169 void *opaque
170 ){
171 char *text_data = blob_buffer(text);
172 size_t text_size = blob_size(text);
173 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
174 BLOB_APPEND_LITERAL(ob, "<li>");
175 blob_append(ob, text_data, text_size);
176 BLOB_APPEND_LITERAL(ob, "</li>\n");
177 }
178
179 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
180 INTER_BLOCK(ob);
181 BLOB_APPEND_LITERAL(ob, "<p>");
182 BLOB_APPEND_BLOB(ob, text);
183 BLOB_APPEND_LITERAL(ob, "</p>\n");
184 }
185
186
187 static void html_table(
188 struct Blob *ob,
@@ -189,68 +189,68 @@
189 struct Blob *head_row,
190 struct Blob *rows,
191 void *opaque
192 ){
193 INTER_BLOCK(ob);
194 BLOB_APPEND_LITERAL(ob, "<table>\n");
195 if( head_row && blob_size(head_row)>0 ){
196 BLOB_APPEND_LITERAL(ob, "<thead>\n");
197 BLOB_APPEND_BLOB(ob, head_row);
198 BLOB_APPEND_LITERAL(ob, "</thead>\n<tbody>\n");
199 }
200 if( rows ){
201 BLOB_APPEND_BLOB(ob, rows);
202 }
203 if( head_row && blob_size(head_row)>0 ){
204 BLOB_APPEND_LITERAL(ob, "</tbody>\n");
205 }
206 BLOB_APPEND_LITERAL(ob, "</table>\n");
207 }
208
209 static void html_table_cell(
210 struct Blob *ob,
211 struct Blob *text,
212 int flags,
213 void *opaque
214 ){
215 if( flags & MKD_CELL_HEAD ){
216 BLOB_APPEND_LITERAL(ob, " <th");
217 }else{
218 BLOB_APPEND_LITERAL(ob, " <td");
219 }
220 switch( flags & MKD_CELL_ALIGN_MASK ){
221 case MKD_CELL_ALIGN_LEFT: {
222 BLOB_APPEND_LITERAL(ob, " align=\"left\"");
223 break;
224 }
225 case MKD_CELL_ALIGN_RIGHT: {
226 BLOB_APPEND_LITERAL(ob, " align=\"right\"");
227 break;
228 }
229 case MKD_CELL_ALIGN_CENTER: {
230 BLOB_APPEND_LITERAL(ob, " align=\"center\"");
231 break;
232 }
233 }
234 BLOB_APPEND_LITERAL(ob, ">");
235 BLOB_APPEND_BLOB(ob, text);
236 if( flags & MKD_CELL_HEAD ){
237 BLOB_APPEND_LITERAL(ob, "</th>\n");
238 }else{
239 BLOB_APPEND_LITERAL(ob, "</td>\n");
240 }
241 }
242
243 static void html_table_row(
244 struct Blob *ob,
245 struct Blob *cells,
246 int flags,
247 void *opaque
248 ){
249 BLOB_APPEND_LITERAL(ob, " <tr>\n");
250 BLOB_APPEND_BLOB(ob, cells);
251 BLOB_APPEND_LITERAL(ob, " </tr>\n");
252 }
253
254
255
256 /* HTML span tags */
@@ -265,52 +265,52 @@
265 struct Blob *link,
266 enum mkd_autolink type,
267 void *opaque
268 ){
269 if( !link || blob_size(link)<=0 ) return 0;
270 BLOB_APPEND_LITERAL(ob, "<a href=\"");
271 if( type==MKDA_IMPLICIT_EMAIL ) BLOB_APPEND_LITERAL(ob, "mailto:");
272 html_escape(ob, blob_buffer(link), blob_size(link));
273 BLOB_APPEND_LITERAL(ob, "\">");
274 if( type==MKDA_EXPLICIT_EMAIL && blob_size(link)>7 ){
275 /* remove "mailto:" from displayed text */
276 html_escape(ob, blob_buffer(link)+7, blob_size(link)-7);
277 }else{
278 html_escape(ob, blob_buffer(link), blob_size(link));
279 }
280 BLOB_APPEND_LITERAL(ob, "</a>");
281 return 1;
282 }
283
284 static int html_code_span(struct Blob *ob, struct Blob *text, void *opaque){
285 BLOB_APPEND_LITERAL(ob, "<code>");
286 html_escape(ob, blob_buffer(text), blob_size(text));
287 BLOB_APPEND_LITERAL(ob, "</code>");
288 return 1;
289 }
290
291 static int html_double_emphasis(
292 struct Blob *ob,
293 struct Blob *text,
294 char c,
295 void *opaque
296 ){
297 BLOB_APPEND_LITERAL(ob, "<strong>");
298 BLOB_APPEND_BLOB(ob, text);
299 BLOB_APPEND_LITERAL(ob, "</strong>");
300 return 1;
301 }
302
303 static int html_emphasis(
304 struct Blob *ob,
305 struct Blob *text,
306 char c,
307 void *opaque
308 ){
309 BLOB_APPEND_LITERAL(ob, "<em>");
310 BLOB_APPEND_BLOB(ob, text);
311 BLOB_APPEND_LITERAL(ob, "</em>");
312 return 1;
313 }
314
315 static int html_image(
316 struct Blob *ob,
@@ -317,24 +317,24 @@
317 struct Blob *link,
318 struct Blob *title,
319 struct Blob *alt,
320 void *opaque
321 ){
322 BLOB_APPEND_LITERAL(ob, "<img src=\"");
323 html_escape(ob, blob_buffer(link), blob_size(link));
324 BLOB_APPEND_LITERAL(ob, "\" alt=\"");
325 html_escape(ob, blob_buffer(alt), blob_size(alt));
326 if( title && blob_size(title)>0 ){
327 BLOB_APPEND_LITERAL(ob, "\" title=\"");
328 html_escape(ob, blob_buffer(title), blob_size(title));
329 }
330 BLOB_APPEND_LITERAL(ob, "\" />");
331 return 1;
332 }
333
334 static int html_line_break(struct Blob *ob, void *opaque){
335 BLOB_APPEND_LITERAL(ob, "<br />\n");
336 return 1;
337 }
338
339 static int html_link(
340 struct Blob *ob,
@@ -341,31 +341,31 @@
341 struct Blob *link,
342 struct Blob *title,
343 struct Blob *content,
344 void *opaque
345 ){
346 BLOB_APPEND_LITERAL(ob, "<a href=\"");
347 html_escape(ob, blob_buffer(link), blob_size(link));
348 if( title && blob_size(title)>0 ){
349 BLOB_APPEND_LITERAL(ob, "\" title=\"");
350 html_escape(ob, blob_buffer(title), blob_size(title));
351 }
352 BLOB_APPEND_LITERAL(ob, "\">");
353 BLOB_APPEND_BLOB(ob, content);
354 BLOB_APPEND_LITERAL(ob, "</a>");
355 return 1;
356 }
357
358 static int html_triple_emphasis(
359 struct Blob *ob,
360 struct Blob *text,
361 char c,
362 void *opaque
363 ){
364 BLOB_APPEND_LITERAL(ob, "<strong><em>");
365 BLOB_APPEND_BLOB(ob, text);
366 BLOB_APPEND_LITERAL(ob, "</em></strong>");
367 return 1;
368 }
369
370
371 static void html_normal_text(struct Blob *ob, struct Blob *text, void *opaque){
372
+1 -1
--- src/merge.c
+++ src/merge.c
@@ -657,11 +657,11 @@
657657
}
658658
db_finalize(&q);
659659
660660
/*
661661
** Rename files that have taken a rename on P->M but which keep the same
662
- ** name o P->V. If a file is renamed on P->V only or on both P->V and
662
+ ** name on P->V. If a file is renamed on P->V only or on both P->V and
663663
** P->M then we retain the V name of the file.
664664
*/
665665
db_prepare(&q,
666666
"SELECT idv, fnp, fnm FROM fv"
667667
" WHERE idv>0 AND idp>0 AND idm>0 AND fnp=fn AND fnm!=fnp"
668668
--- src/merge.c
+++ src/merge.c
@@ -657,11 +657,11 @@
657 }
658 db_finalize(&q);
659
660 /*
661 ** Rename files that have taken a rename on P->M but which keep the same
662 ** name o P->V. If a file is renamed on P->V only or on both P->V and
663 ** P->M then we retain the V name of the file.
664 */
665 db_prepare(&q,
666 "SELECT idv, fnp, fnm FROM fv"
667 " WHERE idv>0 AND idp>0 AND idm>0 AND fnp=fn AND fnm!=fnp"
668
--- src/merge.c
+++ src/merge.c
@@ -657,11 +657,11 @@
657 }
658 db_finalize(&q);
659
660 /*
661 ** Rename files that have taken a rename on P->M but which keep the same
662 ** name on P->V. If a file is renamed on P->V only or on both P->V and
663 ** P->M then we retain the V name of the file.
664 */
665 db_prepare(&q,
666 "SELECT idv, fnp, fnm FROM fv"
667 " WHERE idv>0 AND idp>0 AND idm>0 AND fnp=fn AND fnm!=fnp"
668
+1 -1
--- src/piechart.c
+++ src/piechart.c
@@ -53,11 +53,11 @@
5353
case 4: r=C; g=A; b=v; break;
5454
default: r=v; g=A; b=B; break;
5555
}
5656
}
5757
sqlite3_snprintf(sizeof(zColor),zColor,"#%02x%02x%02x",r,g,b);
58
- return zColor;
58
+ return zColor;
5959
}
6060
6161
/*
6262
** Flags that can be passed into the pie-chart generator
6363
*/
6464
--- src/piechart.c
+++ src/piechart.c
@@ -53,11 +53,11 @@
53 case 4: r=C; g=A; b=v; break;
54 default: r=v; g=A; b=B; break;
55 }
56 }
57 sqlite3_snprintf(sizeof(zColor),zColor,"#%02x%02x%02x",r,g,b);
58 return zColor;
59 }
60
61 /*
62 ** Flags that can be passed into the pie-chart generator
63 */
64
--- src/piechart.c
+++ src/piechart.c
@@ -53,11 +53,11 @@
53 case 4: r=C; g=A; b=v; break;
54 default: r=v; g=A; b=B; break;
55 }
56 }
57 sqlite3_snprintf(sizeof(zColor),zColor,"#%02x%02x%02x",r,g,b);
58 return zColor;
59 }
60
61 /*
62 ** Flags that can be passed into the pie-chart generator
63 */
64
+1 -1
--- src/rss.c
+++ src/rss.c
@@ -94,11 +94,11 @@
9494
blob_append(&bSQL, " AND event.type!='w'", -1);
9595
}else{
9696
blob_append(&bSQL, " AND event.type=='ci'", -1);
9797
}
9898
}else if( !g.perm.RdTkt ){
99
- assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
99
+ assert( !g.perm.RdTkt && g.perm.Read && g.perm.RdWiki );
100100
blob_append(&bSQL, " AND event.type!='t'", -1);
101101
}
102102
}
103103
104104
if( zTicketUuid ){
105105
--- src/rss.c
+++ src/rss.c
@@ -94,11 +94,11 @@
94 blob_append(&bSQL, " AND event.type!='w'", -1);
95 }else{
96 blob_append(&bSQL, " AND event.type=='ci'", -1);
97 }
98 }else if( !g.perm.RdTkt ){
99 assert( !g.perm.RdTkt &&& g.perm.Read && g.perm.RdWiki );
100 blob_append(&bSQL, " AND event.type!='t'", -1);
101 }
102 }
103
104 if( zTicketUuid ){
105
--- src/rss.c
+++ src/rss.c
@@ -94,11 +94,11 @@
94 blob_append(&bSQL, " AND event.type!='w'", -1);
95 }else{
96 blob_append(&bSQL, " AND event.type=='ci'", -1);
97 }
98 }else if( !g.perm.RdTkt ){
99 assert( !g.perm.RdTkt && g.perm.Read && g.perm.RdWiki );
100 blob_append(&bSQL, " AND event.type!='t'", -1);
101 }
102 }
103
104 if( zTicketUuid ){
105
+2 -1
--- src/shell.c
+++ src/shell.c
@@ -3256,11 +3256,12 @@
32563256
azArg[1]);
32573257
rc = 1;
32583258
goto meta_command_exit;
32593259
}
32603260
if( nArg==3 ){
3261
- sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
3261
+ sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3262
+ (int)integerValue(azArg[2]));
32623263
}
32633264
printf("%20s %d\n", aLimit[iLimit].zLimitName,
32643265
sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
32653266
}
32663267
}else
32673268
--- src/shell.c
+++ src/shell.c
@@ -3256,11 +3256,12 @@
3256 azArg[1]);
3257 rc = 1;
3258 goto meta_command_exit;
3259 }
3260 if( nArg==3 ){
3261 sqlite3_limit(p->db, aLimit[iLimit].limitCode, integerValue(azArg[2]));
 
3262 }
3263 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3264 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3265 }
3266 }else
3267
--- src/shell.c
+++ src/shell.c
@@ -3256,11 +3256,12 @@
3256 azArg[1]);
3257 rc = 1;
3258 goto meta_command_exit;
3259 }
3260 if( nArg==3 ){
3261 sqlite3_limit(p->db, aLimit[iLimit].limitCode,
3262 (int)integerValue(azArg[2]));
3263 }
3264 printf("%20s %d\n", aLimit[iLimit].zLimitName,
3265 sqlite3_limit(p->db, aLimit[iLimit].limitCode, -1));
3266 }
3267 }else
3268
+1 -1
--- src/sitemap.c
+++ src/sitemap.c
@@ -145,10 +145,10 @@
145145
if( g.perm.Read ){
146146
@ <li>%z(href("%R/test-rename-list"))List of file renames</a></li>
147147
}
148148
@ <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic
149149
@ colors assigned to branch names</a>
150
- @ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</li>
150
+ @ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</a></li>
151151
@ </ul></li>
152152
@ </ul></li>
153153
style_footer();
154154
}
155155
--- src/sitemap.c
+++ src/sitemap.c
@@ -145,10 +145,10 @@
145 if( g.perm.Read ){
146 @ <li>%z(href("%R/test-rename-list"))List of file renames</a></li>
147 }
148 @ <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic
149 @ colors assigned to branch names</a>
150 @ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</li>
151 @ </ul></li>
152 @ </ul></li>
153 style_footer();
154 }
155
--- src/sitemap.c
+++ src/sitemap.c
@@ -145,10 +145,10 @@
145 if( g.perm.Read ){
146 @ <li>%z(href("%R/test-rename-list"))List of file renames</a></li>
147 }
148 @ <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic
149 @ colors assigned to branch names</a>
150 @ <li>%z(href("%R/test-captcha"))Random ASCII-art Captcha image</a></li>
151 @ </ul></li>
152 @ </ul></li>
153 style_footer();
154 }
155
+4913 -449
--- 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.10.1. By combining all the individual C code files into this
3
+** version 3.8.11. 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.
@@ -316,13 +316,13 @@
316316
**
317317
** See also: [sqlite3_libversion()],
318318
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
319319
** [sqlite_version()] and [sqlite_source_id()].
320320
*/
321
-#define SQLITE_VERSION "3.8.10.1"
322
-#define SQLITE_VERSION_NUMBER 3008010
323
-#define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40"
321
+#define SQLITE_VERSION "3.8.11"
322
+#define SQLITE_VERSION_NUMBER 3008011
323
+#define SQLITE_SOURCE_ID "2015-05-29 17:51:16 db4e9728fae5f7b0fad6aa0a5be317a7c9e7c417"
324324
325325
/*
326326
** CAPI3REF: Run-Time Library Version Numbers
327327
** KEYWORDS: sqlite3_version, sqlite3_sourceid
328328
**
@@ -1161,17 +1161,25 @@
11611161
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
11621162
** opcode causes the xFileControl method to swap the file handle with the one
11631163
** pointed to by the pArg argument. This capability is used during testing
11641164
** and only needs to be supported when SQLITE_TEST is defined.
11651165
**
1166
-** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1166
+* <li>[[SQLITE_FCNTL_WAL_BLOCK]]
11671167
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
11681168
** be advantageous to block on the next WAL lock if the lock is not immediately
11691169
** available. The WAL subsystem issues this signal during rare
11701170
** circumstances in order to fix a problem with priority inversion.
11711171
** Applications should <em>not</em> use this file-control.
11721172
**
1173
+** <li>[[SQLITE_FCNTL_ZIPVFS]]
1174
+** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
1175
+** VFS should return SQLITE_NOTFOUND for this opcode.
1176
+**
1177
+** <li>[[SQLITE_FCNTL_OTA]]
1178
+** The [SQLITE_FCNTL_OTA] opcode is implemented by the special VFS used by
1179
+** the OTA extension only. All other VFS should return SQLITE_NOTFOUND for
1180
+** this opcode.
11731181
** </ul>
11741182
*/
11751183
#define SQLITE_FCNTL_LOCKSTATE 1
11761184
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
11771185
#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1193,10 +1201,12 @@
11931201
#define SQLITE_FCNTL_HAS_MOVED 20
11941202
#define SQLITE_FCNTL_SYNC 21
11951203
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
11961204
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
11971205
#define SQLITE_FCNTL_WAL_BLOCK 24
1206
+#define SQLITE_FCNTL_ZIPVFS 25
1207
+#define SQLITE_FCNTL_OTA 26
11981208
11991209
/* deprecated names */
12001210
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
12011211
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
12021212
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3595,11 +3605,13 @@
35953605
**
35963606
** An sqlite3_value object may be either "protected" or "unprotected".
35973607
** Some interfaces require a protected sqlite3_value. Other interfaces
35983608
** will accept either a protected or an unprotected sqlite3_value.
35993609
** Every interface that accepts sqlite3_value arguments specifies
3600
-** whether or not it requires a protected sqlite3_value.
3610
+** whether or not it requires a protected sqlite3_value. The
3611
+** [sqlite3_value_dup()] interface can be used to construct a new
3612
+** protected sqlite3_value from an unprotected sqlite3_value.
36013613
**
36023614
** The terms "protected" and "unprotected" refer to whether or not
36033615
** a mutex is held. An internal mutex is held for a protected
36043616
** sqlite3_value object but no mutex is held for an unprotected
36053617
** sqlite3_value object. If SQLite is compiled to be single-threaded
@@ -4098,12 +4110,10 @@
40984110
/*
40994111
** CAPI3REF: Result Values From A Query
41004112
** KEYWORDS: {column access functions}
41014113
** METHOD: sqlite3_stmt
41024114
**
4103
-** These routines form the "result set" interface.
4104
-**
41054115
** ^These routines return information about a single column of the current
41064116
** result row of a query. ^In every case the first argument is a pointer
41074117
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
41084118
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
41094119
** and the second argument is the index of the column for which information
@@ -4159,17 +4169,18 @@
41594169
**
41604170
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
41614171
** even empty strings, are always zero-terminated. ^The return
41624172
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
41634173
**
4164
-** ^The object returned by [sqlite3_column_value()] is an
4165
-** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
4166
-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
4174
+** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
4175
+** [unprotected sqlite3_value] object. In a multithreaded environment,
4176
+** an unprotected sqlite3_value object may only be used safely with
4177
+** [sqlite3_bind_value()] and [sqlite3_result_value()].
41674178
** If the [unprotected sqlite3_value] object returned by
41684179
** [sqlite3_column_value()] is used in any other way, including calls
41694180
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
4170
-** or [sqlite3_value_bytes()], then the behavior is undefined.
4181
+** or [sqlite3_value_bytes()], the behavior is not threadsafe.
41714182
**
41724183
** These routines attempt to convert the value where appropriate. ^For
41734184
** example, if the internal representation is FLOAT and a text result
41744185
** is requested, [sqlite3_snprintf()] is used internally to perform the
41754186
** conversion automatically. ^(The following table details the conversions
@@ -4196,16 +4207,10 @@
41964207
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
41974208
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
41984209
** </table>
41994210
** </blockquote>)^
42004211
**
4201
-** The table above makes reference to standard C library functions atoi()
4202
-** and atof(). SQLite does not really use these functions. It has its
4203
-** own equivalent internal routines. The atoi() and atof() names are
4204
-** used in the table for brevity and because they are familiar to most
4205
-** C programmers.
4206
-**
42074212
** Note that when type conversions occur, pointers returned by prior
42084213
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
42094214
** sqlite3_column_text16() may be invalidated.
42104215
** Type conversions and pointer invalidations might occur
42114216
** in the following cases:
@@ -4226,11 +4231,11 @@
42264231
** not invalidate a prior pointer, though of course the content of the buffer
42274232
** that the prior pointer references will have been modified. Other kinds
42284233
** of conversion are done in place when it is possible, but sometimes they
42294234
** are not possible and in those cases prior pointers are invalidated.
42304235
**
4231
-** The safest and easiest to remember policy is to invoke these routines
4236
+** The safest policy is to invoke these routines
42324237
** in one of the following ways:
42334238
**
42344239
** <ul>
42354240
** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
42364241
** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
@@ -4246,11 +4251,11 @@
42464251
** with calls to sqlite3_column_bytes().
42474252
**
42484253
** ^The pointers returned are valid until a type conversion occurs as
42494254
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
42504255
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
4251
-** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
4256
+** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
42524257
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
42534258
** [sqlite3_free()].
42544259
**
42554260
** ^(If a memory allocation error occurs during the evaluation of any
42564261
** of these routines, a default value is returned. The default value
@@ -4496,16 +4501,16 @@
44964501
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
44974502
void*,sqlite3_int64);
44984503
#endif
44994504
45004505
/*
4501
-** CAPI3REF: Obtaining SQL Function Parameter Values
4506
+** CAPI3REF: Obtaining SQL Values
45024507
** METHOD: sqlite3_value
45034508
**
45044509
** The C-language implementation of SQL functions and aggregates uses
45054510
** this set of interface routines to access the parameter values on
4506
-** the function or aggregate.
4511
+** the function or aggregate.
45074512
**
45084513
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
45094514
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
45104515
** define callbacks that implement the SQL functions and aggregates.
45114516
** The 3rd parameter to these callbacks is an array of pointers to
@@ -4554,10 +4559,27 @@
45544559
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
45554560
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
45564561
SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
45574562
SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
45584563
4564
+/*
4565
+** CAPI3REF: Copy And Free SQL Values
4566
+** METHOD: sqlite3_value
4567
+**
4568
+** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
4569
+** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
4570
+** is a [protected sqlite3_value] object even if the input is not.
4571
+** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
4572
+** memory allocation fails.
4573
+**
4574
+** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
4575
+** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
4576
+** then sqlite3_value_free(V) is a harmless no-op.
4577
+*/
4578
+SQLITE_API SQLITE_EXPERIMENTAL sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
4579
+SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
4580
+
45594581
/*
45604582
** CAPI3REF: Obtain Aggregate Function Context
45614583
** METHOD: sqlite3_context
45624584
**
45634585
** Implementations of aggregate SQL functions use this
@@ -4801,11 +4823,11 @@
48014823
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
48024824
** then SQLite makes a copy of the result into space obtained from
48034825
** from [sqlite3_malloc()] before it returns.
48044826
**
48054827
** ^The sqlite3_result_value() interface sets the result of
4806
-** the application-defined function to be a copy the
4828
+** the application-defined function to be a copy of the
48074829
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
48084830
** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
48094831
** so that the [sqlite3_value] specified in the parameter may change or
48104832
** be deallocated after sqlite3_result_value() returns without harm.
48114833
** ^A [protected sqlite3_value] object may always be used where an
@@ -6077,11 +6099,11 @@
60776099
** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
60786100
** always returns zero.
60796101
**
60806102
** ^This function sets the database handle error code and message.
60816103
*/
6082
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
6104
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
60836105
60846106
/*
60856107
** CAPI3REF: Close A BLOB Handle
60866108
** DESTRUCTOR: sqlite3_blob
60876109
**
@@ -7887,11 +7909,11 @@
78877909
** as if the loop did not exist - it returns non-zero and leave the variable
78887910
** that pOut points to unchanged.
78897911
**
78907912
** See also: [sqlite3_stmt_scanstatus_reset()]
78917913
*/
7892
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
7914
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
78937915
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
78947916
int idx, /* Index of loop to report on */
78957917
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
78967918
void *pOut /* Result written here */
78977919
);
@@ -7903,11 +7925,11 @@
79037925
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
79047926
**
79057927
** This API is only available if the library is built with pre-processor
79067928
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
79077929
*/
7908
-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
7930
+SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
79097931
79107932
79117933
/*
79127934
** Undo the hack that converts floating point types to integer for
79137935
** builds on processors without floating point support.
@@ -8018,10 +8040,12 @@
80188040
sqlite3_int64 iRowid; /* Rowid for current entry */
80198041
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
80208042
int eParentWithin; /* Visibility of parent node */
80218043
int eWithin; /* OUT: Visiblity */
80228044
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
8045
+ /* The following fields are only available in 3.8.11 and later */
8046
+ sqlite3_value **apSqlParam; /* Original SQL values of parameters */
80238047
};
80248048
80258049
/*
80268050
** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
80278051
*/
@@ -11167,10 +11191,11 @@
1116711191
#define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
1116811192
#define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
1116911193
#define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
1117011194
#define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
1117111195
#define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
11196
+#define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
1117211197
1117311198
1117411199
/*
1117511200
** Bits of the sqlite3.dbOptFlags field that are used by the
1117611201
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -11548,12 +11573,13 @@
1154811573
#define TF_Readonly 0x01 /* Read-only system table */
1154911574
#define TF_Ephemeral 0x02 /* An ephemeral table */
1155011575
#define TF_HasPrimaryKey 0x04 /* Table has a primary key */
1155111576
#define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
1155211577
#define TF_Virtual 0x10 /* Is a virtual table */
11553
-#define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
11554
-#define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */
11578
+#define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
11579
+#define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
11580
+#define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
1155511581
1155611582
1155711583
/*
1155811584
** Test to see whether or not a table is a virtual table. This is
1155911585
** done as a macro so that it will be optimized out when virtual
@@ -11567,10 +11593,11 @@
1156711593
# define IsHiddenColumn(X) 0
1156811594
#endif
1156911595
1157011596
/* Does the table have a rowid */
1157111597
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
11598
+#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
1157211599
1157311600
/*
1157411601
** Each foreign key constraint is an instance of the following structure.
1157511602
**
1157611603
** A foreign key is associated with two tables. The "from" table is
@@ -11725,10 +11752,18 @@
1172511752
** must be unique and what to do if they are not. When Index.onError=OE_None,
1172611753
** it means this is not a unique index. Otherwise it is a unique index
1172711754
** and the value of Index.onError indicate the which conflict resolution
1172811755
** algorithm to employ whenever an attempt is made to insert a non-unique
1172911756
** element.
11757
+**
11758
+** While parsing a CREATE TABLE or CREATE INDEX statement in order to
11759
+** generate VDBE code (as opposed to parsing one read from an sqlite_master
11760
+** table as part of parsing an existing database schema), transient instances
11761
+** of this structure may be created. In this case the Index.tnum variable is
11762
+** used to store the address of a VDBE instruction, not a database page
11763
+** number (it cannot - the database page is not allocated until the VDBE
11764
+** program is executed). See convertToWithoutRowidTable() for details.
1173011765
*/
1173111766
struct Index {
1173211767
char *zName; /* Name of this index */
1173311768
i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
1173411769
LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */
@@ -12299,23 +12334,24 @@
1229912334
/*
1230012335
** Allowed values for Select.selFlags. The "SF" prefix stands for
1230112336
** "Select Flag".
1230212337
*/
1230312338
#define SF_Distinct 0x0001 /* Output should be DISTINCT */
12304
-#define SF_Resolved 0x0002 /* Identifiers have been resolved */
12305
-#define SF_Aggregate 0x0004 /* Contains aggregate functions */
12306
-#define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
12307
-#define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
12308
-#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
12309
-#define SF_Compound 0x0040 /* Part of a compound query */
12310
-#define SF_Values 0x0080 /* Synthesized from VALUES clause */
12311
-#define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
12312
-#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
12313
-#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
12314
-#define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
12339
+#define SF_All 0x0002 /* Includes the ALL keyword */
12340
+#define SF_Resolved 0x0004 /* Identifiers have been resolved */
12341
+#define SF_Aggregate 0x0008 /* Contains aggregate functions */
12342
+#define SF_UsesEphemeral 0x0010 /* Uses the OpenEphemeral opcode */
12343
+#define SF_Expanded 0x0020 /* sqlite3SelectExpand() called on this */
12344
+#define SF_HasTypeInfo 0x0040 /* FROM subqueries have Table metadata */
12345
+#define SF_Compound 0x0080 /* Part of a compound query */
12346
+#define SF_Values 0x0100 /* Synthesized from VALUES clause */
12347
+#define SF_MultiValue 0x0200 /* Single VALUES term with multiple rows */
12348
+#define SF_NestedFrom 0x0400 /* Part of a parenthesized FROM clause */
12349
+#define SF_MaybeConvert 0x0800 /* Need convertCompoundSelectToSubquery() */
1231512350
#define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
12316
-#define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */
12351
+#define SF_Recursive 0x2000 /* The recursive part of a recursive CTE */
12352
+#define SF_Converted 0x4000 /* By convertCompoundSelectToSubquery() */
1231712353
1231812354
1231912355
/*
1232012356
** The results of a SELECT can be distributed in several ways, as defined
1232112357
** by one of the following macros. The "SRT" prefix means "SELECT Result
@@ -12553,11 +12589,10 @@
1255312589
1255412590
/* Information used while coding trigger programs. */
1255512591
Parse *pToplevel; /* Parse structure for main program (or NULL) */
1255612592
Table *pTriggerTab; /* Table triggers are being coded for */
1255712593
int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
12558
- int addrSkipPK; /* Address of instruction to skip PRIMARY KEY index */
1255912594
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
1256012595
u32 oldmask; /* Mask of old.* columns referenced */
1256112596
u32 newmask; /* Mask of new.* columns referenced */
1256212597
u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
1256312598
u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
@@ -13065,11 +13100,10 @@
1306513100
#define SQLITE_PRINTF_SQLFUNC 0x02
1306613101
SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
1306713102
SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
1306813103
SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
1306913104
SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
13070
-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
1307113105
#if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
1307213106
SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
1307313107
#endif
1307413108
#if defined(SQLITE_TEST)
1307513109
SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
@@ -13084,11 +13118,11 @@
1308413118
SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
1308513119
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
1308613120
#endif
1308713121
1308813122
13089
-SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
13123
+SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
1309013124
SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
1309113125
SQLITE_PRIVATE int sqlite3Dequote(char*);
1309213126
SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
1309313127
SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
1309413128
SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
@@ -13780,10 +13814,14 @@
1378013814
*/
1378113815
#if SQLITE_MAX_WORKER_THREADS>0
1378213816
SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
1378313817
SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
1378413818
#endif
13819
+
13820
+#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
13821
+SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
13822
+#endif
1378513823
1378613824
#endif /* _SQLITEINT_H_ */
1378713825
1378813826
/************** End of sqliteInt.h *******************************************/
1378913827
/************** Begin file global.c ******************************************/
@@ -14685,10 +14723,16 @@
1468514723
Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
1468614724
void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
1468714725
#endif
1468814726
};
1468914727
14728
+/*
14729
+** Size of struct Mem not including the Mem.zMalloc member or anything that
14730
+** follows.
14731
+*/
14732
+#define MEMCELLSIZE offsetof(Mem,zMalloc)
14733
+
1469014734
/* One or more of the following flags are set to indicate the validOK
1469114735
** representations of the value stored in the Mem struct.
1469214736
**
1469314737
** If the MEM_Null flag is set, then the value is an SQL NULL value.
1469414738
** No other flags may be set in this case.
@@ -14890,10 +14934,11 @@
1489014934
#define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
1489114935
1489214936
/*
1489314937
** Function prototypes
1489414938
*/
14939
+SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
1489514940
SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
1489614941
void sqliteVdbePopStack(Vdbe*,int);
1489714942
SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
1489814943
SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
1489914944
#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -20738,28 +20783,24 @@
2073820783
2073920784
/*
2074020785
** Return the amount of memory currently checked out.
2074120786
*/
2074220787
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
20743
- int n, mx;
20744
- sqlite3_int64 res;
20745
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
20746
- res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
20788
+ sqlite3_int64 res, mx;
20789
+ sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
2074720790
return res;
2074820791
}
2074920792
2075020793
/*
2075120794
** Return the maximum amount of memory that has ever been
2075220795
** checked out since either the beginning of this process
2075320796
** or since the most recent reset.
2075420797
*/
2075520798
SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
20756
- int n, mx;
20757
- sqlite3_int64 res;
20758
- sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
20759
- res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
20760
- return res;
20799
+ sqlite3_int64 res, mx;
20800
+ sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
20801
+ return mx;
2076120802
}
2076220803
2076320804
/*
2076420805
** Trigger the alarm
2076520806
*/
@@ -21287,23 +21328,15 @@
2128721328
}
2128821329
return zNew;
2128921330
}
2129021331
2129121332
/*
21292
-** Create a string from the zFromat argument and the va_list that follows.
21293
-** Store the string in memory obtained from sqliteMalloc() and make *pz
21294
-** point to that string.
21333
+** Free any prior content in *pz and replace it with a copy of zNew.
2129521334
*/
21296
-SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
21297
- va_list ap;
21298
- char *z;
21299
-
21300
- va_start(ap, zFormat);
21301
- z = sqlite3VMPrintf(db, zFormat, ap);
21302
- va_end(ap);
21335
+SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
2130321336
sqlite3DbFree(db, *pz);
21304
- *pz = z;
21337
+ *pz = sqlite3DbStrDup(db, zNew);
2130521338
}
2130621339
2130721340
/*
2130821341
** Take actions at the end of an API call to indicate an OOM error
2130921342
*/
@@ -22271,28 +22304,10 @@
2227122304
z = sqlite3VMPrintf(db, zFormat, ap);
2227222305
va_end(ap);
2227322306
return z;
2227422307
}
2227522308
22276
-/*
22277
-** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
22278
-** the string and before returning. This routine is intended to be used
22279
-** to modify an existing string. For example:
22280
-**
22281
-** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
22282
-**
22283
-*/
22284
-SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
22285
- va_list ap;
22286
- char *z;
22287
- va_start(ap, zFormat);
22288
- z = sqlite3VMPrintf(db, zFormat, ap);
22289
- va_end(ap);
22290
- sqlite3DbFree(db, zStr);
22291
- return z;
22292
-}
22293
-
2229422309
/*
2229522310
** Print into memory obtained from sqlite3_malloc(). Omit the internal
2229622311
** %-conversion extensions.
2229722312
*/
2229822313
SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
@@ -36220,10 +36235,16 @@
3622036235
*/
3622136236
if( pFile->locktype>=locktype ){
3622236237
OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
3622336238
return SQLITE_OK;
3622436239
}
36240
+
36241
+ /* Do not allow any kind of write-lock on a read-only database
36242
+ */
36243
+ if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){
36244
+ return SQLITE_IOERR_LOCK;
36245
+ }
3622536246
3622636247
/* Make sure the locking sequence is correct
3622736248
*/
3622836249
assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
3622936250
assert( locktype!=PENDING_LOCK );
@@ -38617,18 +38638,18 @@
3861738638
#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
3861838639
if( sizeof(UUID)<=nBuf-n ){
3861938640
UUID id;
3862038641
memset(&id, 0, sizeof(UUID));
3862138642
osUuidCreate(&id);
38622
- memcpy(zBuf, &id, sizeof(UUID));
38643
+ memcpy(&zBuf[n], &id, sizeof(UUID));
3862338644
n += sizeof(UUID);
3862438645
}
3862538646
if( sizeof(UUID)<=nBuf-n ){
3862638647
UUID id;
3862738648
memset(&id, 0, sizeof(UUID));
3862838649
osUuidCreateSequential(&id);
38629
- memcpy(zBuf, &id, sizeof(UUID));
38650
+ memcpy(&zBuf[n], &id, sizeof(UUID));
3863038651
n += sizeof(UUID);
3863138652
}
3863238653
#endif
3863338654
#endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
3863438655
return n;
@@ -44777,15 +44798,14 @@
4477744798
*/
4477844799
assert( pPager->eState==PAGER_OPEN );
4477944800
assert( pPager->eLock>=SHARED_LOCK );
4478044801
nPage = sqlite3WalDbsize(pPager->pWal);
4478144802
44782
- /* If the database size was not available from the WAL sub-system,
44783
- ** determine it based on the size of the database file. If the size
44784
- ** of the database file is not an integer multiple of the page-size,
44785
- ** round down to the nearest page. Except, any file larger than 0
44786
- ** bytes in size is considered to contain at least one page.
44803
+ /* If the number of pages in the database is not available from the
44804
+ ** WAL sub-system, determine the page counte based on the size of
44805
+ ** the database file. If the size of the database file is not an
44806
+ ** integer multiple of the page-size, round up the result.
4478744807
*/
4478844808
if( nPage==0 ){
4478944809
i64 n = 0; /* Size of db file in bytes */
4479044810
assert( isOpen(pPager->fd) || pPager->tempFile );
4479144811
if( isOpen(pPager->fd) ){
@@ -54245,30 +54265,22 @@
5424554265
u8 *pAddr; /* The i-th cell pointer */
5424654266
pAddr = &data[cellOffset + i*2];
5424754267
pc = get2byte(pAddr);
5424854268
testcase( pc==iCellFirst );
5424954269
testcase( pc==iCellLast );
54250
-#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
5425154270
/* These conditions have already been verified in btreeInitPage()
54252
- ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
54271
+ ** if PRAGMA cell_size_check=ON.
5425354272
*/
5425454273
if( pc<iCellFirst || pc>iCellLast ){
5425554274
return SQLITE_CORRUPT_BKPT;
5425654275
}
54257
-#endif
5425854276
assert( pc>=iCellFirst && pc<=iCellLast );
5425954277
size = cellSizePtr(pPage, &src[pc]);
5426054278
cbrk -= size;
54261
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
54262
- if( cbrk<iCellFirst ){
54263
- return SQLITE_CORRUPT_BKPT;
54264
- }
54265
-#else
5426654279
if( cbrk<iCellFirst || pc+size>usableSize ){
5426754280
return SQLITE_CORRUPT_BKPT;
5426854281
}
54269
-#endif
5427054282
assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
5427154283
testcase( cbrk+size==usableSize );
5427254284
testcase( pc+size==usableSize );
5427354285
put2byte(pAddr, cbrk);
5427454286
if( temp==0 ){
@@ -54340,11 +54352,11 @@
5434054352
}
5434154353
/* Remove the slot from the free-list. Update the number of
5434254354
** fragmented bytes within the page. */
5434354355
memcpy(&aData[iAddr], &aData[pc], 2);
5434454356
aData[hdr+7] += (u8)x;
54345
- }else if( size+pc > usableSize ){
54357
+ }else if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
5434654358
*pRc = SQLITE_CORRUPT_BKPT;
5434754359
return 0;
5434854360
}else{
5434954361
/* The slot remains on the free-list. Reduce its size to account
5435054362
** for the portion used by the new allocation. */
@@ -54392,11 +54404,15 @@
5439254404
** and the reserved space is zero (the usual value for reserved space)
5439354405
** then the cell content offset of an empty page wants to be 65536.
5439454406
** However, that integer is too large to be stored in a 2-byte unsigned
5439554407
** integer, so a value of 0 is used in its place. */
5439654408
top = get2byteNotZero(&data[hdr+5]);
54397
- if( gap>top ) return SQLITE_CORRUPT_BKPT;
54409
+ if( gap>top || NEVER((u32)top>pPage->pBt->usableSize) ){
54410
+ /* The NEVER() is because a oversize "top" value will be blocked from
54411
+ ** reaching this point by btreeInitPage() or btreeGetUnusedPage() */
54412
+ return SQLITE_CORRUPT_BKPT;
54413
+ }
5439854414
5439954415
/* If there is enough space between gap and top for one more cell pointer
5440054416
** array entry offset, and if the freelist is not empty, then search the
5440154417
** freelist looking for a free slot big enough to satisfy the request.
5440254418
*/
@@ -54465,11 +54481,11 @@
5446554481
u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
5446654482
unsigned char *data = pPage->aData; /* Page content */
5446754483
5446854484
assert( pPage->pBt!=0 );
5446954485
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
54470
- assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
54486
+ assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
5447154487
assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
5447254488
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5447354489
assert( iSize>=4 ); /* Minimum cell size is 4 */
5447454490
assert( iStart<=iLast );
5447554491
@@ -54605,10 +54621,11 @@
5460554621
** we failed to detect any corruption.
5460654622
*/
5460754623
static int btreeInitPage(MemPage *pPage){
5460854624
5460954625
assert( pPage->pBt!=0 );
54626
+ assert( pPage->pBt->db!=0 );
5461054627
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5461154628
assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
5461254629
assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
5461354630
assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
5461454631
@@ -54663,12 +54680,11 @@
5466354680
** past the end of a page boundary and causes SQLITE_CORRUPT to be
5466454681
** returned if it does.
5466554682
*/
5466654683
iCellFirst = cellOffset + 2*pPage->nCell;
5466754684
iCellLast = usableSize - 4;
54668
-#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
54669
- {
54685
+ if( pBt->db->flags & SQLITE_CellSizeCk ){
5467054686
int i; /* Index into the cell pointer array */
5467154687
int sz; /* Size of a cell */
5467254688
5467354689
if( !pPage->leaf ) iCellLast--;
5467454690
for(i=0; i<pPage->nCell; i++){
@@ -54684,11 +54700,10 @@
5468454700
return SQLITE_CORRUPT_BKPT;
5468554701
}
5468654702
}
5468754703
if( !pPage->leaf ) iCellLast++;
5468854704
}
54689
-#endif
5469054705
5469154706
/* Compute the total free space on the page
5469254707
** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
5469354708
** start of the first freeblock on the page, or is zero if there are no
5469454709
** freeblocks. */
@@ -54781,14 +54796,14 @@
5478154796
return pPage;
5478254797
}
5478354798
5478454799
/*
5478554800
** Get a page from the pager. Initialize the MemPage.pBt and
54786
-** MemPage.aData elements if needed.
54801
+** MemPage.aData elements if needed. See also: btreeGetUnusedPage().
5478754802
**
54788
-** If the noContent flag is set, it means that we do not care about
54789
-** the content of the page at this time. So do not go to the disk
54803
+** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care
54804
+** about the content of the page at this time. So do not go to the disk
5479054805
** to fetch the content. Just fill in the content with zeros for now.
5479154806
** If in the future we call sqlite3PagerWrite() on this page, that
5479254807
** means we have started to be concerned about content and the disk
5479354808
** read should occur at that point.
5479454809
*/
@@ -54885,10 +54900,40 @@
5488554900
assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
5488654901
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5488754902
sqlite3PagerUnrefNotNull(pPage->pDbPage);
5488854903
}
5488954904
}
54905
+
54906
+/*
54907
+** Get an unused page.
54908
+**
54909
+** This works just like btreeGetPage() with the addition:
54910
+**
54911
+** * If the page is already in use for some other purpose, immediately
54912
+** release it and return an SQLITE_CURRUPT error.
54913
+** * Make sure the isInit flag is clear
54914
+*/
54915
+static int btreeGetUnusedPage(
54916
+ BtShared *pBt, /* The btree */
54917
+ Pgno pgno, /* Number of the page to fetch */
54918
+ MemPage **ppPage, /* Return the page in this parameter */
54919
+ int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
54920
+){
54921
+ int rc = btreeGetPage(pBt, pgno, ppPage, flags);
54922
+ if( rc==SQLITE_OK ){
54923
+ if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
54924
+ releasePage(*ppPage);
54925
+ *ppPage = 0;
54926
+ return SQLITE_CORRUPT_BKPT;
54927
+ }
54928
+ (*ppPage)->isInit = 0;
54929
+ }else{
54930
+ *ppPage = 0;
54931
+ }
54932
+ return rc;
54933
+}
54934
+
5489054935
5489154936
/*
5489254937
** During a rollback, when the pager reloads information into the cache
5489354938
** so that the cache is restored to its original state at the start of
5489454939
** the transaction, for each page restored this routine is called.
@@ -56133,12 +56178,14 @@
5613356178
put4byte(pPage->aData, iTo);
5613456179
}else{
5613556180
u8 isInitOrig = pPage->isInit;
5613656181
int i;
5613756182
int nCell;
56183
+ int rc;
5613856184
56139
- btreeInitPage(pPage);
56185
+ rc = btreeInitPage(pPage);
56186
+ if( rc ) return rc;
5614056187
nCell = pPage->nCell;
5614156188
5614256189
for(i=0; i<nCell; i++){
5614356190
u8 *pCell = findCell(pPage, i);
5614456191
if( eType==PTRMAP_OVERFLOW1 ){
@@ -56935,13 +56982,17 @@
5693556982
int wrFlag, /* 1 to write. 0 read-only */
5693656983
struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
5693756984
BtCursor *pCur /* Write new cursor here */
5693856985
){
5693956986
int rc;
56940
- sqlite3BtreeEnter(p);
56941
- rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
56942
- sqlite3BtreeLeave(p);
56987
+ if( iTable<1 ){
56988
+ rc = SQLITE_CORRUPT_BKPT;
56989
+ }else{
56990
+ sqlite3BtreeEnter(p);
56991
+ rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
56992
+ sqlite3BtreeLeave(p);
56993
+ }
5694356994
return rc;
5694456995
}
5694556996
5694656997
/*
5694756998
** Return the size of a BtCursor object in bytes.
@@ -57965,11 +58016,11 @@
5796558016
assert( lwr+upr>=0 );
5796658017
idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */
5796758018
}
5796858019
}else{
5796958020
for(;;){
57970
- int nCell;
58021
+ int nCell; /* Size of the pCell cell in bytes */
5797158022
pCell = findCell(pPage, idx) + pPage->childPtrSize;
5797258023
5797358024
/* The maximum supported page-size is 65536 bytes. This means that
5797458025
** the maximum number of record bytes stored on an index B-Tree
5797558026
** page is less than 16384 bytes and may be stored as a 2-byte
@@ -57994,16 +58045,29 @@
5799458045
c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
5799558046
}else{
5799658047
/* The record flows over onto one or more overflow pages. In
5799758048
** this case the whole cell needs to be parsed, a buffer allocated
5799858049
** and accessPayload() used to retrieve the record into the
57999
- ** buffer before VdbeRecordCompare() can be called. */
58050
+ ** buffer before VdbeRecordCompare() can be called.
58051
+ **
58052
+ ** If the record is corrupt, the xRecordCompare routine may read
58053
+ ** up to two varints past the end of the buffer. An extra 18
58054
+ ** bytes of padding is allocated at the end of the buffer in
58055
+ ** case this happens. */
5800058056
void *pCellKey;
5800158057
u8 * const pCellBody = pCell - pPage->childPtrSize;
5800258058
btreeParseCellPtr(pPage, pCellBody, &pCur->info);
5800358059
nCell = (int)pCur->info.nKey;
58004
- pCellKey = sqlite3Malloc( nCell );
58060
+ testcase( nCell<0 ); /* True if key size is 2^32 or more */
58061
+ testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
58062
+ testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
58063
+ testcase( nCell==2 ); /* Minimum legal index key size */
58064
+ if( nCell<2 ){
58065
+ rc = SQLITE_CORRUPT_BKPT;
58066
+ goto moveto_finish;
58067
+ }
58068
+ pCellKey = sqlite3Malloc( nCell+18 );
5800558069
if( pCellKey==0 ){
5800658070
rc = SQLITE_NOMEM;
5800758071
goto moveto_finish;
5800858072
}
5800958073
pCur->aiIdx[pCur->iPage] = (u16)idx;
@@ -58387,11 +58451,11 @@
5838758451
}
5838858452
testcase( iTrunk==mxPage );
5838958453
if( iTrunk>mxPage ){
5839058454
rc = SQLITE_CORRUPT_BKPT;
5839158455
}else{
58392
- rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
58456
+ rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
5839358457
}
5839458458
if( rc ){
5839558459
pTrunk = 0;
5839658460
goto end_allocate_page;
5839758461
}
@@ -58452,11 +58516,11 @@
5845258516
if( iNewTrunk>mxPage ){
5845358517
rc = SQLITE_CORRUPT_BKPT;
5845458518
goto end_allocate_page;
5845558519
}
5845658520
testcase( iNewTrunk==mxPage );
58457
- rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
58521
+ rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0);
5845858522
if( rc!=SQLITE_OK ){
5845958523
goto end_allocate_page;
5846058524
}
5846158525
rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
5846258526
if( rc!=SQLITE_OK ){
@@ -58532,11 +58596,11 @@
5853258596
if( closest<k-1 ){
5853358597
memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
5853458598
}
5853558599
put4byte(&aData[4], k-1);
5853658600
noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
58537
- rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
58601
+ rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, noContent);
5853858602
if( rc==SQLITE_OK ){
5853958603
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
5854058604
if( rc!=SQLITE_OK ){
5854158605
releasePage(*ppPage);
5854258606
}
@@ -58580,11 +58644,11 @@
5858058644
** becomes a new pointer-map page, the second is used by the caller.
5858158645
*/
5858258646
MemPage *pPg = 0;
5858358647
TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
5858458648
assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
58585
- rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
58649
+ rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent);
5858658650
if( rc==SQLITE_OK ){
5858758651
rc = sqlite3PagerWrite(pPg->pDbPage);
5858858652
releasePage(pPg);
5858958653
}
5859058654
if( rc ) return rc;
@@ -58594,35 +58658,27 @@
5859458658
#endif
5859558659
put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
5859658660
*pPgno = pBt->nPage;
5859758661
5859858662
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
58599
- rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
58663
+ rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent);
5860058664
if( rc ) return rc;
5860158665
rc = sqlite3PagerWrite((*ppPage)->pDbPage);
5860258666
if( rc!=SQLITE_OK ){
5860358667
releasePage(*ppPage);
58668
+ *ppPage = 0;
5860458669
}
5860558670
TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
5860658671
}
5860758672
5860858673
assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
5860958674
5861058675
end_allocate_page:
5861158676
releasePage(pTrunk);
5861258677
releasePage(pPrevTrunk);
58613
- if( rc==SQLITE_OK ){
58614
- if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
58615
- releasePage(*ppPage);
58616
- *ppPage = 0;
58617
- return SQLITE_CORRUPT_BKPT;
58618
- }
58619
- (*ppPage)->isInit = 0;
58620
- }else{
58621
- *ppPage = 0;
58622
- }
58623
- assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
58678
+ assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 );
58679
+ assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 );
5862458680
return rc;
5862558681
}
5862658682
5862758683
/*
5862858684
** This function is used to add page iPage to the database file free-list.
@@ -58643,13 +58699,14 @@
5864358699
MemPage *pPage; /* Page being freed. May be NULL. */
5864458700
int rc; /* Return Code */
5864558701
int nFree; /* Initial number of pages on free-list */
5864658702
5864758703
assert( sqlite3_mutex_held(pBt->mutex) );
58648
- assert( iPage>1 );
58704
+ assert( CORRUPT_DB || iPage>1 );
5864958705
assert( !pMemPage || pMemPage->pgno==iPage );
5865058706
58707
+ if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
5865158708
if( pMemPage ){
5865258709
pPage = pMemPage;
5865358710
sqlite3PagerRef(pPage->pDbPage);
5865458711
}else{
5865558712
pPage = btreePageLookup(pBt, iPage);
@@ -58797,11 +58854,13 @@
5879758854
}
5879858855
ovflPgno = get4byte(&pCell[info.iOverflow]);
5879958856
assert( pBt->usableSize > 4 );
5880058857
ovflPageSize = pBt->usableSize - 4;
5880158858
nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
58802
- assert( ovflPgno==0 || nOvfl>0 );
58859
+ assert( nOvfl>0 ||
58860
+ (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
58861
+ );
5880358862
while( nOvfl-- ){
5880458863
Pgno iNext = 0;
5880558864
MemPage *pOvfl = 0;
5880658865
if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
5880758866
/* 0 is not a legal page number and page 1 cannot be an
@@ -59052,11 +59111,11 @@
5905259111
int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
5905359112
5905459113
if( *pRC ) return;
5905559114
5905659115
assert( idx>=0 && idx<pPage->nCell );
59057
- assert( sz==cellSize(pPage, idx) );
59116
+ assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
5905859117
assert( sqlite3PagerIswriteable(pPage->pDbPage) );
5905959118
assert( sqlite3_mutex_held(pPage->pBt->mutex) );
5906059119
data = pPage->aData;
5906159120
ptr = &pPage->aCellIdx[2*idx];
5906259121
pc = get2byte(ptr);
@@ -59216,11 +59275,12 @@
5921659275
}
5921759276
pData -= szCell[i];
5921859277
memcpy(pData, pCell, szCell[i]);
5921959278
put2byte(pCellptr, (pData - aData));
5922059279
pCellptr += 2;
59221
- assert( szCell[i]==cellSizePtr(pPg, pCell) );
59280
+ assert( szCell[i]==cellSizePtr(pPg, pCell) || CORRUPT_DB );
59281
+ testcase( szCell[i]==cellSizePtr(pPg,pCell) );
5922259282
}
5922359283
5922459284
/* The pPg->nFree field is now set incorrectly. The caller will fix it. */
5922559285
pPg->nCell = nCell;
5922659286
pPg->nOverflow = 0;
@@ -59893,10 +59953,18 @@
5989359953
leafCorrection = apOld[0]->leaf*4;
5989459954
leafData = apOld[0]->intKeyLeaf;
5989559955
for(i=0; i<nOld; i++){
5989659956
int limit;
5989759957
MemPage *pOld = apOld[i];
59958
+
59959
+ /* Verify that all sibling pages are of the same "type" (table-leaf,
59960
+ ** table-interior, index-leaf, or index-interior).
59961
+ */
59962
+ if( pOld->aData[0]!=apOld[0]->aData[0] ){
59963
+ rc = SQLITE_CORRUPT_BKPT;
59964
+ goto balance_cleanup;
59965
+ }
5989859966
5989959967
limit = pOld->nCell+pOld->nOverflow;
5990059968
if( pOld->nOverflow>0 ){
5990159969
for(j=0; j<limit; j++){
5990259970
assert( nCell<nMaxCells );
@@ -59935,17 +60003,17 @@
5993560003
/* The right pointer of the child page pOld becomes the left
5993660004
** pointer of the divider cell */
5993760005
memcpy(apCell[nCell], &pOld->aData[8], 4);
5993860006
}else{
5993960007
assert( leafCorrection==4 );
59940
- if( szCell[nCell]<4 ){
60008
+ while( szCell[nCell]<4 ){
5994160009
/* Do not allow any cells smaller than 4 bytes. If a smaller cell
5994260010
** does exist, pad it with 0x00 bytes. */
59943
- assert( szCell[nCell]==3 );
59944
- assert( apCell[nCell]==&aSpace1[iSpace1-3] );
60011
+ assert( szCell[nCell]==3 || CORRUPT_DB );
60012
+ assert( apCell[nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
5994560013
aSpace1[iSpace1++] = 0x00;
59946
- szCell[nCell] = 4;
60014
+ szCell[nCell]++;
5994760015
}
5994860016
}
5994960017
nCell++;
5995060018
}
5995160019
}
@@ -60032,14 +60100,10 @@
6003260100
));
6003360101
6003460102
/*
6003560103
** Allocate k new pages. Reuse old pages where possible.
6003660104
*/
60037
- if( apOld[0]->pgno<=1 ){
60038
- rc = SQLITE_CORRUPT_BKPT;
60039
- goto balance_cleanup;
60040
- }
6004160105
pageFlags = apOld[0]->aData[0];
6004260106
for(i=0; i<k; i++){
6004360107
MemPage *pNew;
6004460108
if( i<nOld ){
6004560109
pNew = apNew[i] = apOld[i];
@@ -60817,10 +60881,11 @@
6081760881
int nCell;
6081860882
Pgno n = pCur->apPage[iCellDepth+1]->pgno;
6081960883
unsigned char *pTmp;
6082060884
6082160885
pCell = findCell(pLeaf, pLeaf->nCell-1);
60886
+ if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
6082260887
nCell = cellSizePtr(pLeaf, pCell);
6082360888
assert( MX_CELL_SIZE(pBt) >= nCell );
6082460889
pTmp = pBt->pTmpSpace;
6082560890
assert( pTmp!=0 );
6082660891
rc = sqlite3PagerWrite(pLeaf->pDbPage);
@@ -60909,11 +60974,12 @@
6090960974
*/
6091060975
while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
6091160976
pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
6091260977
pgnoRoot++;
6091360978
}
60914
- assert( pgnoRoot>=3 );
60979
+ assert( pgnoRoot>=3 || CORRUPT_DB );
60980
+ testcase( pgnoRoot<3 );
6091560981
6091660982
/* Allocate a page. The page that currently resides at pgnoRoot will
6091760983
** be moved to the allocated page (unless the allocated page happens
6091860984
** to reside at pgnoRoot).
6091960985
*/
@@ -61059,11 +61125,12 @@
6105961125
}
6106061126
if( !pPage->leaf ){
6106161127
rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
6106261128
if( rc ) goto cleardatabasepage_out;
6106361129
}else if( pnChange ){
61064
- assert( pPage->intKey );
61130
+ assert( pPage->intKey || CORRUPT_DB );
61131
+ testcase( !pPage->intKey );
6106561132
*pnChange += pPage->nCell;
6106661133
}
6106761134
if( freePageFlag ){
6106861135
freePage(pPage, &rc);
6106961136
}else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
@@ -63854,14 +63921,10 @@
6385463921
}
6385563922
pMem->pScopyFrom = 0;
6385663923
}
6385763924
#endif /* SQLITE_DEBUG */
6385863925
63859
-/*
63860
-** Size of struct Mem not including the Mem.zMalloc member.
63861
-*/
63862
-#define MEMCELLSIZE offsetof(Mem,zMalloc)
6386363926
6386463927
/*
6386563928
** Make an shallow copy of pFrom into pTo. Prior contents of
6386663929
** pTo are freed. The pFrom->z field is not duplicated. If
6386763930
** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
@@ -63884,11 +63947,14 @@
6388463947
** freed before the copy is made.
6388563948
*/
6388663949
SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
6388763950
int rc = SQLITE_OK;
6388863951
63889
- assert( pTo->db==pFrom->db );
63952
+ /* The pFrom==0 case in the following assert() is when an sqlite3_value
63953
+ ** from sqlite3_value_dup() is used as the argument
63954
+ ** to sqlite3_result_value(). */
63955
+ assert( pTo->db==pFrom->db || pFrom->db==0 );
6389063956
assert( (pFrom->flags & MEM_RowSet)==0 );
6389163957
if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
6389263958
memcpy(pTo, pFrom, MEMCELLSIZE);
6389363959
pTo->flags &= ~MEM_Dyn;
6389463960
if( pTo->flags&(MEM_Str|MEM_Blob) ){
@@ -64817,10 +64883,21 @@
6481764883
assert( pParse->aLabel==0 );
6481864884
assert( pParse->nLabel==0 );
6481964885
assert( pParse->nOpAlloc==0 );
6482064886
return p;
6482164887
}
64888
+
64889
+/*
64890
+** Change the error string stored in Vdbe.zErrMsg
64891
+*/
64892
+SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
64893
+ va_list ap;
64894
+ sqlite3DbFree(p->db, p->zErrMsg);
64895
+ va_start(ap, zFormat);
64896
+ p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap);
64897
+ va_end(ap);
64898
+}
6482264899
6482364900
/*
6482464901
** Remember the SQL string for a prepared statement.
6482564902
*/
6482664903
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
@@ -66174,11 +66251,11 @@
6617466251
p->rc = SQLITE_OK;
6617566252
rc = SQLITE_DONE;
6617666253
}else if( db->u1.isInterrupted ){
6617766254
p->rc = SQLITE_INTERRUPT;
6617866255
rc = SQLITE_ERROR;
66179
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
66256
+ sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
6618066257
}else{
6618166258
char *zP4;
6618266259
Op *pOp;
6618366260
if( i<p->nOp ){
6618466261
/* The output line number is small enough that we are still in the
@@ -67077,11 +67154,11 @@
6707767154
if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
6707867155
|| (!deferred && p->nFkConstraint>0)
6707967156
){
6708067157
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
6708167158
p->errorAction = OE_Abort;
67082
- sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed");
67159
+ sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
6708367160
return SQLITE_ERROR;
6708467161
}
6708567162
return SQLITE_OK;
6708667163
}
6708767164
#endif
@@ -68420,11 +68497,11 @@
6842068497
6842168498
/* RHS is an integer */
6842268499
if( pRhs->flags & MEM_Int ){
6842368500
serial_type = aKey1[idx1];
6842468501
testcase( serial_type==12 );
68425
- if( serial_type>=12 ){
68502
+ if( serial_type>=10 ){
6842668503
rc = +1;
6842768504
}else if( serial_type==0 ){
6842868505
rc = -1;
6842968506
}else if( serial_type==7 ){
6843068507
double rhs = (double)pRhs->u.i;
@@ -68446,11 +68523,15 @@
6844668523
}
6844768524
6844868525
/* RHS is real */
6844968526
else if( pRhs->flags & MEM_Real ){
6845068527
serial_type = aKey1[idx1];
68451
- if( serial_type>=12 ){
68528
+ if( serial_type>=10 ){
68529
+ /* Serial types 12 or greater are strings and blobs (greater than
68530
+ ** numbers). Types 10 and 11 are currently "reserved for future
68531
+ ** use", so it doesn't really matter what the results of comparing
68532
+ ** them to numberic values are. */
6845268533
rc = +1;
6845368534
}else if( serial_type==0 ){
6845468535
rc = -1;
6845568536
}else{
6845668537
double rhs = pRhs->u.r;
@@ -69184,10 +69265,40 @@
6918469265
SQLITE_INTEGER, /* 0x1e */
6918569266
SQLITE_NULL, /* 0x1f */
6918669267
};
6918769268
return aType[pVal->flags&MEM_AffMask];
6918869269
}
69270
+
69271
+/* Make a copy of an sqlite3_value object
69272
+*/
69273
+SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value *pOrig){
69274
+ sqlite3_value *pNew;
69275
+ if( pOrig==0 ) return 0;
69276
+ pNew = sqlite3_malloc( sizeof(*pNew) );
69277
+ if( pNew==0 ) return 0;
69278
+ memset(pNew, 0, sizeof(*pNew));
69279
+ memcpy(pNew, pOrig, MEMCELLSIZE);
69280
+ pNew->flags &= ~MEM_Dyn;
69281
+ pNew->db = 0;
69282
+ if( pNew->flags&(MEM_Str|MEM_Blob) ){
69283
+ pNew->flags &= ~(MEM_Static|MEM_Dyn);
69284
+ pNew->flags |= MEM_Ephem;
69285
+ if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
69286
+ sqlite3ValueFree(pNew);
69287
+ pNew = 0;
69288
+ }
69289
+ }
69290
+ return pNew;
69291
+}
69292
+
69293
+/* Destroy an sqlite3_value object previously obtained from
69294
+** sqlite3_value_dup().
69295
+*/
69296
+SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value *pOld){
69297
+ sqlite3ValueFree(pOld);
69298
+}
69299
+
6918969300
6919069301
/**************************** sqlite3_result_ *******************************
6919169302
** The following routines are used by user-defined functions to specify
6919269303
** the function result.
6919369304
**
@@ -71037,10 +71148,11 @@
7103771148
** representation.
7103871149
*/
7103971150
if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
7104071151
sqlite3VdbeMemStringify(pRec, enc, 1);
7104171152
}
71153
+ pRec->flags &= ~(MEM_Real|MEM_Int);
7104271154
}
7104371155
}
7104471156
7104571157
/*
7104671158
** Try to convert the type of a function argument or a result column
@@ -71797,16 +71909,15 @@
7179771909
zType = 0;
7179871910
}
7179971911
assert( zType!=0 || pOp->p4.z!=0 );
7180071912
zLogFmt = "abort at %d in [%s]: %s";
7180171913
if( zType && pOp->p4.z ){
71802
- sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
71803
- zType, pOp->p4.z);
71914
+ sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z);
7180471915
}else if( pOp->p4.z ){
71805
- sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
71916
+ sqlite3VdbeError(p, "%s", pOp->p4.z);
7180671917
}else{
71807
- sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
71918
+ sqlite3VdbeError(p, "%s constraint failed", zType);
7180871919
}
7180971920
sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
7181071921
}
7181171922
rc = sqlite3VdbeHalt(p);
7181271923
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -72434,11 +72545,11 @@
7243472545
lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
7243572546
7243672547
/* If the function returned an error, throw an exception */
7243772548
if( ctx.fErrorOrAux ){
7243872549
if( ctx.isError ){
72439
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
72550
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(ctx.pOut));
7244072551
rc = ctx.isError;
7244172552
}
7244272553
sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
7244372554
}
7244472555
@@ -73621,12 +73732,11 @@
7362173732
if( p1==SAVEPOINT_BEGIN ){
7362273733
if( db->nVdbeWrite>0 ){
7362373734
/* A new savepoint cannot be created if there are active write
7362473735
** statements (i.e. open read/write incremental blob handles).
7362573736
*/
73626
- sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
73627
- "SQL statements in progress");
73737
+ sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress");
7362873738
rc = SQLITE_BUSY;
7362973739
}else{
7363073740
nName = sqlite3Strlen30(zName);
7363173741
7363273742
#ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -73673,19 +73783,18 @@
7367373783
pSavepoint = pSavepoint->pNext
7367473784
){
7367573785
iSavepoint++;
7367673786
}
7367773787
if( !pSavepoint ){
73678
- sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
73788
+ sqlite3VdbeError(p, "no such savepoint: %s", zName);
7367973789
rc = SQLITE_ERROR;
7368073790
}else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
7368173791
/* It is not possible to release (commit) a savepoint if there are
7368273792
** active write statements.
7368373793
*/
73684
- sqlite3SetString(&p->zErrMsg, db,
73685
- "cannot release savepoint - SQL statements in progress"
73686
- );
73794
+ sqlite3VdbeError(p, "cannot release savepoint - "
73795
+ "SQL statements in progress");
7368773796
rc = SQLITE_BUSY;
7368873797
}else{
7368973798
7369073799
/* Determine whether or not this is a transaction savepoint. If so,
7369173800
** and this is a RELEASE command, then the current transaction
@@ -73787,27 +73896,16 @@
7378773896
assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
7378873897
assert( desiredAutoCommit==1 || iRollback==0 );
7378973898
assert( db->nVdbeActive>0 ); /* At least this one VM is active */
7379073899
assert( p->bIsReader );
7379173900
73792
-#if 0
73793
- if( turnOnAC && iRollback && db->nVdbeActive>1 ){
73794
- /* If this instruction implements a ROLLBACK and other VMs are
73795
- ** still running, and a transaction is active, return an error indicating
73796
- ** that the other VMs must complete first.
73797
- */
73798
- sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
73799
- "SQL statements in progress");
73800
- rc = SQLITE_BUSY;
73801
- }else
73802
-#endif
7380373901
if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
7380473902
/* If this instruction implements a COMMIT and other VMs are writing
7380573903
** return an error indicating that the other VMs must complete first.
7380673904
*/
73807
- sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
73808
- "SQL statements in progress");
73905
+ sqlite3VdbeError(p, "cannot commit transaction - "
73906
+ "SQL statements in progress");
7380973907
rc = SQLITE_BUSY;
7381073908
}else if( desiredAutoCommit!=db->autoCommit ){
7381173909
if( iRollback ){
7381273910
assert( desiredAutoCommit==1 );
7381373911
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
@@ -73830,11 +73928,11 @@
7383073928
}else{
7383173929
rc = SQLITE_ERROR;
7383273930
}
7383373931
goto vdbe_return;
7383473932
}else{
73835
- sqlite3SetString(&p->zErrMsg, db,
73933
+ sqlite3VdbeError(p,
7383673934
(!desiredAutoCommit)?"cannot start a transaction within a transaction":(
7383773935
(iRollback)?"cannot rollback - no transaction is active":
7383873936
"cannot commit - no transaction is active"));
7383973937
7384073938
rc = SQLITE_ERROR;
@@ -76263,11 +76361,11 @@
7626376361
if( pFrame ) break;
7626476362
}
7626576363
7626676364
if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
7626776365
rc = SQLITE_ERROR;
76268
- sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
76366
+ sqlite3VdbeError(p, "too many levels of trigger recursion");
7626976367
break;
7627076368
}
7627176369
7627276370
/* Register pRt is used to store the memory required to save the state
7627376371
** of the current program, and the memory required at runtime to execute
@@ -76566,11 +76664,11 @@
7656676664
ctx.pVdbe = p;
7656776665
ctx.iOp = (int)(pOp - aOp);
7656876666
ctx.skipFlag = 0;
7656976667
(ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
7657076668
if( ctx.isError ){
76571
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
76669
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
7657276670
rc = ctx.isError;
7657376671
}
7657476672
if( ctx.skipFlag ){
7657576673
assert( pOp[-1].opcode==OP_CollSeq );
7657676674
i = pOp[-1].p1;
@@ -76598,11 +76696,11 @@
7659876696
assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
7659976697
pMem = &aMem[pOp->p1];
7660076698
assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
7660176699
rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
7660276700
if( rc ){
76603
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
76701
+ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
7660476702
}
7660576703
sqlite3VdbeChangeEncoding(pMem, encoding);
7660676704
UPDATE_MAX_BLOBSIZE(pMem);
7660776705
if( sqlite3VdbeMemTooBig(pMem) ){
7660876706
goto too_big;
@@ -76703,11 +76801,11 @@
7670376801
if( (eNew!=eOld)
7670476802
&& (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
7670576803
){
7670676804
if( !db->autoCommit || db->nVdbeRead>1 ){
7670776805
rc = SQLITE_ERROR;
76708
- sqlite3SetString(&p->zErrMsg, db,
76806
+ sqlite3VdbeError(p,
7670976807
"cannot change %s wal mode from within a transaction",
7671076808
(eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
7671176809
);
7671276810
break;
7671376811
}else{
@@ -76834,11 +76932,11 @@
7683476932
assert( DbMaskTest(p->btreeMask, p1) );
7683576933
assert( isWriteLock==0 || isWriteLock==1 );
7683676934
rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
7683776935
if( (rc&0xFF)==SQLITE_LOCKED ){
7683876936
const char *z = pOp->p4.z;
76839
- sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
76937
+ sqlite3VdbeError(p, "database table is locked: %s", z);
7684076938
}
7684176939
}
7684276940
break;
7684376941
}
7684476942
#endif /* SQLITE_OMIT_SHARED_CACHE */
@@ -77382,19 +77480,19 @@
7738277480
7738377481
/* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
7738477482
** is encountered.
7738577483
*/
7738677484
too_big:
77387
- sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
77485
+ sqlite3VdbeError(p, "string or blob too big");
7738877486
rc = SQLITE_TOOBIG;
7738977487
goto vdbe_error_halt;
7739077488
7739177489
/* Jump to here if a malloc() fails.
7739277490
*/
7739377491
no_mem:
7739477492
db->mallocFailed = 1;
77395
- sqlite3SetString(&p->zErrMsg, db, "out of memory");
77493
+ sqlite3VdbeError(p, "out of memory");
7739677494
rc = SQLITE_NOMEM;
7739777495
goto vdbe_error_halt;
7739877496
7739977497
/* Jump to here for any other kind of fatal error. The "rc" variable
7740077498
** should hold the error number.
@@ -77401,11 +77499,11 @@
7740177499
*/
7740277500
abort_due_to_error:
7740377501
assert( p->zErrMsg==0 );
7740477502
if( db->mallocFailed ) rc = SQLITE_NOMEM;
7740577503
if( rc!=SQLITE_IOERR_NOMEM ){
77406
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
77504
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
7740777505
}
7740877506
goto vdbe_error_halt;
7740977507
7741077508
/* Jump to here if the sqlite3_interrupt() API sets the interrupt
7741177509
** flag.
@@ -77412,11 +77510,11 @@
7741277510
*/
7741377511
abort_due_to_interrupt:
7741477512
assert( db->u1.isInterrupted );
7741577513
rc = SQLITE_INTERRUPT;
7741677514
p->rc = rc;
77417
- sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
77515
+ sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
7741877516
goto vdbe_error_halt;
7741977517
}
7742077518
7742177519
7742277520
/************** End of vdbe.c ************************************************/
@@ -81651,11 +81749,11 @@
8165181749
iCol = -1;
8165281750
}
8165381751
break;
8165481752
}
8165581753
}
81656
- if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
81754
+ if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
8165781755
/* IMP: R-51414-32910 */
8165881756
/* IMP: R-44911-55124 */
8165981757
iCol = -1;
8166081758
}
8166181759
if( iCol<pTab->nCol ){
@@ -81681,11 +81779,11 @@
8168181779
8168281780
/*
8168381781
** Perhaps the name is a reference to the ROWID
8168481782
*/
8168581783
if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
81686
- && HasRowid(pMatch->pTab) ){
81784
+ && VisibleRowid(pMatch->pTab) ){
8168781785
cnt = 1;
8168881786
pExpr->iColumn = -1; /* IMP: R-44911-55124 */
8168981787
pExpr->affinity = SQLITE_AFF_INTEGER;
8169081788
}
8169181789
@@ -92125,18 +92223,15 @@
9212592223
#ifndef SQLITE_OMIT_AUTOINCREMENT
9212692224
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
9212792225
"INTEGER PRIMARY KEY");
9212892226
#endif
9212992227
}else{
92130
- Vdbe *v = pParse->pVdbe;
9213192228
Index *p;
92132
- if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop);
9213392229
p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
9213492230
0, sortOrder, 0);
9213592231
if( p ){
9213692232
p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
92137
- if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK);
9213892233
}
9213992234
pList = 0;
9214092235
}
9214192236
9214292237
primary_key_exit:
@@ -92485,18 +92580,10 @@
9248592580
if( pParse->addrCrTab ){
9248692581
assert( v );
9248792582
sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
9248892583
}
9248992584
92490
- /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
92491
- ** table entry.
92492
- */
92493
- if( pParse->addrSkipPK ){
92494
- assert( v );
92495
- sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto;
92496
- }
92497
-
9249892585
/* Locate the PRIMARY KEY index. Or, if this table was originally
9249992586
** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
9250092587
*/
9250192588
if( pTab->iPKey>=0 ){
9250292589
ExprList *pList;
@@ -92510,10 +92597,20 @@
9251092597
if( pPk==0 ) return;
9251192598
pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
9251292599
pTab->iPKey = -1;
9251392600
}else{
9251492601
pPk = sqlite3PrimaryKeyIndex(pTab);
92602
+
92603
+ /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
92604
+ ** table entry. This is only required if currently generating VDBE
92605
+ ** code for a CREATE TABLE (not when parsing one as part of reading
92606
+ ** a database schema). */
92607
+ if( v ){
92608
+ assert( db->init.busy==0 );
92609
+ sqlite3VdbeGetOp(v, pPk->tnum)->opcode = OP_Goto;
92610
+ }
92611
+
9251592612
/*
9251692613
** Remove all redundant columns from the PRIMARY KEY. For example, change
9251792614
** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
9251892615
** code assumes the PRIMARY KEY contains no repeated columns.
9251992616
*/
@@ -92645,11 +92742,11 @@
9264592742
return;
9264692743
}
9264792744
if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
9264892745
sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
9264992746
}else{
92650
- p->tabFlags |= TF_WithoutRowid;
92747
+ p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
9265192748
convertToWithoutRowidTable(pParse, p);
9265292749
}
9265392750
}
9265492751
9265592752
iDb = sqlite3SchemaToIndex(db, p->pSchema);
@@ -92713,30 +92810,49 @@
9271392810
** as a schema-lock must have already been obtained to create it. Since
9271492811
** a schema-lock excludes all other database users, the write-lock would
9271592812
** be redundant.
9271692813
*/
9271792814
if( pSelect ){
92718
- SelectDest dest;
92719
- Table *pSelTab;
92815
+ SelectDest dest; /* Where the SELECT should store results */
92816
+ int regYield; /* Register holding co-routine entry-point */
92817
+ int addrTop; /* Top of the co-routine */
92818
+ int regRec; /* A record to be insert into the new table */
92819
+ int regRowid; /* Rowid of the next row to insert */
92820
+ int addrInsLoop; /* Top of the loop for inserting rows */
92821
+ Table *pSelTab; /* A table that describes the SELECT results */
9272092822
92823
+ regYield = ++pParse->nMem;
92824
+ regRec = ++pParse->nMem;
92825
+ regRowid = ++pParse->nMem;
9272192826
assert(pParse->nTab==1);
9272292827
sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
9272392828
sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
9272492829
pParse->nTab = 2;
92725
- sqlite3SelectDestInit(&dest, SRT_Table, 1);
92830
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
92831
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
92832
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
9272692833
sqlite3Select(pParse, pSelect, &dest);
92834
+ sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
92835
+ sqlite3VdbeJumpHere(v, addrTop - 1);
92836
+ if( pParse->nErr ) return;
92837
+ pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
92838
+ if( pSelTab==0 ) return;
92839
+ assert( p->aCol==0 );
92840
+ p->nCol = pSelTab->nCol;
92841
+ p->aCol = pSelTab->aCol;
92842
+ pSelTab->nCol = 0;
92843
+ pSelTab->aCol = 0;
92844
+ sqlite3DeleteTable(db, pSelTab);
92845
+ addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
92846
+ VdbeCoverage(v);
92847
+ sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
92848
+ sqlite3TableAffinity(v, p, 0);
92849
+ sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
92850
+ sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
92851
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInsLoop);
92852
+ sqlite3VdbeJumpHere(v, addrInsLoop);
9272792853
sqlite3VdbeAddOp1(v, OP_Close, 1);
92728
- if( pParse->nErr==0 ){
92729
- pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
92730
- if( pSelTab==0 ) return;
92731
- assert( p->aCol==0 );
92732
- p->nCol = pSelTab->nCol;
92733
- p->aCol = pSelTab->aCol;
92734
- pSelTab->nCol = 0;
92735
- pSelTab->aCol = 0;
92736
- sqlite3DeleteTable(db, pSelTab);
92737
- }
9273892854
}
9273992855
9274092856
/* Compute the complete text of the CREATE statement */
9274192857
if( pSelect ){
9274292858
zStmt = createTableStmt(db, p);
@@ -94031,14 +94147,19 @@
9403194147
int iMem = ++pParse->nMem;
9403294148
9403394149
v = sqlite3GetVdbe(pParse);
9403494150
if( v==0 ) goto exit_create_index;
9403594151
94036
-
94037
- /* Create the rootpage for the index
94038
- */
9403994152
sqlite3BeginWriteOperation(pParse, 1, iDb);
94153
+
94154
+ /* Create the rootpage for the index using CreateIndex. But before
94155
+ ** doing so, code a Noop instruction and store its address in
94156
+ ** Index.tnum. This is required in case this index is actually a
94157
+ ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In
94158
+ ** that case the convertToWithoutRowidTable() routine will replace
94159
+ ** the Noop with a Goto to jump over the VDBE code generated below. */
94160
+ pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
9404094161
sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
9404194162
9404294163
/* Gather the complete text of the CREATE INDEX statement into
9404394164
** the zStmt variable
9404494165
*/
@@ -94074,10 +94195,12 @@
9407494195
sqlite3ChangeCookie(pParse, iDb);
9407594196
sqlite3VdbeAddParseSchemaOp(v, iDb,
9407694197
sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
9407794198
sqlite3VdbeAddOp1(v, OP_Expire, 0);
9407894199
}
94200
+
94201
+ sqlite3VdbeJumpHere(v, pIndex->tnum);
9407994202
}
9408094203
9408194204
/* When adding an index to the list of indices for a table, make
9408294205
** sure all indices labeled OE_Replace come after all those labeled
9408394206
** OE_Ignore. This is necessary for the correct constraint check
@@ -99669,11 +99792,11 @@
9966999792
sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
9967099793
VdbeComment((v, "%s", pTab->zName));
9967199794
}else{
9967299795
Index *pPk = sqlite3PrimaryKeyIndex(pTab);
9967399796
assert( pPk!=0 );
99674
- assert( pPk->tnum=pTab->tnum );
99797
+ assert( pPk->tnum==pTab->tnum );
9967599798
sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
9967699799
sqlite3VdbeSetP4KeyInfo(pParse, pPk);
9967799800
VdbeComment((v, "%s", pTab->zName));
9967899801
}
9967999802
}
@@ -102119,10 +102242,12 @@
102119102242
void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
102120102243
void(*)(void*));
102121102244
void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
102122102245
void(*)(void*), unsigned char);
102123102246
int (*strglob)(const char*,const char*);
102247
+ sqlite3_value (*value_dup)(const sqlite3_value*);
102248
+ void (*value_free)(sqlite3_value*);
102124102249
};
102125102250
102126102251
/*
102127102252
** The following macros redefine the API routines so that they are
102128102253
** redirected through the global sqlite3_api structure.
@@ -102349,10 +102474,13 @@
102349102474
#define sqlite3_realloc64 sqlite3_api->realloc64
102350102475
#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
102351102476
#define sqlite3_result_blob64 sqlite3_api->result_blob64
102352102477
#define sqlite3_result_text64 sqlite3_api->result_text64
102353102478
#define sqlite3_strglob sqlite3_api->strglob
102479
+/* Version 3.8.11 and later */
102480
+#define sqlite3_value_dup sqlite3_api->value_dup
102481
+#define sqlite3_value_free sqlite3_api->value_free
102354102482
#endif /* SQLITE_CORE */
102355102483
102356102484
#ifndef SQLITE_CORE
102357102485
/* This case when the file really is being compiled as a loadable
102358102486
** extension */
@@ -103255,10 +103383,14 @@
103255103383
#endif
103256103384
{ /* zName: */ "case_sensitive_like",
103257103385
/* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
103258103386
/* ePragFlag: */ 0,
103259103387
/* iArg: */ 0 },
103388
+ { /* zName: */ "cell_size_check",
103389
+ /* ePragTyp: */ PragTyp_FLAG,
103390
+ /* ePragFlag: */ 0,
103391
+ /* iArg: */ SQLITE_CellSizeCk },
103260103392
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
103261103393
{ /* zName: */ "checkpoint_fullfsync",
103262103394
/* ePragTyp: */ PragTyp_FLAG,
103263103395
/* ePragFlag: */ 0,
103264103396
/* iArg: */ SQLITE_CkptFullFSync },
@@ -103612,11 +103744,11 @@
103612103744
/* ePragTyp: */ PragTyp_FLAG,
103613103745
/* ePragFlag: */ 0,
103614103746
/* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
103615103747
#endif
103616103748
};
103617
-/* Number of pragmas: 59 on by default, 72 total. */
103749
+/* Number of pragmas: 60 on by default, 73 total. */
103618103750
103619103751
/************** End of pragma.h **********************************************/
103620103752
/************** Continuing where we left off in pragma.c *********************/
103621103753
103622103754
/*
@@ -105595,17 +105727,17 @@
105595105727
const char *zObj, /* Object being parsed at the point of error */
105596105728
const char *zExtra /* Error information */
105597105729
){
105598105730
sqlite3 *db = pData->db;
105599105731
if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
105732
+ char *z;
105600105733
if( zObj==0 ) zObj = "?";
105601
- sqlite3SetString(pData->pzErrMsg, db,
105602
- "malformed database schema (%s)", zObj);
105603
- if( zExtra ){
105604
- *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
105605
- "%s - %s", *pData->pzErrMsg, zExtra);
105606
- }
105734
+ z = sqlite3_mprintf("malformed database schema (%s)", zObj);
105735
+ if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra);
105736
+ sqlite3DbFree(db, *pData->pzErrMsg);
105737
+ *pData->pzErrMsg = z;
105738
+ if( z==0 ) db->mallocFailed = 1;
105607105739
}
105608105740
pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
105609105741
}
105610105742
105611105743
/*
@@ -105793,11 +105925,11 @@
105793105925
** will be closed before this function returns. */
105794105926
sqlite3BtreeEnter(pDb->pBt);
105795105927
if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
105796105928
rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
105797105929
if( rc!=SQLITE_OK ){
105798
- sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
105930
+ sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
105799105931
goto initone_error_out;
105800105932
}
105801105933
openedTransaction = 1;
105802105934
}
105803105935
@@ -107177,12 +107309,17 @@
107177107309
}
107178107310
}else if( eDest!=SRT_Exists ){
107179107311
/* If the destination is an EXISTS(...) expression, the actual
107180107312
** values returned by the SELECT are not required.
107181107313
*/
107182
- sqlite3ExprCodeExprList(pParse, pEList, regResult,
107183
- (eDest==SRT_Output||eDest==SRT_Coroutine)?SQLITE_ECEL_DUP:0);
107314
+ u8 ecelFlags;
107315
+ if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
107316
+ ecelFlags = SQLITE_ECEL_DUP;
107317
+ }else{
107318
+ ecelFlags = 0;
107319
+ }
107320
+ sqlite3ExprCodeExprList(pParse, pEList, regResult, ecelFlags);
107184107321
}
107185107322
107186107323
/* If the DISTINCT keyword was present on the SELECT statement
107187107324
** and this row has been seen before, then do not make this row
107188107325
** part of the result.
@@ -107275,10 +107412,12 @@
107275107412
case SRT_Table:
107276107413
case SRT_EphemTab: {
107277107414
int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
107278107415
testcase( eDest==SRT_Table );
107279107416
testcase( eDest==SRT_EphemTab );
107417
+ testcase( eDest==SRT_Fifo );
107418
+ testcase( eDest==SRT_DistFifo );
107280107419
sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
107281107420
#ifndef SQLITE_OMIT_CTE
107282107421
if( eDest==SRT_DistFifo ){
107283107422
/* If the destination is DistFifo, then cursor (iParm+1) is open
107284107423
** on an ephemeral index. If the current row is already present
@@ -107690,14 +107829,11 @@
107690107829
for(i=0; i<nSortData; i++){
107691107830
sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
107692107831
VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
107693107832
}
107694107833
switch( eDest ){
107695
- case SRT_Table:
107696107834
case SRT_EphemTab: {
107697
- testcase( eDest==SRT_Table );
107698
- testcase( eDest==SRT_EphemTab );
107699107835
sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
107700107836
sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
107701107837
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
107702107838
break;
107703107839
}
@@ -109042,19 +109178,18 @@
109042109178
109043109179
/* Suppress the first OFFSET entries if there is an OFFSET clause
109044109180
*/
109045109181
codeOffset(v, p->iOffset, iContinue);
109046109182
109183
+ assert( pDest->eDest!=SRT_Exists );
109184
+ assert( pDest->eDest!=SRT_Table );
109047109185
switch( pDest->eDest ){
109048109186
/* Store the result as data using a unique key.
109049109187
*/
109050
- case SRT_Table:
109051109188
case SRT_EphemTab: {
109052109189
int r1 = sqlite3GetTempReg(pParse);
109053109190
int r2 = sqlite3GetTempReg(pParse);
109054
- testcase( pDest->eDest==SRT_Table );
109055
- testcase( pDest->eDest==SRT_EphemTab );
109056109191
sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
109057109192
sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
109058109193
sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
109059109194
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
109060109195
sqlite3ReleaseTempReg(pParse, r2);
@@ -109078,20 +109213,10 @@
109078109213
sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
109079109214
sqlite3ReleaseTempReg(pParse, r1);
109080109215
break;
109081109216
}
109082109217
109083
-#if 0 /* Never occurs on an ORDER BY query */
109084
- /* If any row exist in the result set, record that fact and abort.
109085
- */
109086
- case SRT_Exists: {
109087
- sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
109088
- /* The LIMIT clause will terminate the loop for us */
109089
- break;
109090
- }
109091
-#endif
109092
-
109093109218
/* If this is a scalar select that is part of an expression, then
109094109219
** store the results in the appropriate memory cell and break out
109095109220
** of the scan loop.
109096109221
*/
109097109222
case SRT_Mem: {
@@ -110462,11 +110587,11 @@
110462110587
if( pTab==0 ) return WRC_Abort;
110463110588
pTab->nRef = 1;
110464110589
pTab->zName = sqlite3DbStrDup(db, pCte->zName);
110465110590
pTab->iPKey = -1;
110466110591
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
110467
- pTab->tabFlags |= TF_Ephemeral;
110592
+ pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
110468110593
pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
110469110594
if( db->mallocFailed ) return SQLITE_NOMEM;
110470110595
assert( pFrom->pSelect );
110471110596
110472110597
/* Check if this is a recursive CTE. */
@@ -110707,17 +110832,10 @@
110707110832
ExprList *pNew = 0;
110708110833
int flags = pParse->db->flags;
110709110834
int longNames = (flags & SQLITE_FullColNames)!=0
110710110835
&& (flags & SQLITE_ShortColNames)==0;
110711110836
110712
- /* When processing FROM-clause subqueries, it is always the case
110713
- ** that full_column_names=OFF and short_column_names=ON. The
110714
- ** sqlite3ResultSetOfSelect() routine makes it so. */
110715
- assert( (p->selFlags & SF_NestedFrom)==0
110716
- || ((flags & SQLITE_FullColNames)==0 &&
110717
- (flags & SQLITE_ShortColNames)!=0) );
110718
-
110719110837
for(k=0; k<pEList->nExpr; k++){
110720110838
pE = a[k].pExpr;
110721110839
pRight = pE->pRight;
110722110840
assert( pE->op!=TK_DOT || pRight!=0 );
110723110841
if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
@@ -111295,10 +111413,11 @@
111295111413
isAgg = 1;
111296111414
p->selFlags |= SF_Aggregate;
111297111415
}
111298111416
i = -1;
111299111417
}else if( pTabList->nSrc==1
111418
+ && (p->selFlags & SF_All)==0
111300111419
&& OptimizationEnabled(db, SQLITE_SubqCoroutine)
111301111420
){
111302111421
/* Implement a co-routine that will return a single row of the result
111303111422
** set on each invocation.
111304111423
*/
@@ -111982,13 +112101,13 @@
111982112101
** Generate a human-readable description of a the Select object.
111983112102
*/
111984112103
SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
111985112104
int n = 0;
111986112105
pView = sqlite3TreeViewPush(pView, moreToFollow);
111987
- sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
112106
+ sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
111988112107
((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
111989
- ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
112108
+ ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
111990112109
);
111991112110
if( p->pSrc && p->pSrc->nSrc ) n++;
111992112111
if( p->pWhere ) n++;
111993112112
if( p->pGroupBy ) n++;
111994112113
if( p->pHaving ) n++;
@@ -114138,16 +114257,14 @@
114138114257
/* Create the ephemeral table into which the update results will
114139114258
** be stored.
114140114259
*/
114141114260
assert( v );
114142114261
ephemTab = pParse->nTab++;
114143
- sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
114144
- sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
114145114262
114146114263
/* fill the ephemeral table
114147114264
*/
114148
- sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
114265
+ sqlite3SelectDestInit(&dest, SRT_EphemTab, ephemTab);
114149114266
sqlite3Select(pParse, pSelect, &dest);
114150114267
114151114268
/* Generate code to scan the ephemeral table and call VUpdate. */
114152114269
iReg = ++pParse->nMem;
114153114270
pParse->nMem += pTab->nCol+1;
@@ -115998,10 +116115,11 @@
115998116115
# define TERM_VNULL 0x00 /* Disabled if not using stat3 */
115999116116
#endif
116000116117
#define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
116001116118
#define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
116002116119
#define TERM_LIKE 0x400 /* The original LIKE operator */
116120
+#define TERM_IS 0x800 /* Term.pExpr is an IS operator */
116003116121
116004116122
/*
116005116123
** An instance of the WhereScan object is used as an iterator for locating
116006116124
** terms in the WHERE clause that are useful to the query planner.
116007116125
*/
@@ -116146,25 +116264,26 @@
116146116264
** Bitmasks for the operators on WhereTerm objects. These are all
116147116265
** operators that are of interest to the query planner. An
116148116266
** OR-ed combination of these values can be used when searching for
116149116267
** particular WhereTerms within a WhereClause.
116150116268
*/
116151
-#define WO_IN 0x001
116152
-#define WO_EQ 0x002
116269
+#define WO_IN 0x0001
116270
+#define WO_EQ 0x0002
116153116271
#define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
116154116272
#define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
116155116273
#define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
116156116274
#define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
116157
-#define WO_MATCH 0x040
116158
-#define WO_ISNULL 0x080
116159
-#define WO_OR 0x100 /* Two or more OR-connected terms */
116160
-#define WO_AND 0x200 /* Two or more AND-connected terms */
116161
-#define WO_EQUIV 0x400 /* Of the form A==B, both columns */
116162
-#define WO_NOOP 0x800 /* This term does not restrict search space */
116163
-
116164
-#define WO_ALL 0xfff /* Mask of all possible WO_* values */
116165
-#define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
116275
+#define WO_MATCH 0x0040
116276
+#define WO_IS 0x0080
116277
+#define WO_ISNULL 0x0100
116278
+#define WO_OR 0x0200 /* Two or more OR-connected terms */
116279
+#define WO_AND 0x0400 /* Two or more AND-connected terms */
116280
+#define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
116281
+#define WO_NOOP 0x1000 /* This term does not restrict search space */
116282
+
116283
+#define WO_ALL 0x1fff /* Mask of all possible WO_* values */
116284
+#define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
116166116285
116167116286
/*
116168116287
** These are definitions of bits in the WhereLoop.wsFlags field.
116169116288
** The particular combination of bits in each WhereLoop help to
116170116289
** determine the algorithm that WhereLoop represents.
@@ -116534,11 +116653,11 @@
116534116653
static int allowedOp(int op){
116535116654
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
116536116655
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
116537116656
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
116538116657
assert( TK_GE==TK_EQ+4 );
116539
- return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
116658
+ return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
116540116659
}
116541116660
116542116661
/*
116543116662
** Commute a comparison operator. Expressions of the form "X op Y"
116544116663
** are converted into "Y op X".
@@ -116587,10 +116706,12 @@
116587116706
assert( allowedOp(op) );
116588116707
if( op==TK_IN ){
116589116708
c = WO_IN;
116590116709
}else if( op==TK_ISNULL ){
116591116710
c = WO_ISNULL;
116711
+ }else if( op==TK_IS ){
116712
+ c = WO_IS;
116592116713
}else{
116593116714
assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
116594116715
c = (u16)(WO_EQ<<(op-TK_EQ));
116595116716
}
116596116717
assert( op!=TK_ISNULL || c==WO_ISNULL );
@@ -116598,10 +116719,11 @@
116598116719
assert( op!=TK_EQ || c==WO_EQ );
116599116720
assert( op!=TK_LT || c==WO_LT );
116600116721
assert( op!=TK_LE || c==WO_LE );
116601116722
assert( op!=TK_GT || c==WO_GT );
116602116723
assert( op!=TK_GE || c==WO_GE );
116724
+ assert( op!=TK_IS || c==WO_IS );
116603116725
return c;
116604116726
}
116605116727
116606116728
/*
116607116729
** Advance to the next WhereTerm that matches according to the criteria
@@ -116658,15 +116780,16 @@
116658116780
if( pColl==0 ) pColl = pParse->db->pDfltColl;
116659116781
if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
116660116782
continue;
116661116783
}
116662116784
}
116663
- if( (pTerm->eOperator & WO_EQ)!=0
116785
+ if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
116664116786
&& (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
116665116787
&& pX->iTable==pScan->aEquiv[0]
116666116788
&& pX->iColumn==pScan->aEquiv[1]
116667116789
){
116790
+ testcase( pTerm->eOperator & WO_IS );
116668116791
continue;
116669116792
}
116670116793
pScan->k = k+1;
116671116794
return pTerm;
116672116795
}
@@ -116764,13 +116887,15 @@
116764116887
WhereTerm *pResult = 0;
116765116888
WhereTerm *p;
116766116889
WhereScan scan;
116767116890
116768116891
p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
116892
+ op &= WO_EQ|WO_IS;
116769116893
while( p ){
116770116894
if( (p->prereqRight & notReady)==0 ){
116771
- if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){
116895
+ if( p->prereqRight==0 && (p->eOperator&op)!=0 ){
116896
+ testcase( p->eOperator & WO_IS );
116772116897
return p;
116773116898
}
116774116899
if( pResult==0 ) pResult = p;
116775116900
}
116776116901
p = whereScanNext(&scan);
@@ -116801,11 +116926,11 @@
116801116926
** so and false if not.
116802116927
**
116803116928
** In order for the operator to be optimizible, the RHS must be a string
116804116929
** literal that does not begin with a wildcard. The LHS must be a column
116805116930
** that may only be NULL, a string, or a BLOB, never a number. (This means
116806
-** that virtual tables cannot participate in the LIKE optimization.) If the
116931
+** that virtual tables cannot participate in the LIKE optimization.) The
116807116932
** collating sequence for the column on the LHS must be appropriate for
116808116933
** the operator.
116809116934
*/
116810116935
static int isLikeOrGlob(
116811116936
Parse *pParse, /* Parsing and code generating context */
@@ -117346,10 +117471,50 @@
117346117471
pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */
117347117472
}
117348117473
}
117349117474
}
117350117475
#endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
117476
+
117477
+/*
117478
+** We already know that pExpr is a binary operator where both operands are
117479
+** column references. This routine checks to see if pExpr is an equivalence
117480
+** relation:
117481
+** 1. The SQLITE_Transitive optimization must be enabled
117482
+** 2. Must be either an == or an IS operator
117483
+** 3. Not originating the ON clause of an OUTER JOIN
117484
+** 4. The affinities of A and B must be compatible
117485
+** 5a. Both operands use the same collating sequence OR
117486
+** 5b. The overall collating sequence is BINARY
117487
+** If this routine returns TRUE, that means that the RHS can be substituted
117488
+** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
117489
+** This is an optimization. No harm comes from returning 0. But if 1 is
117490
+** returned when it should not be, then incorrect answers might result.
117491
+*/
117492
+static int termIsEquivalence(Parse *pParse, Expr *pExpr){
117493
+ char aff1, aff2;
117494
+ CollSeq *pColl;
117495
+ const char *zColl1, *zColl2;
117496
+ if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
117497
+ if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
117498
+ if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
117499
+ aff1 = sqlite3ExprAffinity(pExpr->pLeft);
117500
+ aff2 = sqlite3ExprAffinity(pExpr->pRight);
117501
+ if( aff1!=aff2
117502
+ && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
117503
+ ){
117504
+ return 0;
117505
+ }
117506
+ pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
117507
+ if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
117508
+ pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
117509
+ /* Since pLeft and pRight are both a column references, their collating
117510
+ ** sequence should always be defined. */
117511
+ zColl1 = ALWAYS(pColl) ? pColl->zName : 0;
117512
+ pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
117513
+ zColl2 = ALWAYS(pColl) ? pColl->zName : 0;
117514
+ return sqlite3StrICmp(zColl1, zColl2)==0;
117515
+}
117351117516
117352117517
/*
117353117518
** The input to this routine is an WhereTerm structure with only the
117354117519
** "pExpr" field filled in. The job of this routine is to analyze the
117355117520
** subexpression and populate all the other fields of the WhereTerm
@@ -117425,10 +117590,11 @@
117425117590
if( pLeft->op==TK_COLUMN ){
117426117591
pTerm->leftCursor = pLeft->iTable;
117427117592
pTerm->u.leftColumn = pLeft->iColumn;
117428117593
pTerm->eOperator = operatorMask(op) & opMask;
117429117594
}
117595
+ if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
117430117596
if( pRight && pRight->op==TK_COLUMN ){
117431117597
WhereTerm *pNew;
117432117598
Expr *pDup;
117433117599
u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
117434117600
if( pTerm->leftCursor>=0 ){
@@ -117440,16 +117606,15 @@
117440117606
}
117441117607
idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
117442117608
if( idxNew==0 ) return;
117443117609
pNew = &pWC->a[idxNew];
117444117610
markTermAsChild(pWC, idxNew, idxTerm);
117611
+ if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
117445117612
pTerm = &pWC->a[idxTerm];
117446117613
pTerm->wtFlags |= TERM_COPIED;
117447
- if( pExpr->op==TK_EQ
117448
- && !ExprHasProperty(pExpr, EP_FromJoin)
117449
- && OptimizationEnabled(db, SQLITE_Transitive)
117450
- ){
117614
+
117615
+ if( termIsEquivalence(pParse, pDup) ){
117451117616
pTerm->eOperator |= WO_EQUIV;
117452117617
eExtraOp = WO_EQUIV;
117453117618
}
117454117619
}else{
117455117620
pDup = pExpr;
@@ -117639,14 +117804,11 @@
117639117804
/* When sqlite_stat3 histogram data is available an operator of the
117640117805
** form "x IS NOT NULL" can sometimes be evaluated more efficiently
117641117806
** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
117642117807
** virtual term of that form.
117643117808
**
117644
- ** Note that the virtual term must be tagged with TERM_VNULL. This
117645
- ** TERM_VNULL tag will suppress the not-null check at the beginning
117646
- ** of the loop. Without the TERM_VNULL flag, the not-null check at
117647
- ** the start of the loop will prevent any results from being returned.
117809
+ ** Note that the virtual term must be tagged with TERM_VNULL.
117648117810
*/
117649117811
if( pExpr->op==TK_NOTNULL
117650117812
&& pExpr->pLeft->op==TK_COLUMN
117651117813
&& pExpr->pLeft->iColumn>=0
117652117814
&& OptimizationEnabled(db, SQLITE_Stat34)
@@ -117787,10 +117949,40 @@
117787117949
** Estimate the logarithm of the input value to base 2.
117788117950
*/
117789117951
static LogEst estLog(LogEst N){
117790117952
return N<=10 ? 0 : sqlite3LogEst(N) - 33;
117791117953
}
117954
+
117955
+/*
117956
+** Convert OP_Column opcodes to OP_Copy in previously generated code.
117957
+**
117958
+** This routine runs over generated VDBE code and translates OP_Column
117959
+** opcodes into OP_Copy, and OP_Rowid into OP_Null, when the table is being
117960
+** accessed via co-routine instead of via table lookup.
117961
+*/
117962
+static void translateColumnToCopy(
117963
+ Vdbe *v, /* The VDBE containing code to translate */
117964
+ int iStart, /* Translate from this opcode to the end */
117965
+ int iTabCur, /* OP_Column/OP_Rowid references to this table */
117966
+ int iRegister /* The first column is in this register */
117967
+){
117968
+ VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
117969
+ int iEnd = sqlite3VdbeCurrentAddr(v);
117970
+ for(; iStart<iEnd; iStart++, pOp++){
117971
+ if( pOp->p1!=iTabCur ) continue;
117972
+ if( pOp->opcode==OP_Column ){
117973
+ pOp->opcode = OP_Copy;
117974
+ pOp->p1 = pOp->p2 + iRegister;
117975
+ pOp->p2 = pOp->p3;
117976
+ pOp->p3 = 0;
117977
+ }else if( pOp->opcode==OP_Rowid ){
117978
+ pOp->opcode = OP_Null;
117979
+ pOp->p1 = 0;
117980
+ pOp->p3 = 0;
117981
+ }
117982
+ }
117983
+}
117792117984
117793117985
/*
117794117986
** Two routines for printing the content of an sqlite3_index_info
117795117987
** structure. Used for testing and debugging only. If neither
117796117988
** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
@@ -117846,15 +118038,16 @@
117846118038
struct SrcList_item *pSrc, /* Table we are trying to access */
117847118039
Bitmask notReady /* Tables in outer loops of the join */
117848118040
){
117849118041
char aff;
117850118042
if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
117851
- if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
118043
+ if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
117852118044
if( (pTerm->prereqRight & notReady)!=0 ) return 0;
117853118045
if( pTerm->u.leftColumn<0 ) return 0;
117854118046
aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
117855118047
if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
118048
+ testcase( pTerm->pExpr->op==TK_IS );
117856118049
return 1;
117857118050
}
117858118051
#endif
117859118052
117860118053
@@ -117889,10 +118082,11 @@
117889118082
Bitmask idxCols; /* Bitmap of columns used for indexing */
117890118083
Bitmask extraCols; /* Bitmap of additional columns */
117891118084
u8 sentWarning = 0; /* True if a warnning has been issued */
117892118085
Expr *pPartial = 0; /* Partial Index Expression */
117893118086
int iContinue = 0; /* Jump here to skip excluded rows */
118087
+ struct SrcList_item *pTabItem; /* FROM clause term being indexed */
117894118088
117895118089
/* Generate code to skip over the creation and initialization of the
117896118090
** transient index on 2nd and subsequent iterations of the loop. */
117897118091
v = pParse->pVdbe;
117898118092
assert( v!=0 );
@@ -118014,11 +118208,20 @@
118014118208
sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
118015118209
VdbeComment((v, "for %s", pTable->zName));
118016118210
118017118211
/* Fill the automatic index with content */
118018118212
sqlite3ExprCachePush(pParse);
118019
- addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
118213
+ pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
118214
+ if( pTabItem->viaCoroutine ){
118215
+ int regYield = pTabItem->regReturn;
118216
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
118217
+ addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
118218
+ VdbeCoverage(v);
118219
+ VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
118220
+ }else{
118221
+ addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
118222
+ }
118020118223
if( pPartial ){
118021118224
iContinue = sqlite3VdbeMakeLabel(v);
118022118225
sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
118023118226
pLoop->wsFlags |= WHERE_PARTIALIDX;
118024118227
}
@@ -118025,11 +118228,17 @@
118025118228
regRecord = sqlite3GetTempReg(pParse);
118026118229
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
118027118230
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
118028118231
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
118029118232
if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
118030
- sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
118233
+ if( pTabItem->viaCoroutine ){
118234
+ translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
118235
+ sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
118236
+ pTabItem->viaCoroutine = 0;
118237
+ }else{
118238
+ sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
118239
+ }
118031118240
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
118032118241
sqlite3VdbeJumpHere(v, addrTop);
118033118242
sqlite3ReleaseTempReg(pParse, regRecord);
118034118243
sqlite3ExprCachePop(pParse);
118035118244
@@ -118067,12 +118276,13 @@
118067118276
for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
118068118277
if( pTerm->leftCursor != pSrc->iCursor ) continue;
118069118278
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
118070118279
testcase( pTerm->eOperator & WO_IN );
118071118280
testcase( pTerm->eOperator & WO_ISNULL );
118281
+ testcase( pTerm->eOperator & WO_IS );
118072118282
testcase( pTerm->eOperator & WO_ALL );
118073
- if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
118283
+ if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
118074118284
if( pTerm->wtFlags & TERM_VNULL ) continue;
118075118285
nTerm++;
118076118286
}
118077118287
118078118288
/* If the ORDER BY clause contains only columns in the current
@@ -118119,13 +118329,14 @@
118119118329
for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
118120118330
u8 op;
118121118331
if( pTerm->leftCursor != pSrc->iCursor ) continue;
118122118332
assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
118123118333
testcase( pTerm->eOperator & WO_IN );
118334
+ testcase( pTerm->eOperator & WO_IS );
118124118335
testcase( pTerm->eOperator & WO_ISNULL );
118125118336
testcase( pTerm->eOperator & WO_ALL );
118126
- if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
118337
+ if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
118127118338
if( pTerm->wtFlags & TERM_VNULL ) continue;
118128118339
pIdxCons[j].iColumn = pTerm->u.leftColumn;
118129118340
pIdxCons[j].iTermOffset = i;
118130118341
op = (u8)pTerm->eOperator & WO_ALL;
118131118342
if( op==WO_IN ) op = WO_EQ;
@@ -118963,11 +119174,11 @@
118963119174
Expr *pX = pTerm->pExpr;
118964119175
Vdbe *v = pParse->pVdbe;
118965119176
int iReg; /* Register holding results */
118966119177
118967119178
assert( iTarget>0 );
118968
- if( pX->op==TK_EQ ){
119179
+ if( pX->op==TK_EQ || pX->op==TK_IS ){
118969119180
iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
118970119181
}else if( pX->op==TK_ISNULL ){
118971119182
iReg = iTarget;
118972119183
sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
118973119184
#ifndef SQLITE_OMIT_SUBQUERY
@@ -119148,11 +119359,11 @@
119148119359
}
119149119360
testcase( pTerm->eOperator & WO_ISNULL );
119150119361
testcase( pTerm->eOperator & WO_IN );
119151119362
if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
119152119363
Expr *pRight = pTerm->pExpr->pRight;
119153
- if( sqlite3ExprCanBeNull(pRight) ){
119364
+ if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
119154119365
sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
119155119366
VdbeCoverage(v);
119156119367
}
119157119368
if( zAff ){
119158119369
if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
@@ -120270,20 +120481,23 @@
120270120481
*/
120271120482
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
120272120483
Expr *pE, *pEAlt;
120273120484
WhereTerm *pAlt;
120274120485
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
120275
- if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
120486
+ if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
120487
+ if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
120276120488
if( pTerm->leftCursor!=iCur ) continue;
120277120489
if( pLevel->iLeftJoin ) continue;
120278120490
pE = pTerm->pExpr;
120279120491
assert( !ExprHasProperty(pE, EP_FromJoin) );
120280120492
assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
120281
- pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
120493
+ pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
120494
+ WO_EQ|WO_IN|WO_IS, 0);
120282120495
if( pAlt==0 ) continue;
120283120496
if( pAlt->wtFlags & (TERM_CODED) ) continue;
120284120497
testcase( pAlt->eOperator & WO_EQ );
120498
+ testcase( pAlt->eOperator & WO_IS );
120285120499
testcase( pAlt->eOperator & WO_IN );
120286120500
VdbeModuleComment((v, "begin transitive constraint"));
120287120501
pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
120288120502
if( pEAlt ){
120289120503
*pEAlt = *pAlt->pExpr;
@@ -120329,13 +120543,14 @@
120329120543
char zType[4];
120330120544
memcpy(zType, "...", 4);
120331120545
if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
120332120546
if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
120333120547
if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
120334
- sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
120335
- iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
120336
- pTerm->eOperator);
120548
+ sqlite3DebugPrintf(
120549
+ "TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n",
120550
+ iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
120551
+ pTerm->eOperator, pTerm->wtFlags);
120337120552
sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
120338120553
}
120339120554
}
120340120555
#endif
120341120556
@@ -120821,12 +121036,13 @@
120821121036
pLoop->nOut += pTerm->truthProb;
120822121037
}else{
120823121038
/* In the absence of explicit truth probabilities, use heuristics to
120824121039
** guess a reasonable truth probability. */
120825121040
pLoop->nOut--;
120826
- if( pTerm->eOperator&WO_EQ ){
121041
+ if( pTerm->eOperator&(WO_EQ|WO_IS) ){
120827121042
Expr *pRight = pTerm->pExpr->pRight;
121043
+ testcase( pTerm->pExpr->op==TK_IS );
120828121044
if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
120829121045
k = 10;
120830121046
}else{
120831121047
k = 20;
120832121048
}
@@ -120890,14 +121106,14 @@
120890121106
120891121107
assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
120892121108
assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
120893121109
if( pNew->wsFlags & WHERE_BTM_LIMIT ){
120894121110
opMask = WO_LT|WO_LE;
120895
- }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
121111
+ }else if( /*pProbe->tnum<=0 ||*/ (pSrc->jointype & JT_LEFT)!=0 ){
120896121112
opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
120897121113
}else{
120898
- opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
121114
+ opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
120899121115
}
120900121116
if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
120901121117
120902121118
assert( pNew->u.btree.nEq<pProbe->nColumn );
120903121119
iCol = pProbe->aiColumn[pNew->u.btree.nEq];
@@ -120956,11 +121172,11 @@
120956121172
nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
120957121173
}
120958121174
assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
120959121175
** changes "x IN (?)" into "x=?". */
120960121176
120961
- }else if( eOp & (WO_EQ) ){
121177
+ }else if( eOp & (WO_EQ|WO_IS) ){
120962121178
pNew->wsFlags |= WHERE_COLUMN_EQ;
120963121179
if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
120964121180
if( iCol>=0 && pProbe->uniqNotNull==0 ){
120965121181
pNew->wsFlags |= WHERE_UNQ_WANTED;
120966121182
}else{
@@ -121006,11 +121222,11 @@
121006121222
/* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
121007121223
** data, using some other estimate. */
121008121224
whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
121009121225
}else{
121010121226
int nEq = ++pNew->u.btree.nEq;
121011
- assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) );
121227
+ assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
121012121228
121013121229
assert( pNew->nOut==saved_nOut );
121014121230
if( pTerm->truthProb<=0 && iCol>=0 ){
121015121231
assert( (eOp & WO_IN) || nIn==0 );
121016121232
testcase( eOp & WO_IN );
@@ -121023,12 +121239,13 @@
121023121239
&& pProbe->nSample
121024121240
&& pNew->u.btree.nEq<=pProbe->nSampleCol
121025121241
&& ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
121026121242
){
121027121243
Expr *pExpr = pTerm->pExpr;
121028
- if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
121244
+ if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
121029121245
testcase( eOp & WO_EQ );
121246
+ testcase( eOp & WO_IS );
121030121247
testcase( eOp & WO_ISNULL );
121031121248
rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
121032121249
}else{
121033121250
rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
121034121251
}
@@ -121293,19 +121510,18 @@
121293121510
rSize = pTab->nRowLogEst;
121294121511
rLogSize = estLog(rSize);
121295121512
121296121513
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
121297121514
/* Automatic indexes */
121298
- if( !pBuilder->pOrSet
121515
+ if( !pBuilder->pOrSet /* Not part of an OR optimization */
121299121516
&& (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
121300121517
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
121301
- && pSrc->pIndex==0
121302
- && !pSrc->viaCoroutine
121303
- && !pSrc->notIndexed
121304
- && HasRowid(pTab)
121305
- && !pSrc->isCorrelated
121306
- && !pSrc->isRecursive
121518
+ && pSrc->pIndex==0 /* Has no INDEXED BY clause */
121519
+ && !pSrc->notIndexed /* Has no NOT INDEXED clause */
121520
+ && HasRowid(pTab) /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */
121521
+ && !pSrc->isCorrelated /* Not a correlated subquery */
121522
+ && !pSrc->isRecursive /* Not a recursive common table expression. */
121307121523
){
121308121524
/* Generate auto-index WhereLoops */
121309121525
WhereTerm *pTerm;
121310121526
WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
121311121527
for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
@@ -121861,21 +122077,22 @@
121861122077
if( MASKBIT(i) & obSat ) continue;
121862122078
pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
121863122079
if( pOBExpr->op!=TK_COLUMN ) continue;
121864122080
if( pOBExpr->iTable!=iCur ) continue;
121865122081
pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
121866
- ~ready, WO_EQ|WO_ISNULL, 0);
122082
+ ~ready, WO_EQ|WO_ISNULL|WO_IS, 0);
121867122083
if( pTerm==0 ) continue;
121868
- if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
122084
+ if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
121869122085
const char *z1, *z2;
121870122086
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
121871122087
if( !pColl ) pColl = db->pDfltColl;
121872122088
z1 = pColl->zName;
121873122089
pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
121874122090
if( !pColl ) pColl = db->pDfltColl;
121875122091
z2 = pColl->zName;
121876122092
if( sqlite3StrICmp(z1, z2)!=0 ) continue;
122093
+ testcase( pTerm->pExpr->op==TK_IS );
121877122094
}
121878122095
obSat |= MASKBIT(i);
121879122096
}
121880122097
121881122098
if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
@@ -121902,11 +122119,11 @@
121902122119
u8 bOnce; /* True to run the ORDER BY search loop */
121903122120
121904122121
/* Skip over == and IS NULL terms */
121905122122
if( j<pLoop->u.btree.nEq
121906122123
&& pLoop->nSkip==0
121907
- && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
122124
+ && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL|WO_IS))!=0
121908122125
){
121909122126
if( i & WO_ISNULL ){
121910122127
testcase( isOrderDistinct );
121911122128
isOrderDistinct = 0;
121912122129
}
@@ -122475,28 +122692,32 @@
122475122692
iCur = pItem->iCursor;
122476122693
pWC = &pWInfo->sWC;
122477122694
pLoop = pBuilder->pNew;
122478122695
pLoop->wsFlags = 0;
122479122696
pLoop->nSkip = 0;
122480
- pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
122697
+ pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0);
122481122698
if( pTerm ){
122699
+ testcase( pTerm->eOperator & WO_IS );
122482122700
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
122483122701
pLoop->aLTerm[0] = pTerm;
122484122702
pLoop->nLTerm = 1;
122485122703
pLoop->u.btree.nEq = 1;
122486122704
/* TUNING: Cost of a rowid lookup is 10 */
122487122705
pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */
122488122706
}else{
122489122707
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
122708
+ int opMask;
122490122709
assert( pLoop->aLTermSpace==pLoop->aLTerm );
122491122710
if( !IsUniqueIndex(pIdx)
122492122711
|| pIdx->pPartIdxWhere!=0
122493122712
|| pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
122494122713
) continue;
122714
+ opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
122495122715
for(j=0; j<pIdx->nKeyCol; j++){
122496
- pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
122716
+ pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, opMask, pIdx);
122497122717
if( pTerm==0 ) break;
122718
+ testcase( pTerm->eOperator & WO_IS );
122498122719
pLoop->aLTerm[j] = pTerm;
122499122720
}
122500122721
if( j!=pIdx->nKeyCol ) continue;
122501122722
pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
122502122723
if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
@@ -123131,30 +123352,16 @@
123131123352
Table *pTab = pTabItem->pTab;
123132123353
assert( pTab!=0 );
123133123354
pLoop = pLevel->pWLoop;
123134123355
123135123356
/* For a co-routine, change all OP_Column references to the table of
123136
- ** the co-routine into OP_SCopy of result contained in a register.
123357
+ ** the co-routine into OP_Copy of result contained in a register.
123137123358
** OP_Rowid becomes OP_Null.
123138123359
*/
123139123360
if( pTabItem->viaCoroutine && !db->mallocFailed ){
123140
- last = sqlite3VdbeCurrentAddr(v);
123141
- k = pLevel->addrBody;
123142
- pOp = sqlite3VdbeGetOp(v, k);
123143
- for(; k<last; k++, pOp++){
123144
- if( pOp->p1!=pLevel->iTabCur ) continue;
123145
- if( pOp->opcode==OP_Column ){
123146
- pOp->opcode = OP_Copy;
123147
- pOp->p1 = pOp->p2 + pTabItem->regResult;
123148
- pOp->p2 = pOp->p3;
123149
- pOp->p3 = 0;
123150
- }else if( pOp->opcode==OP_Rowid ){
123151
- pOp->opcode = OP_Null;
123152
- pOp->p1 = 0;
123153
- pOp->p3 = 0;
123154
- }
123155
- }
123361
+ translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
123362
+ pTabItem->regResult);
123156123363
continue;
123157123364
}
123158123365
123159123366
/* Close all of the cursors that were opened by sqlite3WhereBegin.
123160123367
** Except, do not close cursors that will be reused by the OR optimization
@@ -125418,11 +125625,11 @@
125418125625
{yygotominor.yy186 = 0;}
125419125626
break;
125420125627
case 35: /* table_options ::= WITHOUT nm */
125421125628
{
125422125629
if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
125423
- yygotominor.yy186 = TF_WithoutRowid;
125630
+ yygotominor.yy186 = TF_WithoutRowid | TF_NoVisibleRowid;
125424125631
}else{
125425125632
yygotominor.yy186 = 0;
125426125633
sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
125427125634
}
125428125635
}
@@ -125642,10 +125849,11 @@
125642125849
{yygotominor.yy3 = yymsp[0].minor.yy3;}
125643125850
break;
125644125851
case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
125645125852
{
125646125853
Select *pRhs = yymsp[0].minor.yy3;
125854
+ Select *pLhs = yymsp[-2].minor.yy3;
125647125855
if( pRhs && pRhs->pPrior ){
125648125856
SrcList *pFrom;
125649125857
Token x;
125650125858
x.n = 0;
125651125859
parserDoubleLinkSelect(pParse, pRhs);
@@ -125652,15 +125860,16 @@
125652125860
pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
125653125861
pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
125654125862
}
125655125863
if( pRhs ){
125656125864
pRhs->op = (u8)yymsp[-1].minor.yy328;
125657
- pRhs->pPrior = yymsp[-2].minor.yy3;
125865
+ pRhs->pPrior = pLhs;
125866
+ if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
125658125867
pRhs->selFlags &= ~SF_MultiValue;
125659125868
if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
125660125869
}else{
125661
- sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
125870
+ sqlite3SelectDelete(pParse->db, pLhs);
125662125871
}
125663125872
yygotominor.yy3 = pRhs;
125664125873
}
125665125874
break;
125666125875
case 116: /* multiselect_op ::= UNION ALL */
@@ -125717,11 +125926,13 @@
125717125926
break;
125718125927
case 122: /* distinct ::= DISTINCT */
125719125928
{yygotominor.yy381 = SF_Distinct;}
125720125929
break;
125721125930
case 123: /* distinct ::= ALL */
125722
- case 124: /* distinct ::= */ yytestcase(yyruleno==124);
125931
+{yygotominor.yy381 = SF_All;}
125932
+ break;
125933
+ case 124: /* distinct ::= */
125723125934
{yygotominor.yy381 = 0;}
125724125935
break;
125725125936
case 125: /* sclp ::= selcollist COMMA */
125726125937
case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243);
125727125938
{yygotominor.yy14 = yymsp[-1].minor.yy14;}
@@ -126012,11 +126223,11 @@
126012126223
if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
126013126224
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
126014126225
}
126015126226
yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
126016126227
spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
126017
- if( yymsp[-2].minor.yy381 && yygotominor.yy346.pExpr ){
126228
+ if( yymsp[-2].minor.yy381==SF_Distinct && yygotominor.yy346.pExpr ){
126018126229
yygotominor.yy346.pExpr->flags |= EP_Distinct;
126019126230
}
126020126231
}
126021126232
break;
126022126233
case 196: /* expr ::= ID|INDEXED LP STAR RP */
@@ -127533,11 +127744,12 @@
127533127744
}
127534127745
}
127535127746
}
127536127747
abort_parse:
127537127748
assert( nErr==0 );
127538
- if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
127749
+ if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
127750
+ assert( zSql[i]==0 );
127539127751
if( lastTokenParsed!=TK_SEMI ){
127540127752
sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
127541127753
pParse->zTail = &zSql[i];
127542127754
}
127543127755
if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
@@ -127555,11 +127767,11 @@
127555127767
db->lookaside.bEnabled = enableLookaside;
127556127768
if( db->mallocFailed ){
127557127769
pParse->rc = SQLITE_NOMEM;
127558127770
}
127559127771
if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
127560
- sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
127772
+ pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
127561127773
}
127562127774
assert( pzErrMsg!=0 );
127563127775
if( pParse->zErrMsg ){
127564127776
*pzErrMsg = pParse->zErrMsg;
127565127777
sqlite3_log(pParse->rc, "%s", *pzErrMsg);
@@ -130747,10 +130959,13 @@
130747130959
| SQLITE_ForeignKeys
130748130960
#endif
130749130961
#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
130750130962
| SQLITE_ReverseOrder
130751130963
#endif
130964
+#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
130965
+ | SQLITE_CellSizeCk
130966
+#endif
130752130967
;
130753130968
sqlite3HashInit(&db->aCollSeq);
130754130969
#ifndef SQLITE_OMIT_VIRTUALTABLE
130755130970
sqlite3HashInit(&db->aModule);
130756130971
#endif
@@ -130866,12 +131081,11 @@
130866131081
}
130867131082
#endif
130868131083
130869131084
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
130870131085
if( !db->mallocFailed && rc==SQLITE_OK){
130871
- int sqlite3_dbstat_register(sqlite3*);
130872
- rc = sqlite3_dbstat_register(db);
131086
+ rc = sqlite3DbstatRegister(db);
130873131087
}
130874131088
#endif
130875131089
130876131090
/* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
130877131091
** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
@@ -132871,10 +133085,12 @@
132871133085
typedef struct Fts3SegFilter Fts3SegFilter;
132872133086
typedef struct Fts3DeferredToken Fts3DeferredToken;
132873133087
typedef struct Fts3SegReader Fts3SegReader;
132874133088
typedef struct Fts3MultiSegReader Fts3MultiSegReader;
132875133089
133090
+typedef struct MatchinfoBuffer MatchinfoBuffer;
133091
+
132876133092
/*
132877133093
** A connection to a fulltext index is an instance of the following
132878133094
** structure. The xCreate and xConnect methods create an instance
132879133095
** of this structure and xDestroy and xDisconnect free that instance.
132880133096
** All other methods receive a pointer to the structure as one of their
@@ -132980,13 +133196,11 @@
132980133196
int nRowAvg; /* Average size of database rows, in pages */
132981133197
sqlite3_int64 nDoc; /* Documents in table */
132982133198
i64 iMinDocid; /* Minimum docid to return */
132983133199
i64 iMaxDocid; /* Maximum docid to return */
132984133200
int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
132985
- u32 *aMatchinfo; /* Information about most recent match */
132986
- int nMatchinfo; /* Number of elements in aMatchinfo[] */
132987
- char *zMatchinfo; /* Matchinfo specification */
133201
+ MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */
132988133202
};
132989133203
132990133204
#define FTS3_EVAL_FILTER 0
132991133205
#define FTS3_EVAL_NEXT 1
132992133206
#define FTS3_EVAL_MATCHINFO 2
@@ -133102,11 +133316,13 @@
133102133316
sqlite3_int64 iDocid; /* Current docid */
133103133317
u8 bEof; /* True this expression is at EOF already */
133104133318
u8 bStart; /* True if iDocid is valid */
133105133319
u8 bDeferred; /* True if this expression is entirely deferred */
133106133320
133107
- u32 *aMI;
133321
+ /* The following are used by the fts3_snippet.c module. */
133322
+ int iPhrase; /* Index of this phrase in matchinfo() results */
133323
+ u32 *aMI; /* See above */
133108133324
};
133109133325
133110133326
/*
133111133327
** Candidate values for Fts3Query.eType. Note that the order of the first
133112133328
** four values is in order of precedence when parsing expressions. For
@@ -133223,10 +133439,11 @@
133223133439
SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
133224133440
SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
133225133441
SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
133226133442
SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
133227133443
SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
133444
+SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
133228133445
133229133446
/* fts3_tokenizer.c */
133230133447
SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
133231133448
SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
133232133449
SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -133238,10 +133455,11 @@
133238133455
SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*);
133239133456
SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
133240133457
const char *, const char *, int, int
133241133458
);
133242133459
SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
133460
+SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p);
133243133461
133244133462
/* fts3_expr.c */
133245133463
SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
133246133464
char **, int, int, int, const char *, int, Fts3Expr **, char **
133247133465
);
@@ -134665,11 +134883,11 @@
134665134883
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
134666134884
sqlite3_finalize(pCsr->pStmt);
134667134885
sqlite3Fts3ExprFree(pCsr->pExpr);
134668134886
sqlite3Fts3FreeDeferredTokens(pCsr);
134669134887
sqlite3_free(pCsr->aDoclist);
134670
- sqlite3_free(pCsr->aMatchinfo);
134888
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
134671134889
assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
134672134890
sqlite3_free(pCsr);
134673134891
return SQLITE_OK;
134674134892
}
134675134893
@@ -136166,11 +136384,11 @@
136166136384
assert( iIdx==nVal );
136167136385
136168136386
/* In case the cursor has been used before, clear it now. */
136169136387
sqlite3_finalize(pCsr->pStmt);
136170136388
sqlite3_free(pCsr->aDoclist);
136171
- sqlite3_free(pCsr->aMatchinfo);
136389
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
136172136390
sqlite3Fts3ExprFree(pCsr->pExpr);
136173136391
memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
136174136392
136175136393
/* Set the lower and upper bounds on docids to return */
136176136394
pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -138064,11 +138282,11 @@
138064138282
** is populated as for "A * C" before returning.
138065138283
**
138066138284
** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is
138067138285
** advanced to point to the next row that matches "x AND y".
138068138286
**
138069
-** See fts3EvalTestDeferredAndNear() for details on testing if a row is
138287
+** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is
138070138288
** really a match, taking into account deferred tokens and NEAR operators.
138071138289
*/
138072138290
static void fts3EvalNextRow(
138073138291
Fts3Cursor *pCsr, /* FTS Cursor handle */
138074138292
Fts3Expr *pExpr, /* Expr. to advance to next matching row */
@@ -138284,11 +138502,11 @@
138284138502
138285138503
return res;
138286138504
}
138287138505
138288138506
/*
138289
-** This function is a helper function for fts3EvalTestDeferredAndNear().
138507
+** This function is a helper function for sqlite3Fts3EvalTestDeferred().
138290138508
** Assuming no error occurs or has occurred, It returns non-zero if the
138291138509
** expression passed as the second argument matches the row that pCsr
138292138510
** currently points to, or zero if it does not.
138293138511
**
138294138512
** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
@@ -138405,11 +138623,11 @@
138405138623
** it is determined that the row does *not* match the query.
138406138624
**
138407138625
** Or, if no error occurs and it seems the current row does match the FTS
138408138626
** query, return 0.
138409138627
*/
138410
-static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){
138628
+SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){
138411138629
int rc = *pRc;
138412138630
int bMiss = 0;
138413138631
if( rc==SQLITE_OK ){
138414138632
138415138633
/* If there are one or more deferred tokens, load the current row into
@@ -138452,11 +138670,11 @@
138452138670
fts3EvalNextRow(pCsr, pExpr, &rc);
138453138671
pCsr->isEof = pExpr->bEof;
138454138672
pCsr->isRequireSeek = 1;
138455138673
pCsr->isMatchinfoNeeded = 1;
138456138674
pCsr->iPrevId = pExpr->iDocid;
138457
- }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
138675
+ }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) );
138458138676
}
138459138677
138460138678
/* Check if the cursor is past the end of the docid range specified
138461138679
** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */
138462138680
if( rc==SQLITE_OK && (
@@ -138613,11 +138831,11 @@
138613138831
pCsr->isRequireSeek = 1;
138614138832
pCsr->isMatchinfoNeeded = 1;
138615138833
pCsr->iPrevId = pRoot->iDocid;
138616138834
}while( pCsr->isEof==0
138617138835
&& pRoot->eType==FTSQUERY_NEAR
138618
- && fts3EvalTestDeferredAndNear(pCsr, &rc)
138836
+ && sqlite3Fts3EvalTestDeferred(pCsr, &rc)
138619138837
);
138620138838
138621138839
if( rc==SQLITE_OK && pCsr->isEof==0 ){
138622138840
fts3EvalUpdateCounts(pRoot);
138623138841
}
@@ -138638,11 +138856,10 @@
138638138856
fts3EvalRestart(pCsr, pRoot, &rc);
138639138857
do {
138640138858
fts3EvalNextRow(pCsr, pRoot, &rc);
138641138859
assert( pRoot->bEof==0 );
138642138860
}while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
138643
- fts3EvalTestDeferredAndNear(pCsr, &rc);
138644138861
}
138645138862
}
138646138863
return rc;
138647138864
}
138648138865
@@ -148650,10 +148867,11 @@
148650148867
#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */
148651148868
#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
148652148869
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
148653148870
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
148654148871
#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
148872
+#define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */
148655148873
148656148874
/*
148657148875
** The default value for the second argument to matchinfo().
148658148876
*/
148659148877
#define FTS3_MATCHINFO_DEFAULT "pcx"
@@ -148711,13 +148929,26 @@
148711148929
struct MatchInfo {
148712148930
Fts3Cursor *pCursor; /* FTS3 Cursor */
148713148931
int nCol; /* Number of columns in table */
148714148932
int nPhrase; /* Number of matchable phrases in query */
148715148933
sqlite3_int64 nDoc; /* Number of docs in database */
148934
+ char flag;
148716148935
u32 *aMatchinfo; /* Pre-allocated buffer */
148717148936
};
148718148937
148938
+/*
148939
+** An instance of this structure is used to manage a pair of buffers, each
148940
+** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below
148941
+** for details.
148942
+*/
148943
+struct MatchinfoBuffer {
148944
+ u8 aRef[3];
148945
+ int nElem;
148946
+ int bGlobal; /* Set if global data is loaded */
148947
+ char *zMatchinfo;
148948
+ u32 aMatchinfo[1];
148949
+};
148719148950
148720148951
148721148952
/*
148722148953
** The snippet() and offsets() functions both return text values. An instance
148723148954
** of the following structure is used to accumulate those values while the
@@ -148728,10 +148959,101 @@
148728148959
char *z; /* Pointer to buffer containing string */
148729148960
int n; /* Length of z in bytes (excl. nul-term) */
148730148961
int nAlloc; /* Allocated size of buffer z in bytes */
148731148962
};
148732148963
148964
+
148965
+/*************************************************************************
148966
+** Start of MatchinfoBuffer code.
148967
+*/
148968
+
148969
+/*
148970
+** Allocate a two-slot MatchinfoBuffer object.
148971
+*/
148972
+static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
148973
+ MatchinfoBuffer *pRet;
148974
+ int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
148975
+ int nStr = (int)strlen(zMatchinfo);
148976
+
148977
+ pRet = sqlite3_malloc(nByte + nStr+1);
148978
+ if( pRet ){
148979
+ memset(pRet, 0, nByte);
148980
+ pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
148981
+ pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
148982
+ pRet->nElem = nElem;
148983
+ pRet->zMatchinfo = ((char*)pRet) + nByte;
148984
+ memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
148985
+ pRet->aRef[0] = 1;
148986
+ }
148987
+
148988
+ return pRet;
148989
+}
148990
+
148991
+static void fts3MIBufferFree(void *p){
148992
+ MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
148993
+
148994
+ assert( (u32*)p==&pBuf->aMatchinfo[1]
148995
+ || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
148996
+ );
148997
+ if( (u32*)p==&pBuf->aMatchinfo[1] ){
148998
+ pBuf->aRef[1] = 0;
148999
+ }else{
149000
+ pBuf->aRef[2] = 0;
149001
+ }
149002
+
149003
+ if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){
149004
+ sqlite3_free(pBuf);
149005
+ }
149006
+}
149007
+
149008
+static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
149009
+ void (*xRet)(void*) = 0;
149010
+ u32 *aOut = 0;
149011
+
149012
+ if( p->aRef[1]==0 ){
149013
+ p->aRef[1] = 1;
149014
+ aOut = &p->aMatchinfo[1];
149015
+ xRet = fts3MIBufferFree;
149016
+ }
149017
+ else if( p->aRef[2]==0 ){
149018
+ p->aRef[2] = 1;
149019
+ aOut = &p->aMatchinfo[p->nElem+2];
149020
+ xRet = fts3MIBufferFree;
149021
+ }else{
149022
+ aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
149023
+ if( aOut ){
149024
+ xRet = sqlite3_free;
149025
+ if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
149026
+ }
149027
+ }
149028
+
149029
+ *paOut = aOut;
149030
+ return xRet;
149031
+}
149032
+
149033
+static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
149034
+ p->bGlobal = 1;
149035
+ memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
149036
+}
149037
+
149038
+/*
149039
+** Free a MatchinfoBuffer object allocated using fts3MIBufferNew()
149040
+*/
149041
+SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
149042
+ if( p ){
149043
+ assert( p->aRef[0]==1 );
149044
+ p->aRef[0] = 0;
149045
+ if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){
149046
+ sqlite3_free(p);
149047
+ }
149048
+ }
149049
+}
149050
+
149051
+/*
149052
+** End of MatchinfoBuffer code.
149053
+*************************************************************************/
149054
+
148733149055
148734149056
/*
148735149057
** This function is used to help iterate through a position-list. A position
148736149058
** list is a list of unique integers, sorted from smallest to largest. Each
148737149059
** element of the list is represented by an FTS3 varint that takes the value
@@ -148765,11 +149087,11 @@
148765149087
int *piPhrase, /* Pointer to phrase counter */
148766149088
int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */
148767149089
void *pCtx /* Second argument to pass to callback */
148768149090
){
148769149091
int rc; /* Return code */
148770
- int eType = pExpr->eType; /* Type of expression node pExpr */
149092
+ int eType = pExpr->eType; /* Type of expression node pExpr */
148771149093
148772149094
if( eType!=FTSQUERY_PHRASE ){
148773149095
assert( pExpr->pLeft && pExpr->pRight );
148774149096
rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx);
148775149097
if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){
@@ -148798,10 +149120,11 @@
148798149120
void *pCtx /* Second argument to pass to callback */
148799149121
){
148800149122
int iPhrase = 0; /* Variable used as the phrase counter */
148801149123
return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
148802149124
}
149125
+
148803149126
148804149127
/*
148805149128
** This is an fts3ExprIterate() callback used while loading the doclists
148806149129
** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
148807149130
** fts3ExprLoadDoclists().
@@ -148843,12 +149166,11 @@
148843149166
return rc;
148844149167
}
148845149168
148846149169
static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
148847149170
(*(int *)ctx)++;
148848
- UNUSED_PARAMETER(pExpr);
148849
- UNUSED_PARAMETER(iPhrase);
149171
+ pExpr->iPhrase = iPhrase;
148850149172
return SQLITE_OK;
148851149173
}
148852149174
static int fts3ExprPhraseCount(Fts3Expr *pExpr){
148853149175
int nPhrase = 0;
148854149176
(void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase);
@@ -149065,11 +149387,11 @@
149065149387
sIter.pCsr = pCsr;
149066149388
sIter.iCol = iCol;
149067149389
sIter.nSnippet = nSnippet;
149068149390
sIter.nPhrase = nList;
149069149391
sIter.iCurrent = -1;
149070
- rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
149392
+ rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
149071149393
if( rc==SQLITE_OK ){
149072149394
149073149395
/* Set the *pmSeen output variable. */
149074149396
for(i=0; i<nList; i++){
149075149397
if( sIter.aPhrase[i].pHead ){
@@ -149365,10 +149687,64 @@
149365149687
}
149366149688
149367149689
*ppCollist = pEnd;
149368149690
return nEntry;
149369149691
}
149692
+
149693
+/*
149694
+** This function gathers 'y' or 'b' data for a single phrase.
149695
+*/
149696
+static void fts3ExprLHits(
149697
+ Fts3Expr *pExpr, /* Phrase expression node */
149698
+ MatchInfo *p /* Matchinfo context */
149699
+){
149700
+ Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
149701
+ int iStart;
149702
+ Fts3Phrase *pPhrase = pExpr->pPhrase;
149703
+ char *pIter = pPhrase->doclist.pList;
149704
+ int iCol = 0;
149705
+
149706
+ assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
149707
+ if( p->flag==FTS3_MATCHINFO_LHITS ){
149708
+ iStart = pExpr->iPhrase * p->nCol;
149709
+ }else{
149710
+ iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
149711
+ }
149712
+
149713
+ while( 1 ){
149714
+ int nHit = fts3ColumnlistCount(&pIter);
149715
+ if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
149716
+ if( p->flag==FTS3_MATCHINFO_LHITS ){
149717
+ p->aMatchinfo[iStart + iCol] = (u32)nHit;
149718
+ }else if( nHit ){
149719
+ p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
149720
+ }
149721
+ }
149722
+ assert( *pIter==0x00 || *pIter==0x01 );
149723
+ if( *pIter!=0x01 ) break;
149724
+ pIter++;
149725
+ pIter += fts3GetVarint32(pIter, &iCol);
149726
+ }
149727
+}
149728
+
149729
+/*
149730
+** Gather the results for matchinfo directives 'y' and 'b'.
149731
+*/
149732
+static void fts3ExprLHitGather(
149733
+ Fts3Expr *pExpr,
149734
+ MatchInfo *p
149735
+){
149736
+ assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
149737
+ if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
149738
+ if( pExpr->pLeft ){
149739
+ fts3ExprLHitGather(pExpr->pLeft, p);
149740
+ fts3ExprLHitGather(pExpr->pRight, p);
149741
+ }else{
149742
+ fts3ExprLHits(pExpr, p);
149743
+ }
149744
+ }
149745
+}
149370149746
149371149747
/*
149372149748
** fts3ExprIterate() callback used to collect the "global" matchinfo stats
149373149749
** for a single query.
149374149750
**
@@ -149432,55 +149808,10 @@
149432149808
}
149433149809
149434149810
return rc;
149435149811
}
149436149812
149437
-/*
149438
-** fts3ExprIterate() callback used to gather information for the matchinfo
149439
-** directive 'y'.
149440
-*/
149441
-static int fts3ExprLHitsCb(
149442
- Fts3Expr *pExpr, /* Phrase expression node */
149443
- int iPhrase, /* Phrase number */
149444
- void *pCtx /* Pointer to MatchInfo structure */
149445
-){
149446
- MatchInfo *p = (MatchInfo *)pCtx;
149447
- Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
149448
- int rc = SQLITE_OK;
149449
- int iStart = iPhrase * p->nCol;
149450
- Fts3Expr *pEof; /* Ancestor node already at EOF */
149451
-
149452
- /* This must be a phrase */
149453
- assert( pExpr->pPhrase );
149454
-
149455
- /* Initialize all output integers to zero. */
149456
- memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
149457
-
149458
- /* Check if this or any parent node is at EOF. If so, then all output
149459
- ** values are zero. */
149460
- for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
149461
-
149462
- if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
149463
- Fts3Phrase *pPhrase = pExpr->pPhrase;
149464
- char *pIter = pPhrase->doclist.pList;
149465
- int iCol = 0;
149466
-
149467
- while( 1 ){
149468
- int nHit = fts3ColumnlistCount(&pIter);
149469
- if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
149470
- p->aMatchinfo[iStart + iCol] = (u32)nHit;
149471
- }
149472
- assert( *pIter==0x00 || *pIter==0x01 );
149473
- if( *pIter!=0x01 ) break;
149474
- pIter++;
149475
- pIter += fts3GetVarint32(pIter, &iCol);
149476
- }
149477
- }
149478
-
149479
- return rc;
149480
-}
149481
-
149482149813
static int fts3MatchinfoCheck(
149483149814
Fts3Table *pTab,
149484149815
char cArg,
149485149816
char **pzErr
149486149817
){
@@ -149490,10 +149821,11 @@
149490149821
|| (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
149491149822
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
149492149823
|| (cArg==FTS3_MATCHINFO_LCS)
149493149824
|| (cArg==FTS3_MATCHINFO_HITS)
149494149825
|| (cArg==FTS3_MATCHINFO_LHITS)
149826
+ || (cArg==FTS3_MATCHINFO_LHITS_BM)
149495149827
){
149496149828
return SQLITE_OK;
149497149829
}
149498149830
sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
149499149831
return SQLITE_ERROR;
@@ -149516,10 +149848,14 @@
149516149848
break;
149517149849
149518149850
case FTS3_MATCHINFO_LHITS:
149519149851
nVal = pInfo->nCol * pInfo->nPhrase;
149520149852
break;
149853
+
149854
+ case FTS3_MATCHINFO_LHITS_BM:
149855
+ nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
149856
+ break;
149521149857
149522149858
default:
149523149859
assert( cArg==FTS3_MATCHINFO_HITS );
149524149860
nVal = pInfo->nCol * pInfo->nPhrase * 3;
149525149861
break;
@@ -149711,11 +150047,11 @@
149711150047
int i;
149712150048
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
149713150049
sqlite3_stmt *pSelect = 0;
149714150050
149715150051
for(i=0; rc==SQLITE_OK && zArg[i]; i++){
149716
-
150052
+ pInfo->flag = zArg[i];
149717150053
switch( zArg[i] ){
149718150054
case FTS3_MATCHINFO_NPHRASE:
149719150055
if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
149720150056
break;
149721150057
@@ -149771,13 +150107,17 @@
149771150107
if( rc==SQLITE_OK ){
149772150108
rc = fts3MatchinfoLcs(pCsr, pInfo);
149773150109
}
149774150110
break;
149775150111
149776
- case FTS3_MATCHINFO_LHITS:
149777
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
150112
+ case FTS3_MATCHINFO_LHITS_BM:
150113
+ case FTS3_MATCHINFO_LHITS: {
150114
+ int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
150115
+ memset(pInfo->aMatchinfo, 0, nZero);
150116
+ fts3ExprLHitGather(pCsr->pExpr, pInfo);
149778150117
break;
150118
+ }
149779150119
149780150120
default: {
149781150121
Fts3Expr *pExpr;
149782150122
assert( zArg[i]==FTS3_MATCHINFO_HITS );
149783150123
pExpr = pCsr->pExpr;
@@ -149787,10 +150127,11 @@
149787150127
if( pCsr->pDeferred ){
149788150128
rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
149789150129
if( rc!=SQLITE_OK ) break;
149790150130
}
149791150131
rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
150132
+ sqlite3Fts3EvalTestDeferred(pCsr, &rc);
149792150133
if( rc!=SQLITE_OK ) break;
149793150134
}
149794150135
(void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
149795150136
break;
149796150137
}
@@ -149806,73 +150147,90 @@
149806150147
149807150148
/*
149808150149
** Populate pCsr->aMatchinfo[] with data for the current row. The
149809150150
** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
149810150151
*/
149811
-static int fts3GetMatchinfo(
150152
+static void fts3GetMatchinfo(
150153
+ sqlite3_context *pCtx, /* Return results here */
149812150154
Fts3Cursor *pCsr, /* FTS3 Cursor object */
149813150155
const char *zArg /* Second argument to matchinfo() function */
149814150156
){
149815150157
MatchInfo sInfo;
149816150158
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
149817150159
int rc = SQLITE_OK;
149818150160
int bGlobal = 0; /* Collect 'global' stats as well as local */
149819150161
150162
+ u32 *aOut = 0;
150163
+ void (*xDestroyOut)(void*) = 0;
150164
+
149820150165
memset(&sInfo, 0, sizeof(MatchInfo));
149821150166
sInfo.pCursor = pCsr;
149822150167
sInfo.nCol = pTab->nColumn;
149823150168
149824150169
/* If there is cached matchinfo() data, but the format string for the
149825150170
** cache does not match the format string for this request, discard
149826150171
** the cached data. */
149827
- if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){
149828
- assert( pCsr->aMatchinfo );
149829
- sqlite3_free(pCsr->aMatchinfo);
149830
- pCsr->zMatchinfo = 0;
149831
- pCsr->aMatchinfo = 0;
150172
+ if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){
150173
+ sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
150174
+ pCsr->pMIBuffer = 0;
149832150175
}
149833150176
149834
- /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
150177
+ /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the
149835150178
** matchinfo function has been called for this query. In this case
149836150179
** allocate the array used to accumulate the matchinfo data and
149837150180
** initialize those elements that are constant for every row.
149838150181
*/
149839
- if( pCsr->aMatchinfo==0 ){
150182
+ if( pCsr->pMIBuffer==0 ){
149840150183
int nMatchinfo = 0; /* Number of u32 elements in match-info */
149841
- int nArg; /* Bytes in zArg */
149842150184
int i; /* Used to iterate through zArg */
149843150185
149844150186
/* Determine the number of phrases in the query */
149845150187
pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr);
149846150188
sInfo.nPhrase = pCsr->nPhrase;
149847150189
149848150190
/* Determine the number of integers in the buffer returned by this call. */
149849150191
for(i=0; zArg[i]; i++){
150192
+ char *zErr = 0;
150193
+ if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
150194
+ sqlite3_result_error(pCtx, zErr, -1);
150195
+ sqlite3_free(zErr);
150196
+ return;
150197
+ }
149850150198
nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
149851150199
}
149852150200
149853150201
/* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
149854
- nArg = (int)strlen(zArg);
149855
- pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1);
149856
- if( !pCsr->aMatchinfo ) return SQLITE_NOMEM;
149857
-
149858
- pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo];
149859
- pCsr->nMatchinfo = nMatchinfo;
149860
- memcpy(pCsr->zMatchinfo, zArg, nArg+1);
149861
- memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo);
150202
+ pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg);
150203
+ if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM;
150204
+
149862150205
pCsr->isMatchinfoNeeded = 1;
149863150206
bGlobal = 1;
149864150207
}
149865150208
149866
- sInfo.aMatchinfo = pCsr->aMatchinfo;
149867
- sInfo.nPhrase = pCsr->nPhrase;
149868
- if( pCsr->isMatchinfoNeeded ){
150209
+ if( rc==SQLITE_OK ){
150210
+ xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut);
150211
+ if( xDestroyOut==0 ){
150212
+ rc = SQLITE_NOMEM;
150213
+ }
150214
+ }
150215
+
150216
+ if( rc==SQLITE_OK ){
150217
+ sInfo.aMatchinfo = aOut;
150218
+ sInfo.nPhrase = pCsr->nPhrase;
149869150219
rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
149870
- pCsr->isMatchinfoNeeded = 0;
150220
+ if( bGlobal ){
150221
+ fts3MIBufferSetGlobal(pCsr->pMIBuffer);
150222
+ }
149871150223
}
149872150224
149873
- return rc;
150225
+ if( rc!=SQLITE_OK ){
150226
+ sqlite3_result_error_code(pCtx, rc);
150227
+ if( xDestroyOut ) xDestroyOut(aOut);
150228
+ }else{
150229
+ int n = pCsr->pMIBuffer->nElem * sizeof(u32);
150230
+ sqlite3_result_blob(pCtx, aOut, n, xDestroyOut);
150231
+ }
149874150232
}
149875150233
149876150234
/*
149877150235
** Implementation of snippet() function.
149878150236
*/
@@ -150074,11 +150432,11 @@
150074150432
** no way that this operation can fail, so the return code from
150075150433
** fts3ExprIterate() can be discarded.
150076150434
*/
150077150435
sCtx.iCol = iCol;
150078150436
sCtx.iTerm = 0;
150079
- (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
150437
+ (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
150080150438
150081150439
/* Retreive the text stored in column iCol. If an SQL NULL is stored
150082150440
** in column iCol, jump immediately to the next iteration of the loop.
150083150441
** If an OOM occurs while retrieving the data (this can happen if SQLite
150084150442
** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -150166,42 +150524,25 @@
150166150524
sqlite3_context *pContext, /* Function call context */
150167150525
Fts3Cursor *pCsr, /* FTS3 table cursor */
150168150526
const char *zArg /* Second arg to matchinfo() function */
150169150527
){
150170150528
Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
150171
- int rc;
150172
- int i;
150173150529
const char *zFormat;
150174150530
150175150531
if( zArg ){
150176
- for(i=0; zArg[i]; i++){
150177
- char *zErr = 0;
150178
- if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
150179
- sqlite3_result_error(pContext, zErr, -1);
150180
- sqlite3_free(zErr);
150181
- return;
150182
- }
150183
- }
150184150532
zFormat = zArg;
150185150533
}else{
150186150534
zFormat = FTS3_MATCHINFO_DEFAULT;
150187150535
}
150188150536
150189150537
if( !pCsr->pExpr ){
150190150538
sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
150191150539
return;
150192
- }
150193
-
150194
- /* Retrieve matchinfo() data. */
150195
- rc = fts3GetMatchinfo(pCsr, zFormat);
150196
- sqlite3Fts3SegmentsClose(pTab);
150197
-
150198
- if( rc!=SQLITE_OK ){
150199
- sqlite3_result_error_code(pContext, rc);
150200150540
}else{
150201
- int n = pCsr->nMatchinfo * sizeof(u32);
150202
- sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
150541
+ /* Retrieve matchinfo() data. */
150542
+ fts3GetMatchinfo(pContext, pCsr, zFormat);
150543
+ sqlite3Fts3SegmentsClose(pTab);
150203150544
}
150204150545
}
150205150546
150206150547
#endif
150207150548
@@ -151318,10 +151659,11 @@
151318151659
*/
151319151660
struct RtreeMatchArg {
151320151661
u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
151321151662
RtreeGeomCallback cb; /* Info about the callback functions */
151322151663
int nParam; /* Number of parameters to the SQL function */
151664
+ sqlite3_value **apSqlParam; /* Original SQL parameter values */
151323151665
RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
151324151666
};
151325151667
151326151668
#ifndef MAX
151327151669
# define MAX(x,y) ((x) < (y) ? (y) : (x))
@@ -152449,13 +152791,11 @@
152449152791
/* Check that value is actually a blob. */
152450152792
if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
152451152793
152452152794
/* Check that the blob is roughly the right size. */
152453152795
nBlob = sqlite3_value_bytes(pValue);
152454
- if( nBlob<(int)sizeof(RtreeMatchArg)
152455
- || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
152456
- ){
152796
+ if( nBlob<(int)sizeof(RtreeMatchArg) ){
152457152797
return SQLITE_ERROR;
152458152798
}
152459152799
152460152800
pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
152461152801
if( !pInfo ) return SQLITE_NOMEM;
@@ -152462,18 +152802,20 @@
152462152802
memset(pInfo, 0, sizeof(*pInfo));
152463152803
pBlob = (RtreeMatchArg*)&pInfo[1];
152464152804
152465152805
memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
152466152806
nExpected = (int)(sizeof(RtreeMatchArg) +
152807
+ pBlob->nParam*sizeof(sqlite3_value*) +
152467152808
(pBlob->nParam-1)*sizeof(RtreeDValue));
152468152809
if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
152469152810
sqlite3_free(pInfo);
152470152811
return SQLITE_ERROR;
152471152812
}
152472152813
pInfo->pContext = pBlob->cb.pContext;
152473152814
pInfo->nParam = pBlob->nParam;
152474152815
pInfo->aParam = pBlob->aParam;
152816
+ pInfo->apSqlParam = pBlob->apSqlParam;
152475152817
152476152818
if( pBlob->cb.xGeom ){
152477152819
pCons->u.xGeom = pBlob->cb.xGeom;
152478152820
}else{
152479152821
pCons->op = RTREE_QUERY;
@@ -152636,21 +152978,34 @@
152636152978
*/
152637152979
static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
152638152980
Rtree *pRtree = (Rtree*)tab;
152639152981
int rc = SQLITE_OK;
152640152982
int ii;
152983
+ int bMatch = 0; /* True if there exists a MATCH constraint */
152641152984
i64 nRow; /* Estimated rows returned by this scan */
152642152985
152643152986
int iIdx = 0;
152644152987
char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
152645152988
memset(zIdxStr, 0, sizeof(zIdxStr));
152989
+
152990
+ /* Check if there exists a MATCH constraint - even an unusable one. If there
152991
+ ** is, do not consider the lookup-by-rowid plan as using such a plan would
152992
+ ** require the VDBE to evaluate the MATCH constraint, which is not currently
152993
+ ** possible. */
152994
+ for(ii=0; ii<pIdxInfo->nConstraint; ii++){
152995
+ if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
152996
+ bMatch = 1;
152997
+ }
152998
+ }
152646152999
152647153000
assert( pIdxInfo->idxStr==0 );
152648153001
for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
152649153002
struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
152650153003
152651
- if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
153004
+ if( bMatch==0 && p->usable
153005
+ && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ
153006
+ ){
152652153007
/* We have an equality constraint on the rowid. Use strategy 1. */
152653153008
int jj;
152654153009
for(jj=0; jj<ii; jj++){
152655153010
pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
152656153011
pIdxInfo->aConstraintUsage[jj].omit = 0;
@@ -154338,10 +154693,22 @@
154338154693
static void rtreeFreeCallback(void *p){
154339154694
RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p;
154340154695
if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext);
154341154696
sqlite3_free(p);
154342154697
}
154698
+
154699
+/*
154700
+** This routine frees the BLOB that is returned by geomCallback().
154701
+*/
154702
+static void rtreeMatchArgFree(void *pArg){
154703
+ int i;
154704
+ RtreeMatchArg *p = (RtreeMatchArg*)pArg;
154705
+ for(i=0; i<p->nParam; i++){
154706
+ sqlite3_value_free(p->apSqlParam[i]);
154707
+ }
154708
+ sqlite3_free(p);
154709
+}
154343154710
154344154711
/*
154345154712
** Each call to sqlite3_rtree_geometry_callback() or
154346154713
** sqlite3_rtree_query_callback() creates an ordinary SQLite
154347154714
** scalar function that is implemented by this routine.
@@ -154357,28 +154724,38 @@
154357154724
*/
154358154725
static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
154359154726
RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
154360154727
RtreeMatchArg *pBlob;
154361154728
int nBlob;
154729
+ int memErr = 0;
154362154730
154363
- nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
154731
+ nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
154732
+ + nArg*sizeof(sqlite3_value*);
154364154733
pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
154365154734
if( !pBlob ){
154366154735
sqlite3_result_error_nomem(ctx);
154367154736
}else{
154368154737
int i;
154369154738
pBlob->magic = RTREE_GEOMETRY_MAGIC;
154370154739
pBlob->cb = pGeomCtx[0];
154740
+ pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
154371154741
pBlob->nParam = nArg;
154372154742
for(i=0; i<nArg; i++){
154743
+ pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
154744
+ if( pBlob->apSqlParam[i]==0 ) memErr = 1;
154373154745
#ifdef SQLITE_RTREE_INT_ONLY
154374154746
pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
154375154747
#else
154376154748
pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
154377154749
#endif
154378154750
}
154379
- sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
154751
+ if( memErr ){
154752
+ sqlite3_result_error_nomem(ctx);
154753
+ rtreeMatchArgFree(pBlob);
154754
+ }else{
154755
+ sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
154756
+ }
154380154757
}
154381154758
}
154382154759
154383154760
/*
154384154761
** Register a new geometry function for use with the r-tree MATCH operator.
@@ -155210,10 +155587,4095 @@
155210155587
155211155588
#endif /* defined(SQLITE_ENABLE_ICU) */
155212155589
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
155213155590
155214155591
/************** End of fts3_icu.c ********************************************/
155592
+/************** Begin file sqlite3ota.c **************************************/
155593
+/*
155594
+** 2014 August 30
155595
+**
155596
+** The author disclaims copyright to this source code. In place of
155597
+** a legal notice, here is a blessing:
155598
+**
155599
+** May you do good and not evil.
155600
+** May you find forgiveness for yourself and forgive others.
155601
+** May you share freely, never taking more than you give.
155602
+**
155603
+*************************************************************************
155604
+**
155605
+**
155606
+** OVERVIEW
155607
+**
155608
+** The OTA extension requires that the OTA update be packaged as an
155609
+** SQLite database. The tables it expects to find are described in
155610
+** sqlite3ota.h. Essentially, for each table xyz in the target database
155611
+** that the user wishes to write to, a corresponding data_xyz table is
155612
+** created in the OTA database and populated with one row for each row to
155613
+** update, insert or delete from the target table.
155614
+**
155615
+** The update proceeds in three stages:
155616
+**
155617
+** 1) The database is updated. The modified database pages are written
155618
+** to a *-oal file. A *-oal file is just like a *-wal file, except
155619
+** that it is named "<database>-oal" instead of "<database>-wal".
155620
+** Because regular SQLite clients do not look for file named
155621
+** "<database>-oal", they go on using the original database in
155622
+** rollback mode while the *-oal file is being generated.
155623
+**
155624
+** During this stage OTA does not update the database by writing
155625
+** directly to the target tables. Instead it creates "imposter"
155626
+** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses
155627
+** to update each b-tree individually. All updates required by each
155628
+** b-tree are completed before moving on to the next, and all
155629
+** updates are done in sorted key order.
155630
+**
155631
+** 2) The "<database>-oal" file is moved to the equivalent "<database>-wal"
155632
+** location using a call to rename(2). Before doing this the OTA
155633
+** module takes an EXCLUSIVE lock on the database file, ensuring
155634
+** that there are no other active readers.
155635
+**
155636
+** Once the EXCLUSIVE lock is released, any other database readers
155637
+** detect the new *-wal file and read the database in wal mode. At
155638
+** this point they see the new version of the database - including
155639
+** the updates made as part of the OTA update.
155640
+**
155641
+** 3) The new *-wal file is checkpointed. This proceeds in the same way
155642
+** as a regular database checkpoint, except that a single frame is
155643
+** checkpointed each time sqlite3ota_step() is called. If the OTA
155644
+** handle is closed before the entire *-wal file is checkpointed,
155645
+** the checkpoint progress is saved in the OTA database and the
155646
+** checkpoint can be resumed by another OTA client at some point in
155647
+** the future.
155648
+**
155649
+** POTENTIAL PROBLEMS
155650
+**
155651
+** The rename() call might not be portable. And OTA is not currently
155652
+** syncing the directory after renaming the file.
155653
+**
155654
+** When state is saved, any commit to the *-oal file and the commit to
155655
+** the OTA update database are not atomic. So if the power fails at the
155656
+** wrong moment they might get out of sync. As the main database will be
155657
+** committed before the OTA update database this will likely either just
155658
+** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE
155659
+** constraint violations).
155660
+**
155661
+** If some client does modify the target database mid OTA update, or some
155662
+** other error occurs, the OTA extension will keep throwing errors. It's
155663
+** not really clear how to get out of this state. The system could just
155664
+** by delete the OTA update database and *-oal file and have the device
155665
+** download the update again and start over.
155666
+**
155667
+** At present, for an UPDATE, both the new.* and old.* records are
155668
+** collected in the ota_xyz table. And for both UPDATEs and DELETEs all
155669
+** fields are collected. This means we're probably writing a lot more
155670
+** data to disk when saving the state of an ongoing update to the OTA
155671
+** update database than is strictly necessary.
155672
+**
155673
+*/
155674
+
155675
+/* #include <assert.h> */
155676
+/* #include <string.h> */
155677
+/* #include <stdio.h> */
155678
+/* #include <unistd.h> */
155679
+
155680
+
155681
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA)
155682
+/************** Include sqlite3ota.h in the middle of sqlite3ota.c ***********/
155683
+/************** Begin file sqlite3ota.h **************************************/
155684
+/*
155685
+** 2014 August 30
155686
+**
155687
+** The author disclaims copyright to this source code. In place of
155688
+** a legal notice, here is a blessing:
155689
+**
155690
+** May you do good and not evil.
155691
+** May you find forgiveness for yourself and forgive others.
155692
+** May you share freely, never taking more than you give.
155693
+**
155694
+*************************************************************************
155695
+**
155696
+** This file contains the public interface for the OTA extension.
155697
+*/
155698
+
155699
+/*
155700
+** SUMMARY
155701
+**
155702
+** Writing a transaction containing a large number of operations on
155703
+** b-tree indexes that are collectively larger than the available cache
155704
+** memory can be very inefficient.
155705
+**
155706
+** The problem is that in order to update a b-tree, the leaf page (at least)
155707
+** containing the entry being inserted or deleted must be modified. If the
155708
+** working set of leaves is larger than the available cache memory, then a
155709
+** single leaf that is modified more than once as part of the transaction
155710
+** may be loaded from or written to the persistent media multiple times.
155711
+** Additionally, because the index updates are likely to be applied in
155712
+** random order, access to pages within the database is also likely to be in
155713
+** random order, which is itself quite inefficient.
155714
+**
155715
+** One way to improve the situation is to sort the operations on each index
155716
+** by index key before applying them to the b-tree. This leads to an IO
155717
+** pattern that resembles a single linear scan through the index b-tree,
155718
+** and all but guarantees each modified leaf page is loaded and stored
155719
+** exactly once. SQLite uses this trick to improve the performance of
155720
+** CREATE INDEX commands. This extension allows it to be used to improve
155721
+** the performance of large transactions on existing databases.
155722
+**
155723
+** Additionally, this extension allows the work involved in writing the
155724
+** large transaction to be broken down into sub-transactions performed
155725
+** sequentially by separate processes. This is useful if the system cannot
155726
+** guarantee that a single update process will run for long enough to apply
155727
+** the entire update, for example because the update is being applied on a
155728
+** mobile device that is frequently rebooted. Even after the writer process
155729
+** has committed one or more sub-transactions, other database clients continue
155730
+** to read from the original database snapshot. In other words, partially
155731
+** applied transactions are not visible to other clients.
155732
+**
155733
+** "OTA" stands for "Over The Air" update. As in a large database update
155734
+** transmitted via a wireless network to a mobile device. A transaction
155735
+** applied using this extension is hence refered to as an "OTA update".
155736
+**
155737
+**
155738
+** LIMITATIONS
155739
+**
155740
+** An "OTA update" transaction is subject to the following limitations:
155741
+**
155742
+** * The transaction must consist of INSERT, UPDATE and DELETE operations
155743
+** only.
155744
+**
155745
+** * INSERT statements may not use any default values.
155746
+**
155747
+** * UPDATE and DELETE statements must identify their target rows by
155748
+** non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY
155749
+** KEY fields may not be updated or deleted. If the table being written
155750
+** has no PRIMARY KEY, affected rows must be identified by rowid.
155751
+**
155752
+** * UPDATE statements may not modify PRIMARY KEY columns.
155753
+**
155754
+** * No triggers will be fired.
155755
+**
155756
+** * No foreign key violations are detected or reported.
155757
+**
155758
+** * CHECK constraints are not enforced.
155759
+**
155760
+** * No constraint handling mode except for "OR ROLLBACK" is supported.
155761
+**
155762
+**
155763
+** PREPARATION
155764
+**
155765
+** An "OTA update" is stored as a separate SQLite database. A database
155766
+** containing an OTA update is an "OTA database". For each table in the
155767
+** target database to be updated, the OTA database should contain a table
155768
+** named "data_<target name>" containing the same set of columns as the
155769
+** target table, and one more - "ota_control". The data_% table should
155770
+** have no PRIMARY KEY or UNIQUE constraints, but each column should have
155771
+** the same type as the corresponding column in the target database.
155772
+** The "ota_control" column should have no type at all. For example, if
155773
+** the target database contains:
155774
+**
155775
+** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE);
155776
+**
155777
+** Then the OTA database should contain:
155778
+**
155779
+** CREATE TABLE data_t1(a INTEGER, b TEXT, c, ota_control);
155780
+**
155781
+** The order of the columns in the data_% table does not matter.
155782
+**
155783
+** If the target database table is a virtual table or a table that has no
155784
+** PRIMARY KEY declaration, the data_% table must also contain a column
155785
+** named "ota_rowid". This column is mapped to the tables implicit primary
155786
+** key column - "rowid". Virtual tables for which the "rowid" column does
155787
+** not function like a primary key value cannot be updated using OTA. For
155788
+** example, if the target db contains either of the following:
155789
+**
155790
+** CREATE VIRTUAL TABLE x1 USING fts3(a, b);
155791
+** CREATE TABLE x1(a, b)
155792
+**
155793
+** then the OTA database should contain:
155794
+**
155795
+** CREATE TABLE data_x1(a, b, ota_rowid, ota_control);
155796
+**
155797
+** All non-hidden columns (i.e. all columns matched by "SELECT *") of the
155798
+** target table must be present in the input table. For virtual tables,
155799
+** hidden columns are optional - they are updated by OTA if present in
155800
+** the input table, or not otherwise. For example, to write to an fts4
155801
+** table with a hidden languageid column such as:
155802
+**
155803
+** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid');
155804
+**
155805
+** Either of the following input table schemas may be used:
155806
+**
155807
+** CREATE TABLE data_ft1(a, b, langid, ota_rowid, ota_control);
155808
+** CREATE TABLE data_ft1(a, b, ota_rowid, ota_control);
155809
+**
155810
+** For each row to INSERT into the target database as part of the OTA
155811
+** update, the corresponding data_% table should contain a single record
155812
+** with the "ota_control" column set to contain integer value 0. The
155813
+** other columns should be set to the values that make up the new record
155814
+** to insert.
155815
+**
155816
+** If the target database table has an INTEGER PRIMARY KEY, it is not
155817
+** possible to insert a NULL value into the IPK column. Attempting to
155818
+** do so results in an SQLITE_MISMATCH error.
155819
+**
155820
+** For each row to DELETE from the target database as part of the OTA
155821
+** update, the corresponding data_% table should contain a single record
155822
+** with the "ota_control" column set to contain integer value 1. The
155823
+** real primary key values of the row to delete should be stored in the
155824
+** corresponding columns of the data_% table. The values stored in the
155825
+** other columns are not used.
155826
+**
155827
+** For each row to UPDATE from the target database as part of the OTA
155828
+** update, the corresponding data_% table should contain a single record
155829
+** with the "ota_control" column set to contain a value of type text.
155830
+** The real primary key values identifying the row to update should be
155831
+** stored in the corresponding columns of the data_% table row, as should
155832
+** the new values of all columns being update. The text value in the
155833
+** "ota_control" column must contain the same number of characters as
155834
+** there are columns in the target database table, and must consist entirely
155835
+** of 'x' and '.' characters (or in some special cases 'd' - see below). For
155836
+** each column that is being updated, the corresponding character is set to
155837
+** 'x'. For those that remain as they are, the corresponding character of the
155838
+** ota_control value should be set to '.'. For example, given the tables
155839
+** above, the update statement:
155840
+**
155841
+** UPDATE t1 SET c = 'usa' WHERE a = 4;
155842
+**
155843
+** is represented by the data_t1 row created by:
155844
+**
155845
+** INSERT INTO data_t1(a, b, c, ota_control) VALUES(4, NULL, 'usa', '..x');
155846
+**
155847
+** Instead of an 'x' character, characters of the ota_control value specified
155848
+** for UPDATEs may also be set to 'd'. In this case, instead of updating the
155849
+** target table with the value stored in the corresponding data_% column, the
155850
+** user-defined SQL function "ota_delta()" is invoked and the result stored in
155851
+** the target table column. ota_delta() is invoked with two arguments - the
155852
+** original value currently stored in the target table column and the
155853
+** value specified in the data_xxx table.
155854
+**
155855
+** For example, this row:
155856
+**
155857
+** INSERT INTO data_t1(a, b, c, ota_control) VALUES(4, NULL, 'usa', '..d');
155858
+**
155859
+** is similar to an UPDATE statement such as:
155860
+**
155861
+** UPDATE t1 SET c = ota_delta(c, 'usa') WHERE a = 4;
155862
+**
155863
+** If the target database table is a virtual table or a table with no PRIMARY
155864
+** KEY, the ota_control value should not include a character corresponding
155865
+** to the ota_rowid value. For example, this:
155866
+**
155867
+** INSERT INTO data_ft1(a, b, ota_rowid, ota_control)
155868
+** VALUES(NULL, 'usa', 12, '.x');
155869
+**
155870
+** causes a result similar to:
155871
+**
155872
+** UPDATE ft1 SET b = 'usa' WHERE rowid = 12;
155873
+**
155874
+** The data_xxx tables themselves should have no PRIMARY KEY declarations.
155875
+** However, OTA is more efficient if reading the rows in from each data_xxx
155876
+** table in "rowid" order is roughly the same as reading them sorted by
155877
+** the PRIMARY KEY of the corresponding target database table. In other
155878
+** words, rows should be sorted using the destination table PRIMARY KEY
155879
+** fields before they are inserted into the data_xxx tables.
155880
+**
155881
+** USAGE
155882
+**
155883
+** The API declared below allows an application to apply an OTA update
155884
+** stored on disk to an existing target database. Essentially, the
155885
+** application:
155886
+**
155887
+** 1) Opens an OTA handle using the sqlite3ota_open() function.
155888
+**
155889
+** 2) Registers any required virtual table modules with the database
155890
+** handle returned by sqlite3ota_db(). Also, if required, register
155891
+** the ota_delta() implementation.
155892
+**
155893
+** 3) Calls the sqlite3ota_step() function one or more times on
155894
+** the new handle. Each call to sqlite3ota_step() performs a single
155895
+** b-tree operation, so thousands of calls may be required to apply
155896
+** a complete update.
155897
+**
155898
+** 4) Calls sqlite3ota_close() to close the OTA update handle. If
155899
+** sqlite3ota_step() has been called enough times to completely
155900
+** apply the update to the target database, then the OTA database
155901
+** is marked as fully applied. Otherwise, the state of the OTA
155902
+** update application is saved in the OTA database for later
155903
+** resumption.
155904
+**
155905
+** See comments below for more detail on APIs.
155906
+**
155907
+** If an update is only partially applied to the target database by the
155908
+** time sqlite3ota_close() is called, various state information is saved
155909
+** within the OTA database. This allows subsequent processes to automatically
155910
+** resume the OTA update from where it left off.
155911
+**
155912
+** To remove all OTA extension state information, returning an OTA database
155913
+** to its original contents, it is sufficient to drop all tables that begin
155914
+** with the prefix "ota_"
155915
+**
155916
+** DATABASE LOCKING
155917
+**
155918
+** An OTA update may not be applied to a database in WAL mode. Attempting
155919
+** to do so is an error (SQLITE_ERROR).
155920
+**
155921
+** While an OTA handle is open, a SHARED lock may be held on the target
155922
+** database file. This means it is possible for other clients to read the
155923
+** database, but not to write it.
155924
+**
155925
+** If an OTA update is started and then suspended before it is completed,
155926
+** then an external client writes to the database, then attempting to resume
155927
+** the suspended OTA update is also an error (SQLITE_BUSY).
155928
+*/
155929
+
155930
+#ifndef _SQLITE3OTA_H
155931
+#define _SQLITE3OTA_H
155932
+
155933
+
155934
+typedef struct sqlite3ota sqlite3ota;
155935
+
155936
+/*
155937
+** Open an OTA handle.
155938
+**
155939
+** Argument zTarget is the path to the target database. Argument zOta is
155940
+** the path to the OTA database. Each call to this function must be matched
155941
+** by a call to sqlite3ota_close(). When opening the databases, OTA passes
155942
+** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget
155943
+** or zOta begin with "file:", it will be interpreted as an SQLite
155944
+** database URI, not a regular file name.
155945
+**
155946
+** If the zState argument is passed a NULL value, the OTA extension stores
155947
+** the current state of the update (how many rows have been updated, which
155948
+** indexes are yet to be updated etc.) within the OTA database itself. This
155949
+** can be convenient, as it means that the OTA application does not need to
155950
+** organize removing a separate state file after the update is concluded.
155951
+** Or, if zState is non-NULL, it must be a path to a database file in which
155952
+** the OTA extension can store the state of the update.
155953
+**
155954
+** When resuming an OTA update, the zState argument must be passed the same
155955
+** value as when the OTA update was started.
155956
+**
155957
+** Once the OTA update is finished, the OTA extension does not
155958
+** automatically remove any zState database file, even if it created it.
155959
+**
155960
+** By default, OTA uses the default VFS to access the files on disk. To
155961
+** use a VFS other than the default, an SQLite "file:" URI containing a
155962
+** "vfs=..." option may be passed as the zTarget option.
155963
+**
155964
+** IMPORTANT NOTE FOR ZIPVFS USERS: The OTA extension works with all of
155965
+** SQLite's built-in VFSs, including the multiplexor VFS. However it does
155966
+** not work out of the box with zipvfs. Refer to the comment describing
155967
+** the zipvfs_create_vfs() API below for details on using OTA with zipvfs.
155968
+*/
155969
+SQLITE_API sqlite3ota *SQLITE_STDCALL sqlite3ota_open(
155970
+ const char *zTarget,
155971
+ const char *zOta,
155972
+ const char *zState
155973
+);
155974
+
155975
+/*
155976
+** Internally, each OTA connection uses a separate SQLite database
155977
+** connection to access the target and ota update databases. This
155978
+** API allows the application direct access to these database handles.
155979
+**
155980
+** The first argument passed to this function must be a valid, open, OTA
155981
+** handle. The second argument should be passed zero to access the target
155982
+** database handle, or non-zero to access the ota update database handle.
155983
+** Accessing the underlying database handles may be useful in the
155984
+** following scenarios:
155985
+**
155986
+** * If any target tables are virtual tables, it may be necessary to
155987
+** call sqlite3_create_module() on the target database handle to
155988
+** register the required virtual table implementations.
155989
+**
155990
+** * If the data_xxx tables in the OTA source database are virtual
155991
+** tables, the application may need to call sqlite3_create_module() on
155992
+** the ota update db handle to any required virtual table
155993
+** implementations.
155994
+**
155995
+** * If the application uses the "ota_delta()" feature described above,
155996
+** it must use sqlite3_create_function() or similar to register the
155997
+** ota_delta() implementation with the target database handle.
155998
+**
155999
+** If an error has occurred, either while opening or stepping the OTA object,
156000
+** this function may return NULL. The error code and message may be collected
156001
+** when sqlite3ota_close() is called.
156002
+*/
156003
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3ota_db(sqlite3ota*, int bOta);
156004
+
156005
+/*
156006
+** Do some work towards applying the OTA update to the target db.
156007
+**
156008
+** Return SQLITE_DONE if the update has been completely applied, or
156009
+** SQLITE_OK if no error occurs but there remains work to do to apply
156010
+** the OTA update. If an error does occur, some other error code is
156011
+** returned.
156012
+**
156013
+** Once a call to sqlite3ota_step() has returned a value other than
156014
+** SQLITE_OK, all subsequent calls on the same OTA handle are no-ops
156015
+** that immediately return the same value.
156016
+*/
156017
+SQLITE_API int SQLITE_STDCALL sqlite3ota_step(sqlite3ota *pOta);
156018
+
156019
+/*
156020
+** Close an OTA handle.
156021
+**
156022
+** If the OTA update has been completely applied, mark the OTA database
156023
+** as fully applied. Otherwise, assuming no error has occurred, save the
156024
+** current state of the OTA update appliation to the OTA database.
156025
+**
156026
+** If an error has already occurred as part of an sqlite3ota_step()
156027
+** or sqlite3ota_open() call, or if one occurs within this function, an
156028
+** SQLite error code is returned. Additionally, *pzErrmsg may be set to
156029
+** point to a buffer containing a utf-8 formatted English language error
156030
+** message. It is the responsibility of the caller to eventually free any
156031
+** such buffer using sqlite3_free().
156032
+**
156033
+** Otherwise, if no error occurs, this function returns SQLITE_OK if the
156034
+** update has been partially applied, or SQLITE_DONE if it has been
156035
+** completely applied.
156036
+*/
156037
+SQLITE_API int SQLITE_STDCALL sqlite3ota_close(sqlite3ota *pOta, char **pzErrmsg);
156038
+
156039
+/*
156040
+** Return the total number of key-value operations (inserts, deletes or
156041
+** updates) that have been performed on the target database since the
156042
+** current OTA update was started.
156043
+*/
156044
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3ota_progress(sqlite3ota *pOta);
156045
+
156046
+/*
156047
+** Create an OTA VFS named zName that accesses the underlying file-system
156048
+** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
156049
+** then the new OTA VFS uses the default system VFS to access the file-system.
156050
+** The new object is registered as a non-default VFS with SQLite before
156051
+** returning.
156052
+**
156053
+** Part of the OTA implementation uses a custom VFS object. Usually, this
156054
+** object is created and deleted automatically by OTA.
156055
+**
156056
+** The exception is for applications that also use zipvfs. In this case,
156057
+** the custom VFS must be explicitly created by the user before the OTA
156058
+** handle is opened. The OTA VFS should be installed so that the zipvfs
156059
+** VFS uses the OTA VFS, which in turn uses any other VFS layers in use
156060
+** (for example multiplexor) to access the file-system. For example,
156061
+** to assemble an OTA enabled VFS stack that uses both zipvfs and
156062
+** multiplexor (error checking omitted):
156063
+**
156064
+** // Create a VFS named "multiplex" (not the default).
156065
+** sqlite3_multiplex_initialize(0, 0);
156066
+**
156067
+** // Create an ota VFS named "ota" that uses multiplexor. If the
156068
+** // second argument were replaced with NULL, the "ota" VFS would
156069
+** // access the file-system via the system default VFS, bypassing the
156070
+** // multiplexor.
156071
+** sqlite3ota_create_vfs("ota", "multiplex");
156072
+**
156073
+** // Create a zipvfs VFS named "zipvfs" that uses ota.
156074
+** zipvfs_create_vfs_v3("zipvfs", "ota", 0, xCompressorAlgorithmDetector);
156075
+**
156076
+** // Make zipvfs the default VFS.
156077
+** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1);
156078
+**
156079
+** Because the default VFS created above includes a OTA functionality, it
156080
+** may be used by OTA clients. Attempting to use OTA with a zipvfs VFS stack
156081
+** that does not include the OTA layer results in an error.
156082
+**
156083
+** The overhead of adding the "ota" VFS to the system is negligible for
156084
+** non-OTA users. There is no harm in an application accessing the
156085
+** file-system via "ota" all the time, even if it only uses OTA functionality
156086
+** occasionally.
156087
+*/
156088
+SQLITE_API int SQLITE_STDCALL sqlite3ota_create_vfs(const char *zName, const char *zParent);
156089
+
156090
+/*
156091
+** Deregister and destroy an OTA vfs created by an earlier call to
156092
+** sqlite3ota_create_vfs().
156093
+**
156094
+** VFS objects are not reference counted. If a VFS object is destroyed
156095
+** before all database handles that use it have been closed, the results
156096
+** are undefined.
156097
+*/
156098
+SQLITE_API void SQLITE_STDCALL sqlite3ota_destroy_vfs(const char *zName);
156099
+
156100
+#endif /* _SQLITE3OTA_H */
156101
+
156102
+
156103
+/************** End of sqlite3ota.h ******************************************/
156104
+/************** Continuing where we left off in sqlite3ota.c *****************/
156105
+
156106
+/* Maximum number of prepared UPDATE statements held by this module */
156107
+#define SQLITE_OTA_UPDATE_CACHESIZE 16
156108
+
156109
+/*
156110
+** Swap two objects of type TYPE.
156111
+*/
156112
+#if !defined(SQLITE_AMALGAMATION)
156113
+# define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
156114
+#endif
156115
+
156116
+/*
156117
+** The ota_state table is used to save the state of a partially applied
156118
+** update so that it can be resumed later. The table consists of integer
156119
+** keys mapped to values as follows:
156120
+**
156121
+** OTA_STATE_STAGE:
156122
+** May be set to integer values 1, 2, 4 or 5. As follows:
156123
+** 1: the *-ota file is currently under construction.
156124
+** 2: the *-ota file has been constructed, but not yet moved
156125
+** to the *-wal path.
156126
+** 4: the checkpoint is underway.
156127
+** 5: the ota update has been checkpointed.
156128
+**
156129
+** OTA_STATE_TBL:
156130
+** Only valid if STAGE==1. The target database name of the table
156131
+** currently being written.
156132
+**
156133
+** OTA_STATE_IDX:
156134
+** Only valid if STAGE==1. The target database name of the index
156135
+** currently being written, or NULL if the main table is currently being
156136
+** updated.
156137
+**
156138
+** OTA_STATE_ROW:
156139
+** Only valid if STAGE==1. Number of rows already processed for the current
156140
+** table/index.
156141
+**
156142
+** OTA_STATE_PROGRESS:
156143
+** Total number of sqlite3ota_step() calls made so far as part of this
156144
+** ota update.
156145
+**
156146
+** OTA_STATE_CKPT:
156147
+** Valid if STAGE==4. The 64-bit checksum associated with the wal-index
156148
+** header created by recovering the *-wal file. This is used to detect
156149
+** cases when another client appends frames to the *-wal file in the
156150
+** middle of an incremental checkpoint (an incremental checkpoint cannot
156151
+** be continued if this happens).
156152
+**
156153
+** OTA_STATE_COOKIE:
156154
+** Valid if STAGE==1. The current change-counter cookie value in the
156155
+** target db file.
156156
+**
156157
+** OTA_STATE_OALSZ:
156158
+** Valid if STAGE==1. The size in bytes of the *-oal file.
156159
+*/
156160
+#define OTA_STATE_STAGE 1
156161
+#define OTA_STATE_TBL 2
156162
+#define OTA_STATE_IDX 3
156163
+#define OTA_STATE_ROW 4
156164
+#define OTA_STATE_PROGRESS 5
156165
+#define OTA_STATE_CKPT 6
156166
+#define OTA_STATE_COOKIE 7
156167
+#define OTA_STATE_OALSZ 8
156168
+
156169
+#define OTA_STAGE_OAL 1
156170
+#define OTA_STAGE_MOVE 2
156171
+#define OTA_STAGE_CAPTURE 3
156172
+#define OTA_STAGE_CKPT 4
156173
+#define OTA_STAGE_DONE 5
156174
+
156175
+
156176
+#define OTA_CREATE_STATE \
156177
+ "CREATE TABLE IF NOT EXISTS %s.ota_state(k INTEGER PRIMARY KEY, v)"
156178
+
156179
+typedef struct OtaFrame OtaFrame;
156180
+typedef struct OtaObjIter OtaObjIter;
156181
+typedef struct OtaState OtaState;
156182
+typedef struct ota_vfs ota_vfs;
156183
+typedef struct ota_file ota_file;
156184
+typedef struct OtaUpdateStmt OtaUpdateStmt;
156185
+
156186
+#if !defined(SQLITE_AMALGAMATION)
156187
+typedef unsigned int u32;
156188
+typedef unsigned char u8;
156189
+typedef sqlite3_int64 i64;
156190
+#endif
156191
+
156192
+/*
156193
+** These values must match the values defined in wal.c for the equivalent
156194
+** locks. These are not magic numbers as they are part of the SQLite file
156195
+** format.
156196
+*/
156197
+#define WAL_LOCK_WRITE 0
156198
+#define WAL_LOCK_CKPT 1
156199
+#define WAL_LOCK_READ0 3
156200
+
156201
+/*
156202
+** A structure to store values read from the ota_state table in memory.
156203
+*/
156204
+struct OtaState {
156205
+ int eStage;
156206
+ char *zTbl;
156207
+ char *zIdx;
156208
+ i64 iWalCksum;
156209
+ int nRow;
156210
+ i64 nProgress;
156211
+ u32 iCookie;
156212
+ i64 iOalSz;
156213
+};
156214
+
156215
+struct OtaUpdateStmt {
156216
+ char *zMask; /* Copy of update mask used with pUpdate */
156217
+ sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */
156218
+ OtaUpdateStmt *pNext;
156219
+};
156220
+
156221
+/*
156222
+** An iterator of this type is used to iterate through all objects in
156223
+** the target database that require updating. For each such table, the
156224
+** iterator visits, in order:
156225
+**
156226
+** * the table itself,
156227
+** * each index of the table (zero or more points to visit), and
156228
+** * a special "cleanup table" state.
156229
+**
156230
+** abIndexed:
156231
+** If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
156232
+** it points to an array of flags nTblCol elements in size. The flag is
156233
+** set for each column that is either a part of the PK or a part of an
156234
+** index. Or clear otherwise.
156235
+**
156236
+*/
156237
+struct OtaObjIter {
156238
+ sqlite3_stmt *pTblIter; /* Iterate through tables */
156239
+ sqlite3_stmt *pIdxIter; /* Index iterator */
156240
+ int nTblCol; /* Size of azTblCol[] array */
156241
+ char **azTblCol; /* Array of unquoted target column names */
156242
+ char **azTblType; /* Array of target column types */
156243
+ int *aiSrcOrder; /* src table col -> target table col */
156244
+ u8 *abTblPk; /* Array of flags, set on target PK columns */
156245
+ u8 *abNotNull; /* Array of flags, set on NOT NULL columns */
156246
+ u8 *abIndexed; /* Array of flags, set on indexed & PK cols */
156247
+ int eType; /* Table type - an OTA_PK_XXX value */
156248
+
156249
+ /* Output variables. zTbl==0 implies EOF. */
156250
+ int bCleanup; /* True in "cleanup" state */
156251
+ const char *zTbl; /* Name of target db table */
156252
+ const char *zIdx; /* Name of target db index (or null) */
156253
+ int iTnum; /* Root page of current object */
156254
+ int iPkTnum; /* If eType==EXTERNAL, root of PK index */
156255
+ int bUnique; /* Current index is unique */
156256
+
156257
+ /* Statements created by otaObjIterPrepareAll() */
156258
+ int nCol; /* Number of columns in current object */
156259
+ sqlite3_stmt *pSelect; /* Source data */
156260
+ sqlite3_stmt *pInsert; /* Statement for INSERT operations */
156261
+ sqlite3_stmt *pDelete; /* Statement for DELETE ops */
156262
+ sqlite3_stmt *pTmpInsert; /* Insert into ota_tmp_$zTbl */
156263
+
156264
+ /* Last UPDATE used (for PK b-tree updates only), or NULL. */
156265
+ OtaUpdateStmt *pOtaUpdate;
156266
+};
156267
+
156268
+/*
156269
+** Values for OtaObjIter.eType
156270
+**
156271
+** 0: Table does not exist (error)
156272
+** 1: Table has an implicit rowid.
156273
+** 2: Table has an explicit IPK column.
156274
+** 3: Table has an external PK index.
156275
+** 4: Table is WITHOUT ROWID.
156276
+** 5: Table is a virtual table.
156277
+*/
156278
+#define OTA_PK_NOTABLE 0
156279
+#define OTA_PK_NONE 1
156280
+#define OTA_PK_IPK 2
156281
+#define OTA_PK_EXTERNAL 3
156282
+#define OTA_PK_WITHOUT_ROWID 4
156283
+#define OTA_PK_VTAB 5
156284
+
156285
+
156286
+/*
156287
+** Within the OTA_STAGE_OAL stage, each call to sqlite3ota_step() performs
156288
+** one of the following operations.
156289
+*/
156290
+#define OTA_INSERT 1 /* Insert on a main table b-tree */
156291
+#define OTA_DELETE 2 /* Delete a row from a main table b-tree */
156292
+#define OTA_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */
156293
+#define OTA_IDX_INSERT 4 /* Insert on an aux. index b-tree */
156294
+#define OTA_UPDATE 5 /* Update a row in a main table b-tree */
156295
+
156296
+
156297
+/*
156298
+** A single step of an incremental checkpoint - frame iWalFrame of the wal
156299
+** file should be copied to page iDbPage of the database file.
156300
+*/
156301
+struct OtaFrame {
156302
+ u32 iDbPage;
156303
+ u32 iWalFrame;
156304
+};
156305
+
156306
+/*
156307
+** OTA handle.
156308
+*/
156309
+struct sqlite3ota {
156310
+ int eStage; /* Value of OTA_STATE_STAGE field */
156311
+ sqlite3 *dbMain; /* target database handle */
156312
+ sqlite3 *dbOta; /* ota database handle */
156313
+ char *zTarget; /* Path to target db */
156314
+ char *zOta; /* Path to ota db */
156315
+ char *zState; /* Path to state db (or NULL if zOta) */
156316
+ char zStateDb[5]; /* Db name for state ("stat" or "main") */
156317
+ int rc; /* Value returned by last ota_step() call */
156318
+ char *zErrmsg; /* Error message if rc!=SQLITE_OK */
156319
+ int nStep; /* Rows processed for current object */
156320
+ int nProgress; /* Rows processed for all objects */
156321
+ OtaObjIter objiter; /* Iterator for skipping through tbl/idx */
156322
+ const char *zVfsName; /* Name of automatically created ota vfs */
156323
+ ota_file *pTargetFd; /* File handle open on target db */
156324
+ i64 iOalSz;
156325
+
156326
+ /* The following state variables are used as part of the incremental
156327
+ ** checkpoint stage (eStage==OTA_STAGE_CKPT). See comments surrounding
156328
+ ** function otaSetupCheckpoint() for details. */
156329
+ u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */
156330
+ u32 mLock;
156331
+ int nFrame; /* Entries in aFrame[] array */
156332
+ int nFrameAlloc; /* Allocated size of aFrame[] array */
156333
+ OtaFrame *aFrame;
156334
+ int pgsz;
156335
+ u8 *aBuf;
156336
+ i64 iWalCksum;
156337
+};
156338
+
156339
+/*
156340
+** An ota VFS is implemented using an instance of this structure.
156341
+*/
156342
+struct ota_vfs {
156343
+ sqlite3_vfs base; /* ota VFS shim methods */
156344
+ sqlite3_vfs *pRealVfs; /* Underlying VFS */
156345
+ sqlite3_mutex *mutex; /* Mutex to protect pMain */
156346
+ ota_file *pMain; /* Linked list of main db files */
156347
+};
156348
+
156349
+/*
156350
+** Each file opened by an ota VFS is represented by an instance of
156351
+** the following structure.
156352
+*/
156353
+struct ota_file {
156354
+ sqlite3_file base; /* sqlite3_file methods */
156355
+ sqlite3_file *pReal; /* Underlying file handle */
156356
+ ota_vfs *pOtaVfs; /* Pointer to the ota_vfs object */
156357
+ sqlite3ota *pOta; /* Pointer to ota object (ota target only) */
156358
+
156359
+ int openFlags; /* Flags this file was opened with */
156360
+ u32 iCookie; /* Cookie value for main db files */
156361
+ u8 iWriteVer; /* "write-version" value for main db files */
156362
+
156363
+ int nShm; /* Number of entries in apShm[] array */
156364
+ char **apShm; /* Array of mmap'd *-shm regions */
156365
+ char *zDel; /* Delete this when closing file */
156366
+
156367
+ const char *zWal; /* Wal filename for this main db file */
156368
+ ota_file *pWalFd; /* Wal file descriptor for this main db */
156369
+ ota_file *pMainNext; /* Next MAIN_DB file */
156370
+};
156371
+
156372
+
156373
+/*
156374
+** Prepare the SQL statement in buffer zSql against database handle db.
156375
+** If successful, set *ppStmt to point to the new statement and return
156376
+** SQLITE_OK.
156377
+**
156378
+** Otherwise, if an error does occur, set *ppStmt to NULL and return
156379
+** an SQLite error code. Additionally, set output variable *pzErrmsg to
156380
+** point to a buffer containing an error message. It is the responsibility
156381
+** of the caller to (eventually) free this buffer using sqlite3_free().
156382
+*/
156383
+static int prepareAndCollectError(
156384
+ sqlite3 *db,
156385
+ sqlite3_stmt **ppStmt,
156386
+ char **pzErrmsg,
156387
+ const char *zSql
156388
+){
156389
+ int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
156390
+ if( rc!=SQLITE_OK ){
156391
+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
156392
+ *ppStmt = 0;
156393
+ }
156394
+ return rc;
156395
+}
156396
+
156397
+/*
156398
+** Reset the SQL statement passed as the first argument. Return a copy
156399
+** of the value returned by sqlite3_reset().
156400
+**
156401
+** If an error has occurred, then set *pzErrmsg to point to a buffer
156402
+** containing an error message. It is the responsibility of the caller
156403
+** to eventually free this buffer using sqlite3_free().
156404
+*/
156405
+static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){
156406
+ int rc = sqlite3_reset(pStmt);
156407
+ if( rc!=SQLITE_OK ){
156408
+ *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
156409
+ }
156410
+ return rc;
156411
+}
156412
+
156413
+/*
156414
+** Unless it is NULL, argument zSql points to a buffer allocated using
156415
+** sqlite3_malloc containing an SQL statement. This function prepares the SQL
156416
+** statement against database db and frees the buffer. If statement
156417
+** compilation is successful, *ppStmt is set to point to the new statement
156418
+** handle and SQLITE_OK is returned.
156419
+**
156420
+** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code
156421
+** returned. In this case, *pzErrmsg may also be set to point to an error
156422
+** message. It is the responsibility of the caller to free this error message
156423
+** buffer using sqlite3_free().
156424
+**
156425
+** If argument zSql is NULL, this function assumes that an OOM has occurred.
156426
+** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL.
156427
+*/
156428
+static int prepareFreeAndCollectError(
156429
+ sqlite3 *db,
156430
+ sqlite3_stmt **ppStmt,
156431
+ char **pzErrmsg,
156432
+ char *zSql
156433
+){
156434
+ int rc;
156435
+ assert( *pzErrmsg==0 );
156436
+ if( zSql==0 ){
156437
+ rc = SQLITE_NOMEM;
156438
+ *ppStmt = 0;
156439
+ }else{
156440
+ rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql);
156441
+ sqlite3_free(zSql);
156442
+ }
156443
+ return rc;
156444
+}
156445
+
156446
+/*
156447
+** Free the OtaObjIter.azTblCol[] and OtaObjIter.abTblPk[] arrays allocated
156448
+** by an earlier call to otaObjIterCacheTableInfo().
156449
+*/
156450
+static void otaObjIterFreeCols(OtaObjIter *pIter){
156451
+ int i;
156452
+ for(i=0; i<pIter->nTblCol; i++){
156453
+ sqlite3_free(pIter->azTblCol[i]);
156454
+ sqlite3_free(pIter->azTblType[i]);
156455
+ }
156456
+ sqlite3_free(pIter->azTblCol);
156457
+ pIter->azTblCol = 0;
156458
+ pIter->azTblType = 0;
156459
+ pIter->aiSrcOrder = 0;
156460
+ pIter->abTblPk = 0;
156461
+ pIter->abNotNull = 0;
156462
+ pIter->nTblCol = 0;
156463
+ pIter->eType = 0; /* Invalid value */
156464
+}
156465
+
156466
+/*
156467
+** Finalize all statements and free all allocations that are specific to
156468
+** the current object (table/index pair).
156469
+*/
156470
+static void otaObjIterClearStatements(OtaObjIter *pIter){
156471
+ OtaUpdateStmt *pUp;
156472
+
156473
+ sqlite3_finalize(pIter->pSelect);
156474
+ sqlite3_finalize(pIter->pInsert);
156475
+ sqlite3_finalize(pIter->pDelete);
156476
+ sqlite3_finalize(pIter->pTmpInsert);
156477
+ pUp = pIter->pOtaUpdate;
156478
+ while( pUp ){
156479
+ OtaUpdateStmt *pTmp = pUp->pNext;
156480
+ sqlite3_finalize(pUp->pUpdate);
156481
+ sqlite3_free(pUp);
156482
+ pUp = pTmp;
156483
+ }
156484
+
156485
+ pIter->pSelect = 0;
156486
+ pIter->pInsert = 0;
156487
+ pIter->pDelete = 0;
156488
+ pIter->pOtaUpdate = 0;
156489
+ pIter->pTmpInsert = 0;
156490
+ pIter->nCol = 0;
156491
+}
156492
+
156493
+/*
156494
+** Clean up any resources allocated as part of the iterator object passed
156495
+** as the only argument.
156496
+*/
156497
+static void otaObjIterFinalize(OtaObjIter *pIter){
156498
+ otaObjIterClearStatements(pIter);
156499
+ sqlite3_finalize(pIter->pTblIter);
156500
+ sqlite3_finalize(pIter->pIdxIter);
156501
+ otaObjIterFreeCols(pIter);
156502
+ memset(pIter, 0, sizeof(OtaObjIter));
156503
+}
156504
+
156505
+/*
156506
+** Advance the iterator to the next position.
156507
+**
156508
+** If no error occurs, SQLITE_OK is returned and the iterator is left
156509
+** pointing to the next entry. Otherwise, an error code and message is
156510
+** left in the OTA handle passed as the first argument. A copy of the
156511
+** error code is returned.
156512
+*/
156513
+static int otaObjIterNext(sqlite3ota *p, OtaObjIter *pIter){
156514
+ int rc = p->rc;
156515
+ if( rc==SQLITE_OK ){
156516
+
156517
+ /* Free any SQLite statements used while processing the previous object */
156518
+ otaObjIterClearStatements(pIter);
156519
+ if( pIter->zIdx==0 ){
156520
+ rc = sqlite3_exec(p->dbMain,
156521
+ "DROP TRIGGER IF EXISTS temp.ota_insert_tr;"
156522
+ "DROP TRIGGER IF EXISTS temp.ota_update1_tr;"
156523
+ "DROP TRIGGER IF EXISTS temp.ota_update2_tr;"
156524
+ "DROP TRIGGER IF EXISTS temp.ota_delete_tr;"
156525
+ , 0, 0, &p->zErrmsg
156526
+ );
156527
+ }
156528
+
156529
+ if( rc==SQLITE_OK ){
156530
+ if( pIter->bCleanup ){
156531
+ otaObjIterFreeCols(pIter);
156532
+ pIter->bCleanup = 0;
156533
+ rc = sqlite3_step(pIter->pTblIter);
156534
+ if( rc!=SQLITE_ROW ){
156535
+ rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
156536
+ pIter->zTbl = 0;
156537
+ }else{
156538
+ pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
156539
+ rc = pIter->zTbl ? SQLITE_OK : SQLITE_NOMEM;
156540
+ }
156541
+ }else{
156542
+ if( pIter->zIdx==0 ){
156543
+ sqlite3_stmt *pIdx = pIter->pIdxIter;
156544
+ rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
156545
+ }
156546
+ if( rc==SQLITE_OK ){
156547
+ rc = sqlite3_step(pIter->pIdxIter);
156548
+ if( rc!=SQLITE_ROW ){
156549
+ rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg);
156550
+ pIter->bCleanup = 1;
156551
+ pIter->zIdx = 0;
156552
+ }else{
156553
+ pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
156554
+ pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
156555
+ pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
156556
+ rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM;
156557
+ }
156558
+ }
156559
+ }
156560
+ }
156561
+ }
156562
+
156563
+ if( rc!=SQLITE_OK ){
156564
+ otaObjIterFinalize(pIter);
156565
+ p->rc = rc;
156566
+ }
156567
+ return rc;
156568
+}
156569
+
156570
+/*
156571
+** Initialize the iterator structure passed as the second argument.
156572
+**
156573
+** If no error occurs, SQLITE_OK is returned and the iterator is left
156574
+** pointing to the first entry. Otherwise, an error code and message is
156575
+** left in the OTA handle passed as the first argument. A copy of the
156576
+** error code is returned.
156577
+*/
156578
+static int otaObjIterFirst(sqlite3ota *p, OtaObjIter *pIter){
156579
+ int rc;
156580
+ memset(pIter, 0, sizeof(OtaObjIter));
156581
+
156582
+ rc = prepareAndCollectError(p->dbOta, &pIter->pTblIter, &p->zErrmsg,
156583
+ "SELECT substr(name, 6) FROM sqlite_master "
156584
+ "WHERE type='table' AND name LIKE 'data_%'"
156585
+ );
156586
+
156587
+ if( rc==SQLITE_OK ){
156588
+ rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
156589
+ "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
156590
+ " FROM main.sqlite_master "
156591
+ " WHERE type='index' AND tbl_name = ?"
156592
+ );
156593
+ }
156594
+
156595
+ pIter->bCleanup = 1;
156596
+ p->rc = rc;
156597
+ return otaObjIterNext(p, pIter);
156598
+}
156599
+
156600
+/*
156601
+** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs,
156602
+** an error code is stored in the OTA handle passed as the first argument.
156603
+**
156604
+** If an error has already occurred (p->rc is already set to something other
156605
+** than SQLITE_OK), then this function returns NULL without modifying the
156606
+** stored error code. In this case it still calls sqlite3_free() on any
156607
+** printf() parameters associated with %z conversions.
156608
+*/
156609
+static char *otaMPrintf(sqlite3ota *p, const char *zFmt, ...){
156610
+ char *zSql = 0;
156611
+ va_list ap;
156612
+ va_start(ap, zFmt);
156613
+ zSql = sqlite3_vmprintf(zFmt, ap);
156614
+ if( p->rc==SQLITE_OK ){
156615
+ if( zSql==0 ) p->rc = SQLITE_NOMEM;
156616
+ }else{
156617
+ sqlite3_free(zSql);
156618
+ zSql = 0;
156619
+ }
156620
+ va_end(ap);
156621
+ return zSql;
156622
+}
156623
+
156624
+/*
156625
+** Argument zFmt is a sqlite3_mprintf() style format string. The trailing
156626
+** arguments are the usual subsitution values. This function performs
156627
+** the printf() style substitutions and executes the result as an SQL
156628
+** statement on the OTA handles database.
156629
+**
156630
+** If an error occurs, an error code and error message is stored in the
156631
+** OTA handle. If an error has already occurred when this function is
156632
+** called, it is a no-op.
156633
+*/
156634
+static int otaMPrintfExec(sqlite3ota *p, sqlite3 *db, const char *zFmt, ...){
156635
+ va_list ap;
156636
+ va_start(ap, zFmt);
156637
+ char *zSql = sqlite3_vmprintf(zFmt, ap);
156638
+ if( p->rc==SQLITE_OK ){
156639
+ if( zSql==0 ){
156640
+ p->rc = SQLITE_NOMEM;
156641
+ }else{
156642
+ p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg);
156643
+ }
156644
+ }
156645
+ sqlite3_free(zSql);
156646
+ va_end(ap);
156647
+ return p->rc;
156648
+}
156649
+
156650
+/*
156651
+** Attempt to allocate and return a pointer to a zeroed block of nByte
156652
+** bytes.
156653
+**
156654
+** If an error (i.e. an OOM condition) occurs, return NULL and leave an
156655
+** error code in the ota handle passed as the first argument. Or, if an
156656
+** error has already occurred when this function is called, return NULL
156657
+** immediately without attempting the allocation or modifying the stored
156658
+** error code.
156659
+*/
156660
+static void *otaMalloc(sqlite3ota *p, int nByte){
156661
+ void *pRet = 0;
156662
+ if( p->rc==SQLITE_OK ){
156663
+ assert( nByte>0 );
156664
+ pRet = sqlite3_malloc(nByte);
156665
+ if( pRet==0 ){
156666
+ p->rc = SQLITE_NOMEM;
156667
+ }else{
156668
+ memset(pRet, 0, nByte);
156669
+ }
156670
+ }
156671
+ return pRet;
156672
+}
156673
+
156674
+
156675
+/*
156676
+** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that
156677
+** there is room for at least nCol elements. If an OOM occurs, store an
156678
+** error code in the OTA handle passed as the first argument.
156679
+*/
156680
+static void otaAllocateIterArrays(sqlite3ota *p, OtaObjIter *pIter, int nCol){
156681
+ int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
156682
+ char **azNew;
156683
+
156684
+ azNew = (char**)otaMalloc(p, nByte);
156685
+ if( azNew ){
156686
+ pIter->azTblCol = azNew;
156687
+ pIter->azTblType = &azNew[nCol];
156688
+ pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol];
156689
+ pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol];
156690
+ pIter->abNotNull = (u8*)&pIter->abTblPk[nCol];
156691
+ pIter->abIndexed = (u8*)&pIter->abNotNull[nCol];
156692
+ }
156693
+}
156694
+
156695
+/*
156696
+** The first argument must be a nul-terminated string. This function
156697
+** returns a copy of the string in memory obtained from sqlite3_malloc().
156698
+** It is the responsibility of the caller to eventually free this memory
156699
+** using sqlite3_free().
156700
+**
156701
+** If an OOM condition is encountered when attempting to allocate memory,
156702
+** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
156703
+** if the allocation succeeds, (*pRc) is left unchanged.
156704
+*/
156705
+static char *otaStrndup(const char *zStr, int *pRc){
156706
+ char *zRet = 0;
156707
+
156708
+ assert( *pRc==SQLITE_OK );
156709
+ if( zStr ){
156710
+ int nCopy = strlen(zStr) + 1;
156711
+ zRet = (char*)sqlite3_malloc(nCopy);
156712
+ if( zRet ){
156713
+ memcpy(zRet, zStr, nCopy);
156714
+ }else{
156715
+ *pRc = SQLITE_NOMEM;
156716
+ }
156717
+ }
156718
+
156719
+ return zRet;
156720
+}
156721
+
156722
+/*
156723
+** Finalize the statement passed as the second argument.
156724
+**
156725
+** If the sqlite3_finalize() call indicates that an error occurs, and the
156726
+** ota handle error code is not already set, set the error code and error
156727
+** message accordingly.
156728
+*/
156729
+static void otaFinalize(sqlite3ota *p, sqlite3_stmt *pStmt){
156730
+ sqlite3 *db = sqlite3_db_handle(pStmt);
156731
+ int rc = sqlite3_finalize(pStmt);
156732
+ if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
156733
+ p->rc = rc;
156734
+ p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
156735
+ }
156736
+}
156737
+
156738
+/* Determine the type of a table.
156739
+**
156740
+** peType is of type (int*), a pointer to an output parameter of type
156741
+** (int). This call sets the output parameter as follows, depending
156742
+** on the type of the table specified by parameters dbName and zTbl.
156743
+**
156744
+** OTA_PK_NOTABLE: No such table.
156745
+** OTA_PK_NONE: Table has an implicit rowid.
156746
+** OTA_PK_IPK: Table has an explicit IPK column.
156747
+** OTA_PK_EXTERNAL: Table has an external PK index.
156748
+** OTA_PK_WITHOUT_ROWID: Table is WITHOUT ROWID.
156749
+** OTA_PK_VTAB: Table is a virtual table.
156750
+**
156751
+** Argument *piPk is also of type (int*), and also points to an output
156752
+** parameter. Unless the table has an external primary key index
156753
+** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
156754
+** if the table does have an external primary key index, then *piPk
156755
+** is set to the root page number of the primary key index before
156756
+** returning.
156757
+**
156758
+** ALGORITHM:
156759
+**
156760
+** if( no entry exists in sqlite_master ){
156761
+** return OTA_PK_NOTABLE
156762
+** }else if( sql for the entry starts with "CREATE VIRTUAL" ){
156763
+** return OTA_PK_VTAB
156764
+** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
156765
+** if( the index that is the pk exists in sqlite_master ){
156766
+** *piPK = rootpage of that index.
156767
+** return OTA_PK_EXTERNAL
156768
+** }else{
156769
+** return OTA_PK_WITHOUT_ROWID
156770
+** }
156771
+** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
156772
+** return OTA_PK_IPK
156773
+** }else{
156774
+** return OTA_PK_NONE
156775
+** }
156776
+*/
156777
+static void otaTableType(
156778
+ sqlite3ota *p,
156779
+ const char *zTab,
156780
+ int *peType,
156781
+ int *piTnum,
156782
+ int *piPk
156783
+){
156784
+ /*
156785
+ ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q)
156786
+ ** 1) PRAGMA index_list = ?
156787
+ ** 2) SELECT count(*) FROM sqlite_master where name=%Q
156788
+ ** 3) PRAGMA table_info = ?
156789
+ */
156790
+ sqlite3_stmt *aStmt[4] = {0, 0, 0, 0};
156791
+
156792
+ *peType = OTA_PK_NOTABLE;
156793
+ *piPk = 0;
156794
+
156795
+ assert( p->rc==SQLITE_OK );
156796
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg,
156797
+ sqlite3_mprintf(
156798
+ "SELECT (sql LIKE 'create virtual%%'), rootpage"
156799
+ " FROM sqlite_master"
156800
+ " WHERE name=%Q", zTab
156801
+ ));
156802
+ if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){
156803
+ /* Either an error, or no such table. */
156804
+ goto otaTableType_end;
156805
+ }
156806
+ if( sqlite3_column_int(aStmt[0], 0) ){
156807
+ *peType = OTA_PK_VTAB; /* virtual table */
156808
+ goto otaTableType_end;
156809
+ }
156810
+ *piTnum = sqlite3_column_int(aStmt[0], 1);
156811
+
156812
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg,
156813
+ sqlite3_mprintf("PRAGMA index_list=%Q",zTab)
156814
+ );
156815
+ if( p->rc ) goto otaTableType_end;
156816
+ while( sqlite3_step(aStmt[1])==SQLITE_ROW ){
156817
+ const u8 *zOrig = sqlite3_column_text(aStmt[1], 3);
156818
+ const u8 *zIdx = sqlite3_column_text(aStmt[1], 1);
156819
+ if( zOrig && zIdx && zOrig[0]=='p' ){
156820
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg,
156821
+ sqlite3_mprintf(
156822
+ "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx
156823
+ ));
156824
+ if( p->rc==SQLITE_OK ){
156825
+ if( sqlite3_step(aStmt[2])==SQLITE_ROW ){
156826
+ *piPk = sqlite3_column_int(aStmt[2], 0);
156827
+ *peType = OTA_PK_EXTERNAL;
156828
+ }else{
156829
+ *peType = OTA_PK_WITHOUT_ROWID;
156830
+ }
156831
+ }
156832
+ goto otaTableType_end;
156833
+ }
156834
+ }
156835
+
156836
+ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg,
156837
+ sqlite3_mprintf("PRAGMA table_info=%Q",zTab)
156838
+ );
156839
+ if( p->rc==SQLITE_OK ){
156840
+ while( sqlite3_step(aStmt[3])==SQLITE_ROW ){
156841
+ if( sqlite3_column_int(aStmt[3],5)>0 ){
156842
+ *peType = OTA_PK_IPK; /* explicit IPK column */
156843
+ goto otaTableType_end;
156844
+ }
156845
+ }
156846
+ *peType = OTA_PK_NONE;
156847
+ }
156848
+
156849
+otaTableType_end: {
156850
+ int i;
156851
+ for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){
156852
+ otaFinalize(p, aStmt[i]);
156853
+ }
156854
+ }
156855
+}
156856
+
156857
+/*
156858
+** This is a helper function for otaObjIterCacheTableInfo(). It populates
156859
+** the pIter->abIndexed[] array.
156860
+*/
156861
+static void otaObjIterCacheIndexedCols(sqlite3ota *p, OtaObjIter *pIter){
156862
+ sqlite3_stmt *pList = 0;
156863
+ int bIndex = 0;
156864
+
156865
+ if( p->rc==SQLITE_OK ){
156866
+ memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol);
156867
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg,
156868
+ sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
156869
+ );
156870
+ }
156871
+
156872
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
156873
+ const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
156874
+ sqlite3_stmt *pXInfo = 0;
156875
+ if( zIdx==0 ) break;
156876
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
156877
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
156878
+ );
156879
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
156880
+ int iCid = sqlite3_column_int(pXInfo, 1);
156881
+ if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
156882
+ }
156883
+ otaFinalize(p, pXInfo);
156884
+ bIndex = 1;
156885
+ }
156886
+
156887
+ otaFinalize(p, pList);
156888
+ if( bIndex==0 ) pIter->abIndexed = 0;
156889
+}
156890
+
156891
+
156892
+/*
156893
+** If they are not already populated, populate the pIter->azTblCol[],
156894
+** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
156895
+** the table (not index) that the iterator currently points to.
156896
+**
156897
+** Return SQLITE_OK if successful, or an SQLite error code otherwise. If
156898
+** an error does occur, an error code and error message are also left in
156899
+** the OTA handle.
156900
+*/
156901
+static int otaObjIterCacheTableInfo(sqlite3ota *p, OtaObjIter *pIter){
156902
+ if( pIter->azTblCol==0 ){
156903
+ sqlite3_stmt *pStmt = 0;
156904
+ int nCol = 0;
156905
+ int i; /* for() loop iterator variable */
156906
+ int bOtaRowid = 0; /* If input table has column "ota_rowid" */
156907
+ int iOrder = 0;
156908
+ int iTnum = 0;
156909
+
156910
+ /* Figure out the type of table this step will deal with. */
156911
+ assert( pIter->eType==0 );
156912
+ otaTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum);
156913
+ if( p->rc==SQLITE_OK && pIter->eType==OTA_PK_NOTABLE ){
156914
+ p->rc = SQLITE_ERROR;
156915
+ p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl);
156916
+ }
156917
+ if( p->rc ) return p->rc;
156918
+ if( pIter->zIdx==0 ) pIter->iTnum = iTnum;
156919
+
156920
+ assert( pIter->eType==OTA_PK_NONE || pIter->eType==OTA_PK_IPK
156921
+ || pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_WITHOUT_ROWID
156922
+ || pIter->eType==OTA_PK_VTAB
156923
+ );
156924
+
156925
+ /* Populate the azTblCol[] and nTblCol variables based on the columns
156926
+ ** of the input table. Ignore any input table columns that begin with
156927
+ ** "ota_". */
156928
+ p->rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg,
156929
+ sqlite3_mprintf("SELECT * FROM 'data_%q'", pIter->zTbl)
156930
+ );
156931
+ if( p->rc==SQLITE_OK ){
156932
+ nCol = sqlite3_column_count(pStmt);
156933
+ otaAllocateIterArrays(p, pIter, nCol);
156934
+ }
156935
+ for(i=0; p->rc==SQLITE_OK && i<nCol; i++){
156936
+ const char *zName = (const char*)sqlite3_column_name(pStmt, i);
156937
+ if( sqlite3_strnicmp("ota_", zName, 4) ){
156938
+ char *zCopy = otaStrndup(zName, &p->rc);
156939
+ pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol;
156940
+ pIter->azTblCol[pIter->nTblCol++] = zCopy;
156941
+ }
156942
+ else if( 0==sqlite3_stricmp("ota_rowid", zName) ){
156943
+ bOtaRowid = 1;
156944
+ }
156945
+ }
156946
+ sqlite3_finalize(pStmt);
156947
+ pStmt = 0;
156948
+
156949
+ if( p->rc==SQLITE_OK
156950
+ && bOtaRowid!=(pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
156951
+ ){
156952
+ p->rc = SQLITE_ERROR;
156953
+ p->zErrmsg = sqlite3_mprintf(
156954
+ "table data_%q %s ota_rowid column", pIter->zTbl,
156955
+ (bOtaRowid ? "may not have" : "requires")
156956
+ );
156957
+ }
156958
+
156959
+ /* Check that all non-HIDDEN columns in the destination table are also
156960
+ ** present in the input table. Populate the abTblPk[], azTblType[] and
156961
+ ** aiTblOrder[] arrays at the same time. */
156962
+ if( p->rc==SQLITE_OK ){
156963
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
156964
+ sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl)
156965
+ );
156966
+ }
156967
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
156968
+ const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
156969
+ if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */
156970
+ for(i=iOrder; i<pIter->nTblCol; i++){
156971
+ if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
156972
+ }
156973
+ if( i==pIter->nTblCol ){
156974
+ p->rc = SQLITE_ERROR;
156975
+ p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s",
156976
+ pIter->zTbl, zName
156977
+ );
156978
+ }else{
156979
+ int iPk = sqlite3_column_int(pStmt, 5);
156980
+ int bNotNull = sqlite3_column_int(pStmt, 3);
156981
+ const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
156982
+
156983
+ if( i!=iOrder ){
156984
+ SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
156985
+ SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
156986
+ }
156987
+
156988
+ pIter->azTblType[iOrder] = otaStrndup(zType, &p->rc);
156989
+ pIter->abTblPk[iOrder] = (iPk!=0);
156990
+ pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
156991
+ iOrder++;
156992
+ }
156993
+ }
156994
+
156995
+ otaFinalize(p, pStmt);
156996
+ otaObjIterCacheIndexedCols(p, pIter);
156997
+ assert( pIter->eType!=OTA_PK_VTAB || pIter->abIndexed==0 );
156998
+ }
156999
+
157000
+ return p->rc;
157001
+}
157002
+
157003
+/*
157004
+** This function constructs and returns a pointer to a nul-terminated
157005
+** string containing some SQL clause or list based on one or more of the
157006
+** column names currently stored in the pIter->azTblCol[] array.
157007
+*/
157008
+static char *otaObjIterGetCollist(
157009
+ sqlite3ota *p, /* OTA object */
157010
+ OtaObjIter *pIter /* Object iterator for column names */
157011
+){
157012
+ char *zList = 0;
157013
+ const char *zSep = "";
157014
+ int i;
157015
+ for(i=0; i<pIter->nTblCol; i++){
157016
+ const char *z = pIter->azTblCol[i];
157017
+ zList = otaMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
157018
+ zSep = ", ";
157019
+ }
157020
+ return zList;
157021
+}
157022
+
157023
+/*
157024
+** This function is used to create a SELECT list (the list of SQL
157025
+** expressions that follows a SELECT keyword) for a SELECT statement
157026
+** used to read from an data_xxx or ota_tmp_xxx table while updating the
157027
+** index object currently indicated by the iterator object passed as the
157028
+** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used
157029
+** to obtain the required information.
157030
+**
157031
+** If the index is of the following form:
157032
+**
157033
+** CREATE INDEX i1 ON t1(c, b COLLATE nocase);
157034
+**
157035
+** and "t1" is a table with an explicit INTEGER PRIMARY KEY column
157036
+** "ipk", the returned string is:
157037
+**
157038
+** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'"
157039
+**
157040
+** As well as the returned string, three other malloc'd strings are
157041
+** returned via output parameters. As follows:
157042
+**
157043
+** pzImposterCols: ...
157044
+** pzImposterPk: ...
157045
+** pzWhere: ...
157046
+*/
157047
+static char *otaObjIterGetIndexCols(
157048
+ sqlite3ota *p, /* OTA object */
157049
+ OtaObjIter *pIter, /* Object iterator for column names */
157050
+ char **pzImposterCols, /* OUT: Columns for imposter table */
157051
+ char **pzImposterPk, /* OUT: Imposter PK clause */
157052
+ char **pzWhere, /* OUT: WHERE clause */
157053
+ int *pnBind /* OUT: Total number of columns */
157054
+){
157055
+ int rc = p->rc; /* Error code */
157056
+ int rc2; /* sqlite3_finalize() return code */
157057
+ char *zRet = 0; /* String to return */
157058
+ char *zImpCols = 0; /* String to return via *pzImposterCols */
157059
+ char *zImpPK = 0; /* String to return via *pzImposterPK */
157060
+ char *zWhere = 0; /* String to return via *pzWhere */
157061
+ int nBind = 0; /* Value to return via *pnBind */
157062
+ const char *zCom = ""; /* Set to ", " later on */
157063
+ const char *zAnd = ""; /* Set to " AND " later on */
157064
+ sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */
157065
+
157066
+ if( rc==SQLITE_OK ){
157067
+ assert( p->zErrmsg==0 );
157068
+ rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
157069
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
157070
+ );
157071
+ }
157072
+
157073
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
157074
+ int iCid = sqlite3_column_int(pXInfo, 1);
157075
+ int bDesc = sqlite3_column_int(pXInfo, 3);
157076
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
157077
+ const char *zCol;
157078
+ const char *zType;
157079
+
157080
+ if( iCid<0 ){
157081
+ /* An integer primary key. If the table has an explicit IPK, use
157082
+ ** its name. Otherwise, use "ota_rowid". */
157083
+ if( pIter->eType==OTA_PK_IPK ){
157084
+ int i;
157085
+ for(i=0; pIter->abTblPk[i]==0; i++);
157086
+ assert( i<pIter->nTblCol );
157087
+ zCol = pIter->azTblCol[i];
157088
+ }else{
157089
+ zCol = "ota_rowid";
157090
+ }
157091
+ zType = "INTEGER";
157092
+ }else{
157093
+ zCol = pIter->azTblCol[iCid];
157094
+ zType = pIter->azTblType[iCid];
157095
+ }
157096
+
157097
+ zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
157098
+ if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
157099
+ const char *zOrder = (bDesc ? " DESC" : "");
157100
+ zImpPK = sqlite3_mprintf("%z%s\"ota_imp_%d%w\"%s",
157101
+ zImpPK, zCom, nBind, zCol, zOrder
157102
+ );
157103
+ }
157104
+ zImpCols = sqlite3_mprintf("%z%s\"ota_imp_%d%w\" %s COLLATE %Q",
157105
+ zImpCols, zCom, nBind, zCol, zType, zCollate
157106
+ );
157107
+ zWhere = sqlite3_mprintf(
157108
+ "%z%s\"ota_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol
157109
+ );
157110
+ if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM;
157111
+ zCom = ", ";
157112
+ zAnd = " AND ";
157113
+ nBind++;
157114
+ }
157115
+
157116
+ rc2 = sqlite3_finalize(pXInfo);
157117
+ if( rc==SQLITE_OK ) rc = rc2;
157118
+
157119
+ if( rc!=SQLITE_OK ){
157120
+ sqlite3_free(zRet);
157121
+ sqlite3_free(zImpCols);
157122
+ sqlite3_free(zImpPK);
157123
+ sqlite3_free(zWhere);
157124
+ zRet = 0;
157125
+ zImpCols = 0;
157126
+ zImpPK = 0;
157127
+ zWhere = 0;
157128
+ p->rc = rc;
157129
+ }
157130
+
157131
+ *pzImposterCols = zImpCols;
157132
+ *pzImposterPk = zImpPK;
157133
+ *pzWhere = zWhere;
157134
+ *pnBind = nBind;
157135
+ return zRet;
157136
+}
157137
+
157138
+/*
157139
+** Assuming the current table columns are "a", "b" and "c", and the zObj
157140
+** paramter is passed "old", return a string of the form:
157141
+**
157142
+** "old.a, old.b, old.b"
157143
+**
157144
+** With the column names escaped.
157145
+**
157146
+** For tables with implicit rowids - OTA_PK_EXTERNAL and OTA_PK_NONE, append
157147
+** the text ", old._rowid_" to the returned value.
157148
+*/
157149
+static char *otaObjIterGetOldlist(
157150
+ sqlite3ota *p,
157151
+ OtaObjIter *pIter,
157152
+ const char *zObj
157153
+){
157154
+ char *zList = 0;
157155
+ if( p->rc==SQLITE_OK && pIter->abIndexed ){
157156
+ const char *zS = "";
157157
+ int i;
157158
+ for(i=0; i<pIter->nTblCol; i++){
157159
+ if( pIter->abIndexed[i] ){
157160
+ const char *zCol = pIter->azTblCol[i];
157161
+ zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol);
157162
+ }else{
157163
+ zList = sqlite3_mprintf("%z%sNULL", zList, zS);
157164
+ }
157165
+ zS = ", ";
157166
+ if( zList==0 ){
157167
+ p->rc = SQLITE_NOMEM;
157168
+ break;
157169
+ }
157170
+ }
157171
+
157172
+ /* For a table with implicit rowids, append "old._rowid_" to the list. */
157173
+ if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157174
+ zList = otaMPrintf(p, "%z, %s._rowid_", zList, zObj);
157175
+ }
157176
+ }
157177
+ return zList;
157178
+}
157179
+
157180
+/*
157181
+** Return an expression that can be used in a WHERE clause to match the
157182
+** primary key of the current table. For example, if the table is:
157183
+**
157184
+** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c));
157185
+**
157186
+** Return the string:
157187
+**
157188
+** "b = ?1 AND c = ?2"
157189
+*/
157190
+static char *otaObjIterGetWhere(
157191
+ sqlite3ota *p,
157192
+ OtaObjIter *pIter
157193
+){
157194
+ char *zList = 0;
157195
+ if( pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE ){
157196
+ zList = otaMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1);
157197
+ }else if( pIter->eType==OTA_PK_EXTERNAL ){
157198
+ const char *zSep = "";
157199
+ int i;
157200
+ for(i=0; i<pIter->nTblCol; i++){
157201
+ if( pIter->abTblPk[i] ){
157202
+ zList = otaMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1);
157203
+ zSep = " AND ";
157204
+ }
157205
+ }
157206
+ zList = otaMPrintf(p,
157207
+ "_rowid_ = (SELECT id FROM ota_imposter2 WHERE %z)", zList
157208
+ );
157209
+
157210
+ }else{
157211
+ const char *zSep = "";
157212
+ int i;
157213
+ for(i=0; i<pIter->nTblCol; i++){
157214
+ if( pIter->abTblPk[i] ){
157215
+ const char *zCol = pIter->azTblCol[i];
157216
+ zList = otaMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1);
157217
+ zSep = " AND ";
157218
+ }
157219
+ }
157220
+ }
157221
+ return zList;
157222
+}
157223
+
157224
+/*
157225
+** The SELECT statement iterating through the keys for the current object
157226
+** (p->objiter.pSelect) currently points to a valid row. However, there
157227
+** is something wrong with the ota_control value in the ota_control value
157228
+** stored in the (p->nCol+1)'th column. Set the error code and error message
157229
+** of the OTA handle to something reflecting this.
157230
+*/
157231
+static void otaBadControlError(sqlite3ota *p){
157232
+ p->rc = SQLITE_ERROR;
157233
+ p->zErrmsg = sqlite3_mprintf("invalid ota_control value");
157234
+}
157235
+
157236
+
157237
+/*
157238
+** Return a nul-terminated string containing the comma separated list of
157239
+** assignments that should be included following the "SET" keyword of
157240
+** an UPDATE statement used to update the table object that the iterator
157241
+** passed as the second argument currently points to if the ota_control
157242
+** column of the data_xxx table entry is set to zMask.
157243
+**
157244
+** The memory for the returned string is obtained from sqlite3_malloc().
157245
+** It is the responsibility of the caller to eventually free it using
157246
+** sqlite3_free().
157247
+**
157248
+** If an OOM error is encountered when allocating space for the new
157249
+** string, an error code is left in the ota handle passed as the first
157250
+** argument and NULL is returned. Or, if an error has already occurred
157251
+** when this function is called, NULL is returned immediately, without
157252
+** attempting the allocation or modifying the stored error code.
157253
+*/
157254
+static char *otaObjIterGetSetlist(
157255
+ sqlite3ota *p,
157256
+ OtaObjIter *pIter,
157257
+ const char *zMask
157258
+){
157259
+ char *zList = 0;
157260
+ if( p->rc==SQLITE_OK ){
157261
+ int i;
157262
+
157263
+ if( strlen(zMask)!=pIter->nTblCol ){
157264
+ otaBadControlError(p);
157265
+ }else{
157266
+ const char *zSep = "";
157267
+ for(i=0; i<pIter->nTblCol; i++){
157268
+ char c = zMask[pIter->aiSrcOrder[i]];
157269
+ if( c=='x' ){
157270
+ zList = otaMPrintf(p, "%z%s\"%w\"=?%d",
157271
+ zList, zSep, pIter->azTblCol[i], i+1
157272
+ );
157273
+ zSep = ", ";
157274
+ }
157275
+ if( c=='d' ){
157276
+ zList = otaMPrintf(p, "%z%s\"%w\"=ota_delta(\"%w\", ?%d)",
157277
+ zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
157278
+ );
157279
+ zSep = ", ";
157280
+ }
157281
+ }
157282
+ }
157283
+ }
157284
+ return zList;
157285
+}
157286
+
157287
+/*
157288
+** Return a nul-terminated string consisting of nByte comma separated
157289
+** "?" expressions. For example, if nByte is 3, return a pointer to
157290
+** a buffer containing the string "?,?,?".
157291
+**
157292
+** The memory for the returned string is obtained from sqlite3_malloc().
157293
+** It is the responsibility of the caller to eventually free it using
157294
+** sqlite3_free().
157295
+**
157296
+** If an OOM error is encountered when allocating space for the new
157297
+** string, an error code is left in the ota handle passed as the first
157298
+** argument and NULL is returned. Or, if an error has already occurred
157299
+** when this function is called, NULL is returned immediately, without
157300
+** attempting the allocation or modifying the stored error code.
157301
+*/
157302
+static char *otaObjIterGetBindlist(sqlite3ota *p, int nBind){
157303
+ char *zRet = 0;
157304
+ int nByte = nBind*2 + 1;
157305
+
157306
+ zRet = (char*)otaMalloc(p, nByte);
157307
+ if( zRet ){
157308
+ int i;
157309
+ for(i=0; i<nBind; i++){
157310
+ zRet[i*2] = '?';
157311
+ zRet[i*2+1] = (i+1==nBind) ? '\0' : ',';
157312
+ }
157313
+ }
157314
+ return zRet;
157315
+}
157316
+
157317
+/*
157318
+** The iterator currently points to a table (not index) of type
157319
+** OTA_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY
157320
+** declaration for the corresponding imposter table. For example,
157321
+** if the iterator points to a table created as:
157322
+**
157323
+** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
157324
+**
157325
+** this function returns:
157326
+**
157327
+** PRIMARY KEY("b", "a" DESC)
157328
+*/
157329
+static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){
157330
+ char *z = 0;
157331
+ assert( pIter->zIdx==0 );
157332
+ if( p->rc==SQLITE_OK ){
157333
+ const char *zSep = "PRIMARY KEY(";
157334
+ sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */
157335
+ sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = <pk-index> */
157336
+
157337
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg,
157338
+ sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
157339
+ );
157340
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){
157341
+ const char *zOrig = (const char*)sqlite3_column_text(pXList,3);
157342
+ if( zOrig && strcmp(zOrig, "pk")==0 ){
157343
+ const char *zIdx = (const char*)sqlite3_column_text(pXList,1);
157344
+ if( zIdx ){
157345
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
157346
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
157347
+ );
157348
+ }
157349
+ break;
157350
+ }
157351
+ }
157352
+ otaFinalize(p, pXList);
157353
+
157354
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
157355
+ if( sqlite3_column_int(pXInfo, 5) ){
157356
+ /* int iCid = sqlite3_column_int(pXInfo, 0); */
157357
+ const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
157358
+ const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
157359
+ z = otaMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
157360
+ zSep = ", ";
157361
+ }
157362
+ }
157363
+ z = otaMPrintf(p, "%z)", z);
157364
+ otaFinalize(p, pXInfo);
157365
+ }
157366
+ return z;
157367
+}
157368
+
157369
+/*
157370
+** This function creates the second imposter table used when writing to
157371
+** a table b-tree where the table has an external primary key. If the
157372
+** iterator passed as the second argument does not currently point to
157373
+** a table (not index) with an external primary key, this function is a
157374
+** no-op.
157375
+**
157376
+** Assuming the iterator does point to a table with an external PK, this
157377
+** function creates a WITHOUT ROWID imposter table named "ota_imposter2"
157378
+** used to access that PK index. For example, if the target table is
157379
+** declared as follows:
157380
+**
157381
+** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c));
157382
+**
157383
+** then the imposter table schema is:
157384
+**
157385
+** CREATE TABLE ota_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID;
157386
+**
157387
+*/
157388
+static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){
157389
+ if( p->rc==SQLITE_OK && pIter->eType==OTA_PK_EXTERNAL ){
157390
+ int tnum = pIter->iPkTnum; /* Root page of PK index */
157391
+ sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */
157392
+ const char *zIdx = 0; /* Name of PK index */
157393
+ sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */
157394
+ const char *zComma = "";
157395
+ char *zCols = 0; /* Used to build up list of table cols */
157396
+ char *zPk = 0; /* Used to build up table PK declaration */
157397
+
157398
+ /* Figure out the name of the primary key index for the current table.
157399
+ ** This is needed for the argument to "PRAGMA index_xinfo". Set
157400
+ ** zIdx to point to a nul-terminated string containing this name. */
157401
+ p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg,
157402
+ "SELECT name FROM sqlite_master WHERE rootpage = ?"
157403
+ );
157404
+ if( p->rc==SQLITE_OK ){
157405
+ sqlite3_bind_int(pQuery, 1, tnum);
157406
+ if( SQLITE_ROW==sqlite3_step(pQuery) ){
157407
+ zIdx = (const char*)sqlite3_column_text(pQuery, 0);
157408
+ }
157409
+ }
157410
+ if( zIdx ){
157411
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
157412
+ sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
157413
+ );
157414
+ }
157415
+ otaFinalize(p, pQuery);
157416
+
157417
+ while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
157418
+ int bKey = sqlite3_column_int(pXInfo, 5);
157419
+ if( bKey ){
157420
+ int iCid = sqlite3_column_int(pXInfo, 1);
157421
+ int bDesc = sqlite3_column_int(pXInfo, 3);
157422
+ const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
157423
+ zCols = otaMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma,
157424
+ iCid, pIter->azTblType[iCid], zCollate
157425
+ );
157426
+ zPk = otaMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
157427
+ zComma = ", ";
157428
+ }
157429
+ }
157430
+ zCols = otaMPrintf(p, "%z, id INTEGER", zCols);
157431
+ otaFinalize(p, pXInfo);
157432
+
157433
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
157434
+ otaMPrintfExec(p, p->dbMain,
157435
+ "CREATE TABLE ota_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID",
157436
+ zCols, zPk
157437
+ );
157438
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
157439
+ }
157440
+}
157441
+
157442
+/*
157443
+** If an error has already occurred when this function is called, it
157444
+** immediately returns zero (without doing any work). Or, if an error
157445
+** occurs during the execution of this function, it sets the error code
157446
+** in the sqlite3ota object indicated by the first argument and returns
157447
+** zero.
157448
+**
157449
+** The iterator passed as the second argument is guaranteed to point to
157450
+** a table (not an index) when this function is called. This function
157451
+** attempts to create any imposter table required to write to the main
157452
+** table b-tree of the table before returning. Non-zero is returned if
157453
+** an imposter table are created, or zero otherwise.
157454
+**
157455
+** An imposter table is required in all cases except OTA_PK_VTAB. Only
157456
+** virtual tables are written to directly. The imposter table has the
157457
+** same schema as the actual target table (less any UNIQUE constraints).
157458
+** More precisely, the "same schema" means the same columns, types,
157459
+** collation sequences. For tables that do not have an external PRIMARY
157460
+** KEY, it also means the same PRIMARY KEY declaration.
157461
+*/
157462
+static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){
157463
+ if( p->rc==SQLITE_OK && pIter->eType!=OTA_PK_VTAB ){
157464
+ int tnum = pIter->iTnum;
157465
+ const char *zComma = "";
157466
+ char *zSql = 0;
157467
+ int iCol;
157468
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
157469
+
157470
+ for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){
157471
+ const char *zPk = "";
157472
+ const char *zCol = pIter->azTblCol[iCol];
157473
+ const char *zColl = 0;
157474
+
157475
+ p->rc = sqlite3_table_column_metadata(
157476
+ p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0
157477
+ );
157478
+
157479
+ if( pIter->eType==OTA_PK_IPK && pIter->abTblPk[iCol] ){
157480
+ /* If the target table column is an "INTEGER PRIMARY KEY", add
157481
+ ** "PRIMARY KEY" to the imposter table column declaration. */
157482
+ zPk = "PRIMARY KEY ";
157483
+ }
157484
+ zSql = otaMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s",
157485
+ zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
157486
+ (pIter->abNotNull[iCol] ? " NOT NULL" : "")
157487
+ );
157488
+ zComma = ", ";
157489
+ }
157490
+
157491
+ if( pIter->eType==OTA_PK_WITHOUT_ROWID ){
157492
+ char *zPk = otaWithoutRowidPK(p, pIter);
157493
+ if( zPk ){
157494
+ zSql = otaMPrintf(p, "%z, %z", zSql, zPk);
157495
+ }
157496
+ }
157497
+
157498
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
157499
+ otaMPrintfExec(p, p->dbMain, "CREATE TABLE \"ota_imp_%w\"(%z)%s",
157500
+ pIter->zTbl, zSql,
157501
+ (pIter->eType==OTA_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "")
157502
+ );
157503
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
157504
+ }
157505
+}
157506
+
157507
+/*
157508
+** Prepare a statement used to insert rows into the "ota_tmp_xxx" table.
157509
+** Specifically a statement of the form:
157510
+**
157511
+** INSERT INTO ota_tmp_xxx VALUES(?, ?, ? ...);
157512
+**
157513
+** The number of bound variables is equal to the number of columns in
157514
+** the target table, plus one (for the ota_control column), plus one more
157515
+** (for the ota_rowid column) if the target table is an implicit IPK or
157516
+** virtual table.
157517
+*/
157518
+static void otaObjIterPrepareTmpInsert(
157519
+ sqlite3ota *p,
157520
+ OtaObjIter *pIter,
157521
+ const char *zCollist,
157522
+ const char *zOtaRowid
157523
+){
157524
+ int bOtaRowid = (pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE);
157525
+ char *zBind = otaObjIterGetBindlist(p, pIter->nTblCol + 1 + bOtaRowid);
157526
+ if( zBind ){
157527
+ assert( pIter->pTmpInsert==0 );
157528
+ p->rc = prepareFreeAndCollectError(
157529
+ p->dbOta, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
157530
+ "INSERT INTO %s.'ota_tmp_%q'(ota_control,%s%s) VALUES(%z)",
157531
+ p->zStateDb, pIter->zTbl, zCollist, zOtaRowid, zBind
157532
+ ));
157533
+ }
157534
+}
157535
+
157536
+static void otaTmpInsertFunc(
157537
+ sqlite3_context *pCtx,
157538
+ int nVal,
157539
+ sqlite3_value **apVal
157540
+){
157541
+ sqlite3ota *p = sqlite3_user_data(pCtx);
157542
+ int rc = SQLITE_OK;
157543
+ int i;
157544
+
157545
+ for(i=0; rc==SQLITE_OK && i<nVal; i++){
157546
+ rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
157547
+ }
157548
+ if( rc==SQLITE_OK ){
157549
+ sqlite3_step(p->objiter.pTmpInsert);
157550
+ rc = sqlite3_reset(p->objiter.pTmpInsert);
157551
+ }
157552
+
157553
+ if( rc!=SQLITE_OK ){
157554
+ sqlite3_result_error_code(pCtx, rc);
157555
+ }
157556
+}
157557
+
157558
+/*
157559
+** Ensure that the SQLite statement handles required to update the
157560
+** target database object currently indicated by the iterator passed
157561
+** as the second argument are available.
157562
+*/
157563
+static int otaObjIterPrepareAll(
157564
+ sqlite3ota *p,
157565
+ OtaObjIter *pIter,
157566
+ int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */
157567
+){
157568
+ assert( pIter->bCleanup==0 );
157569
+ if( pIter->pSelect==0 && otaObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){
157570
+ const int tnum = pIter->iTnum;
157571
+ char *zCollist = 0; /* List of indexed columns */
157572
+ char **pz = &p->zErrmsg;
157573
+ const char *zIdx = pIter->zIdx;
157574
+ char *zLimit = 0;
157575
+
157576
+ if( nOffset ){
157577
+ zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset);
157578
+ if( !zLimit ) p->rc = SQLITE_NOMEM;
157579
+ }
157580
+
157581
+ if( zIdx ){
157582
+ const char *zTbl = pIter->zTbl;
157583
+ char *zImposterCols = 0; /* Columns for imposter table */
157584
+ char *zImposterPK = 0; /* Primary key declaration for imposter */
157585
+ char *zWhere = 0; /* WHERE clause on PK columns */
157586
+ char *zBind = 0;
157587
+ int nBind = 0;
157588
+
157589
+ assert( pIter->eType!=OTA_PK_VTAB );
157590
+ zCollist = otaObjIterGetIndexCols(
157591
+ p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
157592
+ );
157593
+ zBind = otaObjIterGetBindlist(p, nBind);
157594
+
157595
+ /* Create the imposter table used to write to this index. */
157596
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
157597
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
157598
+ otaMPrintfExec(p, p->dbMain,
157599
+ "CREATE TABLE \"ota_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
157600
+ zTbl, zImposterCols, zImposterPK
157601
+ );
157602
+ sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
157603
+
157604
+ /* Create the statement to insert index entries */
157605
+ pIter->nCol = nBind;
157606
+ if( p->rc==SQLITE_OK ){
157607
+ p->rc = prepareFreeAndCollectError(
157608
+ p->dbMain, &pIter->pInsert, &p->zErrmsg,
157609
+ sqlite3_mprintf("INSERT INTO \"ota_imp_%w\" VALUES(%s)", zTbl, zBind)
157610
+ );
157611
+ }
157612
+
157613
+ /* And to delete index entries */
157614
+ if( p->rc==SQLITE_OK ){
157615
+ p->rc = prepareFreeAndCollectError(
157616
+ p->dbMain, &pIter->pDelete, &p->zErrmsg,
157617
+ sqlite3_mprintf("DELETE FROM \"ota_imp_%w\" WHERE %s", zTbl, zWhere)
157618
+ );
157619
+ }
157620
+
157621
+ /* Create the SELECT statement to read keys in sorted order */
157622
+ if( p->rc==SQLITE_OK ){
157623
+ char *zSql;
157624
+ if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157625
+ zSql = sqlite3_mprintf(
157626
+ "SELECT %s, ota_control FROM %s.'ota_tmp_%q' ORDER BY %s%s",
157627
+ zCollist, p->zStateDb, pIter->zTbl,
157628
+ zCollist, zLimit
157629
+ );
157630
+ }else{
157631
+ zSql = sqlite3_mprintf(
157632
+ "SELECT %s, ota_control FROM 'data_%q' "
157633
+ "WHERE typeof(ota_control)='integer' AND ota_control!=1 "
157634
+ "UNION ALL "
157635
+ "SELECT %s, ota_control FROM %s.'ota_tmp_%q' "
157636
+ "ORDER BY %s%s",
157637
+ zCollist, pIter->zTbl,
157638
+ zCollist, p->zStateDb, pIter->zTbl,
157639
+ zCollist, zLimit
157640
+ );
157641
+ }
157642
+ p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz, zSql);
157643
+ }
157644
+
157645
+ sqlite3_free(zImposterCols);
157646
+ sqlite3_free(zImposterPK);
157647
+ sqlite3_free(zWhere);
157648
+ sqlite3_free(zBind);
157649
+ }else{
157650
+ int bOtaRowid = (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE);
157651
+ const char *zTbl = pIter->zTbl; /* Table this step applies to */
157652
+ const char *zWrite; /* Imposter table name */
157653
+
157654
+ char *zBindings = otaObjIterGetBindlist(p, pIter->nTblCol + bOtaRowid);
157655
+ char *zWhere = otaObjIterGetWhere(p, pIter);
157656
+ char *zOldlist = otaObjIterGetOldlist(p, pIter, "old");
157657
+ char *zNewlist = otaObjIterGetOldlist(p, pIter, "new");
157658
+
157659
+ zCollist = otaObjIterGetCollist(p, pIter);
157660
+ pIter->nCol = pIter->nTblCol;
157661
+
157662
+ /* Create the SELECT statement to read keys from data_xxx */
157663
+ if( p->rc==SQLITE_OK ){
157664
+ p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz,
157665
+ sqlite3_mprintf(
157666
+ "SELECT %s, ota_control%s FROM 'data_%q'%s",
157667
+ zCollist, (bOtaRowid ? ", ota_rowid" : ""), zTbl, zLimit
157668
+ )
157669
+ );
157670
+ }
157671
+
157672
+ /* Create the imposter table or tables (if required). */
157673
+ otaCreateImposterTable(p, pIter);
157674
+ otaCreateImposterTable2(p, pIter);
157675
+ zWrite = (pIter->eType==OTA_PK_VTAB ? "" : "ota_imp_");
157676
+
157677
+ /* Create the INSERT statement to write to the target PK b-tree */
157678
+ if( p->rc==SQLITE_OK ){
157679
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
157680
+ sqlite3_mprintf(
157681
+ "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)",
157682
+ zWrite, zTbl, zCollist, (bOtaRowid ? ", _rowid_" : ""), zBindings
157683
+ )
157684
+ );
157685
+ }
157686
+
157687
+ /* Create the DELETE statement to write to the target PK b-tree */
157688
+ if( p->rc==SQLITE_OK ){
157689
+ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
157690
+ sqlite3_mprintf(
157691
+ "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
157692
+ )
157693
+ );
157694
+ }
157695
+
157696
+ if( pIter->abIndexed ){
157697
+ const char *zOtaRowid = "";
157698
+ if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157699
+ zOtaRowid = ", ota_rowid";
157700
+ }
157701
+
157702
+ /* Create the ota_tmp_xxx table and the triggers to populate it. */
157703
+ otaMPrintfExec(p, p->dbOta,
157704
+ "CREATE TABLE IF NOT EXISTS %s.'ota_tmp_%q' AS "
157705
+ "SELECT *%s FROM 'data_%q' WHERE 0;"
157706
+ , p->zStateDb
157707
+ , zTbl, (pIter->eType==OTA_PK_EXTERNAL ? ", 0 AS ota_rowid" : "")
157708
+ , zTbl
157709
+ );
157710
+
157711
+ otaMPrintfExec(p, p->dbMain,
157712
+ "CREATE TEMP TRIGGER ota_delete_tr BEFORE DELETE ON \"%s%w\" "
157713
+ "BEGIN "
157714
+ " SELECT ota_tmp_insert(2, %s);"
157715
+ "END;"
157716
+
157717
+ "CREATE TEMP TRIGGER ota_update1_tr BEFORE UPDATE ON \"%s%w\" "
157718
+ "BEGIN "
157719
+ " SELECT ota_tmp_insert(2, %s);"
157720
+ "END;"
157721
+
157722
+ "CREATE TEMP TRIGGER ota_update2_tr AFTER UPDATE ON \"%s%w\" "
157723
+ "BEGIN "
157724
+ " SELECT ota_tmp_insert(3, %s);"
157725
+ "END;",
157726
+ zWrite, zTbl, zOldlist,
157727
+ zWrite, zTbl, zOldlist,
157728
+ zWrite, zTbl, zNewlist
157729
+ );
157730
+
157731
+ if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157732
+ otaMPrintfExec(p, p->dbMain,
157733
+ "CREATE TEMP TRIGGER ota_insert_tr AFTER INSERT ON \"%s%w\" "
157734
+ "BEGIN "
157735
+ " SELECT ota_tmp_insert(0, %s);"
157736
+ "END;",
157737
+ zWrite, zTbl, zNewlist
157738
+ );
157739
+ }
157740
+
157741
+ otaObjIterPrepareTmpInsert(p, pIter, zCollist, zOtaRowid);
157742
+ }
157743
+
157744
+ sqlite3_free(zWhere);
157745
+ sqlite3_free(zOldlist);
157746
+ sqlite3_free(zNewlist);
157747
+ sqlite3_free(zBindings);
157748
+ }
157749
+ sqlite3_free(zCollist);
157750
+ sqlite3_free(zLimit);
157751
+ }
157752
+
157753
+ return p->rc;
157754
+}
157755
+
157756
+/*
157757
+** Set output variable *ppStmt to point to an UPDATE statement that may
157758
+** be used to update the imposter table for the main table b-tree of the
157759
+** table object that pIter currently points to, assuming that the
157760
+** ota_control column of the data_xyz table contains zMask.
157761
+**
157762
+** If the zMask string does not specify any columns to update, then this
157763
+** is not an error. Output variable *ppStmt is set to NULL in this case.
157764
+*/
157765
+static int otaGetUpdateStmt(
157766
+ sqlite3ota *p, /* OTA handle */
157767
+ OtaObjIter *pIter, /* Object iterator */
157768
+ const char *zMask, /* ota_control value ('x.x.') */
157769
+ sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */
157770
+){
157771
+ OtaUpdateStmt **pp;
157772
+ OtaUpdateStmt *pUp = 0;
157773
+ int nUp = 0;
157774
+
157775
+ /* In case an error occurs */
157776
+ *ppStmt = 0;
157777
+
157778
+ /* Search for an existing statement. If one is found, shift it to the front
157779
+ ** of the LRU queue and return immediately. Otherwise, leave nUp pointing
157780
+ ** to the number of statements currently in the cache and pUp to the
157781
+ ** last object in the list. */
157782
+ for(pp=&pIter->pOtaUpdate; *pp; pp=&((*pp)->pNext)){
157783
+ pUp = *pp;
157784
+ if( strcmp(pUp->zMask, zMask)==0 ){
157785
+ *pp = pUp->pNext;
157786
+ pUp->pNext = pIter->pOtaUpdate;
157787
+ pIter->pOtaUpdate = pUp;
157788
+ *ppStmt = pUp->pUpdate;
157789
+ return SQLITE_OK;
157790
+ }
157791
+ nUp++;
157792
+ }
157793
+ assert( pUp==0 || pUp->pNext==0 );
157794
+
157795
+ if( nUp>=SQLITE_OTA_UPDATE_CACHESIZE ){
157796
+ for(pp=&pIter->pOtaUpdate; *pp!=pUp; pp=&((*pp)->pNext));
157797
+ *pp = 0;
157798
+ sqlite3_finalize(pUp->pUpdate);
157799
+ pUp->pUpdate = 0;
157800
+ }else{
157801
+ pUp = (OtaUpdateStmt*)otaMalloc(p, sizeof(OtaUpdateStmt)+pIter->nTblCol+1);
157802
+ }
157803
+
157804
+ if( pUp ){
157805
+ char *zWhere = otaObjIterGetWhere(p, pIter);
157806
+ char *zSet = otaObjIterGetSetlist(p, pIter, zMask);
157807
+ char *zUpdate = 0;
157808
+
157809
+ pUp->zMask = (char*)&pUp[1];
157810
+ memcpy(pUp->zMask, zMask, pIter->nTblCol);
157811
+ pUp->pNext = pIter->pOtaUpdate;
157812
+ pIter->pOtaUpdate = pUp;
157813
+
157814
+ if( zSet ){
157815
+ const char *zPrefix = "";
157816
+
157817
+ if( pIter->eType!=OTA_PK_VTAB ) zPrefix = "ota_imp_";
157818
+ zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
157819
+ zPrefix, pIter->zTbl, zSet, zWhere
157820
+ );
157821
+ p->rc = prepareFreeAndCollectError(
157822
+ p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate
157823
+ );
157824
+ *ppStmt = pUp->pUpdate;
157825
+ }
157826
+ sqlite3_free(zWhere);
157827
+ sqlite3_free(zSet);
157828
+ }
157829
+
157830
+ return p->rc;
157831
+}
157832
+
157833
+static sqlite3 *otaOpenDbhandle(sqlite3ota *p, const char *zName){
157834
+ sqlite3 *db = 0;
157835
+ if( p->rc==SQLITE_OK ){
157836
+ const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
157837
+ p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName);
157838
+ if( p->rc ){
157839
+ p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
157840
+ sqlite3_close(db);
157841
+ db = 0;
157842
+ }
157843
+ }
157844
+ return db;
157845
+}
157846
+
157847
+/*
157848
+** Open the database handle and attach the OTA database as "ota". If an
157849
+** error occurs, leave an error code and message in the OTA handle.
157850
+*/
157851
+static void otaOpenDatabase(sqlite3ota *p){
157852
+ assert( p->rc==SQLITE_OK );
157853
+ assert( p->dbMain==0 && p->dbOta==0 );
157854
+
157855
+ p->eStage = 0;
157856
+ p->dbMain = otaOpenDbhandle(p, p->zTarget);
157857
+ p->dbOta = otaOpenDbhandle(p, p->zOta);
157858
+
157859
+ /* If using separate OTA and state databases, attach the state database to
157860
+ ** the OTA db handle now. */
157861
+ if( p->zState ){
157862
+ otaMPrintfExec(p, p->dbOta, "ATTACH %Q AS stat", p->zState);
157863
+ memcpy(p->zStateDb, "stat", 4);
157864
+ }else{
157865
+ memcpy(p->zStateDb, "main", 4);
157866
+ }
157867
+
157868
+ if( p->rc==SQLITE_OK ){
157869
+ p->rc = sqlite3_create_function(p->dbMain,
157870
+ "ota_tmp_insert", -1, SQLITE_UTF8, (void*)p, otaTmpInsertFunc, 0, 0
157871
+ );
157872
+ }
157873
+
157874
+ if( p->rc==SQLITE_OK ){
157875
+ p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_OTA, (void*)p);
157876
+ }
157877
+ otaMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
157878
+
157879
+ /* Mark the database file just opened as an OTA target database. If
157880
+ ** this call returns SQLITE_NOTFOUND, then the OTA vfs is not in use.
157881
+ ** This is an error. */
157882
+ if( p->rc==SQLITE_OK ){
157883
+ p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_OTA, (void*)p);
157884
+ }
157885
+
157886
+ if( p->rc==SQLITE_NOTFOUND ){
157887
+ p->rc = SQLITE_ERROR;
157888
+ p->zErrmsg = sqlite3_mprintf("ota vfs not found");
157889
+ }
157890
+}
157891
+
157892
+/*
157893
+** This routine is a copy of the sqlite3FileSuffix3() routine from the core.
157894
+** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined.
157895
+**
157896
+** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
157897
+** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
157898
+** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
157899
+** three characters, then shorten the suffix on z[] to be the last three
157900
+** characters of the original suffix.
157901
+**
157902
+** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
157903
+** do the suffix shortening regardless of URI parameter.
157904
+**
157905
+** Examples:
157906
+**
157907
+** test.db-journal => test.nal
157908
+** test.db-wal => test.wal
157909
+** test.db-shm => test.shm
157910
+** test.db-mj7f3319fa => test.9fa
157911
+*/
157912
+static void otaFileSuffix3(const char *zBase, char *z){
157913
+#ifdef SQLITE_ENABLE_8_3_NAMES
157914
+#if SQLITE_ENABLE_8_3_NAMES<2
157915
+ if( sqlite3_uri_boolean(zBase, "8_3_names", 0) )
157916
+#endif
157917
+ {
157918
+ int i, sz;
157919
+ sz = sqlite3Strlen30(z);
157920
+ for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
157921
+ if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
157922
+ }
157923
+#endif
157924
+}
157925
+
157926
+/*
157927
+** Return the current wal-index header checksum for the target database
157928
+** as a 64-bit integer.
157929
+**
157930
+** The checksum is store in the first page of xShmMap memory as an 8-byte
157931
+** blob starting at byte offset 40.
157932
+*/
157933
+static i64 otaShmChecksum(sqlite3ota *p){
157934
+ i64 iRet = 0;
157935
+ if( p->rc==SQLITE_OK ){
157936
+ sqlite3_file *pDb = p->pTargetFd->pReal;
157937
+ u32 volatile *ptr;
157938
+ p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
157939
+ if( p->rc==SQLITE_OK ){
157940
+ iRet = ((i64)ptr[10] << 32) + ptr[11];
157941
+ }
157942
+ }
157943
+ return iRet;
157944
+}
157945
+
157946
+/*
157947
+** This function is called as part of initializing or reinitializing an
157948
+** incremental checkpoint.
157949
+**
157950
+** It populates the sqlite3ota.aFrame[] array with the set of
157951
+** (wal frame -> db page) copy operations required to checkpoint the
157952
+** current wal file, and obtains the set of shm locks required to safely
157953
+** perform the copy operations directly on the file-system.
157954
+**
157955
+** If argument pState is not NULL, then the incremental checkpoint is
157956
+** being resumed. In this case, if the checksum of the wal-index-header
157957
+** following recovery is not the same as the checksum saved in the OtaState
157958
+** object, then the ota handle is set to DONE state. This occurs if some
157959
+** other client appends a transaction to the wal file in the middle of
157960
+** an incremental checkpoint.
157961
+*/
157962
+static void otaSetupCheckpoint(sqlite3ota *p, OtaState *pState){
157963
+
157964
+ /* If pState is NULL, then the wal file may not have been opened and
157965
+ ** recovered. Running a read-statement here to ensure that doing so
157966
+ ** does not interfere with the "capture" process below. */
157967
+ if( pState==0 ){
157968
+ p->eStage = 0;
157969
+ if( p->rc==SQLITE_OK ){
157970
+ p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0);
157971
+ }
157972
+ }
157973
+
157974
+ /* Assuming no error has occurred, run a "restart" checkpoint with the
157975
+ ** sqlite3ota.eStage variable set to CAPTURE. This turns on the following
157976
+ ** special behaviour in the ota VFS:
157977
+ **
157978
+ ** * If the exclusive shm WRITER or READ0 lock cannot be obtained,
157979
+ ** the checkpoint fails with SQLITE_BUSY (normally SQLite would
157980
+ ** proceed with running a passive checkpoint instead of failing).
157981
+ **
157982
+ ** * Attempts to read from the *-wal file or write to the database file
157983
+ ** do not perform any IO. Instead, the frame/page combinations that
157984
+ ** would be read/written are recorded in the sqlite3ota.aFrame[]
157985
+ ** array.
157986
+ **
157987
+ ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER,
157988
+ ** READ0 and CHECKPOINT locks taken as part of the checkpoint are
157989
+ ** no-ops. These locks will not be released until the connection
157990
+ ** is closed.
157991
+ **
157992
+ ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL
157993
+ ** error.
157994
+ **
157995
+ ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
157996
+ ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
157997
+ ** array populated with a set of (frame -> page) mappings. Because the
157998
+ ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy
157999
+ ** data from the wal file into the database file according to the
158000
+ ** contents of aFrame[].
158001
+ */
158002
+ if( p->rc==SQLITE_OK ){
158003
+ int rc2;
158004
+ p->eStage = OTA_STAGE_CAPTURE;
158005
+ rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
158006
+ if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
158007
+ }
158008
+
158009
+ if( p->rc==SQLITE_OK ){
158010
+ p->eStage = OTA_STAGE_CKPT;
158011
+ p->nStep = (pState ? pState->nRow : 0);
158012
+ p->aBuf = otaMalloc(p, p->pgsz);
158013
+ p->iWalCksum = otaShmChecksum(p);
158014
+ }
158015
+
158016
+ if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){
158017
+ p->rc = SQLITE_DONE;
158018
+ p->eStage = OTA_STAGE_DONE;
158019
+ }
158020
+}
158021
+
158022
+/*
158023
+** Called when iAmt bytes are read from offset iOff of the wal file while
158024
+** the ota object is in capture mode. Record the frame number of the frame
158025
+** being read in the aFrame[] array.
158026
+*/
158027
+static int otaCaptureWalRead(sqlite3ota *pOta, i64 iOff, int iAmt){
158028
+ const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0);
158029
+ u32 iFrame;
158030
+
158031
+ if( pOta->mLock!=mReq ){
158032
+ pOta->rc = SQLITE_BUSY;
158033
+ return SQLITE_INTERNAL;
158034
+ }
158035
+
158036
+ pOta->pgsz = iAmt;
158037
+ if( pOta->nFrame==pOta->nFrameAlloc ){
158038
+ int nNew = (pOta->nFrameAlloc ? pOta->nFrameAlloc : 64) * 2;
158039
+ OtaFrame *aNew;
158040
+ aNew = (OtaFrame*)sqlite3_realloc(pOta->aFrame, nNew * sizeof(OtaFrame));
158041
+ if( aNew==0 ) return SQLITE_NOMEM;
158042
+ pOta->aFrame = aNew;
158043
+ pOta->nFrameAlloc = nNew;
158044
+ }
158045
+
158046
+ iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1;
158047
+ if( pOta->iMaxFrame<iFrame ) pOta->iMaxFrame = iFrame;
158048
+ pOta->aFrame[pOta->nFrame].iWalFrame = iFrame;
158049
+ pOta->aFrame[pOta->nFrame].iDbPage = 0;
158050
+ pOta->nFrame++;
158051
+ return SQLITE_OK;
158052
+}
158053
+
158054
+/*
158055
+** Called when a page of data is written to offset iOff of the database
158056
+** file while the ota handle is in capture mode. Record the page number
158057
+** of the page being written in the aFrame[] array.
158058
+*/
158059
+static int otaCaptureDbWrite(sqlite3ota *pOta, i64 iOff){
158060
+ pOta->aFrame[pOta->nFrame-1].iDbPage = (u32)(iOff / pOta->pgsz) + 1;
158061
+ return SQLITE_OK;
158062
+}
158063
+
158064
+/*
158065
+** This is called as part of an incremental checkpoint operation. Copy
158066
+** a single frame of data from the wal file into the database file, as
158067
+** indicated by the OtaFrame object.
158068
+*/
158069
+static void otaCheckpointFrame(sqlite3ota *p, OtaFrame *pFrame){
158070
+ sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
158071
+ sqlite3_file *pDb = p->pTargetFd->pReal;
158072
+ i64 iOff;
158073
+
158074
+ assert( p->rc==SQLITE_OK );
158075
+ iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24;
158076
+ p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff);
158077
+ if( p->rc ) return;
158078
+
158079
+ iOff = (i64)(pFrame->iDbPage-1) * p->pgsz;
158080
+ p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
158081
+}
158082
+
158083
+
158084
+/*
158085
+** Take an EXCLUSIVE lock on the database file.
158086
+*/
158087
+static void otaLockDatabase(sqlite3ota *p){
158088
+ sqlite3_file *pReal = p->pTargetFd->pReal;
158089
+ assert( p->rc==SQLITE_OK );
158090
+ p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
158091
+ if( p->rc==SQLITE_OK ){
158092
+ p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
158093
+ }
158094
+}
158095
+
158096
+/*
158097
+** The OTA handle is currently in OTA_STAGE_OAL state, with a SHARED lock
158098
+** on the database file. This proc moves the *-oal file to the *-wal path,
158099
+** then reopens the database file (this time in vanilla, non-oal, WAL mode).
158100
+** If an error occurs, leave an error code and error message in the ota
158101
+** handle.
158102
+*/
158103
+static void otaMoveOalFile(sqlite3ota *p){
158104
+ const char *zBase = sqlite3_db_filename(p->dbMain, "main");
158105
+
158106
+ char *zWal = sqlite3_mprintf("%s-wal", zBase);
158107
+ char *zOal = sqlite3_mprintf("%s-oal", zBase);
158108
+
158109
+ assert( p->eStage==OTA_STAGE_MOVE );
158110
+ assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
158111
+ if( zWal==0 || zOal==0 ){
158112
+ p->rc = SQLITE_NOMEM;
158113
+ }else{
158114
+ /* Move the *-oal file to *-wal. At this point connection p->db is
158115
+ ** holding a SHARED lock on the target database file (because it is
158116
+ ** in WAL mode). So no other connection may be writing the db.
158117
+ **
158118
+ ** In order to ensure that there are no database readers, an EXCLUSIVE
158119
+ ** lock is obtained here before the *-oal is moved to *-wal.
158120
+ */
158121
+ otaLockDatabase(p);
158122
+ if( p->rc==SQLITE_OK ){
158123
+ otaFileSuffix3(zBase, zWal);
158124
+ otaFileSuffix3(zBase, zOal);
158125
+
158126
+ /* Re-open the databases. */
158127
+ otaObjIterFinalize(&p->objiter);
158128
+ sqlite3_close(p->dbMain);
158129
+ sqlite3_close(p->dbOta);
158130
+ p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
158131
+ if( p->rc==SQLITE_OK ){
158132
+ p->dbMain = 0;
158133
+ p->dbOta = 0;
158134
+ otaOpenDatabase(p);
158135
+ otaSetupCheckpoint(p, 0);
158136
+ }
158137
+ }
158138
+ }
158139
+
158140
+ sqlite3_free(zWal);
158141
+ sqlite3_free(zOal);
158142
+}
158143
+
158144
+/*
158145
+** The SELECT statement iterating through the keys for the current object
158146
+** (p->objiter.pSelect) currently points to a valid row. This function
158147
+** determines the type of operation requested by this row and returns
158148
+** one of the following values to indicate the result:
158149
+**
158150
+** * OTA_INSERT
158151
+** * OTA_DELETE
158152
+** * OTA_IDX_DELETE
158153
+** * OTA_UPDATE
158154
+**
158155
+** If OTA_UPDATE is returned, then output variable *pzMask is set to
158156
+** point to the text value indicating the columns to update.
158157
+**
158158
+** If the ota_control field contains an invalid value, an error code and
158159
+** message are left in the OTA handle and zero returned.
158160
+*/
158161
+static int otaStepType(sqlite3ota *p, const char **pzMask){
158162
+ int iCol = p->objiter.nCol; /* Index of ota_control column */
158163
+ int res = 0; /* Return value */
158164
+
158165
+ switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
158166
+ case SQLITE_INTEGER: {
158167
+ int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
158168
+ if( iVal==0 ){
158169
+ res = OTA_INSERT;
158170
+ }else if( iVal==1 ){
158171
+ res = OTA_DELETE;
158172
+ }else if( iVal==2 ){
158173
+ res = OTA_IDX_DELETE;
158174
+ }else if( iVal==3 ){
158175
+ res = OTA_IDX_INSERT;
158176
+ }
158177
+ break;
158178
+ }
158179
+
158180
+ case SQLITE_TEXT: {
158181
+ const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
158182
+ if( z==0 ){
158183
+ p->rc = SQLITE_NOMEM;
158184
+ }else{
158185
+ *pzMask = (const char*)z;
158186
+ }
158187
+ res = OTA_UPDATE;
158188
+
158189
+ break;
158190
+ }
158191
+
158192
+ default:
158193
+ break;
158194
+ }
158195
+
158196
+ if( res==0 ){
158197
+ otaBadControlError(p);
158198
+ }
158199
+ return res;
158200
+}
158201
+
158202
+#ifdef SQLITE_DEBUG
158203
+/*
158204
+** Assert that column iCol of statement pStmt is named zName.
158205
+*/
158206
+static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
158207
+ const char *zCol = sqlite3_column_name(pStmt, iCol);
158208
+ assert( 0==sqlite3_stricmp(zName, zCol) );
158209
+}
158210
+#else
158211
+# define assertColumnName(x,y,z)
158212
+#endif
158213
+
158214
+/*
158215
+** This function does the work for an sqlite3ota_step() call.
158216
+**
158217
+** The object-iterator (p->objiter) currently points to a valid object,
158218
+** and the input cursor (p->objiter.pSelect) currently points to a valid
158219
+** input row. Perform whatever processing is required and return.
158220
+**
158221
+** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
158222
+** and message is left in the OTA handle and a copy of the error code
158223
+** returned.
158224
+*/
158225
+static int otaStep(sqlite3ota *p){
158226
+ OtaObjIter *pIter = &p->objiter;
158227
+ const char *zMask = 0;
158228
+ int i;
158229
+ int eType = otaStepType(p, &zMask);
158230
+
158231
+ if( eType ){
158232
+ assert( eType!=OTA_UPDATE || pIter->zIdx==0 );
158233
+
158234
+ if( pIter->zIdx==0 && eType==OTA_IDX_DELETE ){
158235
+ otaBadControlError(p);
158236
+ }
158237
+ else if(
158238
+ eType==OTA_INSERT
158239
+ || eType==OTA_DELETE
158240
+ || eType==OTA_IDX_DELETE
158241
+ || eType==OTA_IDX_INSERT
158242
+ ){
158243
+ sqlite3_value *pVal;
158244
+ sqlite3_stmt *pWriter;
158245
+
158246
+ assert( eType!=OTA_UPDATE );
158247
+ assert( eType!=OTA_DELETE || pIter->zIdx==0 );
158248
+
158249
+ if( eType==OTA_IDX_DELETE || eType==OTA_DELETE ){
158250
+ pWriter = pIter->pDelete;
158251
+ }else{
158252
+ pWriter = pIter->pInsert;
158253
+ }
158254
+
158255
+ for(i=0; i<pIter->nCol; i++){
158256
+ /* If this is an INSERT into a table b-tree and the table has an
158257
+ ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
158258
+ ** to write a NULL into the IPK column. That is not permitted. */
158259
+ if( eType==OTA_INSERT
158260
+ && pIter->zIdx==0 && pIter->eType==OTA_PK_IPK && pIter->abTblPk[i]
158261
+ && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
158262
+ ){
158263
+ p->rc = SQLITE_MISMATCH;
158264
+ p->zErrmsg = sqlite3_mprintf("datatype mismatch");
158265
+ goto step_out;
158266
+ }
158267
+
158268
+ if( eType==OTA_DELETE && pIter->abTblPk[i]==0 ){
158269
+ continue;
158270
+ }
158271
+
158272
+ pVal = sqlite3_column_value(pIter->pSelect, i);
158273
+ p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
158274
+ if( p->rc ) goto step_out;
158275
+ }
158276
+ if( pIter->zIdx==0
158277
+ && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
158278
+ ){
158279
+ /* For a virtual table, or a table with no primary key, the
158280
+ ** SELECT statement is:
158281
+ **
158282
+ ** SELECT <cols>, ota_control, ota_rowid FROM ....
158283
+ **
158284
+ ** Hence column_value(pIter->nCol+1).
158285
+ */
158286
+ assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
158287
+ pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
158288
+ p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
158289
+ }
158290
+ if( p->rc==SQLITE_OK ){
158291
+ sqlite3_step(pWriter);
158292
+ p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
158293
+ }
158294
+ }else{
158295
+ sqlite3_value *pVal;
158296
+ sqlite3_stmt *pUpdate = 0;
158297
+ assert( eType==OTA_UPDATE );
158298
+ otaGetUpdateStmt(p, pIter, zMask, &pUpdate);
158299
+ if( pUpdate ){
158300
+ for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
158301
+ char c = zMask[pIter->aiSrcOrder[i]];
158302
+ pVal = sqlite3_column_value(pIter->pSelect, i);
158303
+ if( pIter->abTblPk[i] || c=='x' || c=='d' ){
158304
+ p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
158305
+ }
158306
+ }
158307
+ if( p->rc==SQLITE_OK
158308
+ && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
158309
+ ){
158310
+ /* Bind the ota_rowid value to column _rowid_ */
158311
+ assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
158312
+ pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
158313
+ p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
158314
+ }
158315
+ if( p->rc==SQLITE_OK ){
158316
+ sqlite3_step(pUpdate);
158317
+ p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
158318
+ }
158319
+ }
158320
+ }
158321
+ }
158322
+
158323
+ step_out:
158324
+ return p->rc;
158325
+}
158326
+
158327
+/*
158328
+** Increment the schema cookie of the main database opened by p->dbMain.
158329
+*/
158330
+static void otaIncrSchemaCookie(sqlite3ota *p){
158331
+ if( p->rc==SQLITE_OK ){
158332
+ int iCookie = 1000000;
158333
+ sqlite3_stmt *pStmt;
158334
+
158335
+ p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
158336
+ "PRAGMA schema_version"
158337
+ );
158338
+ if( p->rc==SQLITE_OK ){
158339
+ /* Coverage: it may be that this sqlite3_step() cannot fail. There
158340
+ ** is already a transaction open, so the prepared statement cannot
158341
+ ** throw an SQLITE_SCHEMA exception. The only database page the
158342
+ ** statement reads is page 1, which is guaranteed to be in the cache.
158343
+ ** And no memory allocations are required. */
158344
+ if( SQLITE_ROW==sqlite3_step(pStmt) ){
158345
+ iCookie = sqlite3_column_int(pStmt, 0);
158346
+ }
158347
+ otaFinalize(p, pStmt);
158348
+ }
158349
+ if( p->rc==SQLITE_OK ){
158350
+ otaMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1);
158351
+ }
158352
+ }
158353
+}
158354
+
158355
+/*
158356
+** Update the contents of the ota_state table within the ota database. The
158357
+** value stored in the OTA_STATE_STAGE column is eStage. All other values
158358
+** are determined by inspecting the ota handle passed as the first argument.
158359
+*/
158360
+static void otaSaveState(sqlite3ota *p, int eStage){
158361
+ if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
158362
+ sqlite3_stmt *pInsert = 0;
158363
+ int rc;
158364
+
158365
+ assert( p->zErrmsg==0 );
158366
+ rc = prepareFreeAndCollectError(p->dbOta, &pInsert, &p->zErrmsg,
158367
+ sqlite3_mprintf(
158368
+ "INSERT OR REPLACE INTO %s.ota_state(k, v) VALUES "
158369
+ "(%d, %d), "
158370
+ "(%d, %Q), "
158371
+ "(%d, %Q), "
158372
+ "(%d, %d), "
158373
+ "(%d, %d), "
158374
+ "(%d, %lld), "
158375
+ "(%d, %lld), "
158376
+ "(%d, %lld) ",
158377
+ p->zStateDb,
158378
+ OTA_STATE_STAGE, eStage,
158379
+ OTA_STATE_TBL, p->objiter.zTbl,
158380
+ OTA_STATE_IDX, p->objiter.zIdx,
158381
+ OTA_STATE_ROW, p->nStep,
158382
+ OTA_STATE_PROGRESS, p->nProgress,
158383
+ OTA_STATE_CKPT, p->iWalCksum,
158384
+ OTA_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
158385
+ OTA_STATE_OALSZ, p->iOalSz
158386
+ )
158387
+ );
158388
+ assert( pInsert==0 || rc==SQLITE_OK );
158389
+
158390
+ if( rc==SQLITE_OK ){
158391
+ sqlite3_step(pInsert);
158392
+ rc = sqlite3_finalize(pInsert);
158393
+ }
158394
+ if( rc!=SQLITE_OK ) p->rc = rc;
158395
+ }
158396
+}
158397
+
158398
+
158399
+/*
158400
+** Step the OTA object.
158401
+*/
158402
+SQLITE_API int SQLITE_STDCALL sqlite3ota_step(sqlite3ota *p){
158403
+ if( p ){
158404
+ switch( p->eStage ){
158405
+ case OTA_STAGE_OAL: {
158406
+ OtaObjIter *pIter = &p->objiter;
158407
+ while( p->rc==SQLITE_OK && pIter->zTbl ){
158408
+
158409
+ if( pIter->bCleanup ){
158410
+ /* Clean up the ota_tmp_xxx table for the previous table. It
158411
+ ** cannot be dropped as there are currently active SQL statements.
158412
+ ** But the contents can be deleted. */
158413
+ if( pIter->abIndexed ){
158414
+ otaMPrintfExec(p, p->dbOta,
158415
+ "DELETE FROM %s.'ota_tmp_%q'", p->zStateDb, pIter->zTbl
158416
+ );
158417
+ }
158418
+ }else{
158419
+ otaObjIterPrepareAll(p, pIter, 0);
158420
+
158421
+ /* Advance to the next row to process. */
158422
+ if( p->rc==SQLITE_OK ){
158423
+ int rc = sqlite3_step(pIter->pSelect);
158424
+ if( rc==SQLITE_ROW ){
158425
+ p->nProgress++;
158426
+ p->nStep++;
158427
+ return otaStep(p);
158428
+ }
158429
+ p->rc = sqlite3_reset(pIter->pSelect);
158430
+ p->nStep = 0;
158431
+ }
158432
+ }
158433
+
158434
+ otaObjIterNext(p, pIter);
158435
+ }
158436
+
158437
+ if( p->rc==SQLITE_OK ){
158438
+ assert( pIter->zTbl==0 );
158439
+ otaSaveState(p, OTA_STAGE_MOVE);
158440
+ otaIncrSchemaCookie(p);
158441
+ if( p->rc==SQLITE_OK ){
158442
+ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
158443
+ }
158444
+ if( p->rc==SQLITE_OK ){
158445
+ p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
158446
+ }
158447
+ p->eStage = OTA_STAGE_MOVE;
158448
+ }
158449
+ break;
158450
+ }
158451
+
158452
+ case OTA_STAGE_MOVE: {
158453
+ if( p->rc==SQLITE_OK ){
158454
+ otaMoveOalFile(p);
158455
+ p->nProgress++;
158456
+ }
158457
+ break;
158458
+ }
158459
+
158460
+ case OTA_STAGE_CKPT: {
158461
+ if( p->rc==SQLITE_OK ){
158462
+ if( p->nStep>=p->nFrame ){
158463
+ sqlite3_file *pDb = p->pTargetFd->pReal;
158464
+
158465
+ /* Sync the db file */
158466
+ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
158467
+
158468
+ /* Update nBackfill */
158469
+ if( p->rc==SQLITE_OK ){
158470
+ void volatile *ptr;
158471
+ p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr);
158472
+ if( p->rc==SQLITE_OK ){
158473
+ ((u32 volatile*)ptr)[24] = p->iMaxFrame;
158474
+ }
158475
+ }
158476
+
158477
+ if( p->rc==SQLITE_OK ){
158478
+ p->eStage = OTA_STAGE_DONE;
158479
+ p->rc = SQLITE_DONE;
158480
+ }
158481
+ }else{
158482
+ OtaFrame *pFrame = &p->aFrame[p->nStep];
158483
+ otaCheckpointFrame(p, pFrame);
158484
+ p->nStep++;
158485
+ }
158486
+ p->nProgress++;
158487
+ }
158488
+ break;
158489
+ }
158490
+
158491
+ default:
158492
+ break;
158493
+ }
158494
+ return p->rc;
158495
+ }else{
158496
+ return SQLITE_NOMEM;
158497
+ }
158498
+}
158499
+
158500
+/*
158501
+** Free an OtaState object allocated by otaLoadState().
158502
+*/
158503
+static void otaFreeState(OtaState *p){
158504
+ if( p ){
158505
+ sqlite3_free(p->zTbl);
158506
+ sqlite3_free(p->zIdx);
158507
+ sqlite3_free(p);
158508
+ }
158509
+}
158510
+
158511
+/*
158512
+** Allocate an OtaState object and load the contents of the ota_state
158513
+** table into it. Return a pointer to the new object. It is the
158514
+** responsibility of the caller to eventually free the object using
158515
+** sqlite3_free().
158516
+**
158517
+** If an error occurs, leave an error code and message in the ota handle
158518
+** and return NULL.
158519
+*/
158520
+static OtaState *otaLoadState(sqlite3ota *p){
158521
+ OtaState *pRet = 0;
158522
+ sqlite3_stmt *pStmt = 0;
158523
+ int rc;
158524
+ int rc2;
158525
+
158526
+ pRet = (OtaState*)otaMalloc(p, sizeof(OtaState));
158527
+ if( pRet==0 ) return 0;
158528
+
158529
+ rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg,
158530
+ sqlite3_mprintf("SELECT k, v FROM %s.ota_state", p->zStateDb)
158531
+ );
158532
+ while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
158533
+ switch( sqlite3_column_int(pStmt, 0) ){
158534
+ case OTA_STATE_STAGE:
158535
+ pRet->eStage = sqlite3_column_int(pStmt, 1);
158536
+ if( pRet->eStage!=OTA_STAGE_OAL
158537
+ && pRet->eStage!=OTA_STAGE_MOVE
158538
+ && pRet->eStage!=OTA_STAGE_CKPT
158539
+ ){
158540
+ p->rc = SQLITE_CORRUPT;
158541
+ }
158542
+ break;
158543
+
158544
+ case OTA_STATE_TBL:
158545
+ pRet->zTbl = otaStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
158546
+ break;
158547
+
158548
+ case OTA_STATE_IDX:
158549
+ pRet->zIdx = otaStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
158550
+ break;
158551
+
158552
+ case OTA_STATE_ROW:
158553
+ pRet->nRow = sqlite3_column_int(pStmt, 1);
158554
+ break;
158555
+
158556
+ case OTA_STATE_PROGRESS:
158557
+ pRet->nProgress = sqlite3_column_int64(pStmt, 1);
158558
+ break;
158559
+
158560
+ case OTA_STATE_CKPT:
158561
+ pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
158562
+ break;
158563
+
158564
+ case OTA_STATE_COOKIE:
158565
+ pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
158566
+ break;
158567
+
158568
+ case OTA_STATE_OALSZ:
158569
+ pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
158570
+ break;
158571
+
158572
+ default:
158573
+ rc = SQLITE_CORRUPT;
158574
+ break;
158575
+ }
158576
+ }
158577
+ rc2 = sqlite3_finalize(pStmt);
158578
+ if( rc==SQLITE_OK ) rc = rc2;
158579
+
158580
+ p->rc = rc;
158581
+ return pRet;
158582
+}
158583
+
158584
+/*
158585
+** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
158586
+** otherwise. Either or both argument may be NULL. Two NULL values are
158587
+** considered equal, and NULL is considered distinct from all other values.
158588
+*/
158589
+static int otaStrCompare(const char *z1, const char *z2){
158590
+ if( z1==0 && z2==0 ) return 0;
158591
+ if( z1==0 || z2==0 ) return 1;
158592
+ return (sqlite3_stricmp(z1, z2)!=0);
158593
+}
158594
+
158595
+/*
158596
+** This function is called as part of sqlite3ota_open() when initializing
158597
+** an ota handle in OAL stage. If the ota update has not started (i.e.
158598
+** the ota_state table was empty) it is a no-op. Otherwise, it arranges
158599
+** things so that the next call to sqlite3ota_step() continues on from
158600
+** where the previous ota handle left off.
158601
+**
158602
+** If an error occurs, an error code and error message are left in the
158603
+** ota handle passed as the first argument.
158604
+*/
158605
+static void otaSetupOal(sqlite3ota *p, OtaState *pState){
158606
+ assert( p->rc==SQLITE_OK );
158607
+ if( pState->zTbl ){
158608
+ OtaObjIter *pIter = &p->objiter;
158609
+ int rc = SQLITE_OK;
158610
+
158611
+ while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup
158612
+ || otaStrCompare(pIter->zIdx, pState->zIdx)
158613
+ || otaStrCompare(pIter->zTbl, pState->zTbl)
158614
+ )){
158615
+ rc = otaObjIterNext(p, pIter);
158616
+ }
158617
+
158618
+ if( rc==SQLITE_OK && !pIter->zTbl ){
158619
+ rc = SQLITE_ERROR;
158620
+ p->zErrmsg = sqlite3_mprintf("ota_state mismatch error");
158621
+ }
158622
+
158623
+ if( rc==SQLITE_OK ){
158624
+ p->nStep = pState->nRow;
158625
+ rc = otaObjIterPrepareAll(p, &p->objiter, p->nStep);
158626
+ }
158627
+
158628
+ p->rc = rc;
158629
+ }
158630
+}
158631
+
158632
+/*
158633
+** If there is a "*-oal" file in the file-system corresponding to the
158634
+** target database in the file-system, delete it. If an error occurs,
158635
+** leave an error code and error message in the ota handle.
158636
+*/
158637
+static void otaDeleteOalFile(sqlite3ota *p){
158638
+ char *zOal = sqlite3_mprintf("%s-oal", p->zTarget);
158639
+ assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
158640
+ unlink(zOal);
158641
+ sqlite3_free(zOal);
158642
+}
158643
+
158644
+/*
158645
+** Allocate a private ota VFS for the ota handle passed as the only
158646
+** argument. This VFS will be used unless the call to sqlite3ota_open()
158647
+** specified a URI with a vfs=? option in place of a target database
158648
+** file name.
158649
+*/
158650
+static void otaCreateVfs(sqlite3ota *p){
158651
+ int rnd;
158652
+ char zRnd[64];
158653
+
158654
+ assert( p->rc==SQLITE_OK );
158655
+ sqlite3_randomness(sizeof(int), (void*)&rnd);
158656
+ sprintf(zRnd, "ota_vfs_%d", rnd);
158657
+ p->rc = sqlite3ota_create_vfs(zRnd, 0);
158658
+ if( p->rc==SQLITE_OK ){
158659
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
158660
+ assert( pVfs );
158661
+ p->zVfsName = pVfs->zName;
158662
+ }
158663
+}
158664
+
158665
+/*
158666
+** Destroy the private VFS created for the ota handle passed as the only
158667
+** argument by an earlier call to otaCreateVfs().
158668
+*/
158669
+static void otaDeleteVfs(sqlite3ota *p){
158670
+ if( p->zVfsName ){
158671
+ sqlite3ota_destroy_vfs(p->zVfsName);
158672
+ p->zVfsName = 0;
158673
+ }
158674
+}
158675
+
158676
+/*
158677
+** Open and return a new OTA handle.
158678
+*/
158679
+SQLITE_API sqlite3ota *SQLITE_STDCALL sqlite3ota_open(
158680
+ const char *zTarget,
158681
+ const char *zOta,
158682
+ const char *zState
158683
+){
158684
+ sqlite3ota *p;
158685
+ int nTarget = strlen(zTarget);
158686
+ int nOta = strlen(zOta);
158687
+ int nState = zState ? strlen(zState) : 0;
158688
+
158689
+ p = (sqlite3ota*)sqlite3_malloc(sizeof(sqlite3ota)+nTarget+1+nOta+1+nState+1);
158690
+ if( p ){
158691
+ OtaState *pState = 0;
158692
+
158693
+ /* Create the custom VFS. */
158694
+ memset(p, 0, sizeof(sqlite3ota));
158695
+ otaCreateVfs(p);
158696
+
158697
+ /* Open the target database */
158698
+ if( p->rc==SQLITE_OK ){
158699
+ p->zTarget = (char*)&p[1];
158700
+ memcpy(p->zTarget, zTarget, nTarget+1);
158701
+ p->zOta = &p->zTarget[nTarget+1];
158702
+ memcpy(p->zOta, zOta, nOta+1);
158703
+ if( zState ){
158704
+ p->zState = &p->zOta[nOta+1];
158705
+ memcpy(p->zState, zState, nState+1);
158706
+ }
158707
+ otaOpenDatabase(p);
158708
+ }
158709
+
158710
+ /* If it has not already been created, create the ota_state table */
158711
+ otaMPrintfExec(p, p->dbOta, OTA_CREATE_STATE, p->zStateDb);
158712
+
158713
+ if( p->rc==SQLITE_OK ){
158714
+ pState = otaLoadState(p);
158715
+ assert( pState || p->rc!=SQLITE_OK );
158716
+ if( p->rc==SQLITE_OK ){
158717
+
158718
+ if( pState->eStage==0 ){
158719
+ otaDeleteOalFile(p);
158720
+ p->eStage = OTA_STAGE_OAL;
158721
+ }else{
158722
+ p->eStage = pState->eStage;
158723
+ }
158724
+ p->nProgress = pState->nProgress;
158725
+ p->iOalSz = pState->iOalSz;
158726
+ }
158727
+ }
158728
+ assert( p->rc!=SQLITE_OK || p->eStage!=0 );
158729
+
158730
+ if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
158731
+ if( p->eStage==OTA_STAGE_OAL ){
158732
+ p->rc = SQLITE_ERROR;
158733
+ p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
158734
+ }else if( p->eStage==OTA_STAGE_MOVE ){
158735
+ p->eStage = OTA_STAGE_CKPT;
158736
+ p->nStep = 0;
158737
+ }
158738
+ }
158739
+
158740
+ if( p->rc==SQLITE_OK
158741
+ && (p->eStage==OTA_STAGE_OAL || p->eStage==OTA_STAGE_MOVE)
158742
+ && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
158743
+ ){
158744
+ /* At this point (pTargetFd->iCookie) contains the value of the
158745
+ ** change-counter cookie (the thing that gets incremented when a
158746
+ ** transaction is committed in rollback mode) currently stored on
158747
+ ** page 1 of the database file. */
158748
+ p->rc = SQLITE_BUSY;
158749
+ p->zErrmsg = sqlite3_mprintf("database modified during ota update");
158750
+ }
158751
+
158752
+ if( p->rc==SQLITE_OK ){
158753
+ if( p->eStage==OTA_STAGE_OAL ){
158754
+
158755
+ /* Open transactions both databases. The *-oal file is opened or
158756
+ ** created at this point. */
158757
+ p->rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
158758
+ if( p->rc==SQLITE_OK ){
158759
+ p->rc = sqlite3_exec(p->dbOta, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
158760
+ }
158761
+
158762
+ /* Point the object iterator at the first object */
158763
+ if( p->rc==SQLITE_OK ){
158764
+ p->rc = otaObjIterFirst(p, &p->objiter);
158765
+ }
158766
+
158767
+ /* If the OTA database contains no data_xxx tables, declare the OTA
158768
+ ** update finished. */
158769
+ if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
158770
+ p->rc = SQLITE_DONE;
158771
+ }
158772
+
158773
+ if( p->rc==SQLITE_OK ){
158774
+ otaSetupOal(p, pState);
158775
+ }
158776
+
158777
+ }else if( p->eStage==OTA_STAGE_MOVE ){
158778
+ /* no-op */
158779
+ }else if( p->eStage==OTA_STAGE_CKPT ){
158780
+ otaSetupCheckpoint(p, pState);
158781
+ }else if( p->eStage==OTA_STAGE_DONE ){
158782
+ p->rc = SQLITE_DONE;
158783
+ }else{
158784
+ p->rc = SQLITE_CORRUPT;
158785
+ }
158786
+ }
158787
+
158788
+ otaFreeState(pState);
158789
+ }
158790
+
158791
+ return p;
158792
+}
158793
+
158794
+
158795
+/*
158796
+** Return the database handle used by pOta.
158797
+*/
158798
+SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3ota_db(sqlite3ota *pOta, int bOta){
158799
+ sqlite3 *db = 0;
158800
+ if( pOta ){
158801
+ db = (bOta ? pOta->dbOta : pOta->dbMain);
158802
+ }
158803
+ return db;
158804
+}
158805
+
158806
+
158807
+/*
158808
+** If the error code currently stored in the OTA handle is SQLITE_CONSTRAINT,
158809
+** then edit any error message string so as to remove all occurrences of
158810
+** the pattern "ota_imp_[0-9]*".
158811
+*/
158812
+static void otaEditErrmsg(sqlite3ota *p){
158813
+ if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
158814
+ int i;
158815
+ int nErrmsg = strlen(p->zErrmsg);
158816
+ for(i=0; i<(nErrmsg-8); i++){
158817
+ if( memcmp(&p->zErrmsg[i], "ota_imp_", 8)==0 ){
158818
+ int nDel = 8;
158819
+ while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++;
158820
+ memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel);
158821
+ nErrmsg -= nDel;
158822
+ }
158823
+ }
158824
+ }
158825
+}
158826
+
158827
+/*
158828
+** Close the OTA handle.
158829
+*/
158830
+SQLITE_API int SQLITE_STDCALL sqlite3ota_close(sqlite3ota *p, char **pzErrmsg){
158831
+ int rc;
158832
+ if( p ){
158833
+
158834
+ /* Commit the transaction to the *-oal file. */
158835
+ if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_OAL ){
158836
+ p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
158837
+ }
158838
+
158839
+ otaSaveState(p, p->eStage);
158840
+
158841
+ if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_OAL ){
158842
+ p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
158843
+ }
158844
+
158845
+ /* Close any open statement handles. */
158846
+ otaObjIterFinalize(&p->objiter);
158847
+
158848
+ /* Close the open database handle and VFS object. */
158849
+ sqlite3_close(p->dbMain);
158850
+ sqlite3_close(p->dbOta);
158851
+ otaDeleteVfs(p);
158852
+ sqlite3_free(p->aBuf);
158853
+ sqlite3_free(p->aFrame);
158854
+
158855
+ otaEditErrmsg(p);
158856
+ rc = p->rc;
158857
+ *pzErrmsg = p->zErrmsg;
158858
+ sqlite3_free(p);
158859
+ }else{
158860
+ rc = SQLITE_NOMEM;
158861
+ *pzErrmsg = 0;
158862
+ }
158863
+ return rc;
158864
+}
158865
+
158866
+/*
158867
+** Return the total number of key-value operations (inserts, deletes or
158868
+** updates) that have been performed on the target database since the
158869
+** current OTA update was started.
158870
+*/
158871
+SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3ota_progress(sqlite3ota *pOta){
158872
+ return pOta->nProgress;
158873
+}
158874
+
158875
+/**************************************************************************
158876
+** Beginning of OTA VFS shim methods. The VFS shim modifies the behaviour
158877
+** of a standard VFS in the following ways:
158878
+**
158879
+** 1. Whenever the first page of a main database file is read or
158880
+** written, the value of the change-counter cookie is stored in
158881
+** ota_file.iCookie. Similarly, the value of the "write-version"
158882
+** database header field is stored in ota_file.iWriteVer. This ensures
158883
+** that the values are always trustworthy within an open transaction.
158884
+**
158885
+** 2. Whenever an SQLITE_OPEN_WAL file is opened, the (ota_file.pWalFd)
158886
+** member variable of the associated database file descriptor is set
158887
+** to point to the new file. A mutex protected linked list of all main
158888
+** db fds opened using a particular OTA VFS is maintained at
158889
+** ota_vfs.pMain to facilitate this.
158890
+**
158891
+** 3. Using a new file-control "SQLITE_FCNTL_OTA", a main db ota_file
158892
+** object can be marked as the target database of an OTA update. This
158893
+** turns on the following extra special behaviour:
158894
+**
158895
+** 3a. If xAccess() is called to check if there exists a *-wal file
158896
+** associated with an OTA target database currently in OTA_STAGE_OAL
158897
+** stage (preparing the *-oal file), the following special handling
158898
+** applies:
158899
+**
158900
+** * if the *-wal file does exist, return SQLITE_CANTOPEN. An OTA
158901
+** target database may not be in wal mode already.
158902
+**
158903
+** * if the *-wal file does not exist, set the output parameter to
158904
+** non-zero (to tell SQLite that it does exist) anyway.
158905
+**
158906
+** Then, when xOpen() is called to open the *-wal file associated with
158907
+** the OTA target in OTA_STAGE_OAL stage, instead of opening the *-wal
158908
+** file, the ota vfs opens the corresponding *-oal file instead.
158909
+**
158910
+** 3b. The *-shm pages returned by xShmMap() for a target db file in
158911
+** OTA_STAGE_OAL mode are actually stored in heap memory. This is to
158912
+** avoid creating a *-shm file on disk. Additionally, xShmLock() calls
158913
+** are no-ops on target database files in OTA_STAGE_OAL mode. This is
158914
+** because assert() statements in some VFS implementations fail if
158915
+** xShmLock() is called before xShmMap().
158916
+**
158917
+** 3c. If an EXCLUSIVE lock is attempted on a target database file in any
158918
+** mode except OTA_STAGE_DONE (all work completed and checkpointed), it
158919
+** fails with an SQLITE_BUSY error. This is to stop OTA connections
158920
+** from automatically checkpointing a *-wal (or *-oal) file from within
158921
+** sqlite3_close().
158922
+**
158923
+** 3d. In OTA_STAGE_CAPTURE mode, all xRead() calls on the wal file, and
158924
+** all xWrite() calls on the target database file perform no IO.
158925
+** Instead the frame and page numbers that would be read and written
158926
+** are recorded. Additionally, successful attempts to obtain exclusive
158927
+** xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target
158928
+** database file are recorded. xShmLock() calls to unlock the same
158929
+** locks are no-ops (so that once obtained, these locks are never
158930
+** relinquished). Finally, calls to xSync() on the target database
158931
+** file fail with SQLITE_INTERNAL errors.
158932
+*/
158933
+
158934
+static void otaUnlockShm(ota_file *p){
158935
+ if( p->pOta ){
158936
+ int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
158937
+ int i;
158938
+ for(i=0; i<SQLITE_SHM_NLOCK;i++){
158939
+ if( (1<<i) & p->pOta->mLock ){
158940
+ xShmLock(p->pReal, i, 1, SQLITE_SHM_UNLOCK|SQLITE_SHM_EXCLUSIVE);
158941
+ }
158942
+ }
158943
+ p->pOta->mLock = 0;
158944
+ }
158945
+}
158946
+
158947
+/*
158948
+** Close an ota file.
158949
+*/
158950
+static int otaVfsClose(sqlite3_file *pFile){
158951
+ ota_file *p = (ota_file*)pFile;
158952
+ int rc;
158953
+ int i;
158954
+
158955
+ /* Free the contents of the apShm[] array. And the array itself. */
158956
+ for(i=0; i<p->nShm; i++){
158957
+ sqlite3_free(p->apShm[i]);
158958
+ }
158959
+ sqlite3_free(p->apShm);
158960
+ p->apShm = 0;
158961
+ sqlite3_free(p->zDel);
158962
+
158963
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
158964
+ ota_file **pp;
158965
+ sqlite3_mutex_enter(p->pOtaVfs->mutex);
158966
+ for(pp=&p->pOtaVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
158967
+ *pp = p->pMainNext;
158968
+ sqlite3_mutex_leave(p->pOtaVfs->mutex);
158969
+ otaUnlockShm(p);
158970
+ p->pReal->pMethods->xShmUnmap(p->pReal, 0);
158971
+ }
158972
+
158973
+ /* Close the underlying file handle */
158974
+ rc = p->pReal->pMethods->xClose(p->pReal);
158975
+ return rc;
158976
+}
158977
+
158978
+
158979
+/*
158980
+** Read and return an unsigned 32-bit big-endian integer from the buffer
158981
+** passed as the only argument.
158982
+*/
158983
+static u32 otaGetU32(u8 *aBuf){
158984
+ return ((u32)aBuf[0] << 24)
158985
+ + ((u32)aBuf[1] << 16)
158986
+ + ((u32)aBuf[2] << 8)
158987
+ + ((u32)aBuf[3]);
158988
+}
158989
+
158990
+/*
158991
+** Read data from an otaVfs-file.
158992
+*/
158993
+static int otaVfsRead(
158994
+ sqlite3_file *pFile,
158995
+ void *zBuf,
158996
+ int iAmt,
158997
+ sqlite_int64 iOfst
158998
+){
158999
+ ota_file *p = (ota_file*)pFile;
159000
+ sqlite3ota *pOta = p->pOta;
159001
+ int rc;
159002
+
159003
+ if( pOta && pOta->eStage==OTA_STAGE_CAPTURE ){
159004
+ assert( p->openFlags & SQLITE_OPEN_WAL );
159005
+ rc = otaCaptureWalRead(p->pOta, iOfst, iAmt);
159006
+ }else{
159007
+ if( pOta && pOta->eStage==OTA_STAGE_OAL
159008
+ && (p->openFlags & SQLITE_OPEN_WAL)
159009
+ && iOfst>=pOta->iOalSz
159010
+ ){
159011
+ rc = SQLITE_OK;
159012
+ memset(zBuf, 0, iAmt);
159013
+ }else{
159014
+ rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
159015
+ }
159016
+ if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
159017
+ /* These look like magic numbers. But they are stable, as they are part
159018
+ ** of the definition of the SQLite file format, which may not change. */
159019
+ u8 *pBuf = (u8*)zBuf;
159020
+ p->iCookie = otaGetU32(&pBuf[24]);
159021
+ p->iWriteVer = pBuf[19];
159022
+ }
159023
+ }
159024
+ return rc;
159025
+}
159026
+
159027
+/*
159028
+** Write data to an otaVfs-file.
159029
+*/
159030
+static int otaVfsWrite(
159031
+ sqlite3_file *pFile,
159032
+ const void *zBuf,
159033
+ int iAmt,
159034
+ sqlite_int64 iOfst
159035
+){
159036
+ ota_file *p = (ota_file*)pFile;
159037
+ sqlite3ota *pOta = p->pOta;
159038
+ int rc;
159039
+
159040
+ if( pOta && pOta->eStage==OTA_STAGE_CAPTURE ){
159041
+ assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
159042
+ rc = otaCaptureDbWrite(p->pOta, iOfst);
159043
+ }else{
159044
+ if( pOta && pOta->eStage==OTA_STAGE_OAL
159045
+ && (p->openFlags & SQLITE_OPEN_WAL)
159046
+ && iOfst>=pOta->iOalSz
159047
+ ){
159048
+ pOta->iOalSz = iAmt + iOfst;
159049
+ }
159050
+ rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
159051
+ if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
159052
+ /* These look like magic numbers. But they are stable, as they are part
159053
+ ** of the definition of the SQLite file format, which may not change. */
159054
+ u8 *pBuf = (u8*)zBuf;
159055
+ p->iCookie = otaGetU32(&pBuf[24]);
159056
+ p->iWriteVer = pBuf[19];
159057
+ }
159058
+ }
159059
+ return rc;
159060
+}
159061
+
159062
+/*
159063
+** Truncate an otaVfs-file.
159064
+*/
159065
+static int otaVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
159066
+ ota_file *p = (ota_file*)pFile;
159067
+ return p->pReal->pMethods->xTruncate(p->pReal, size);
159068
+}
159069
+
159070
+/*
159071
+** Sync an otaVfs-file.
159072
+*/
159073
+static int otaVfsSync(sqlite3_file *pFile, int flags){
159074
+ ota_file *p = (ota_file *)pFile;
159075
+ if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){
159076
+ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
159077
+ return SQLITE_INTERNAL;
159078
+ }
159079
+ return SQLITE_OK;
159080
+ }
159081
+ return p->pReal->pMethods->xSync(p->pReal, flags);
159082
+}
159083
+
159084
+/*
159085
+** Return the current file-size of an otaVfs-file.
159086
+*/
159087
+static int otaVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
159088
+ ota_file *p = (ota_file *)pFile;
159089
+ return p->pReal->pMethods->xFileSize(p->pReal, pSize);
159090
+}
159091
+
159092
+/*
159093
+** Lock an otaVfs-file.
159094
+*/
159095
+static int otaVfsLock(sqlite3_file *pFile, int eLock){
159096
+ ota_file *p = (ota_file*)pFile;
159097
+ sqlite3ota *pOta = p->pOta;
159098
+ int rc = SQLITE_OK;
159099
+
159100
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159101
+ if( pOta && eLock==SQLITE_LOCK_EXCLUSIVE && pOta->eStage!=OTA_STAGE_DONE ){
159102
+ /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this
159103
+ ** prevents it from checkpointing the database from sqlite3_close(). */
159104
+ rc = SQLITE_BUSY;
159105
+ }else{
159106
+ rc = p->pReal->pMethods->xLock(p->pReal, eLock);
159107
+ }
159108
+
159109
+ return rc;
159110
+}
159111
+
159112
+/*
159113
+** Unlock an otaVfs-file.
159114
+*/
159115
+static int otaVfsUnlock(sqlite3_file *pFile, int eLock){
159116
+ ota_file *p = (ota_file *)pFile;
159117
+ return p->pReal->pMethods->xUnlock(p->pReal, eLock);
159118
+}
159119
+
159120
+/*
159121
+** Check if another file-handle holds a RESERVED lock on an otaVfs-file.
159122
+*/
159123
+static int otaVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
159124
+ ota_file *p = (ota_file *)pFile;
159125
+ return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
159126
+}
159127
+
159128
+/*
159129
+** File control method. For custom operations on an otaVfs-file.
159130
+*/
159131
+static int otaVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
159132
+ ota_file *p = (ota_file *)pFile;
159133
+ int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl;
159134
+ int rc;
159135
+
159136
+ assert( p->openFlags &
159137
+ (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB|SQLITE_OPEN_TRANSIENT_DB)
159138
+ );
159139
+ if( op==SQLITE_FCNTL_OTA ){
159140
+ sqlite3ota *pOta = (sqlite3ota*)pArg;
159141
+
159142
+ /* First try to find another OTA vfs lower down in the vfs stack. If
159143
+ ** one is found, this vfs will operate in pass-through mode. The lower
159144
+ ** level vfs will do the special OTA handling. */
159145
+ rc = xControl(p->pReal, op, pArg);
159146
+
159147
+ if( rc==SQLITE_NOTFOUND ){
159148
+ /* Now search for a zipvfs instance lower down in the VFS stack. If
159149
+ ** one is found, this is an error. */
159150
+ void *dummy = 0;
159151
+ rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
159152
+ if( rc==SQLITE_OK ){
159153
+ rc = SQLITE_ERROR;
159154
+ pOta->zErrmsg = sqlite3_mprintf("ota/zipvfs setup error");
159155
+ }else if( rc==SQLITE_NOTFOUND ){
159156
+ pOta->pTargetFd = p;
159157
+ p->pOta = pOta;
159158
+ if( p->pWalFd ) p->pWalFd->pOta = pOta;
159159
+ rc = SQLITE_OK;
159160
+ }
159161
+ }
159162
+ return rc;
159163
+ }
159164
+
159165
+ rc = xControl(p->pReal, op, pArg);
159166
+ if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
159167
+ ota_vfs *pOtaVfs = p->pOtaVfs;
159168
+ char *zIn = *(char**)pArg;
159169
+ char *zOut = sqlite3_mprintf("ota(%s)/%z", pOtaVfs->base.zName, zIn);
159170
+ *(char**)pArg = zOut;
159171
+ if( zOut==0 ) rc = SQLITE_NOMEM;
159172
+ }
159173
+
159174
+ return rc;
159175
+}
159176
+
159177
+/*
159178
+** Return the sector-size in bytes for an otaVfs-file.
159179
+*/
159180
+static int otaVfsSectorSize(sqlite3_file *pFile){
159181
+ ota_file *p = (ota_file *)pFile;
159182
+ return p->pReal->pMethods->xSectorSize(p->pReal);
159183
+}
159184
+
159185
+/*
159186
+** Return the device characteristic flags supported by an otaVfs-file.
159187
+*/
159188
+static int otaVfsDeviceCharacteristics(sqlite3_file *pFile){
159189
+ ota_file *p = (ota_file *)pFile;
159190
+ return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
159191
+}
159192
+
159193
+/*
159194
+** Take or release a shared-memory lock.
159195
+*/
159196
+static int otaVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
159197
+ ota_file *p = (ota_file*)pFile;
159198
+ sqlite3ota *pOta = p->pOta;
159199
+ int rc = SQLITE_OK;
159200
+
159201
+#ifdef SQLITE_AMALGAMATION
159202
+ assert( WAL_CKPT_LOCK==1 );
159203
+#endif
159204
+
159205
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159206
+ if( pOta && (pOta->eStage==OTA_STAGE_OAL || pOta->eStage==OTA_STAGE_MOVE) ){
159207
+ /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
159208
+ ** taking this lock also prevents any checkpoints from occurring.
159209
+ ** todo: really, it's not clear why this might occur, as
159210
+ ** wal_autocheckpoint ought to be turned off. */
159211
+ if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
159212
+ }else{
159213
+ int bCapture = 0;
159214
+ if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
159215
+ && pOta && pOta->eStage==OTA_STAGE_CAPTURE
159216
+ && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
159217
+ ){
159218
+ bCapture = 1;
159219
+ }
159220
+
159221
+ if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
159222
+ rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
159223
+ if( bCapture && rc==SQLITE_OK ){
159224
+ pOta->mLock |= (1 << ofst);
159225
+ }
159226
+ }
159227
+ }
159228
+
159229
+ return rc;
159230
+}
159231
+
159232
+/*
159233
+** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file.
159234
+*/
159235
+static int otaVfsShmMap(
159236
+ sqlite3_file *pFile,
159237
+ int iRegion,
159238
+ int szRegion,
159239
+ int isWrite,
159240
+ void volatile **pp
159241
+){
159242
+ ota_file *p = (ota_file*)pFile;
159243
+ int rc = SQLITE_OK;
159244
+ int eStage = (p->pOta ? p->pOta->eStage : 0);
159245
+
159246
+ /* If not in OTA_STAGE_OAL, allow this call to pass through. Or, if this
159247
+ ** ota is in the OTA_STAGE_OAL state, use heap memory for *-shm space
159248
+ ** instead of a file on disk. */
159249
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159250
+ if( eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_MOVE ){
159251
+ if( iRegion<=p->nShm ){
159252
+ int nByte = (iRegion+1) * sizeof(char*);
159253
+ char **apNew = (char**)sqlite3_realloc(p->apShm, nByte);
159254
+ if( apNew==0 ){
159255
+ rc = SQLITE_NOMEM;
159256
+ }else{
159257
+ memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
159258
+ p->apShm = apNew;
159259
+ p->nShm = iRegion+1;
159260
+ }
159261
+ }
159262
+
159263
+ if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
159264
+ char *pNew = (char*)sqlite3_malloc(szRegion);
159265
+ if( pNew==0 ){
159266
+ rc = SQLITE_NOMEM;
159267
+ }else{
159268
+ memset(pNew, 0, szRegion);
159269
+ p->apShm[iRegion] = pNew;
159270
+ }
159271
+ }
159272
+
159273
+ if( rc==SQLITE_OK ){
159274
+ *pp = p->apShm[iRegion];
159275
+ }else{
159276
+ *pp = 0;
159277
+ }
159278
+ }else{
159279
+ assert( p->apShm==0 );
159280
+ rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
159281
+ }
159282
+
159283
+ return rc;
159284
+}
159285
+
159286
+/*
159287
+** Memory barrier.
159288
+*/
159289
+static void otaVfsShmBarrier(sqlite3_file *pFile){
159290
+ ota_file *p = (ota_file *)pFile;
159291
+ p->pReal->pMethods->xShmBarrier(p->pReal);
159292
+}
159293
+
159294
+/*
159295
+** The xShmUnmap method.
159296
+*/
159297
+static int otaVfsShmUnmap(sqlite3_file *pFile, int delFlag){
159298
+ ota_file *p = (ota_file*)pFile;
159299
+ int rc = SQLITE_OK;
159300
+ int eStage = (p->pOta ? p->pOta->eStage : 0);
159301
+
159302
+ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159303
+ if( eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_MOVE ){
159304
+ /* no-op */
159305
+ }else{
159306
+ /* Release the checkpointer and writer locks */
159307
+ otaUnlockShm(p);
159308
+ rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
159309
+ }
159310
+ return rc;
159311
+}
159312
+
159313
+/*
159314
+** Given that zWal points to a buffer containing a wal file name passed to
159315
+** either the xOpen() or xAccess() VFS method, return a pointer to the
159316
+** file-handle opened by the same database connection on the corresponding
159317
+** database file.
159318
+*/
159319
+static ota_file *otaFindMaindb(ota_vfs *pOtaVfs, const char *zWal){
159320
+ ota_file *pDb;
159321
+ sqlite3_mutex_enter(pOtaVfs->mutex);
159322
+ for(pDb=pOtaVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext);
159323
+ sqlite3_mutex_leave(pOtaVfs->mutex);
159324
+ return pDb;
159325
+}
159326
+
159327
+/*
159328
+** Open an ota file handle.
159329
+*/
159330
+static int otaVfsOpen(
159331
+ sqlite3_vfs *pVfs,
159332
+ const char *zName,
159333
+ sqlite3_file *pFile,
159334
+ int flags,
159335
+ int *pOutFlags
159336
+){
159337
+ static sqlite3_io_methods otavfs_io_methods = {
159338
+ 2, /* iVersion */
159339
+ otaVfsClose, /* xClose */
159340
+ otaVfsRead, /* xRead */
159341
+ otaVfsWrite, /* xWrite */
159342
+ otaVfsTruncate, /* xTruncate */
159343
+ otaVfsSync, /* xSync */
159344
+ otaVfsFileSize, /* xFileSize */
159345
+ otaVfsLock, /* xLock */
159346
+ otaVfsUnlock, /* xUnlock */
159347
+ otaVfsCheckReservedLock, /* xCheckReservedLock */
159348
+ otaVfsFileControl, /* xFileControl */
159349
+ otaVfsSectorSize, /* xSectorSize */
159350
+ otaVfsDeviceCharacteristics, /* xDeviceCharacteristics */
159351
+ otaVfsShmMap, /* xShmMap */
159352
+ otaVfsShmLock, /* xShmLock */
159353
+ otaVfsShmBarrier, /* xShmBarrier */
159354
+ otaVfsShmUnmap /* xShmUnmap */
159355
+ };
159356
+ ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
159357
+ sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
159358
+ ota_file *pFd = (ota_file *)pFile;
159359
+ int rc = SQLITE_OK;
159360
+ const char *zOpen = zName;
159361
+
159362
+ memset(pFd, 0, sizeof(ota_file));
159363
+ pFd->pReal = (sqlite3_file*)&pFd[1];
159364
+ pFd->pOtaVfs = pOtaVfs;
159365
+ pFd->openFlags = flags;
159366
+ if( zName ){
159367
+ if( flags & SQLITE_OPEN_MAIN_DB ){
159368
+ /* A main database has just been opened. The following block sets
159369
+ ** (pFd->zWal) to point to a buffer owned by SQLite that contains
159370
+ ** the name of the *-wal file this db connection will use. SQLite
159371
+ ** happens to pass a pointer to this buffer when using xAccess()
159372
+ ** or xOpen() to operate on the *-wal file. */
159373
+ int n = strlen(zName);
159374
+ const char *z = &zName[n];
159375
+ if( flags & SQLITE_OPEN_URI ){
159376
+ int odd = 0;
159377
+ while( 1 ){
159378
+ if( z[0]==0 ){
159379
+ odd = 1 - odd;
159380
+ if( odd && z[1]==0 ) break;
159381
+ }
159382
+ z++;
159383
+ }
159384
+ z += 2;
159385
+ }else{
159386
+ while( *z==0 ) z++;
159387
+ }
159388
+ z += (n + 8 + 1);
159389
+ pFd->zWal = z;
159390
+ }
159391
+ else if( flags & SQLITE_OPEN_WAL ){
159392
+ ota_file *pDb = otaFindMaindb(pOtaVfs, zName);
159393
+ if( pDb ){
159394
+ if( pDb->pOta && pDb->pOta->eStage==OTA_STAGE_OAL ){
159395
+ /* This call is to open a *-wal file. Intead, open the *-oal. This
159396
+ ** code ensures that the string passed to xOpen() is terminated by a
159397
+ ** pair of '\0' bytes in case the VFS attempts to extract a URI
159398
+ ** parameter from it. */
159399
+ int nCopy = strlen(zName);
159400
+ char *zCopy = sqlite3_malloc(nCopy+2);
159401
+ if( zCopy ){
159402
+ memcpy(zCopy, zName, nCopy);
159403
+ zCopy[nCopy-3] = 'o';
159404
+ zCopy[nCopy] = '\0';
159405
+ zCopy[nCopy+1] = '\0';
159406
+ zOpen = (const char*)(pFd->zDel = zCopy);
159407
+ }else{
159408
+ rc = SQLITE_NOMEM;
159409
+ }
159410
+ pFd->pOta = pDb->pOta;
159411
+ }
159412
+ pDb->pWalFd = pFd;
159413
+ }
159414
+ }
159415
+ }
159416
+
159417
+ if( rc==SQLITE_OK ){
159418
+ rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
159419
+ }
159420
+ if( pFd->pReal->pMethods ){
159421
+ /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
159422
+ ** pointer and, if the file is a main database file, link it into the
159423
+ ** mutex protected linked list of all such files. */
159424
+ pFile->pMethods = &otavfs_io_methods;
159425
+ if( flags & SQLITE_OPEN_MAIN_DB ){
159426
+ sqlite3_mutex_enter(pOtaVfs->mutex);
159427
+ pFd->pMainNext = pOtaVfs->pMain;
159428
+ pOtaVfs->pMain = pFd;
159429
+ sqlite3_mutex_leave(pOtaVfs->mutex);
159430
+ }
159431
+ }else{
159432
+ sqlite3_free(pFd->zDel);
159433
+ }
159434
+
159435
+ return rc;
159436
+}
159437
+
159438
+/*
159439
+** Delete the file located at zPath.
159440
+*/
159441
+static int otaVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
159442
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159443
+ return pRealVfs->xDelete(pRealVfs, zPath, dirSync);
159444
+}
159445
+
159446
+/*
159447
+** Test for access permissions. Return true if the requested permission
159448
+** is available, or false otherwise.
159449
+*/
159450
+static int otaVfsAccess(
159451
+ sqlite3_vfs *pVfs,
159452
+ const char *zPath,
159453
+ int flags,
159454
+ int *pResOut
159455
+){
159456
+ ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
159457
+ sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
159458
+ int rc;
159459
+
159460
+ rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut);
159461
+
159462
+ /* If this call is to check if a *-wal file associated with an OTA target
159463
+ ** database connection exists, and the OTA update is in OTA_STAGE_OAL,
159464
+ ** the following special handling is activated:
159465
+ **
159466
+ ** a) if the *-wal file does exist, return SQLITE_CANTOPEN. This
159467
+ ** ensures that the OTA extension never tries to update a database
159468
+ ** in wal mode, even if the first page of the database file has
159469
+ ** been damaged.
159470
+ **
159471
+ ** b) if the *-wal file does not exist, claim that it does anyway,
159472
+ ** causing SQLite to call xOpen() to open it. This call will also
159473
+ ** be intercepted (see the otaVfsOpen() function) and the *-oal
159474
+ ** file opened instead.
159475
+ */
159476
+ if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
159477
+ ota_file *pDb = otaFindMaindb(pOtaVfs, zPath);
159478
+ if( pDb && pDb->pOta && pDb->pOta->eStage==OTA_STAGE_OAL ){
159479
+ if( *pResOut ){
159480
+ rc = SQLITE_CANTOPEN;
159481
+ }else{
159482
+ *pResOut = 1;
159483
+ }
159484
+ }
159485
+ }
159486
+
159487
+ return rc;
159488
+}
159489
+
159490
+/*
159491
+** Populate buffer zOut with the full canonical pathname corresponding
159492
+** to the pathname in zPath. zOut is guaranteed to point to a buffer
159493
+** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
159494
+*/
159495
+static int otaVfsFullPathname(
159496
+ sqlite3_vfs *pVfs,
159497
+ const char *zPath,
159498
+ int nOut,
159499
+ char *zOut
159500
+){
159501
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159502
+ return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut);
159503
+}
159504
+
159505
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
159506
+/*
159507
+** Open the dynamic library located at zPath and return a handle.
159508
+*/
159509
+static void *otaVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
159510
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159511
+ return pRealVfs->xDlOpen(pRealVfs, zPath);
159512
+}
159513
+
159514
+/*
159515
+** Populate the buffer zErrMsg (size nByte bytes) with a human readable
159516
+** utf-8 string describing the most recent error encountered associated
159517
+** with dynamic libraries.
159518
+*/
159519
+static void otaVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
159520
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159521
+ pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
159522
+}
159523
+
159524
+/*
159525
+** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
159526
+*/
159527
+static void (*otaVfsDlSym(
159528
+ sqlite3_vfs *pVfs,
159529
+ void *pArg,
159530
+ const char *zSym
159531
+))(void){
159532
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159533
+ return pRealVfs->xDlSym(pRealVfs, pArg, zSym);
159534
+}
159535
+
159536
+/*
159537
+** Close the dynamic library handle pHandle.
159538
+*/
159539
+static void otaVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){
159540
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159541
+ return pRealVfs->xDlClose(pRealVfs, pHandle);
159542
+}
159543
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
159544
+
159545
+/*
159546
+** Populate the buffer pointed to by zBufOut with nByte bytes of
159547
+** random data.
159548
+*/
159549
+static int otaVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
159550
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159551
+ return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut);
159552
+}
159553
+
159554
+/*
159555
+** Sleep for nMicro microseconds. Return the number of microseconds
159556
+** actually slept.
159557
+*/
159558
+static int otaVfsSleep(sqlite3_vfs *pVfs, int nMicro){
159559
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159560
+ return pRealVfs->xSleep(pRealVfs, nMicro);
159561
+}
159562
+
159563
+/*
159564
+** Return the current time as a Julian Day number in *pTimeOut.
159565
+*/
159566
+static int otaVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
159567
+ sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159568
+ return pRealVfs->xCurrentTime(pRealVfs, pTimeOut);
159569
+}
159570
+
159571
+/*
159572
+** No-op.
159573
+*/
159574
+static int otaVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
159575
+ return 0;
159576
+}
159577
+
159578
+/*
159579
+** Deregister and destroy an OTA vfs created by an earlier call to
159580
+** sqlite3ota_create_vfs().
159581
+*/
159582
+SQLITE_API void SQLITE_STDCALL sqlite3ota_destroy_vfs(const char *zName){
159583
+ sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
159584
+ if( pVfs && pVfs->xOpen==otaVfsOpen ){
159585
+ sqlite3_mutex_free(((ota_vfs*)pVfs)->mutex);
159586
+ sqlite3_vfs_unregister(pVfs);
159587
+ sqlite3_free(pVfs);
159588
+ }
159589
+}
159590
+
159591
+/*
159592
+** Create an OTA VFS named zName that accesses the underlying file-system
159593
+** via existing VFS zParent. The new object is registered as a non-default
159594
+** VFS with SQLite before returning.
159595
+*/
159596
+SQLITE_API int SQLITE_STDCALL sqlite3ota_create_vfs(const char *zName, const char *zParent){
159597
+
159598
+ /* Template for VFS */
159599
+ static sqlite3_vfs vfs_template = {
159600
+ 1, /* iVersion */
159601
+ 0, /* szOsFile */
159602
+ 0, /* mxPathname */
159603
+ 0, /* pNext */
159604
+ 0, /* zName */
159605
+ 0, /* pAppData */
159606
+ otaVfsOpen, /* xOpen */
159607
+ otaVfsDelete, /* xDelete */
159608
+ otaVfsAccess, /* xAccess */
159609
+ otaVfsFullPathname, /* xFullPathname */
159610
+
159611
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
159612
+ otaVfsDlOpen, /* xDlOpen */
159613
+ otaVfsDlError, /* xDlError */
159614
+ otaVfsDlSym, /* xDlSym */
159615
+ otaVfsDlClose, /* xDlClose */
159616
+#else
159617
+ 0, 0, 0, 0,
159618
+#endif
159619
+
159620
+ otaVfsRandomness, /* xRandomness */
159621
+ otaVfsSleep, /* xSleep */
159622
+ otaVfsCurrentTime, /* xCurrentTime */
159623
+ otaVfsGetLastError, /* xGetLastError */
159624
+ 0, /* xCurrentTimeInt64 (version 2) */
159625
+ 0, 0, 0 /* Unimplemented version 3 methods */
159626
+ };
159627
+
159628
+ ota_vfs *pNew = 0; /* Newly allocated VFS */
159629
+ int nName;
159630
+ int rc = SQLITE_OK;
159631
+
159632
+ int nByte;
159633
+ nName = strlen(zName);
159634
+ nByte = sizeof(ota_vfs) + nName + 1;
159635
+ pNew = (ota_vfs*)sqlite3_malloc(nByte);
159636
+ if( pNew==0 ){
159637
+ rc = SQLITE_NOMEM;
159638
+ }else{
159639
+ sqlite3_vfs *pParent; /* Parent VFS */
159640
+ memset(pNew, 0, nByte);
159641
+ pParent = sqlite3_vfs_find(zParent);
159642
+ if( pParent==0 ){
159643
+ rc = SQLITE_NOTFOUND;
159644
+ }else{
159645
+ char *zSpace;
159646
+ memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
159647
+ pNew->base.mxPathname = pParent->mxPathname;
159648
+ pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile;
159649
+ pNew->pRealVfs = pParent;
159650
+ pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
159651
+ memcpy(zSpace, zName, nName);
159652
+
159653
+ /* Allocate the mutex and register the new VFS (not as the default) */
159654
+ pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
159655
+ if( pNew->mutex==0 ){
159656
+ rc = SQLITE_NOMEM;
159657
+ }else{
159658
+ rc = sqlite3_vfs_register(&pNew->base, 0);
159659
+ }
159660
+ }
159661
+
159662
+ if( rc!=SQLITE_OK ){
159663
+ sqlite3_mutex_free(pNew->mutex);
159664
+ sqlite3_free(pNew);
159665
+ }
159666
+ }
159667
+
159668
+ return rc;
159669
+}
159670
+
159671
+
159672
+/**************************************************************************/
159673
+
159674
+#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA) */
159675
+
159676
+/************** End of sqlite3ota.c ******************************************/
155215159677
/************** Begin file dbstat.c ******************************************/
155216159678
/*
155217159679
** 2010 July 12
155218159680
**
155219159681
** The author disclaims copyright to this source code. In place of
@@ -155833,11 +160295,11 @@
155833160295
}
155834160296
155835160297
/*
155836160298
** Invoke this routine to register the "dbstat" virtual table module
155837160299
*/
155838
-SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){
160300
+SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){
155839160301
static sqlite3_module dbstat_module = {
155840160302
0, /* iVersion */
155841160303
statConnect, /* xCreate */
155842160304
statConnect, /* xConnect */
155843160305
statBestIndex, /* xBestIndex */
@@ -155858,8 +160320,10 @@
155858160320
0, /* xFindMethod */
155859160321
0, /* xRename */
155860160322
};
155861160323
return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
155862160324
}
160325
+#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
160326
+SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
155863160327
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
155864160328
155865160329
/************** End of dbstat.c **********************************************/
155866160330
--- 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.10.1. 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.
@@ -316,13 +316,13 @@
316 **
317 ** See also: [sqlite3_libversion()],
318 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
319 ** [sqlite_version()] and [sqlite_source_id()].
320 */
321 #define SQLITE_VERSION "3.8.10.1"
322 #define SQLITE_VERSION_NUMBER 3008010
323 #define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40"
324
325 /*
326 ** CAPI3REF: Run-Time Library Version Numbers
327 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
328 **
@@ -1161,17 +1161,25 @@
1161 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1162 ** opcode causes the xFileControl method to swap the file handle with the one
1163 ** pointed to by the pArg argument. This capability is used during testing
1164 ** and only needs to be supported when SQLITE_TEST is defined.
1165 **
1166 ** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1167 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
1168 ** be advantageous to block on the next WAL lock if the lock is not immediately
1169 ** available. The WAL subsystem issues this signal during rare
1170 ** circumstances in order to fix a problem with priority inversion.
1171 ** Applications should <em>not</em> use this file-control.
1172 **
 
 
 
 
 
 
 
 
1173 ** </ul>
1174 */
1175 #define SQLITE_FCNTL_LOCKSTATE 1
1176 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
1177 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1193,10 +1201,12 @@
1193 #define SQLITE_FCNTL_HAS_MOVED 20
1194 #define SQLITE_FCNTL_SYNC 21
1195 #define SQLITE_FCNTL_COMMIT_PHASETWO 22
1196 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23
1197 #define SQLITE_FCNTL_WAL_BLOCK 24
 
 
1198
1199 /* deprecated names */
1200 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1201 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1202 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3595,11 +3605,13 @@
3595 **
3596 ** An sqlite3_value object may be either "protected" or "unprotected".
3597 ** Some interfaces require a protected sqlite3_value. Other interfaces
3598 ** will accept either a protected or an unprotected sqlite3_value.
3599 ** Every interface that accepts sqlite3_value arguments specifies
3600 ** whether or not it requires a protected sqlite3_value.
 
 
3601 **
3602 ** The terms "protected" and "unprotected" refer to whether or not
3603 ** a mutex is held. An internal mutex is held for a protected
3604 ** sqlite3_value object but no mutex is held for an unprotected
3605 ** sqlite3_value object. If SQLite is compiled to be single-threaded
@@ -4098,12 +4110,10 @@
4098 /*
4099 ** CAPI3REF: Result Values From A Query
4100 ** KEYWORDS: {column access functions}
4101 ** METHOD: sqlite3_stmt
4102 **
4103 ** These routines form the "result set" interface.
4104 **
4105 ** ^These routines return information about a single column of the current
4106 ** result row of a query. ^In every case the first argument is a pointer
4107 ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
4108 ** that was returned from [sqlite3_prepare_v2()] or one of its variants)
4109 ** and the second argument is the index of the column for which information
@@ -4159,17 +4169,18 @@
4159 **
4160 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
4161 ** even empty strings, are always zero-terminated. ^The return
4162 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
4163 **
4164 ** ^The object returned by [sqlite3_column_value()] is an
4165 ** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
4166 ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
 
4167 ** If the [unprotected sqlite3_value] object returned by
4168 ** [sqlite3_column_value()] is used in any other way, including calls
4169 ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
4170 ** or [sqlite3_value_bytes()], then the behavior is undefined.
4171 **
4172 ** These routines attempt to convert the value where appropriate. ^For
4173 ** example, if the internal representation is FLOAT and a text result
4174 ** is requested, [sqlite3_snprintf()] is used internally to perform the
4175 ** conversion automatically. ^(The following table details the conversions
@@ -4196,16 +4207,10 @@
4196 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
4197 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
4198 ** </table>
4199 ** </blockquote>)^
4200 **
4201 ** The table above makes reference to standard C library functions atoi()
4202 ** and atof(). SQLite does not really use these functions. It has its
4203 ** own equivalent internal routines. The atoi() and atof() names are
4204 ** used in the table for brevity and because they are familiar to most
4205 ** C programmers.
4206 **
4207 ** Note that when type conversions occur, pointers returned by prior
4208 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
4209 ** sqlite3_column_text16() may be invalidated.
4210 ** Type conversions and pointer invalidations might occur
4211 ** in the following cases:
@@ -4226,11 +4231,11 @@
4226 ** not invalidate a prior pointer, though of course the content of the buffer
4227 ** that the prior pointer references will have been modified. Other kinds
4228 ** of conversion are done in place when it is possible, but sometimes they
4229 ** are not possible and in those cases prior pointers are invalidated.
4230 **
4231 ** The safest and easiest to remember policy is to invoke these routines
4232 ** in one of the following ways:
4233 **
4234 ** <ul>
4235 ** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
4236 ** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
@@ -4246,11 +4251,11 @@
4246 ** with calls to sqlite3_column_bytes().
4247 **
4248 ** ^The pointers returned are valid until a type conversion occurs as
4249 ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
4250 ** [sqlite3_finalize()] is called. ^The memory space used to hold strings
4251 ** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
4252 ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
4253 ** [sqlite3_free()].
4254 **
4255 ** ^(If a memory allocation error occurs during the evaluation of any
4256 ** of these routines, a default value is returned. The default value
@@ -4496,16 +4501,16 @@
4496 SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
4497 void*,sqlite3_int64);
4498 #endif
4499
4500 /*
4501 ** CAPI3REF: Obtaining SQL Function Parameter Values
4502 ** METHOD: sqlite3_value
4503 **
4504 ** The C-language implementation of SQL functions and aggregates uses
4505 ** this set of interface routines to access the parameter values on
4506 ** the function or aggregate.
4507 **
4508 ** The xFunc (for scalar functions) or xStep (for aggregates) parameters
4509 ** to [sqlite3_create_function()] and [sqlite3_create_function16()]
4510 ** define callbacks that implement the SQL functions and aggregates.
4511 ** The 3rd parameter to these callbacks is an array of pointers to
@@ -4554,10 +4559,27 @@
4554 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
4555 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
4556 SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
4557 SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
4558
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4559 /*
4560 ** CAPI3REF: Obtain Aggregate Function Context
4561 ** METHOD: sqlite3_context
4562 **
4563 ** Implementations of aggregate SQL functions use this
@@ -4801,11 +4823,11 @@
4801 ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
4802 ** then SQLite makes a copy of the result into space obtained from
4803 ** from [sqlite3_malloc()] before it returns.
4804 **
4805 ** ^The sqlite3_result_value() interface sets the result of
4806 ** the application-defined function to be a copy the
4807 ** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
4808 ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
4809 ** so that the [sqlite3_value] specified in the parameter may change or
4810 ** be deallocated after sqlite3_result_value() returns without harm.
4811 ** ^A [protected sqlite3_value] object may always be used where an
@@ -6077,11 +6099,11 @@
6077 ** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
6078 ** always returns zero.
6079 **
6080 ** ^This function sets the database handle error code and message.
6081 */
6082 SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
6083
6084 /*
6085 ** CAPI3REF: Close A BLOB Handle
6086 ** DESTRUCTOR: sqlite3_blob
6087 **
@@ -7887,11 +7909,11 @@
7887 ** as if the loop did not exist - it returns non-zero and leave the variable
7888 ** that pOut points to unchanged.
7889 **
7890 ** See also: [sqlite3_stmt_scanstatus_reset()]
7891 */
7892 SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
7893 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
7894 int idx, /* Index of loop to report on */
7895 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
7896 void *pOut /* Result written here */
7897 );
@@ -7903,11 +7925,11 @@
7903 ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
7904 **
7905 ** This API is only available if the library is built with pre-processor
7906 ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
7907 */
7908 SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
7909
7910
7911 /*
7912 ** Undo the hack that converts floating point types to integer for
7913 ** builds on processors without floating point support.
@@ -8018,10 +8040,12 @@
8018 sqlite3_int64 iRowid; /* Rowid for current entry */
8019 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
8020 int eParentWithin; /* Visibility of parent node */
8021 int eWithin; /* OUT: Visiblity */
8022 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
 
 
8023 };
8024
8025 /*
8026 ** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
8027 */
@@ -11167,10 +11191,11 @@
11167 #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
11168 #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
11169 #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
11170 #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
11171 #define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
 
11172
11173
11174 /*
11175 ** Bits of the sqlite3.dbOptFlags field that are used by the
11176 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -11548,12 +11573,13 @@
11548 #define TF_Readonly 0x01 /* Read-only system table */
11549 #define TF_Ephemeral 0x02 /* An ephemeral table */
11550 #define TF_HasPrimaryKey 0x04 /* Table has a primary key */
11551 #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
11552 #define TF_Virtual 0x10 /* Is a virtual table */
11553 #define TF_WithoutRowid 0x20 /* No rowid used. PRIMARY KEY is the key */
11554 #define TF_OOOHidden 0x40 /* Out-of-Order hidden columns */
 
11555
11556
11557 /*
11558 ** Test to see whether or not a table is a virtual table. This is
11559 ** done as a macro so that it will be optimized out when virtual
@@ -11567,10 +11593,11 @@
11567 # define IsHiddenColumn(X) 0
11568 #endif
11569
11570 /* Does the table have a rowid */
11571 #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
 
11572
11573 /*
11574 ** Each foreign key constraint is an instance of the following structure.
11575 **
11576 ** A foreign key is associated with two tables. The "from" table is
@@ -11725,10 +11752,18 @@
11725 ** must be unique and what to do if they are not. When Index.onError=OE_None,
11726 ** it means this is not a unique index. Otherwise it is a unique index
11727 ** and the value of Index.onError indicate the which conflict resolution
11728 ** algorithm to employ whenever an attempt is made to insert a non-unique
11729 ** element.
 
 
 
 
 
 
 
 
11730 */
11731 struct Index {
11732 char *zName; /* Name of this index */
11733 i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
11734 LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */
@@ -12299,23 +12334,24 @@
12299 /*
12300 ** Allowed values for Select.selFlags. The "SF" prefix stands for
12301 ** "Select Flag".
12302 */
12303 #define SF_Distinct 0x0001 /* Output should be DISTINCT */
12304 #define SF_Resolved 0x0002 /* Identifiers have been resolved */
12305 #define SF_Aggregate 0x0004 /* Contains aggregate functions */
12306 #define SF_UsesEphemeral 0x0008 /* Uses the OpenEphemeral opcode */
12307 #define SF_Expanded 0x0010 /* sqlite3SelectExpand() called on this */
12308 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
12309 #define SF_Compound 0x0040 /* Part of a compound query */
12310 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
12311 #define SF_MultiValue 0x0100 /* Single VALUES term with multiple rows */
12312 #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
12313 #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
12314 #define SF_Recursive 0x0800 /* The recursive part of a recursive CTE */
12315 #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
12316 #define SF_Converted 0x2000 /* By convertCompoundSelectToSubquery() */
 
12317
12318
12319 /*
12320 ** The results of a SELECT can be distributed in several ways, as defined
12321 ** by one of the following macros. The "SRT" prefix means "SELECT Result
@@ -12553,11 +12589,10 @@
12553
12554 /* Information used while coding trigger programs. */
12555 Parse *pToplevel; /* Parse structure for main program (or NULL) */
12556 Table *pTriggerTab; /* Table triggers are being coded for */
12557 int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
12558 int addrSkipPK; /* Address of instruction to skip PRIMARY KEY index */
12559 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
12560 u32 oldmask; /* Mask of old.* columns referenced */
12561 u32 newmask; /* Mask of new.* columns referenced */
12562 u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
12563 u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
@@ -13065,11 +13100,10 @@
13065 #define SQLITE_PRINTF_SQLFUNC 0x02
13066 SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
13067 SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
13068 SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
13069 SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
13070 SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
13071 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
13072 SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
13073 #endif
13074 #if defined(SQLITE_TEST)
13075 SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
@@ -13084,11 +13118,11 @@
13084 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
13085 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
13086 #endif
13087
13088
13089 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
13090 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
13091 SQLITE_PRIVATE int sqlite3Dequote(char*);
13092 SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
13093 SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
13094 SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
@@ -13780,10 +13814,14 @@
13780 */
13781 #if SQLITE_MAX_WORKER_THREADS>0
13782 SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
13783 SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
13784 #endif
 
 
 
 
13785
13786 #endif /* _SQLITEINT_H_ */
13787
13788 /************** End of sqliteInt.h *******************************************/
13789 /************** Begin file global.c ******************************************/
@@ -14685,10 +14723,16 @@
14685 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
14686 void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
14687 #endif
14688 };
14689
 
 
 
 
 
 
14690 /* One or more of the following flags are set to indicate the validOK
14691 ** representations of the value stored in the Mem struct.
14692 **
14693 ** If the MEM_Null flag is set, then the value is an SQL NULL value.
14694 ** No other flags may be set in this case.
@@ -14890,10 +14934,11 @@
14890 #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
14891
14892 /*
14893 ** Function prototypes
14894 */
 
14895 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
14896 void sqliteVdbePopStack(Vdbe*,int);
14897 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
14898 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
14899 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -20738,28 +20783,24 @@
20738
20739 /*
20740 ** Return the amount of memory currently checked out.
20741 */
20742 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
20743 int n, mx;
20744 sqlite3_int64 res;
20745 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
20746 res = (sqlite3_int64)n; /* Work around bug in Borland C. Ticket #3216 */
20747 return res;
20748 }
20749
20750 /*
20751 ** Return the maximum amount of memory that has ever been
20752 ** checked out since either the beginning of this process
20753 ** or since the most recent reset.
20754 */
20755 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
20756 int n, mx;
20757 sqlite3_int64 res;
20758 sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
20759 res = (sqlite3_int64)mx; /* Work around bug in Borland C. Ticket #3216 */
20760 return res;
20761 }
20762
20763 /*
20764 ** Trigger the alarm
20765 */
@@ -21287,23 +21328,15 @@
21287 }
21288 return zNew;
21289 }
21290
21291 /*
21292 ** Create a string from the zFromat argument and the va_list that follows.
21293 ** Store the string in memory obtained from sqliteMalloc() and make *pz
21294 ** point to that string.
21295 */
21296 SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
21297 va_list ap;
21298 char *z;
21299
21300 va_start(ap, zFormat);
21301 z = sqlite3VMPrintf(db, zFormat, ap);
21302 va_end(ap);
21303 sqlite3DbFree(db, *pz);
21304 *pz = z;
21305 }
21306
21307 /*
21308 ** Take actions at the end of an API call to indicate an OOM error
21309 */
@@ -22271,28 +22304,10 @@
22271 z = sqlite3VMPrintf(db, zFormat, ap);
22272 va_end(ap);
22273 return z;
22274 }
22275
22276 /*
22277 ** Like sqlite3MPrintf(), but call sqlite3DbFree() on zStr after formatting
22278 ** the string and before returning. This routine is intended to be used
22279 ** to modify an existing string. For example:
22280 **
22281 ** x = sqlite3MPrintf(db, x, "prefix %s suffix", x);
22282 **
22283 */
22284 SQLITE_PRIVATE char *sqlite3MAppendf(sqlite3 *db, char *zStr, const char *zFormat, ...){
22285 va_list ap;
22286 char *z;
22287 va_start(ap, zFormat);
22288 z = sqlite3VMPrintf(db, zFormat, ap);
22289 va_end(ap);
22290 sqlite3DbFree(db, zStr);
22291 return z;
22292 }
22293
22294 /*
22295 ** Print into memory obtained from sqlite3_malloc(). Omit the internal
22296 ** %-conversion extensions.
22297 */
22298 SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
@@ -36220,10 +36235,16 @@
36220 */
36221 if( pFile->locktype>=locktype ){
36222 OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
36223 return SQLITE_OK;
36224 }
 
 
 
 
 
 
36225
36226 /* Make sure the locking sequence is correct
36227 */
36228 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
36229 assert( locktype!=PENDING_LOCK );
@@ -38617,18 +38638,18 @@
38617 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
38618 if( sizeof(UUID)<=nBuf-n ){
38619 UUID id;
38620 memset(&id, 0, sizeof(UUID));
38621 osUuidCreate(&id);
38622 memcpy(zBuf, &id, sizeof(UUID));
38623 n += sizeof(UUID);
38624 }
38625 if( sizeof(UUID)<=nBuf-n ){
38626 UUID id;
38627 memset(&id, 0, sizeof(UUID));
38628 osUuidCreateSequential(&id);
38629 memcpy(zBuf, &id, sizeof(UUID));
38630 n += sizeof(UUID);
38631 }
38632 #endif
38633 #endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
38634 return n;
@@ -44777,15 +44798,14 @@
44777 */
44778 assert( pPager->eState==PAGER_OPEN );
44779 assert( pPager->eLock>=SHARED_LOCK );
44780 nPage = sqlite3WalDbsize(pPager->pWal);
44781
44782 /* If the database size was not available from the WAL sub-system,
44783 ** determine it based on the size of the database file. If the size
44784 ** of the database file is not an integer multiple of the page-size,
44785 ** round down to the nearest page. Except, any file larger than 0
44786 ** bytes in size is considered to contain at least one page.
44787 */
44788 if( nPage==0 ){
44789 i64 n = 0; /* Size of db file in bytes */
44790 assert( isOpen(pPager->fd) || pPager->tempFile );
44791 if( isOpen(pPager->fd) ){
@@ -54245,30 +54265,22 @@
54245 u8 *pAddr; /* The i-th cell pointer */
54246 pAddr = &data[cellOffset + i*2];
54247 pc = get2byte(pAddr);
54248 testcase( pc==iCellFirst );
54249 testcase( pc==iCellLast );
54250 #if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
54251 /* These conditions have already been verified in btreeInitPage()
54252 ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined
54253 */
54254 if( pc<iCellFirst || pc>iCellLast ){
54255 return SQLITE_CORRUPT_BKPT;
54256 }
54257 #endif
54258 assert( pc>=iCellFirst && pc<=iCellLast );
54259 size = cellSizePtr(pPage, &src[pc]);
54260 cbrk -= size;
54261 #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
54262 if( cbrk<iCellFirst ){
54263 return SQLITE_CORRUPT_BKPT;
54264 }
54265 #else
54266 if( cbrk<iCellFirst || pc+size>usableSize ){
54267 return SQLITE_CORRUPT_BKPT;
54268 }
54269 #endif
54270 assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
54271 testcase( cbrk+size==usableSize );
54272 testcase( pc+size==usableSize );
54273 put2byte(pAddr, cbrk);
54274 if( temp==0 ){
@@ -54340,11 +54352,11 @@
54340 }
54341 /* Remove the slot from the free-list. Update the number of
54342 ** fragmented bytes within the page. */
54343 memcpy(&aData[iAddr], &aData[pc], 2);
54344 aData[hdr+7] += (u8)x;
54345 }else if( size+pc > usableSize ){
54346 *pRc = SQLITE_CORRUPT_BKPT;
54347 return 0;
54348 }else{
54349 /* The slot remains on the free-list. Reduce its size to account
54350 ** for the portion used by the new allocation. */
@@ -54392,11 +54404,15 @@
54392 ** and the reserved space is zero (the usual value for reserved space)
54393 ** then the cell content offset of an empty page wants to be 65536.
54394 ** However, that integer is too large to be stored in a 2-byte unsigned
54395 ** integer, so a value of 0 is used in its place. */
54396 top = get2byteNotZero(&data[hdr+5]);
54397 if( gap>top ) return SQLITE_CORRUPT_BKPT;
 
 
 
 
54398
54399 /* If there is enough space between gap and top for one more cell pointer
54400 ** array entry offset, and if the freelist is not empty, then search the
54401 ** freelist looking for a free slot big enough to satisfy the request.
54402 */
@@ -54465,11 +54481,11 @@
54465 u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
54466 unsigned char *data = pPage->aData; /* Page content */
54467
54468 assert( pPage->pBt!=0 );
54469 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
54470 assert( iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
54471 assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
54472 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
54473 assert( iSize>=4 ); /* Minimum cell size is 4 */
54474 assert( iStart<=iLast );
54475
@@ -54605,10 +54621,11 @@
54605 ** we failed to detect any corruption.
54606 */
54607 static int btreeInitPage(MemPage *pPage){
54608
54609 assert( pPage->pBt!=0 );
 
54610 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
54611 assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
54612 assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
54613 assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
54614
@@ -54663,12 +54680,11 @@
54663 ** past the end of a page boundary and causes SQLITE_CORRUPT to be
54664 ** returned if it does.
54665 */
54666 iCellFirst = cellOffset + 2*pPage->nCell;
54667 iCellLast = usableSize - 4;
54668 #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
54669 {
54670 int i; /* Index into the cell pointer array */
54671 int sz; /* Size of a cell */
54672
54673 if( !pPage->leaf ) iCellLast--;
54674 for(i=0; i<pPage->nCell; i++){
@@ -54684,11 +54700,10 @@
54684 return SQLITE_CORRUPT_BKPT;
54685 }
54686 }
54687 if( !pPage->leaf ) iCellLast++;
54688 }
54689 #endif
54690
54691 /* Compute the total free space on the page
54692 ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
54693 ** start of the first freeblock on the page, or is zero if there are no
54694 ** freeblocks. */
@@ -54781,14 +54796,14 @@
54781 return pPage;
54782 }
54783
54784 /*
54785 ** Get a page from the pager. Initialize the MemPage.pBt and
54786 ** MemPage.aData elements if needed.
54787 **
54788 ** If the noContent flag is set, it means that we do not care about
54789 ** the content of the page at this time. So do not go to the disk
54790 ** to fetch the content. Just fill in the content with zeros for now.
54791 ** If in the future we call sqlite3PagerWrite() on this page, that
54792 ** means we have started to be concerned about content and the disk
54793 ** read should occur at that point.
54794 */
@@ -54885,10 +54900,40 @@
54885 assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
54886 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
54887 sqlite3PagerUnrefNotNull(pPage->pDbPage);
54888 }
54889 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54890
54891 /*
54892 ** During a rollback, when the pager reloads information into the cache
54893 ** so that the cache is restored to its original state at the start of
54894 ** the transaction, for each page restored this routine is called.
@@ -56133,12 +56178,14 @@
56133 put4byte(pPage->aData, iTo);
56134 }else{
56135 u8 isInitOrig = pPage->isInit;
56136 int i;
56137 int nCell;
 
56138
56139 btreeInitPage(pPage);
 
56140 nCell = pPage->nCell;
56141
56142 for(i=0; i<nCell; i++){
56143 u8 *pCell = findCell(pPage, i);
56144 if( eType==PTRMAP_OVERFLOW1 ){
@@ -56935,13 +56982,17 @@
56935 int wrFlag, /* 1 to write. 0 read-only */
56936 struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
56937 BtCursor *pCur /* Write new cursor here */
56938 ){
56939 int rc;
56940 sqlite3BtreeEnter(p);
56941 rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
56942 sqlite3BtreeLeave(p);
 
 
 
 
56943 return rc;
56944 }
56945
56946 /*
56947 ** Return the size of a BtCursor object in bytes.
@@ -57965,11 +58016,11 @@
57965 assert( lwr+upr>=0 );
57966 idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */
57967 }
57968 }else{
57969 for(;;){
57970 int nCell;
57971 pCell = findCell(pPage, idx) + pPage->childPtrSize;
57972
57973 /* The maximum supported page-size is 65536 bytes. This means that
57974 ** the maximum number of record bytes stored on an index B-Tree
57975 ** page is less than 16384 bytes and may be stored as a 2-byte
@@ -57994,16 +58045,29 @@
57994 c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
57995 }else{
57996 /* The record flows over onto one or more overflow pages. In
57997 ** this case the whole cell needs to be parsed, a buffer allocated
57998 ** and accessPayload() used to retrieve the record into the
57999 ** buffer before VdbeRecordCompare() can be called. */
 
 
 
 
 
58000 void *pCellKey;
58001 u8 * const pCellBody = pCell - pPage->childPtrSize;
58002 btreeParseCellPtr(pPage, pCellBody, &pCur->info);
58003 nCell = (int)pCur->info.nKey;
58004 pCellKey = sqlite3Malloc( nCell );
 
 
 
 
 
 
 
 
58005 if( pCellKey==0 ){
58006 rc = SQLITE_NOMEM;
58007 goto moveto_finish;
58008 }
58009 pCur->aiIdx[pCur->iPage] = (u16)idx;
@@ -58387,11 +58451,11 @@
58387 }
58388 testcase( iTrunk==mxPage );
58389 if( iTrunk>mxPage ){
58390 rc = SQLITE_CORRUPT_BKPT;
58391 }else{
58392 rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0);
58393 }
58394 if( rc ){
58395 pTrunk = 0;
58396 goto end_allocate_page;
58397 }
@@ -58452,11 +58516,11 @@
58452 if( iNewTrunk>mxPage ){
58453 rc = SQLITE_CORRUPT_BKPT;
58454 goto end_allocate_page;
58455 }
58456 testcase( iNewTrunk==mxPage );
58457 rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0);
58458 if( rc!=SQLITE_OK ){
58459 goto end_allocate_page;
58460 }
58461 rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
58462 if( rc!=SQLITE_OK ){
@@ -58532,11 +58596,11 @@
58532 if( closest<k-1 ){
58533 memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
58534 }
58535 put4byte(&aData[4], k-1);
58536 noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
58537 rc = btreeGetPage(pBt, *pPgno, ppPage, noContent);
58538 if( rc==SQLITE_OK ){
58539 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
58540 if( rc!=SQLITE_OK ){
58541 releasePage(*ppPage);
58542 }
@@ -58580,11 +58644,11 @@
58580 ** becomes a new pointer-map page, the second is used by the caller.
58581 */
58582 MemPage *pPg = 0;
58583 TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
58584 assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
58585 rc = btreeGetPage(pBt, pBt->nPage, &pPg, bNoContent);
58586 if( rc==SQLITE_OK ){
58587 rc = sqlite3PagerWrite(pPg->pDbPage);
58588 releasePage(pPg);
58589 }
58590 if( rc ) return rc;
@@ -58594,35 +58658,27 @@
58594 #endif
58595 put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
58596 *pPgno = pBt->nPage;
58597
58598 assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
58599 rc = btreeGetPage(pBt, *pPgno, ppPage, bNoContent);
58600 if( rc ) return rc;
58601 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
58602 if( rc!=SQLITE_OK ){
58603 releasePage(*ppPage);
 
58604 }
58605 TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
58606 }
58607
58608 assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
58609
58610 end_allocate_page:
58611 releasePage(pTrunk);
58612 releasePage(pPrevTrunk);
58613 if( rc==SQLITE_OK ){
58614 if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
58615 releasePage(*ppPage);
58616 *ppPage = 0;
58617 return SQLITE_CORRUPT_BKPT;
58618 }
58619 (*ppPage)->isInit = 0;
58620 }else{
58621 *ppPage = 0;
58622 }
58623 assert( rc!=SQLITE_OK || sqlite3PagerIswriteable((*ppPage)->pDbPage) );
58624 return rc;
58625 }
58626
58627 /*
58628 ** This function is used to add page iPage to the database file free-list.
@@ -58643,13 +58699,14 @@
58643 MemPage *pPage; /* Page being freed. May be NULL. */
58644 int rc; /* Return Code */
58645 int nFree; /* Initial number of pages on free-list */
58646
58647 assert( sqlite3_mutex_held(pBt->mutex) );
58648 assert( iPage>1 );
58649 assert( !pMemPage || pMemPage->pgno==iPage );
58650
 
58651 if( pMemPage ){
58652 pPage = pMemPage;
58653 sqlite3PagerRef(pPage->pDbPage);
58654 }else{
58655 pPage = btreePageLookup(pBt, iPage);
@@ -58797,11 +58854,13 @@
58797 }
58798 ovflPgno = get4byte(&pCell[info.iOverflow]);
58799 assert( pBt->usableSize > 4 );
58800 ovflPageSize = pBt->usableSize - 4;
58801 nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
58802 assert( ovflPgno==0 || nOvfl>0 );
 
 
58803 while( nOvfl-- ){
58804 Pgno iNext = 0;
58805 MemPage *pOvfl = 0;
58806 if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
58807 /* 0 is not a legal page number and page 1 cannot be an
@@ -59052,11 +59111,11 @@
59052 int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
59053
59054 if( *pRC ) return;
59055
59056 assert( idx>=0 && idx<pPage->nCell );
59057 assert( sz==cellSize(pPage, idx) );
59058 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
59059 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
59060 data = pPage->aData;
59061 ptr = &pPage->aCellIdx[2*idx];
59062 pc = get2byte(ptr);
@@ -59216,11 +59275,12 @@
59216 }
59217 pData -= szCell[i];
59218 memcpy(pData, pCell, szCell[i]);
59219 put2byte(pCellptr, (pData - aData));
59220 pCellptr += 2;
59221 assert( szCell[i]==cellSizePtr(pPg, pCell) );
 
59222 }
59223
59224 /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
59225 pPg->nCell = nCell;
59226 pPg->nOverflow = 0;
@@ -59893,10 +59953,18 @@
59893 leafCorrection = apOld[0]->leaf*4;
59894 leafData = apOld[0]->intKeyLeaf;
59895 for(i=0; i<nOld; i++){
59896 int limit;
59897 MemPage *pOld = apOld[i];
 
 
 
 
 
 
 
 
59898
59899 limit = pOld->nCell+pOld->nOverflow;
59900 if( pOld->nOverflow>0 ){
59901 for(j=0; j<limit; j++){
59902 assert( nCell<nMaxCells );
@@ -59935,17 +60003,17 @@
59935 /* The right pointer of the child page pOld becomes the left
59936 ** pointer of the divider cell */
59937 memcpy(apCell[nCell], &pOld->aData[8], 4);
59938 }else{
59939 assert( leafCorrection==4 );
59940 if( szCell[nCell]<4 ){
59941 /* Do not allow any cells smaller than 4 bytes. If a smaller cell
59942 ** does exist, pad it with 0x00 bytes. */
59943 assert( szCell[nCell]==3 );
59944 assert( apCell[nCell]==&aSpace1[iSpace1-3] );
59945 aSpace1[iSpace1++] = 0x00;
59946 szCell[nCell] = 4;
59947 }
59948 }
59949 nCell++;
59950 }
59951 }
@@ -60032,14 +60100,10 @@
60032 ));
60033
60034 /*
60035 ** Allocate k new pages. Reuse old pages where possible.
60036 */
60037 if( apOld[0]->pgno<=1 ){
60038 rc = SQLITE_CORRUPT_BKPT;
60039 goto balance_cleanup;
60040 }
60041 pageFlags = apOld[0]->aData[0];
60042 for(i=0; i<k; i++){
60043 MemPage *pNew;
60044 if( i<nOld ){
60045 pNew = apNew[i] = apOld[i];
@@ -60817,10 +60881,11 @@
60817 int nCell;
60818 Pgno n = pCur->apPage[iCellDepth+1]->pgno;
60819 unsigned char *pTmp;
60820
60821 pCell = findCell(pLeaf, pLeaf->nCell-1);
 
60822 nCell = cellSizePtr(pLeaf, pCell);
60823 assert( MX_CELL_SIZE(pBt) >= nCell );
60824 pTmp = pBt->pTmpSpace;
60825 assert( pTmp!=0 );
60826 rc = sqlite3PagerWrite(pLeaf->pDbPage);
@@ -60909,11 +60974,12 @@
60909 */
60910 while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
60911 pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
60912 pgnoRoot++;
60913 }
60914 assert( pgnoRoot>=3 );
 
60915
60916 /* Allocate a page. The page that currently resides at pgnoRoot will
60917 ** be moved to the allocated page (unless the allocated page happens
60918 ** to reside at pgnoRoot).
60919 */
@@ -61059,11 +61125,12 @@
61059 }
61060 if( !pPage->leaf ){
61061 rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
61062 if( rc ) goto cleardatabasepage_out;
61063 }else if( pnChange ){
61064 assert( pPage->intKey );
 
61065 *pnChange += pPage->nCell;
61066 }
61067 if( freePageFlag ){
61068 freePage(pPage, &rc);
61069 }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
@@ -63854,14 +63921,10 @@
63854 }
63855 pMem->pScopyFrom = 0;
63856 }
63857 #endif /* SQLITE_DEBUG */
63858
63859 /*
63860 ** Size of struct Mem not including the Mem.zMalloc member.
63861 */
63862 #define MEMCELLSIZE offsetof(Mem,zMalloc)
63863
63864 /*
63865 ** Make an shallow copy of pFrom into pTo. Prior contents of
63866 ** pTo are freed. The pFrom->z field is not duplicated. If
63867 ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
@@ -63884,11 +63947,14 @@
63884 ** freed before the copy is made.
63885 */
63886 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
63887 int rc = SQLITE_OK;
63888
63889 assert( pTo->db==pFrom->db );
 
 
 
63890 assert( (pFrom->flags & MEM_RowSet)==0 );
63891 if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
63892 memcpy(pTo, pFrom, MEMCELLSIZE);
63893 pTo->flags &= ~MEM_Dyn;
63894 if( pTo->flags&(MEM_Str|MEM_Blob) ){
@@ -64817,10 +64883,21 @@
64817 assert( pParse->aLabel==0 );
64818 assert( pParse->nLabel==0 );
64819 assert( pParse->nOpAlloc==0 );
64820 return p;
64821 }
 
 
 
 
 
 
 
 
 
 
 
64822
64823 /*
64824 ** Remember the SQL string for a prepared statement.
64825 */
64826 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
@@ -66174,11 +66251,11 @@
66174 p->rc = SQLITE_OK;
66175 rc = SQLITE_DONE;
66176 }else if( db->u1.isInterrupted ){
66177 p->rc = SQLITE_INTERRUPT;
66178 rc = SQLITE_ERROR;
66179 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
66180 }else{
66181 char *zP4;
66182 Op *pOp;
66183 if( i<p->nOp ){
66184 /* The output line number is small enough that we are still in the
@@ -67077,11 +67154,11 @@
67077 if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
67078 || (!deferred && p->nFkConstraint>0)
67079 ){
67080 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
67081 p->errorAction = OE_Abort;
67082 sqlite3SetString(&p->zErrMsg, db, "FOREIGN KEY constraint failed");
67083 return SQLITE_ERROR;
67084 }
67085 return SQLITE_OK;
67086 }
67087 #endif
@@ -68420,11 +68497,11 @@
68420
68421 /* RHS is an integer */
68422 if( pRhs->flags & MEM_Int ){
68423 serial_type = aKey1[idx1];
68424 testcase( serial_type==12 );
68425 if( serial_type>=12 ){
68426 rc = +1;
68427 }else if( serial_type==0 ){
68428 rc = -1;
68429 }else if( serial_type==7 ){
68430 double rhs = (double)pRhs->u.i;
@@ -68446,11 +68523,15 @@
68446 }
68447
68448 /* RHS is real */
68449 else if( pRhs->flags & MEM_Real ){
68450 serial_type = aKey1[idx1];
68451 if( serial_type>=12 ){
 
 
 
 
68452 rc = +1;
68453 }else if( serial_type==0 ){
68454 rc = -1;
68455 }else{
68456 double rhs = pRhs->u.r;
@@ -69184,10 +69265,40 @@
69184 SQLITE_INTEGER, /* 0x1e */
69185 SQLITE_NULL, /* 0x1f */
69186 };
69187 return aType[pVal->flags&MEM_AffMask];
69188 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69189
69190 /**************************** sqlite3_result_ *******************************
69191 ** The following routines are used by user-defined functions to specify
69192 ** the function result.
69193 **
@@ -71037,10 +71148,11 @@
71037 ** representation.
71038 */
71039 if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
71040 sqlite3VdbeMemStringify(pRec, enc, 1);
71041 }
 
71042 }
71043 }
71044
71045 /*
71046 ** Try to convert the type of a function argument or a result column
@@ -71797,16 +71909,15 @@
71797 zType = 0;
71798 }
71799 assert( zType!=0 || pOp->p4.z!=0 );
71800 zLogFmt = "abort at %d in [%s]: %s";
71801 if( zType && pOp->p4.z ){
71802 sqlite3SetString(&p->zErrMsg, db, "%s constraint failed: %s",
71803 zType, pOp->p4.z);
71804 }else if( pOp->p4.z ){
71805 sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
71806 }else{
71807 sqlite3SetString(&p->zErrMsg, db, "%s constraint failed", zType);
71808 }
71809 sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
71810 }
71811 rc = sqlite3VdbeHalt(p);
71812 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -72434,11 +72545,11 @@
72434 lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
72435
72436 /* If the function returned an error, throw an exception */
72437 if( ctx.fErrorOrAux ){
72438 if( ctx.isError ){
72439 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(ctx.pOut));
72440 rc = ctx.isError;
72441 }
72442 sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
72443 }
72444
@@ -73621,12 +73732,11 @@
73621 if( p1==SAVEPOINT_BEGIN ){
73622 if( db->nVdbeWrite>0 ){
73623 /* A new savepoint cannot be created if there are active write
73624 ** statements (i.e. open read/write incremental blob handles).
73625 */
73626 sqlite3SetString(&p->zErrMsg, db, "cannot open savepoint - "
73627 "SQL statements in progress");
73628 rc = SQLITE_BUSY;
73629 }else{
73630 nName = sqlite3Strlen30(zName);
73631
73632 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -73673,19 +73783,18 @@
73673 pSavepoint = pSavepoint->pNext
73674 ){
73675 iSavepoint++;
73676 }
73677 if( !pSavepoint ){
73678 sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", zName);
73679 rc = SQLITE_ERROR;
73680 }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
73681 /* It is not possible to release (commit) a savepoint if there are
73682 ** active write statements.
73683 */
73684 sqlite3SetString(&p->zErrMsg, db,
73685 "cannot release savepoint - SQL statements in progress"
73686 );
73687 rc = SQLITE_BUSY;
73688 }else{
73689
73690 /* Determine whether or not this is a transaction savepoint. If so,
73691 ** and this is a RELEASE command, then the current transaction
@@ -73787,27 +73896,16 @@
73787 assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
73788 assert( desiredAutoCommit==1 || iRollback==0 );
73789 assert( db->nVdbeActive>0 ); /* At least this one VM is active */
73790 assert( p->bIsReader );
73791
73792 #if 0
73793 if( turnOnAC && iRollback && db->nVdbeActive>1 ){
73794 /* If this instruction implements a ROLLBACK and other VMs are
73795 ** still running, and a transaction is active, return an error indicating
73796 ** that the other VMs must complete first.
73797 */
73798 sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - "
73799 "SQL statements in progress");
73800 rc = SQLITE_BUSY;
73801 }else
73802 #endif
73803 if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
73804 /* If this instruction implements a COMMIT and other VMs are writing
73805 ** return an error indicating that the other VMs must complete first.
73806 */
73807 sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - "
73808 "SQL statements in progress");
73809 rc = SQLITE_BUSY;
73810 }else if( desiredAutoCommit!=db->autoCommit ){
73811 if( iRollback ){
73812 assert( desiredAutoCommit==1 );
73813 sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
@@ -73830,11 +73928,11 @@
73830 }else{
73831 rc = SQLITE_ERROR;
73832 }
73833 goto vdbe_return;
73834 }else{
73835 sqlite3SetString(&p->zErrMsg, db,
73836 (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
73837 (iRollback)?"cannot rollback - no transaction is active":
73838 "cannot commit - no transaction is active"));
73839
73840 rc = SQLITE_ERROR;
@@ -76263,11 +76361,11 @@
76263 if( pFrame ) break;
76264 }
76265
76266 if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
76267 rc = SQLITE_ERROR;
76268 sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion");
76269 break;
76270 }
76271
76272 /* Register pRt is used to store the memory required to save the state
76273 ** of the current program, and the memory required at runtime to execute
@@ -76566,11 +76664,11 @@
76566 ctx.pVdbe = p;
76567 ctx.iOp = (int)(pOp - aOp);
76568 ctx.skipFlag = 0;
76569 (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
76570 if( ctx.isError ){
76571 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&t));
76572 rc = ctx.isError;
76573 }
76574 if( ctx.skipFlag ){
76575 assert( pOp[-1].opcode==OP_CollSeq );
76576 i = pOp[-1].p1;
@@ -76598,11 +76696,11 @@
76598 assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
76599 pMem = &aMem[pOp->p1];
76600 assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
76601 rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
76602 if( rc ){
76603 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
76604 }
76605 sqlite3VdbeChangeEncoding(pMem, encoding);
76606 UPDATE_MAX_BLOBSIZE(pMem);
76607 if( sqlite3VdbeMemTooBig(pMem) ){
76608 goto too_big;
@@ -76703,11 +76801,11 @@
76703 if( (eNew!=eOld)
76704 && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
76705 ){
76706 if( !db->autoCommit || db->nVdbeRead>1 ){
76707 rc = SQLITE_ERROR;
76708 sqlite3SetString(&p->zErrMsg, db,
76709 "cannot change %s wal mode from within a transaction",
76710 (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
76711 );
76712 break;
76713 }else{
@@ -76834,11 +76932,11 @@
76834 assert( DbMaskTest(p->btreeMask, p1) );
76835 assert( isWriteLock==0 || isWriteLock==1 );
76836 rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
76837 if( (rc&0xFF)==SQLITE_LOCKED ){
76838 const char *z = pOp->p4.z;
76839 sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
76840 }
76841 }
76842 break;
76843 }
76844 #endif /* SQLITE_OMIT_SHARED_CACHE */
@@ -77382,19 +77480,19 @@
77382
77383 /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
77384 ** is encountered.
77385 */
77386 too_big:
77387 sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
77388 rc = SQLITE_TOOBIG;
77389 goto vdbe_error_halt;
77390
77391 /* Jump to here if a malloc() fails.
77392 */
77393 no_mem:
77394 db->mallocFailed = 1;
77395 sqlite3SetString(&p->zErrMsg, db, "out of memory");
77396 rc = SQLITE_NOMEM;
77397 goto vdbe_error_halt;
77398
77399 /* Jump to here for any other kind of fatal error. The "rc" variable
77400 ** should hold the error number.
@@ -77401,11 +77499,11 @@
77401 */
77402 abort_due_to_error:
77403 assert( p->zErrMsg==0 );
77404 if( db->mallocFailed ) rc = SQLITE_NOMEM;
77405 if( rc!=SQLITE_IOERR_NOMEM ){
77406 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
77407 }
77408 goto vdbe_error_halt;
77409
77410 /* Jump to here if the sqlite3_interrupt() API sets the interrupt
77411 ** flag.
@@ -77412,11 +77510,11 @@
77412 */
77413 abort_due_to_interrupt:
77414 assert( db->u1.isInterrupted );
77415 rc = SQLITE_INTERRUPT;
77416 p->rc = rc;
77417 sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
77418 goto vdbe_error_halt;
77419 }
77420
77421
77422 /************** End of vdbe.c ************************************************/
@@ -81651,11 +81749,11 @@
81651 iCol = -1;
81652 }
81653 break;
81654 }
81655 }
81656 if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
81657 /* IMP: R-51414-32910 */
81658 /* IMP: R-44911-55124 */
81659 iCol = -1;
81660 }
81661 if( iCol<pTab->nCol ){
@@ -81681,11 +81779,11 @@
81681
81682 /*
81683 ** Perhaps the name is a reference to the ROWID
81684 */
81685 if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
81686 && HasRowid(pMatch->pTab) ){
81687 cnt = 1;
81688 pExpr->iColumn = -1; /* IMP: R-44911-55124 */
81689 pExpr->affinity = SQLITE_AFF_INTEGER;
81690 }
81691
@@ -92125,18 +92223,15 @@
92125 #ifndef SQLITE_OMIT_AUTOINCREMENT
92126 sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
92127 "INTEGER PRIMARY KEY");
92128 #endif
92129 }else{
92130 Vdbe *v = pParse->pVdbe;
92131 Index *p;
92132 if( v ) pParse->addrSkipPK = sqlite3VdbeAddOp0(v, OP_Noop);
92133 p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
92134 0, sortOrder, 0);
92135 if( p ){
92136 p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
92137 if( v ) sqlite3VdbeJumpHere(v, pParse->addrSkipPK);
92138 }
92139 pList = 0;
92140 }
92141
92142 primary_key_exit:
@@ -92485,18 +92580,10 @@
92485 if( pParse->addrCrTab ){
92486 assert( v );
92487 sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
92488 }
92489
92490 /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
92491 ** table entry.
92492 */
92493 if( pParse->addrSkipPK ){
92494 assert( v );
92495 sqlite3VdbeGetOp(v, pParse->addrSkipPK)->opcode = OP_Goto;
92496 }
92497
92498 /* Locate the PRIMARY KEY index. Or, if this table was originally
92499 ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
92500 */
92501 if( pTab->iPKey>=0 ){
92502 ExprList *pList;
@@ -92510,10 +92597,20 @@
92510 if( pPk==0 ) return;
92511 pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
92512 pTab->iPKey = -1;
92513 }else{
92514 pPk = sqlite3PrimaryKeyIndex(pTab);
 
 
 
 
 
 
 
 
 
 
92515 /*
92516 ** Remove all redundant columns from the PRIMARY KEY. For example, change
92517 ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
92518 ** code assumes the PRIMARY KEY contains no repeated columns.
92519 */
@@ -92645,11 +92742,11 @@
92645 return;
92646 }
92647 if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
92648 sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
92649 }else{
92650 p->tabFlags |= TF_WithoutRowid;
92651 convertToWithoutRowidTable(pParse, p);
92652 }
92653 }
92654
92655 iDb = sqlite3SchemaToIndex(db, p->pSchema);
@@ -92713,30 +92810,49 @@
92713 ** as a schema-lock must have already been obtained to create it. Since
92714 ** a schema-lock excludes all other database users, the write-lock would
92715 ** be redundant.
92716 */
92717 if( pSelect ){
92718 SelectDest dest;
92719 Table *pSelTab;
 
 
 
 
 
92720
 
 
 
92721 assert(pParse->nTab==1);
92722 sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
92723 sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
92724 pParse->nTab = 2;
92725 sqlite3SelectDestInit(&dest, SRT_Table, 1);
 
 
92726 sqlite3Select(pParse, pSelect, &dest);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92727 sqlite3VdbeAddOp1(v, OP_Close, 1);
92728 if( pParse->nErr==0 ){
92729 pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
92730 if( pSelTab==0 ) return;
92731 assert( p->aCol==0 );
92732 p->nCol = pSelTab->nCol;
92733 p->aCol = pSelTab->aCol;
92734 pSelTab->nCol = 0;
92735 pSelTab->aCol = 0;
92736 sqlite3DeleteTable(db, pSelTab);
92737 }
92738 }
92739
92740 /* Compute the complete text of the CREATE statement */
92741 if( pSelect ){
92742 zStmt = createTableStmt(db, p);
@@ -94031,14 +94147,19 @@
94031 int iMem = ++pParse->nMem;
94032
94033 v = sqlite3GetVdbe(pParse);
94034 if( v==0 ) goto exit_create_index;
94035
94036
94037 /* Create the rootpage for the index
94038 */
94039 sqlite3BeginWriteOperation(pParse, 1, iDb);
 
 
 
 
 
 
 
 
94040 sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
94041
94042 /* Gather the complete text of the CREATE INDEX statement into
94043 ** the zStmt variable
94044 */
@@ -94074,10 +94195,12 @@
94074 sqlite3ChangeCookie(pParse, iDb);
94075 sqlite3VdbeAddParseSchemaOp(v, iDb,
94076 sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
94077 sqlite3VdbeAddOp1(v, OP_Expire, 0);
94078 }
 
 
94079 }
94080
94081 /* When adding an index to the list of indices for a table, make
94082 ** sure all indices labeled OE_Replace come after all those labeled
94083 ** OE_Ignore. This is necessary for the correct constraint check
@@ -99669,11 +99792,11 @@
99669 sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
99670 VdbeComment((v, "%s", pTab->zName));
99671 }else{
99672 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
99673 assert( pPk!=0 );
99674 assert( pPk->tnum=pTab->tnum );
99675 sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
99676 sqlite3VdbeSetP4KeyInfo(pParse, pPk);
99677 VdbeComment((v, "%s", pTab->zName));
99678 }
99679 }
@@ -102119,10 +102242,12 @@
102119 void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
102120 void(*)(void*));
102121 void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
102122 void(*)(void*), unsigned char);
102123 int (*strglob)(const char*,const char*);
 
 
102124 };
102125
102126 /*
102127 ** The following macros redefine the API routines so that they are
102128 ** redirected through the global sqlite3_api structure.
@@ -102349,10 +102474,13 @@
102349 #define sqlite3_realloc64 sqlite3_api->realloc64
102350 #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
102351 #define sqlite3_result_blob64 sqlite3_api->result_blob64
102352 #define sqlite3_result_text64 sqlite3_api->result_text64
102353 #define sqlite3_strglob sqlite3_api->strglob
 
 
 
102354 #endif /* SQLITE_CORE */
102355
102356 #ifndef SQLITE_CORE
102357 /* This case when the file really is being compiled as a loadable
102358 ** extension */
@@ -103255,10 +103383,14 @@
103255 #endif
103256 { /* zName: */ "case_sensitive_like",
103257 /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
103258 /* ePragFlag: */ 0,
103259 /* iArg: */ 0 },
 
 
 
 
103260 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
103261 { /* zName: */ "checkpoint_fullfsync",
103262 /* ePragTyp: */ PragTyp_FLAG,
103263 /* ePragFlag: */ 0,
103264 /* iArg: */ SQLITE_CkptFullFSync },
@@ -103612,11 +103744,11 @@
103612 /* ePragTyp: */ PragTyp_FLAG,
103613 /* ePragFlag: */ 0,
103614 /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
103615 #endif
103616 };
103617 /* Number of pragmas: 59 on by default, 72 total. */
103618
103619 /************** End of pragma.h **********************************************/
103620 /************** Continuing where we left off in pragma.c *********************/
103621
103622 /*
@@ -105595,17 +105727,17 @@
105595 const char *zObj, /* Object being parsed at the point of error */
105596 const char *zExtra /* Error information */
105597 ){
105598 sqlite3 *db = pData->db;
105599 if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
 
105600 if( zObj==0 ) zObj = "?";
105601 sqlite3SetString(pData->pzErrMsg, db,
105602 "malformed database schema (%s)", zObj);
105603 if( zExtra ){
105604 *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg,
105605 "%s - %s", *pData->pzErrMsg, zExtra);
105606 }
105607 }
105608 pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
105609 }
105610
105611 /*
@@ -105793,11 +105925,11 @@
105793 ** will be closed before this function returns. */
105794 sqlite3BtreeEnter(pDb->pBt);
105795 if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
105796 rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
105797 if( rc!=SQLITE_OK ){
105798 sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
105799 goto initone_error_out;
105800 }
105801 openedTransaction = 1;
105802 }
105803
@@ -107177,12 +107309,17 @@
107177 }
107178 }else if( eDest!=SRT_Exists ){
107179 /* If the destination is an EXISTS(...) expression, the actual
107180 ** values returned by the SELECT are not required.
107181 */
107182 sqlite3ExprCodeExprList(pParse, pEList, regResult,
107183 (eDest==SRT_Output||eDest==SRT_Coroutine)?SQLITE_ECEL_DUP:0);
 
 
 
 
 
107184 }
107185
107186 /* If the DISTINCT keyword was present on the SELECT statement
107187 ** and this row has been seen before, then do not make this row
107188 ** part of the result.
@@ -107275,10 +107412,12 @@
107275 case SRT_Table:
107276 case SRT_EphemTab: {
107277 int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
107278 testcase( eDest==SRT_Table );
107279 testcase( eDest==SRT_EphemTab );
 
 
107280 sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
107281 #ifndef SQLITE_OMIT_CTE
107282 if( eDest==SRT_DistFifo ){
107283 /* If the destination is DistFifo, then cursor (iParm+1) is open
107284 ** on an ephemeral index. If the current row is already present
@@ -107690,14 +107829,11 @@
107690 for(i=0; i<nSortData; i++){
107691 sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
107692 VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
107693 }
107694 switch( eDest ){
107695 case SRT_Table:
107696 case SRT_EphemTab: {
107697 testcase( eDest==SRT_Table );
107698 testcase( eDest==SRT_EphemTab );
107699 sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
107700 sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
107701 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
107702 break;
107703 }
@@ -109042,19 +109178,18 @@
109042
109043 /* Suppress the first OFFSET entries if there is an OFFSET clause
109044 */
109045 codeOffset(v, p->iOffset, iContinue);
109046
 
 
109047 switch( pDest->eDest ){
109048 /* Store the result as data using a unique key.
109049 */
109050 case SRT_Table:
109051 case SRT_EphemTab: {
109052 int r1 = sqlite3GetTempReg(pParse);
109053 int r2 = sqlite3GetTempReg(pParse);
109054 testcase( pDest->eDest==SRT_Table );
109055 testcase( pDest->eDest==SRT_EphemTab );
109056 sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
109057 sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
109058 sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
109059 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
109060 sqlite3ReleaseTempReg(pParse, r2);
@@ -109078,20 +109213,10 @@
109078 sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
109079 sqlite3ReleaseTempReg(pParse, r1);
109080 break;
109081 }
109082
109083 #if 0 /* Never occurs on an ORDER BY query */
109084 /* If any row exist in the result set, record that fact and abort.
109085 */
109086 case SRT_Exists: {
109087 sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm);
109088 /* The LIMIT clause will terminate the loop for us */
109089 break;
109090 }
109091 #endif
109092
109093 /* If this is a scalar select that is part of an expression, then
109094 ** store the results in the appropriate memory cell and break out
109095 ** of the scan loop.
109096 */
109097 case SRT_Mem: {
@@ -110462,11 +110587,11 @@
110462 if( pTab==0 ) return WRC_Abort;
110463 pTab->nRef = 1;
110464 pTab->zName = sqlite3DbStrDup(db, pCte->zName);
110465 pTab->iPKey = -1;
110466 pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
110467 pTab->tabFlags |= TF_Ephemeral;
110468 pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
110469 if( db->mallocFailed ) return SQLITE_NOMEM;
110470 assert( pFrom->pSelect );
110471
110472 /* Check if this is a recursive CTE. */
@@ -110707,17 +110832,10 @@
110707 ExprList *pNew = 0;
110708 int flags = pParse->db->flags;
110709 int longNames = (flags & SQLITE_FullColNames)!=0
110710 && (flags & SQLITE_ShortColNames)==0;
110711
110712 /* When processing FROM-clause subqueries, it is always the case
110713 ** that full_column_names=OFF and short_column_names=ON. The
110714 ** sqlite3ResultSetOfSelect() routine makes it so. */
110715 assert( (p->selFlags & SF_NestedFrom)==0
110716 || ((flags & SQLITE_FullColNames)==0 &&
110717 (flags & SQLITE_ShortColNames)!=0) );
110718
110719 for(k=0; k<pEList->nExpr; k++){
110720 pE = a[k].pExpr;
110721 pRight = pE->pRight;
110722 assert( pE->op!=TK_DOT || pRight!=0 );
110723 if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
@@ -111295,10 +111413,11 @@
111295 isAgg = 1;
111296 p->selFlags |= SF_Aggregate;
111297 }
111298 i = -1;
111299 }else if( pTabList->nSrc==1
 
111300 && OptimizationEnabled(db, SQLITE_SubqCoroutine)
111301 ){
111302 /* Implement a co-routine that will return a single row of the result
111303 ** set on each invocation.
111304 */
@@ -111982,13 +112101,13 @@
111982 ** Generate a human-readable description of a the Select object.
111983 */
111984 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
111985 int n = 0;
111986 pView = sqlite3TreeViewPush(pView, moreToFollow);
111987 sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p)",
111988 ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
111989 ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p
111990 );
111991 if( p->pSrc && p->pSrc->nSrc ) n++;
111992 if( p->pWhere ) n++;
111993 if( p->pGroupBy ) n++;
111994 if( p->pHaving ) n++;
@@ -114138,16 +114257,14 @@
114138 /* Create the ephemeral table into which the update results will
114139 ** be stored.
114140 */
114141 assert( v );
114142 ephemTab = pParse->nTab++;
114143 sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab->nCol+1+(pRowid!=0));
114144 sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
114145
114146 /* fill the ephemeral table
114147 */
114148 sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
114149 sqlite3Select(pParse, pSelect, &dest);
114150
114151 /* Generate code to scan the ephemeral table and call VUpdate. */
114152 iReg = ++pParse->nMem;
114153 pParse->nMem += pTab->nCol+1;
@@ -115998,10 +116115,11 @@
115998 # define TERM_VNULL 0x00 /* Disabled if not using stat3 */
115999 #endif
116000 #define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
116001 #define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
116002 #define TERM_LIKE 0x400 /* The original LIKE operator */
 
116003
116004 /*
116005 ** An instance of the WhereScan object is used as an iterator for locating
116006 ** terms in the WHERE clause that are useful to the query planner.
116007 */
@@ -116146,25 +116264,26 @@
116146 ** Bitmasks for the operators on WhereTerm objects. These are all
116147 ** operators that are of interest to the query planner. An
116148 ** OR-ed combination of these values can be used when searching for
116149 ** particular WhereTerms within a WhereClause.
116150 */
116151 #define WO_IN 0x001
116152 #define WO_EQ 0x002
116153 #define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
116154 #define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
116155 #define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
116156 #define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
116157 #define WO_MATCH 0x040
116158 #define WO_ISNULL 0x080
116159 #define WO_OR 0x100 /* Two or more OR-connected terms */
116160 #define WO_AND 0x200 /* Two or more AND-connected terms */
116161 #define WO_EQUIV 0x400 /* Of the form A==B, both columns */
116162 #define WO_NOOP 0x800 /* This term does not restrict search space */
116163
116164 #define WO_ALL 0xfff /* Mask of all possible WO_* values */
116165 #define WO_SINGLE 0x0ff /* Mask of all non-compound WO_* values */
 
116166
116167 /*
116168 ** These are definitions of bits in the WhereLoop.wsFlags field.
116169 ** The particular combination of bits in each WhereLoop help to
116170 ** determine the algorithm that WhereLoop represents.
@@ -116534,11 +116653,11 @@
116534 static int allowedOp(int op){
116535 assert( TK_GT>TK_EQ && TK_GT<TK_GE );
116536 assert( TK_LT>TK_EQ && TK_LT<TK_GE );
116537 assert( TK_LE>TK_EQ && TK_LE<TK_GE );
116538 assert( TK_GE==TK_EQ+4 );
116539 return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL;
116540 }
116541
116542 /*
116543 ** Commute a comparison operator. Expressions of the form "X op Y"
116544 ** are converted into "Y op X".
@@ -116587,10 +116706,12 @@
116587 assert( allowedOp(op) );
116588 if( op==TK_IN ){
116589 c = WO_IN;
116590 }else if( op==TK_ISNULL ){
116591 c = WO_ISNULL;
 
 
116592 }else{
116593 assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
116594 c = (u16)(WO_EQ<<(op-TK_EQ));
116595 }
116596 assert( op!=TK_ISNULL || c==WO_ISNULL );
@@ -116598,10 +116719,11 @@
116598 assert( op!=TK_EQ || c==WO_EQ );
116599 assert( op!=TK_LT || c==WO_LT );
116600 assert( op!=TK_LE || c==WO_LE );
116601 assert( op!=TK_GT || c==WO_GT );
116602 assert( op!=TK_GE || c==WO_GE );
 
116603 return c;
116604 }
116605
116606 /*
116607 ** Advance to the next WhereTerm that matches according to the criteria
@@ -116658,15 +116780,16 @@
116658 if( pColl==0 ) pColl = pParse->db->pDfltColl;
116659 if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
116660 continue;
116661 }
116662 }
116663 if( (pTerm->eOperator & WO_EQ)!=0
116664 && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
116665 && pX->iTable==pScan->aEquiv[0]
116666 && pX->iColumn==pScan->aEquiv[1]
116667 ){
 
116668 continue;
116669 }
116670 pScan->k = k+1;
116671 return pTerm;
116672 }
@@ -116764,13 +116887,15 @@
116764 WhereTerm *pResult = 0;
116765 WhereTerm *p;
116766 WhereScan scan;
116767
116768 p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
 
116769 while( p ){
116770 if( (p->prereqRight & notReady)==0 ){
116771 if( p->prereqRight==0 && (p->eOperator&WO_EQ)!=0 ){
 
116772 return p;
116773 }
116774 if( pResult==0 ) pResult = p;
116775 }
116776 p = whereScanNext(&scan);
@@ -116801,11 +116926,11 @@
116801 ** so and false if not.
116802 **
116803 ** In order for the operator to be optimizible, the RHS must be a string
116804 ** literal that does not begin with a wildcard. The LHS must be a column
116805 ** that may only be NULL, a string, or a BLOB, never a number. (This means
116806 ** that virtual tables cannot participate in the LIKE optimization.) If the
116807 ** collating sequence for the column on the LHS must be appropriate for
116808 ** the operator.
116809 */
116810 static int isLikeOrGlob(
116811 Parse *pParse, /* Parsing and code generating context */
@@ -117346,10 +117471,50 @@
117346 pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */
117347 }
117348 }
117349 }
117350 #endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117351
117352 /*
117353 ** The input to this routine is an WhereTerm structure with only the
117354 ** "pExpr" field filled in. The job of this routine is to analyze the
117355 ** subexpression and populate all the other fields of the WhereTerm
@@ -117425,10 +117590,11 @@
117425 if( pLeft->op==TK_COLUMN ){
117426 pTerm->leftCursor = pLeft->iTable;
117427 pTerm->u.leftColumn = pLeft->iColumn;
117428 pTerm->eOperator = operatorMask(op) & opMask;
117429 }
 
117430 if( pRight && pRight->op==TK_COLUMN ){
117431 WhereTerm *pNew;
117432 Expr *pDup;
117433 u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
117434 if( pTerm->leftCursor>=0 ){
@@ -117440,16 +117606,15 @@
117440 }
117441 idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
117442 if( idxNew==0 ) return;
117443 pNew = &pWC->a[idxNew];
117444 markTermAsChild(pWC, idxNew, idxTerm);
 
117445 pTerm = &pWC->a[idxTerm];
117446 pTerm->wtFlags |= TERM_COPIED;
117447 if( pExpr->op==TK_EQ
117448 && !ExprHasProperty(pExpr, EP_FromJoin)
117449 && OptimizationEnabled(db, SQLITE_Transitive)
117450 ){
117451 pTerm->eOperator |= WO_EQUIV;
117452 eExtraOp = WO_EQUIV;
117453 }
117454 }else{
117455 pDup = pExpr;
@@ -117639,14 +117804,11 @@
117639 /* When sqlite_stat3 histogram data is available an operator of the
117640 ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
117641 ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
117642 ** virtual term of that form.
117643 **
117644 ** Note that the virtual term must be tagged with TERM_VNULL. This
117645 ** TERM_VNULL tag will suppress the not-null check at the beginning
117646 ** of the loop. Without the TERM_VNULL flag, the not-null check at
117647 ** the start of the loop will prevent any results from being returned.
117648 */
117649 if( pExpr->op==TK_NOTNULL
117650 && pExpr->pLeft->op==TK_COLUMN
117651 && pExpr->pLeft->iColumn>=0
117652 && OptimizationEnabled(db, SQLITE_Stat34)
@@ -117787,10 +117949,40 @@
117787 ** Estimate the logarithm of the input value to base 2.
117788 */
117789 static LogEst estLog(LogEst N){
117790 return N<=10 ? 0 : sqlite3LogEst(N) - 33;
117791 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117792
117793 /*
117794 ** Two routines for printing the content of an sqlite3_index_info
117795 ** structure. Used for testing and debugging only. If neither
117796 ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
@@ -117846,15 +118038,16 @@
117846 struct SrcList_item *pSrc, /* Table we are trying to access */
117847 Bitmask notReady /* Tables in outer loops of the join */
117848 ){
117849 char aff;
117850 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
117851 if( (pTerm->eOperator & WO_EQ)==0 ) return 0;
117852 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
117853 if( pTerm->u.leftColumn<0 ) return 0;
117854 aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
117855 if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
 
117856 return 1;
117857 }
117858 #endif
117859
117860
@@ -117889,10 +118082,11 @@
117889 Bitmask idxCols; /* Bitmap of columns used for indexing */
117890 Bitmask extraCols; /* Bitmap of additional columns */
117891 u8 sentWarning = 0; /* True if a warnning has been issued */
117892 Expr *pPartial = 0; /* Partial Index Expression */
117893 int iContinue = 0; /* Jump here to skip excluded rows */
 
117894
117895 /* Generate code to skip over the creation and initialization of the
117896 ** transient index on 2nd and subsequent iterations of the loop. */
117897 v = pParse->pVdbe;
117898 assert( v!=0 );
@@ -118014,11 +118208,20 @@
118014 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
118015 VdbeComment((v, "for %s", pTable->zName));
118016
118017 /* Fill the automatic index with content */
118018 sqlite3ExprCachePush(pParse);
118019 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
 
 
 
 
 
 
 
 
 
118020 if( pPartial ){
118021 iContinue = sqlite3VdbeMakeLabel(v);
118022 sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
118023 pLoop->wsFlags |= WHERE_PARTIALIDX;
118024 }
@@ -118025,11 +118228,17 @@
118025 regRecord = sqlite3GetTempReg(pParse);
118026 sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
118027 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
118028 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
118029 if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
118030 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
 
 
 
 
 
 
118031 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
118032 sqlite3VdbeJumpHere(v, addrTop);
118033 sqlite3ReleaseTempReg(pParse, regRecord);
118034 sqlite3ExprCachePop(pParse);
118035
@@ -118067,12 +118276,13 @@
118067 for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
118068 if( pTerm->leftCursor != pSrc->iCursor ) continue;
118069 assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
118070 testcase( pTerm->eOperator & WO_IN );
118071 testcase( pTerm->eOperator & WO_ISNULL );
 
118072 testcase( pTerm->eOperator & WO_ALL );
118073 if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
118074 if( pTerm->wtFlags & TERM_VNULL ) continue;
118075 nTerm++;
118076 }
118077
118078 /* If the ORDER BY clause contains only columns in the current
@@ -118119,13 +118329,14 @@
118119 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
118120 u8 op;
118121 if( pTerm->leftCursor != pSrc->iCursor ) continue;
118122 assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
118123 testcase( pTerm->eOperator & WO_IN );
 
118124 testcase( pTerm->eOperator & WO_ISNULL );
118125 testcase( pTerm->eOperator & WO_ALL );
118126 if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV))==0 ) continue;
118127 if( pTerm->wtFlags & TERM_VNULL ) continue;
118128 pIdxCons[j].iColumn = pTerm->u.leftColumn;
118129 pIdxCons[j].iTermOffset = i;
118130 op = (u8)pTerm->eOperator & WO_ALL;
118131 if( op==WO_IN ) op = WO_EQ;
@@ -118963,11 +119174,11 @@
118963 Expr *pX = pTerm->pExpr;
118964 Vdbe *v = pParse->pVdbe;
118965 int iReg; /* Register holding results */
118966
118967 assert( iTarget>0 );
118968 if( pX->op==TK_EQ ){
118969 iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
118970 }else if( pX->op==TK_ISNULL ){
118971 iReg = iTarget;
118972 sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
118973 #ifndef SQLITE_OMIT_SUBQUERY
@@ -119148,11 +119359,11 @@
119148 }
119149 testcase( pTerm->eOperator & WO_ISNULL );
119150 testcase( pTerm->eOperator & WO_IN );
119151 if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
119152 Expr *pRight = pTerm->pExpr->pRight;
119153 if( sqlite3ExprCanBeNull(pRight) ){
119154 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
119155 VdbeCoverage(v);
119156 }
119157 if( zAff ){
119158 if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
@@ -120270,20 +120481,23 @@
120270 */
120271 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
120272 Expr *pE, *pEAlt;
120273 WhereTerm *pAlt;
120274 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
120275 if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
 
120276 if( pTerm->leftCursor!=iCur ) continue;
120277 if( pLevel->iLeftJoin ) continue;
120278 pE = pTerm->pExpr;
120279 assert( !ExprHasProperty(pE, EP_FromJoin) );
120280 assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
120281 pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN, 0);
 
120282 if( pAlt==0 ) continue;
120283 if( pAlt->wtFlags & (TERM_CODED) ) continue;
120284 testcase( pAlt->eOperator & WO_EQ );
 
120285 testcase( pAlt->eOperator & WO_IN );
120286 VdbeModuleComment((v, "begin transitive constraint"));
120287 pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
120288 if( pEAlt ){
120289 *pEAlt = *pAlt->pExpr;
@@ -120329,13 +120543,14 @@
120329 char zType[4];
120330 memcpy(zType, "...", 4);
120331 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
120332 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
120333 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
120334 sqlite3DebugPrintf("TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x\n",
120335 iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
120336 pTerm->eOperator);
 
120337 sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
120338 }
120339 }
120340 #endif
120341
@@ -120821,12 +121036,13 @@
120821 pLoop->nOut += pTerm->truthProb;
120822 }else{
120823 /* In the absence of explicit truth probabilities, use heuristics to
120824 ** guess a reasonable truth probability. */
120825 pLoop->nOut--;
120826 if( pTerm->eOperator&WO_EQ ){
120827 Expr *pRight = pTerm->pExpr->pRight;
 
120828 if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
120829 k = 10;
120830 }else{
120831 k = 20;
120832 }
@@ -120890,14 +121106,14 @@
120890
120891 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
120892 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
120893 if( pNew->wsFlags & WHERE_BTM_LIMIT ){
120894 opMask = WO_LT|WO_LE;
120895 }else if( pProbe->tnum<=0 || (pSrc->jointype & JT_LEFT)!=0 ){
120896 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
120897 }else{
120898 opMask = WO_EQ|WO_IN|WO_ISNULL|WO_GT|WO_GE|WO_LT|WO_LE;
120899 }
120900 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
120901
120902 assert( pNew->u.btree.nEq<pProbe->nColumn );
120903 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
@@ -120956,11 +121172,11 @@
120956 nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
120957 }
120958 assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
120959 ** changes "x IN (?)" into "x=?". */
120960
120961 }else if( eOp & (WO_EQ) ){
120962 pNew->wsFlags |= WHERE_COLUMN_EQ;
120963 if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
120964 if( iCol>=0 && pProbe->uniqNotNull==0 ){
120965 pNew->wsFlags |= WHERE_UNQ_WANTED;
120966 }else{
@@ -121006,11 +121222,11 @@
121006 /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
121007 ** data, using some other estimate. */
121008 whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
121009 }else{
121010 int nEq = ++pNew->u.btree.nEq;
121011 assert( eOp & (WO_ISNULL|WO_EQ|WO_IN) );
121012
121013 assert( pNew->nOut==saved_nOut );
121014 if( pTerm->truthProb<=0 && iCol>=0 ){
121015 assert( (eOp & WO_IN) || nIn==0 );
121016 testcase( eOp & WO_IN );
@@ -121023,12 +121239,13 @@
121023 && pProbe->nSample
121024 && pNew->u.btree.nEq<=pProbe->nSampleCol
121025 && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
121026 ){
121027 Expr *pExpr = pTerm->pExpr;
121028 if( (eOp & (WO_EQ|WO_ISNULL))!=0 ){
121029 testcase( eOp & WO_EQ );
 
121030 testcase( eOp & WO_ISNULL );
121031 rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
121032 }else{
121033 rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
121034 }
@@ -121293,19 +121510,18 @@
121293 rSize = pTab->nRowLogEst;
121294 rLogSize = estLog(rSize);
121295
121296 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
121297 /* Automatic indexes */
121298 if( !pBuilder->pOrSet
121299 && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
121300 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
121301 && pSrc->pIndex==0
121302 && !pSrc->viaCoroutine
121303 && !pSrc->notIndexed
121304 && HasRowid(pTab)
121305 && !pSrc->isCorrelated
121306 && !pSrc->isRecursive
121307 ){
121308 /* Generate auto-index WhereLoops */
121309 WhereTerm *pTerm;
121310 WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
121311 for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
@@ -121861,21 +122077,22 @@
121861 if( MASKBIT(i) & obSat ) continue;
121862 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
121863 if( pOBExpr->op!=TK_COLUMN ) continue;
121864 if( pOBExpr->iTable!=iCur ) continue;
121865 pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
121866 ~ready, WO_EQ|WO_ISNULL, 0);
121867 if( pTerm==0 ) continue;
121868 if( (pTerm->eOperator&WO_EQ)!=0 && pOBExpr->iColumn>=0 ){
121869 const char *z1, *z2;
121870 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
121871 if( !pColl ) pColl = db->pDfltColl;
121872 z1 = pColl->zName;
121873 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
121874 if( !pColl ) pColl = db->pDfltColl;
121875 z2 = pColl->zName;
121876 if( sqlite3StrICmp(z1, z2)!=0 ) continue;
 
121877 }
121878 obSat |= MASKBIT(i);
121879 }
121880
121881 if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
@@ -121902,11 +122119,11 @@
121902 u8 bOnce; /* True to run the ORDER BY search loop */
121903
121904 /* Skip over == and IS NULL terms */
121905 if( j<pLoop->u.btree.nEq
121906 && pLoop->nSkip==0
121907 && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL))!=0
121908 ){
121909 if( i & WO_ISNULL ){
121910 testcase( isOrderDistinct );
121911 isOrderDistinct = 0;
121912 }
@@ -122475,28 +122692,32 @@
122475 iCur = pItem->iCursor;
122476 pWC = &pWInfo->sWC;
122477 pLoop = pBuilder->pNew;
122478 pLoop->wsFlags = 0;
122479 pLoop->nSkip = 0;
122480 pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ, 0);
122481 if( pTerm ){
 
122482 pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
122483 pLoop->aLTerm[0] = pTerm;
122484 pLoop->nLTerm = 1;
122485 pLoop->u.btree.nEq = 1;
122486 /* TUNING: Cost of a rowid lookup is 10 */
122487 pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */
122488 }else{
122489 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
 
122490 assert( pLoop->aLTermSpace==pLoop->aLTerm );
122491 if( !IsUniqueIndex(pIdx)
122492 || pIdx->pPartIdxWhere!=0
122493 || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
122494 ) continue;
 
122495 for(j=0; j<pIdx->nKeyCol; j++){
122496 pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
122497 if( pTerm==0 ) break;
 
122498 pLoop->aLTerm[j] = pTerm;
122499 }
122500 if( j!=pIdx->nKeyCol ) continue;
122501 pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
122502 if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
@@ -123131,30 +123352,16 @@
123131 Table *pTab = pTabItem->pTab;
123132 assert( pTab!=0 );
123133 pLoop = pLevel->pWLoop;
123134
123135 /* For a co-routine, change all OP_Column references to the table of
123136 ** the co-routine into OP_SCopy of result contained in a register.
123137 ** OP_Rowid becomes OP_Null.
123138 */
123139 if( pTabItem->viaCoroutine && !db->mallocFailed ){
123140 last = sqlite3VdbeCurrentAddr(v);
123141 k = pLevel->addrBody;
123142 pOp = sqlite3VdbeGetOp(v, k);
123143 for(; k<last; k++, pOp++){
123144 if( pOp->p1!=pLevel->iTabCur ) continue;
123145 if( pOp->opcode==OP_Column ){
123146 pOp->opcode = OP_Copy;
123147 pOp->p1 = pOp->p2 + pTabItem->regResult;
123148 pOp->p2 = pOp->p3;
123149 pOp->p3 = 0;
123150 }else if( pOp->opcode==OP_Rowid ){
123151 pOp->opcode = OP_Null;
123152 pOp->p1 = 0;
123153 pOp->p3 = 0;
123154 }
123155 }
123156 continue;
123157 }
123158
123159 /* Close all of the cursors that were opened by sqlite3WhereBegin.
123160 ** Except, do not close cursors that will be reused by the OR optimization
@@ -125418,11 +125625,11 @@
125418 {yygotominor.yy186 = 0;}
125419 break;
125420 case 35: /* table_options ::= WITHOUT nm */
125421 {
125422 if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
125423 yygotominor.yy186 = TF_WithoutRowid;
125424 }else{
125425 yygotominor.yy186 = 0;
125426 sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
125427 }
125428 }
@@ -125642,10 +125849,11 @@
125642 {yygotominor.yy3 = yymsp[0].minor.yy3;}
125643 break;
125644 case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
125645 {
125646 Select *pRhs = yymsp[0].minor.yy3;
 
125647 if( pRhs && pRhs->pPrior ){
125648 SrcList *pFrom;
125649 Token x;
125650 x.n = 0;
125651 parserDoubleLinkSelect(pParse, pRhs);
@@ -125652,15 +125860,16 @@
125652 pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
125653 pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
125654 }
125655 if( pRhs ){
125656 pRhs->op = (u8)yymsp[-1].minor.yy328;
125657 pRhs->pPrior = yymsp[-2].minor.yy3;
 
125658 pRhs->selFlags &= ~SF_MultiValue;
125659 if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
125660 }else{
125661 sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3);
125662 }
125663 yygotominor.yy3 = pRhs;
125664 }
125665 break;
125666 case 116: /* multiselect_op ::= UNION ALL */
@@ -125717,11 +125926,13 @@
125717 break;
125718 case 122: /* distinct ::= DISTINCT */
125719 {yygotominor.yy381 = SF_Distinct;}
125720 break;
125721 case 123: /* distinct ::= ALL */
125722 case 124: /* distinct ::= */ yytestcase(yyruleno==124);
 
 
125723 {yygotominor.yy381 = 0;}
125724 break;
125725 case 125: /* sclp ::= selcollist COMMA */
125726 case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243);
125727 {yygotominor.yy14 = yymsp[-1].minor.yy14;}
@@ -126012,11 +126223,11 @@
126012 if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
126013 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
126014 }
126015 yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
126016 spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
126017 if( yymsp[-2].minor.yy381 && yygotominor.yy346.pExpr ){
126018 yygotominor.yy346.pExpr->flags |= EP_Distinct;
126019 }
126020 }
126021 break;
126022 case 196: /* expr ::= ID|INDEXED LP STAR RP */
@@ -127533,11 +127744,12 @@
127533 }
127534 }
127535 }
127536 abort_parse:
127537 assert( nErr==0 );
127538 if( zSql[i]==0 && pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
 
127539 if( lastTokenParsed!=TK_SEMI ){
127540 sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
127541 pParse->zTail = &zSql[i];
127542 }
127543 if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
@@ -127555,11 +127767,11 @@
127555 db->lookaside.bEnabled = enableLookaside;
127556 if( db->mallocFailed ){
127557 pParse->rc = SQLITE_NOMEM;
127558 }
127559 if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
127560 sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
127561 }
127562 assert( pzErrMsg!=0 );
127563 if( pParse->zErrMsg ){
127564 *pzErrMsg = pParse->zErrMsg;
127565 sqlite3_log(pParse->rc, "%s", *pzErrMsg);
@@ -130747,10 +130959,13 @@
130747 | SQLITE_ForeignKeys
130748 #endif
130749 #if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
130750 | SQLITE_ReverseOrder
130751 #endif
 
 
 
130752 ;
130753 sqlite3HashInit(&db->aCollSeq);
130754 #ifndef SQLITE_OMIT_VIRTUALTABLE
130755 sqlite3HashInit(&db->aModule);
130756 #endif
@@ -130866,12 +131081,11 @@
130866 }
130867 #endif
130868
130869 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
130870 if( !db->mallocFailed && rc==SQLITE_OK){
130871 int sqlite3_dbstat_register(sqlite3*);
130872 rc = sqlite3_dbstat_register(db);
130873 }
130874 #endif
130875
130876 /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
130877 ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
@@ -132871,10 +133085,12 @@
132871 typedef struct Fts3SegFilter Fts3SegFilter;
132872 typedef struct Fts3DeferredToken Fts3DeferredToken;
132873 typedef struct Fts3SegReader Fts3SegReader;
132874 typedef struct Fts3MultiSegReader Fts3MultiSegReader;
132875
 
 
132876 /*
132877 ** A connection to a fulltext index is an instance of the following
132878 ** structure. The xCreate and xConnect methods create an instance
132879 ** of this structure and xDestroy and xDisconnect free that instance.
132880 ** All other methods receive a pointer to the structure as one of their
@@ -132980,13 +133196,11 @@
132980 int nRowAvg; /* Average size of database rows, in pages */
132981 sqlite3_int64 nDoc; /* Documents in table */
132982 i64 iMinDocid; /* Minimum docid to return */
132983 i64 iMaxDocid; /* Maximum docid to return */
132984 int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
132985 u32 *aMatchinfo; /* Information about most recent match */
132986 int nMatchinfo; /* Number of elements in aMatchinfo[] */
132987 char *zMatchinfo; /* Matchinfo specification */
132988 };
132989
132990 #define FTS3_EVAL_FILTER 0
132991 #define FTS3_EVAL_NEXT 1
132992 #define FTS3_EVAL_MATCHINFO 2
@@ -133102,11 +133316,13 @@
133102 sqlite3_int64 iDocid; /* Current docid */
133103 u8 bEof; /* True this expression is at EOF already */
133104 u8 bStart; /* True if iDocid is valid */
133105 u8 bDeferred; /* True if this expression is entirely deferred */
133106
133107 u32 *aMI;
 
 
133108 };
133109
133110 /*
133111 ** Candidate values for Fts3Query.eType. Note that the order of the first
133112 ** four values is in order of precedence when parsing expressions. For
@@ -133223,10 +133439,11 @@
133223 SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
133224 SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
133225 SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
133226 SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
133227 SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
 
133228
133229 /* fts3_tokenizer.c */
133230 SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
133231 SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
133232 SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -133238,10 +133455,11 @@
133238 SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*);
133239 SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
133240 const char *, const char *, int, int
133241 );
133242 SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
 
133243
133244 /* fts3_expr.c */
133245 SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
133246 char **, int, int, int, const char *, int, Fts3Expr **, char **
133247 );
@@ -134665,11 +134883,11 @@
134665 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
134666 sqlite3_finalize(pCsr->pStmt);
134667 sqlite3Fts3ExprFree(pCsr->pExpr);
134668 sqlite3Fts3FreeDeferredTokens(pCsr);
134669 sqlite3_free(pCsr->aDoclist);
134670 sqlite3_free(pCsr->aMatchinfo);
134671 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
134672 sqlite3_free(pCsr);
134673 return SQLITE_OK;
134674 }
134675
@@ -136166,11 +136384,11 @@
136166 assert( iIdx==nVal );
136167
136168 /* In case the cursor has been used before, clear it now. */
136169 sqlite3_finalize(pCsr->pStmt);
136170 sqlite3_free(pCsr->aDoclist);
136171 sqlite3_free(pCsr->aMatchinfo);
136172 sqlite3Fts3ExprFree(pCsr->pExpr);
136173 memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
136174
136175 /* Set the lower and upper bounds on docids to return */
136176 pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -138064,11 +138282,11 @@
138064 ** is populated as for "A * C" before returning.
138065 **
138066 ** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is
138067 ** advanced to point to the next row that matches "x AND y".
138068 **
138069 ** See fts3EvalTestDeferredAndNear() for details on testing if a row is
138070 ** really a match, taking into account deferred tokens and NEAR operators.
138071 */
138072 static void fts3EvalNextRow(
138073 Fts3Cursor *pCsr, /* FTS Cursor handle */
138074 Fts3Expr *pExpr, /* Expr. to advance to next matching row */
@@ -138284,11 +138502,11 @@
138284
138285 return res;
138286 }
138287
138288 /*
138289 ** This function is a helper function for fts3EvalTestDeferredAndNear().
138290 ** Assuming no error occurs or has occurred, It returns non-zero if the
138291 ** expression passed as the second argument matches the row that pCsr
138292 ** currently points to, or zero if it does not.
138293 **
138294 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
@@ -138405,11 +138623,11 @@
138405 ** it is determined that the row does *not* match the query.
138406 **
138407 ** Or, if no error occurs and it seems the current row does match the FTS
138408 ** query, return 0.
138409 */
138410 static int fts3EvalTestDeferredAndNear(Fts3Cursor *pCsr, int *pRc){
138411 int rc = *pRc;
138412 int bMiss = 0;
138413 if( rc==SQLITE_OK ){
138414
138415 /* If there are one or more deferred tokens, load the current row into
@@ -138452,11 +138670,11 @@
138452 fts3EvalNextRow(pCsr, pExpr, &rc);
138453 pCsr->isEof = pExpr->bEof;
138454 pCsr->isRequireSeek = 1;
138455 pCsr->isMatchinfoNeeded = 1;
138456 pCsr->iPrevId = pExpr->iDocid;
138457 }while( pCsr->isEof==0 && fts3EvalTestDeferredAndNear(pCsr, &rc) );
138458 }
138459
138460 /* Check if the cursor is past the end of the docid range specified
138461 ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */
138462 if( rc==SQLITE_OK && (
@@ -138613,11 +138831,11 @@
138613 pCsr->isRequireSeek = 1;
138614 pCsr->isMatchinfoNeeded = 1;
138615 pCsr->iPrevId = pRoot->iDocid;
138616 }while( pCsr->isEof==0
138617 && pRoot->eType==FTSQUERY_NEAR
138618 && fts3EvalTestDeferredAndNear(pCsr, &rc)
138619 );
138620
138621 if( rc==SQLITE_OK && pCsr->isEof==0 ){
138622 fts3EvalUpdateCounts(pRoot);
138623 }
@@ -138638,11 +138856,10 @@
138638 fts3EvalRestart(pCsr, pRoot, &rc);
138639 do {
138640 fts3EvalNextRow(pCsr, pRoot, &rc);
138641 assert( pRoot->bEof==0 );
138642 }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
138643 fts3EvalTestDeferredAndNear(pCsr, &rc);
138644 }
138645 }
138646 return rc;
138647 }
138648
@@ -148650,10 +148867,11 @@
148650 #define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */
148651 #define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
148652 #define FTS3_MATCHINFO_LCS 's' /* nCol values */
148653 #define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
148654 #define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
 
148655
148656 /*
148657 ** The default value for the second argument to matchinfo().
148658 */
148659 #define FTS3_MATCHINFO_DEFAULT "pcx"
@@ -148711,13 +148929,26 @@
148711 struct MatchInfo {
148712 Fts3Cursor *pCursor; /* FTS3 Cursor */
148713 int nCol; /* Number of columns in table */
148714 int nPhrase; /* Number of matchable phrases in query */
148715 sqlite3_int64 nDoc; /* Number of docs in database */
 
148716 u32 *aMatchinfo; /* Pre-allocated buffer */
148717 };
148718
 
 
 
 
 
 
 
 
 
 
 
 
148719
148720
148721 /*
148722 ** The snippet() and offsets() functions both return text values. An instance
148723 ** of the following structure is used to accumulate those values while the
@@ -148728,10 +148959,101 @@
148728 char *z; /* Pointer to buffer containing string */
148729 int n; /* Length of z in bytes (excl. nul-term) */
148730 int nAlloc; /* Allocated size of buffer z in bytes */
148731 };
148732
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148733
148734 /*
148735 ** This function is used to help iterate through a position-list. A position
148736 ** list is a list of unique integers, sorted from smallest to largest. Each
148737 ** element of the list is represented by an FTS3 varint that takes the value
@@ -148765,11 +149087,11 @@
148765 int *piPhrase, /* Pointer to phrase counter */
148766 int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */
148767 void *pCtx /* Second argument to pass to callback */
148768 ){
148769 int rc; /* Return code */
148770 int eType = pExpr->eType; /* Type of expression node pExpr */
148771
148772 if( eType!=FTSQUERY_PHRASE ){
148773 assert( pExpr->pLeft && pExpr->pRight );
148774 rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx);
148775 if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){
@@ -148798,10 +149120,11 @@
148798 void *pCtx /* Second argument to pass to callback */
148799 ){
148800 int iPhrase = 0; /* Variable used as the phrase counter */
148801 return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
148802 }
 
148803
148804 /*
148805 ** This is an fts3ExprIterate() callback used while loading the doclists
148806 ** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
148807 ** fts3ExprLoadDoclists().
@@ -148843,12 +149166,11 @@
148843 return rc;
148844 }
148845
148846 static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
148847 (*(int *)ctx)++;
148848 UNUSED_PARAMETER(pExpr);
148849 UNUSED_PARAMETER(iPhrase);
148850 return SQLITE_OK;
148851 }
148852 static int fts3ExprPhraseCount(Fts3Expr *pExpr){
148853 int nPhrase = 0;
148854 (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase);
@@ -149065,11 +149387,11 @@
149065 sIter.pCsr = pCsr;
149066 sIter.iCol = iCol;
149067 sIter.nSnippet = nSnippet;
149068 sIter.nPhrase = nList;
149069 sIter.iCurrent = -1;
149070 rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void *)&sIter);
149071 if( rc==SQLITE_OK ){
149072
149073 /* Set the *pmSeen output variable. */
149074 for(i=0; i<nList; i++){
149075 if( sIter.aPhrase[i].pHead ){
@@ -149365,10 +149687,64 @@
149365 }
149366
149367 *ppCollist = pEnd;
149368 return nEntry;
149369 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149370
149371 /*
149372 ** fts3ExprIterate() callback used to collect the "global" matchinfo stats
149373 ** for a single query.
149374 **
@@ -149432,55 +149808,10 @@
149432 }
149433
149434 return rc;
149435 }
149436
149437 /*
149438 ** fts3ExprIterate() callback used to gather information for the matchinfo
149439 ** directive 'y'.
149440 */
149441 static int fts3ExprLHitsCb(
149442 Fts3Expr *pExpr, /* Phrase expression node */
149443 int iPhrase, /* Phrase number */
149444 void *pCtx /* Pointer to MatchInfo structure */
149445 ){
149446 MatchInfo *p = (MatchInfo *)pCtx;
149447 Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
149448 int rc = SQLITE_OK;
149449 int iStart = iPhrase * p->nCol;
149450 Fts3Expr *pEof; /* Ancestor node already at EOF */
149451
149452 /* This must be a phrase */
149453 assert( pExpr->pPhrase );
149454
149455 /* Initialize all output integers to zero. */
149456 memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
149457
149458 /* Check if this or any parent node is at EOF. If so, then all output
149459 ** values are zero. */
149460 for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
149461
149462 if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
149463 Fts3Phrase *pPhrase = pExpr->pPhrase;
149464 char *pIter = pPhrase->doclist.pList;
149465 int iCol = 0;
149466
149467 while( 1 ){
149468 int nHit = fts3ColumnlistCount(&pIter);
149469 if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
149470 p->aMatchinfo[iStart + iCol] = (u32)nHit;
149471 }
149472 assert( *pIter==0x00 || *pIter==0x01 );
149473 if( *pIter!=0x01 ) break;
149474 pIter++;
149475 pIter += fts3GetVarint32(pIter, &iCol);
149476 }
149477 }
149478
149479 return rc;
149480 }
149481
149482 static int fts3MatchinfoCheck(
149483 Fts3Table *pTab,
149484 char cArg,
149485 char **pzErr
149486 ){
@@ -149490,10 +149821,11 @@
149490 || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
149491 || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
149492 || (cArg==FTS3_MATCHINFO_LCS)
149493 || (cArg==FTS3_MATCHINFO_HITS)
149494 || (cArg==FTS3_MATCHINFO_LHITS)
 
149495 ){
149496 return SQLITE_OK;
149497 }
149498 sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
149499 return SQLITE_ERROR;
@@ -149516,10 +149848,14 @@
149516 break;
149517
149518 case FTS3_MATCHINFO_LHITS:
149519 nVal = pInfo->nCol * pInfo->nPhrase;
149520 break;
 
 
 
 
149521
149522 default:
149523 assert( cArg==FTS3_MATCHINFO_HITS );
149524 nVal = pInfo->nCol * pInfo->nPhrase * 3;
149525 break;
@@ -149711,11 +150047,11 @@
149711 int i;
149712 Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
149713 sqlite3_stmt *pSelect = 0;
149714
149715 for(i=0; rc==SQLITE_OK && zArg[i]; i++){
149716
149717 switch( zArg[i] ){
149718 case FTS3_MATCHINFO_NPHRASE:
149719 if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
149720 break;
149721
@@ -149771,13 +150107,17 @@
149771 if( rc==SQLITE_OK ){
149772 rc = fts3MatchinfoLcs(pCsr, pInfo);
149773 }
149774 break;
149775
149776 case FTS3_MATCHINFO_LHITS:
149777 (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
 
 
 
149778 break;
 
149779
149780 default: {
149781 Fts3Expr *pExpr;
149782 assert( zArg[i]==FTS3_MATCHINFO_HITS );
149783 pExpr = pCsr->pExpr;
@@ -149787,10 +150127,11 @@
149787 if( pCsr->pDeferred ){
149788 rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
149789 if( rc!=SQLITE_OK ) break;
149790 }
149791 rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
 
149792 if( rc!=SQLITE_OK ) break;
149793 }
149794 (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
149795 break;
149796 }
@@ -149806,73 +150147,90 @@
149806
149807 /*
149808 ** Populate pCsr->aMatchinfo[] with data for the current row. The
149809 ** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
149810 */
149811 static int fts3GetMatchinfo(
 
149812 Fts3Cursor *pCsr, /* FTS3 Cursor object */
149813 const char *zArg /* Second argument to matchinfo() function */
149814 ){
149815 MatchInfo sInfo;
149816 Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
149817 int rc = SQLITE_OK;
149818 int bGlobal = 0; /* Collect 'global' stats as well as local */
149819
 
 
 
149820 memset(&sInfo, 0, sizeof(MatchInfo));
149821 sInfo.pCursor = pCsr;
149822 sInfo.nCol = pTab->nColumn;
149823
149824 /* If there is cached matchinfo() data, but the format string for the
149825 ** cache does not match the format string for this request, discard
149826 ** the cached data. */
149827 if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){
149828 assert( pCsr->aMatchinfo );
149829 sqlite3_free(pCsr->aMatchinfo);
149830 pCsr->zMatchinfo = 0;
149831 pCsr->aMatchinfo = 0;
149832 }
149833
149834 /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the
149835 ** matchinfo function has been called for this query. In this case
149836 ** allocate the array used to accumulate the matchinfo data and
149837 ** initialize those elements that are constant for every row.
149838 */
149839 if( pCsr->aMatchinfo==0 ){
149840 int nMatchinfo = 0; /* Number of u32 elements in match-info */
149841 int nArg; /* Bytes in zArg */
149842 int i; /* Used to iterate through zArg */
149843
149844 /* Determine the number of phrases in the query */
149845 pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr);
149846 sInfo.nPhrase = pCsr->nPhrase;
149847
149848 /* Determine the number of integers in the buffer returned by this call. */
149849 for(i=0; zArg[i]; i++){
 
 
 
 
 
 
149850 nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
149851 }
149852
149853 /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
149854 nArg = (int)strlen(zArg);
149855 pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1);
149856 if( !pCsr->aMatchinfo ) return SQLITE_NOMEM;
149857
149858 pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo];
149859 pCsr->nMatchinfo = nMatchinfo;
149860 memcpy(pCsr->zMatchinfo, zArg, nArg+1);
149861 memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo);
149862 pCsr->isMatchinfoNeeded = 1;
149863 bGlobal = 1;
149864 }
149865
149866 sInfo.aMatchinfo = pCsr->aMatchinfo;
149867 sInfo.nPhrase = pCsr->nPhrase;
149868 if( pCsr->isMatchinfoNeeded ){
 
 
 
 
 
 
 
149869 rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
149870 pCsr->isMatchinfoNeeded = 0;
 
 
149871 }
149872
149873 return rc;
 
 
 
 
 
 
149874 }
149875
149876 /*
149877 ** Implementation of snippet() function.
149878 */
@@ -150074,11 +150432,11 @@
150074 ** no way that this operation can fail, so the return code from
150075 ** fts3ExprIterate() can be discarded.
150076 */
150077 sCtx.iCol = iCol;
150078 sCtx.iTerm = 0;
150079 (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void *)&sCtx);
150080
150081 /* Retreive the text stored in column iCol. If an SQL NULL is stored
150082 ** in column iCol, jump immediately to the next iteration of the loop.
150083 ** If an OOM occurs while retrieving the data (this can happen if SQLite
150084 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -150166,42 +150524,25 @@
150166 sqlite3_context *pContext, /* Function call context */
150167 Fts3Cursor *pCsr, /* FTS3 table cursor */
150168 const char *zArg /* Second arg to matchinfo() function */
150169 ){
150170 Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
150171 int rc;
150172 int i;
150173 const char *zFormat;
150174
150175 if( zArg ){
150176 for(i=0; zArg[i]; i++){
150177 char *zErr = 0;
150178 if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
150179 sqlite3_result_error(pContext, zErr, -1);
150180 sqlite3_free(zErr);
150181 return;
150182 }
150183 }
150184 zFormat = zArg;
150185 }else{
150186 zFormat = FTS3_MATCHINFO_DEFAULT;
150187 }
150188
150189 if( !pCsr->pExpr ){
150190 sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
150191 return;
150192 }
150193
150194 /* Retrieve matchinfo() data. */
150195 rc = fts3GetMatchinfo(pCsr, zFormat);
150196 sqlite3Fts3SegmentsClose(pTab);
150197
150198 if( rc!=SQLITE_OK ){
150199 sqlite3_result_error_code(pContext, rc);
150200 }else{
150201 int n = pCsr->nMatchinfo * sizeof(u32);
150202 sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT);
 
150203 }
150204 }
150205
150206 #endif
150207
@@ -151318,10 +151659,11 @@
151318 */
151319 struct RtreeMatchArg {
151320 u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
151321 RtreeGeomCallback cb; /* Info about the callback functions */
151322 int nParam; /* Number of parameters to the SQL function */
 
151323 RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
151324 };
151325
151326 #ifndef MAX
151327 # define MAX(x,y) ((x) < (y) ? (y) : (x))
@@ -152449,13 +152791,11 @@
152449 /* Check that value is actually a blob. */
152450 if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
152451
152452 /* Check that the blob is roughly the right size. */
152453 nBlob = sqlite3_value_bytes(pValue);
152454 if( nBlob<(int)sizeof(RtreeMatchArg)
152455 || ((nBlob-sizeof(RtreeMatchArg))%sizeof(RtreeDValue))!=0
152456 ){
152457 return SQLITE_ERROR;
152458 }
152459
152460 pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
152461 if( !pInfo ) return SQLITE_NOMEM;
@@ -152462,18 +152802,20 @@
152462 memset(pInfo, 0, sizeof(*pInfo));
152463 pBlob = (RtreeMatchArg*)&pInfo[1];
152464
152465 memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
152466 nExpected = (int)(sizeof(RtreeMatchArg) +
 
152467 (pBlob->nParam-1)*sizeof(RtreeDValue));
152468 if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
152469 sqlite3_free(pInfo);
152470 return SQLITE_ERROR;
152471 }
152472 pInfo->pContext = pBlob->cb.pContext;
152473 pInfo->nParam = pBlob->nParam;
152474 pInfo->aParam = pBlob->aParam;
 
152475
152476 if( pBlob->cb.xGeom ){
152477 pCons->u.xGeom = pBlob->cb.xGeom;
152478 }else{
152479 pCons->op = RTREE_QUERY;
@@ -152636,21 +152978,34 @@
152636 */
152637 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
152638 Rtree *pRtree = (Rtree*)tab;
152639 int rc = SQLITE_OK;
152640 int ii;
 
152641 i64 nRow; /* Estimated rows returned by this scan */
152642
152643 int iIdx = 0;
152644 char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
152645 memset(zIdxStr, 0, sizeof(zIdxStr));
 
 
 
 
 
 
 
 
 
 
152646
152647 assert( pIdxInfo->idxStr==0 );
152648 for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
152649 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
152650
152651 if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
 
 
152652 /* We have an equality constraint on the rowid. Use strategy 1. */
152653 int jj;
152654 for(jj=0; jj<ii; jj++){
152655 pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
152656 pIdxInfo->aConstraintUsage[jj].omit = 0;
@@ -154338,10 +154693,22 @@
154338 static void rtreeFreeCallback(void *p){
154339 RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p;
154340 if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext);
154341 sqlite3_free(p);
154342 }
 
 
 
 
 
 
 
 
 
 
 
 
154343
154344 /*
154345 ** Each call to sqlite3_rtree_geometry_callback() or
154346 ** sqlite3_rtree_query_callback() creates an ordinary SQLite
154347 ** scalar function that is implemented by this routine.
@@ -154357,28 +154724,38 @@
154357 */
154358 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
154359 RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
154360 RtreeMatchArg *pBlob;
154361 int nBlob;
 
154362
154363 nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue);
 
154364 pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
154365 if( !pBlob ){
154366 sqlite3_result_error_nomem(ctx);
154367 }else{
154368 int i;
154369 pBlob->magic = RTREE_GEOMETRY_MAGIC;
154370 pBlob->cb = pGeomCtx[0];
 
154371 pBlob->nParam = nArg;
154372 for(i=0; i<nArg; i++){
 
 
154373 #ifdef SQLITE_RTREE_INT_ONLY
154374 pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
154375 #else
154376 pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
154377 #endif
154378 }
154379 sqlite3_result_blob(ctx, pBlob, nBlob, sqlite3_free);
 
 
 
 
 
154380 }
154381 }
154382
154383 /*
154384 ** Register a new geometry function for use with the r-tree MATCH operator.
@@ -155210,10 +155587,4095 @@
155210
155211 #endif /* defined(SQLITE_ENABLE_ICU) */
155212 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
155213
155214 /************** End of fts3_icu.c ********************************************/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
155215 /************** Begin file dbstat.c ******************************************/
155216 /*
155217 ** 2010 July 12
155218 **
155219 ** The author disclaims copyright to this source code. In place of
@@ -155833,11 +160295,11 @@
155833 }
155834
155835 /*
155836 ** Invoke this routine to register the "dbstat" virtual table module
155837 */
155838 SQLITE_API int SQLITE_STDCALL sqlite3_dbstat_register(sqlite3 *db){
155839 static sqlite3_module dbstat_module = {
155840 0, /* iVersion */
155841 statConnect, /* xCreate */
155842 statConnect, /* xConnect */
155843 statBestIndex, /* xBestIndex */
@@ -155858,8 +160320,10 @@
155858 0, /* xFindMethod */
155859 0, /* xRename */
155860 };
155861 return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
155862 }
 
 
155863 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
155864
155865 /************** End of dbstat.c **********************************************/
155866
--- 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.11. 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.
@@ -316,13 +316,13 @@
316 **
317 ** See also: [sqlite3_libversion()],
318 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
319 ** [sqlite_version()] and [sqlite_source_id()].
320 */
321 #define SQLITE_VERSION "3.8.11"
322 #define SQLITE_VERSION_NUMBER 3008011
323 #define SQLITE_SOURCE_ID "2015-05-29 17:51:16 db4e9728fae5f7b0fad6aa0a5be317a7c9e7c417"
324
325 /*
326 ** CAPI3REF: Run-Time Library Version Numbers
327 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
328 **
@@ -1161,17 +1161,25 @@
1161 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
1162 ** opcode causes the xFileControl method to swap the file handle with the one
1163 ** pointed to by the pArg argument. This capability is used during testing
1164 ** and only needs to be supported when SQLITE_TEST is defined.
1165 **
1166 * <li>[[SQLITE_FCNTL_WAL_BLOCK]]
1167 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
1168 ** be advantageous to block on the next WAL lock if the lock is not immediately
1169 ** available. The WAL subsystem issues this signal during rare
1170 ** circumstances in order to fix a problem with priority inversion.
1171 ** Applications should <em>not</em> use this file-control.
1172 **
1173 ** <li>[[SQLITE_FCNTL_ZIPVFS]]
1174 ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
1175 ** VFS should return SQLITE_NOTFOUND for this opcode.
1176 **
1177 ** <li>[[SQLITE_FCNTL_OTA]]
1178 ** The [SQLITE_FCNTL_OTA] opcode is implemented by the special VFS used by
1179 ** the OTA extension only. All other VFS should return SQLITE_NOTFOUND for
1180 ** this opcode.
1181 ** </ul>
1182 */
1183 #define SQLITE_FCNTL_LOCKSTATE 1
1184 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
1185 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -1193,10 +1201,12 @@
1201 #define SQLITE_FCNTL_HAS_MOVED 20
1202 #define SQLITE_FCNTL_SYNC 21
1203 #define SQLITE_FCNTL_COMMIT_PHASETWO 22
1204 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23
1205 #define SQLITE_FCNTL_WAL_BLOCK 24
1206 #define SQLITE_FCNTL_ZIPVFS 25
1207 #define SQLITE_FCNTL_OTA 26
1208
1209 /* deprecated names */
1210 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1211 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1212 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3595,11 +3605,13 @@
3605 **
3606 ** An sqlite3_value object may be either "protected" or "unprotected".
3607 ** Some interfaces require a protected sqlite3_value. Other interfaces
3608 ** will accept either a protected or an unprotected sqlite3_value.
3609 ** Every interface that accepts sqlite3_value arguments specifies
3610 ** whether or not it requires a protected sqlite3_value. The
3611 ** [sqlite3_value_dup()] interface can be used to construct a new
3612 ** protected sqlite3_value from an unprotected sqlite3_value.
3613 **
3614 ** The terms "protected" and "unprotected" refer to whether or not
3615 ** a mutex is held. An internal mutex is held for a protected
3616 ** sqlite3_value object but no mutex is held for an unprotected
3617 ** sqlite3_value object. If SQLite is compiled to be single-threaded
@@ -4098,12 +4110,10 @@
4110 /*
4111 ** CAPI3REF: Result Values From A Query
4112 ** KEYWORDS: {column access functions}
4113 ** METHOD: sqlite3_stmt
4114 **
 
 
4115 ** ^These routines return information about a single column of the current
4116 ** result row of a query. ^In every case the first argument is a pointer
4117 ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
4118 ** that was returned from [sqlite3_prepare_v2()] or one of its variants)
4119 ** and the second argument is the index of the column for which information
@@ -4159,17 +4169,18 @@
4169 **
4170 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
4171 ** even empty strings, are always zero-terminated. ^The return
4172 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
4173 **
4174 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
4175 ** [unprotected sqlite3_value] object. In a multithreaded environment,
4176 ** an unprotected sqlite3_value object may only be used safely with
4177 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
4178 ** If the [unprotected sqlite3_value] object returned by
4179 ** [sqlite3_column_value()] is used in any other way, including calls
4180 ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
4181 ** or [sqlite3_value_bytes()], the behavior is not threadsafe.
4182 **
4183 ** These routines attempt to convert the value where appropriate. ^For
4184 ** example, if the internal representation is FLOAT and a text result
4185 ** is requested, [sqlite3_snprintf()] is used internally to perform the
4186 ** conversion automatically. ^(The following table details the conversions
@@ -4196,16 +4207,10 @@
4207 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
4208 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
4209 ** </table>
4210 ** </blockquote>)^
4211 **
 
 
 
 
 
 
4212 ** Note that when type conversions occur, pointers returned by prior
4213 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
4214 ** sqlite3_column_text16() may be invalidated.
4215 ** Type conversions and pointer invalidations might occur
4216 ** in the following cases:
@@ -4226,11 +4231,11 @@
4231 ** not invalidate a prior pointer, though of course the content of the buffer
4232 ** that the prior pointer references will have been modified. Other kinds
4233 ** of conversion are done in place when it is possible, but sometimes they
4234 ** are not possible and in those cases prior pointers are invalidated.
4235 **
4236 ** The safest policy is to invoke these routines
4237 ** in one of the following ways:
4238 **
4239 ** <ul>
4240 ** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
4241 ** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
@@ -4246,11 +4251,11 @@
4251 ** with calls to sqlite3_column_bytes().
4252 **
4253 ** ^The pointers returned are valid until a type conversion occurs as
4254 ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
4255 ** [sqlite3_finalize()] is called. ^The memory space used to hold strings
4256 ** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
4257 ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
4258 ** [sqlite3_free()].
4259 **
4260 ** ^(If a memory allocation error occurs during the evaluation of any
4261 ** of these routines, a default value is returned. The default value
@@ -4496,16 +4501,16 @@
4501 SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
4502 void*,sqlite3_int64);
4503 #endif
4504
4505 /*
4506 ** CAPI3REF: Obtaining SQL Values
4507 ** METHOD: sqlite3_value
4508 **
4509 ** The C-language implementation of SQL functions and aggregates uses
4510 ** this set of interface routines to access the parameter values on
4511 ** the function or aggregate.
4512 **
4513 ** The xFunc (for scalar functions) or xStep (for aggregates) parameters
4514 ** to [sqlite3_create_function()] and [sqlite3_create_function16()]
4515 ** define callbacks that implement the SQL functions and aggregates.
4516 ** The 3rd parameter to these callbacks is an array of pointers to
@@ -4554,10 +4559,27 @@
4559 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
4560 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
4561 SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
4562 SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
4563
4564 /*
4565 ** CAPI3REF: Copy And Free SQL Values
4566 ** METHOD: sqlite3_value
4567 **
4568 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
4569 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
4570 ** is a [protected sqlite3_value] object even if the input is not.
4571 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
4572 ** memory allocation fails.
4573 **
4574 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
4575 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
4576 ** then sqlite3_value_free(V) is a harmless no-op.
4577 */
4578 SQLITE_API SQLITE_EXPERIMENTAL sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
4579 SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
4580
4581 /*
4582 ** CAPI3REF: Obtain Aggregate Function Context
4583 ** METHOD: sqlite3_context
4584 **
4585 ** Implementations of aggregate SQL functions use this
@@ -4801,11 +4823,11 @@
4823 ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
4824 ** then SQLite makes a copy of the result into space obtained from
4825 ** from [sqlite3_malloc()] before it returns.
4826 **
4827 ** ^The sqlite3_result_value() interface sets the result of
4828 ** the application-defined function to be a copy of the
4829 ** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
4830 ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
4831 ** so that the [sqlite3_value] specified in the parameter may change or
4832 ** be deallocated after sqlite3_result_value() returns without harm.
4833 ** ^A [protected sqlite3_value] object may always be used where an
@@ -6077,11 +6099,11 @@
6099 ** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
6100 ** always returns zero.
6101 **
6102 ** ^This function sets the database handle error code and message.
6103 */
6104 SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
6105
6106 /*
6107 ** CAPI3REF: Close A BLOB Handle
6108 ** DESTRUCTOR: sqlite3_blob
6109 **
@@ -7887,11 +7909,11 @@
7909 ** as if the loop did not exist - it returns non-zero and leave the variable
7910 ** that pOut points to unchanged.
7911 **
7912 ** See also: [sqlite3_stmt_scanstatus_reset()]
7913 */
7914 SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
7915 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
7916 int idx, /* Index of loop to report on */
7917 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
7918 void *pOut /* Result written here */
7919 );
@@ -7903,11 +7925,11 @@
7925 ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
7926 **
7927 ** This API is only available if the library is built with pre-processor
7928 ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
7929 */
7930 SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
7931
7932
7933 /*
7934 ** Undo the hack that converts floating point types to integer for
7935 ** builds on processors without floating point support.
@@ -8018,10 +8040,12 @@
8040 sqlite3_int64 iRowid; /* Rowid for current entry */
8041 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
8042 int eParentWithin; /* Visibility of parent node */
8043 int eWithin; /* OUT: Visiblity */
8044 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
8045 /* The following fields are only available in 3.8.11 and later */
8046 sqlite3_value **apSqlParam; /* Original SQL values of parameters */
8047 };
8048
8049 /*
8050 ** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
8051 */
@@ -11167,10 +11191,11 @@
11191 #define SQLITE_EnableTrigger 0x00800000 /* True to enable triggers */
11192 #define SQLITE_DeferFKs 0x01000000 /* Defer all FK constraints */
11193 #define SQLITE_QueryOnly 0x02000000 /* Disable database changes */
11194 #define SQLITE_VdbeEQP 0x04000000 /* Debug EXPLAIN QUERY PLAN */
11195 #define SQLITE_Vacuum 0x08000000 /* Currently in a VACUUM */
11196 #define SQLITE_CellSizeCk 0x10000000 /* Check btree cell sizes on load */
11197
11198
11199 /*
11200 ** Bits of the sqlite3.dbOptFlags field that are used by the
11201 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
@@ -11548,12 +11573,13 @@
11573 #define TF_Readonly 0x01 /* Read-only system table */
11574 #define TF_Ephemeral 0x02 /* An ephemeral table */
11575 #define TF_HasPrimaryKey 0x04 /* Table has a primary key */
11576 #define TF_Autoincrement 0x08 /* Integer primary key is autoincrement */
11577 #define TF_Virtual 0x10 /* Is a virtual table */
11578 #define TF_WithoutRowid 0x20 /* No rowid. PRIMARY KEY is the key */
11579 #define TF_NoVisibleRowid 0x40 /* No user-visible "rowid" column */
11580 #define TF_OOOHidden 0x80 /* Out-of-Order hidden columns */
11581
11582
11583 /*
11584 ** Test to see whether or not a table is a virtual table. This is
11585 ** done as a macro so that it will be optimized out when virtual
@@ -11567,10 +11593,11 @@
11593 # define IsHiddenColumn(X) 0
11594 #endif
11595
11596 /* Does the table have a rowid */
11597 #define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
11598 #define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
11599
11600 /*
11601 ** Each foreign key constraint is an instance of the following structure.
11602 **
11603 ** A foreign key is associated with two tables. The "from" table is
@@ -11725,10 +11752,18 @@
11752 ** must be unique and what to do if they are not. When Index.onError=OE_None,
11753 ** it means this is not a unique index. Otherwise it is a unique index
11754 ** and the value of Index.onError indicate the which conflict resolution
11755 ** algorithm to employ whenever an attempt is made to insert a non-unique
11756 ** element.
11757 **
11758 ** While parsing a CREATE TABLE or CREATE INDEX statement in order to
11759 ** generate VDBE code (as opposed to parsing one read from an sqlite_master
11760 ** table as part of parsing an existing database schema), transient instances
11761 ** of this structure may be created. In this case the Index.tnum variable is
11762 ** used to store the address of a VDBE instruction, not a database page
11763 ** number (it cannot - the database page is not allocated until the VDBE
11764 ** program is executed). See convertToWithoutRowidTable() for details.
11765 */
11766 struct Index {
11767 char *zName; /* Name of this index */
11768 i16 *aiColumn; /* Which columns are used by this index. 1st is 0 */
11769 LogEst *aiRowLogEst; /* From ANALYZE: Est. rows selected by each column */
@@ -12299,23 +12334,24 @@
12334 /*
12335 ** Allowed values for Select.selFlags. The "SF" prefix stands for
12336 ** "Select Flag".
12337 */
12338 #define SF_Distinct 0x0001 /* Output should be DISTINCT */
12339 #define SF_All 0x0002 /* Includes the ALL keyword */
12340 #define SF_Resolved 0x0004 /* Identifiers have been resolved */
12341 #define SF_Aggregate 0x0008 /* Contains aggregate functions */
12342 #define SF_UsesEphemeral 0x0010 /* Uses the OpenEphemeral opcode */
12343 #define SF_Expanded 0x0020 /* sqlite3SelectExpand() called on this */
12344 #define SF_HasTypeInfo 0x0040 /* FROM subqueries have Table metadata */
12345 #define SF_Compound 0x0080 /* Part of a compound query */
12346 #define SF_Values 0x0100 /* Synthesized from VALUES clause */
12347 #define SF_MultiValue 0x0200 /* Single VALUES term with multiple rows */
12348 #define SF_NestedFrom 0x0400 /* Part of a parenthesized FROM clause */
12349 #define SF_MaybeConvert 0x0800 /* Need convertCompoundSelectToSubquery() */
12350 #define SF_MinMaxAgg 0x1000 /* Aggregate containing min() or max() */
12351 #define SF_Recursive 0x2000 /* The recursive part of a recursive CTE */
12352 #define SF_Converted 0x4000 /* By convertCompoundSelectToSubquery() */
12353
12354
12355 /*
12356 ** The results of a SELECT can be distributed in several ways, as defined
12357 ** by one of the following macros. The "SRT" prefix means "SELECT Result
@@ -12553,11 +12589,10 @@
12589
12590 /* Information used while coding trigger programs. */
12591 Parse *pToplevel; /* Parse structure for main program (or NULL) */
12592 Table *pTriggerTab; /* Table triggers are being coded for */
12593 int addrCrTab; /* Address of OP_CreateTable opcode on CREATE TABLE */
 
12594 u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
12595 u32 oldmask; /* Mask of old.* columns referenced */
12596 u32 newmask; /* Mask of new.* columns referenced */
12597 u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */
12598 u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */
@@ -13065,11 +13100,10 @@
13100 #define SQLITE_PRINTF_SQLFUNC 0x02
13101 SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
13102 SQLITE_PRIVATE void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
13103 SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
13104 SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
 
13105 #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
13106 SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...);
13107 #endif
13108 #if defined(SQLITE_TEST)
13109 SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*);
@@ -13084,11 +13118,11 @@
13118 SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*);
13119 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8);
13120 #endif
13121
13122
13123 SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*);
13124 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
13125 SQLITE_PRIVATE int sqlite3Dequote(char*);
13126 SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int);
13127 SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **);
13128 SQLITE_PRIVATE void sqlite3FinishCoding(Parse*);
@@ -13780,10 +13814,14 @@
13814 */
13815 #if SQLITE_MAX_WORKER_THREADS>0
13816 SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
13817 SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**);
13818 #endif
13819
13820 #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
13821 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*);
13822 #endif
13823
13824 #endif /* _SQLITEINT_H_ */
13825
13826 /************** End of sqliteInt.h *******************************************/
13827 /************** Begin file global.c ******************************************/
@@ -14685,10 +14723,16 @@
14723 Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */
14724 void *pFiller; /* So that sizeof(Mem) is a multiple of 8 */
14725 #endif
14726 };
14727
14728 /*
14729 ** Size of struct Mem not including the Mem.zMalloc member or anything that
14730 ** follows.
14731 */
14732 #define MEMCELLSIZE offsetof(Mem,zMalloc)
14733
14734 /* One or more of the following flags are set to indicate the validOK
14735 ** representations of the value stored in the Mem struct.
14736 **
14737 ** If the MEM_Null flag is set, then the value is an SQL NULL value.
14738 ** No other flags may be set in this case.
@@ -14890,10 +14934,11 @@
14934 #define VDBE_MAGIC_DEAD 0xb606c3c8 /* The VDBE has been deallocated */
14935
14936 /*
14937 ** Function prototypes
14938 */
14939 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...);
14940 SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
14941 void sqliteVdbePopStack(Vdbe*,int);
14942 SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor*);
14943 SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*);
14944 #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
@@ -20738,28 +20783,24 @@
20783
20784 /*
20785 ** Return the amount of memory currently checked out.
20786 */
20787 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_used(void){
20788 sqlite3_int64 res, mx;
20789 sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0);
 
 
20790 return res;
20791 }
20792
20793 /*
20794 ** Return the maximum amount of memory that has ever been
20795 ** checked out since either the beginning of this process
20796 ** or since the most recent reset.
20797 */
20798 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3_memory_highwater(int resetFlag){
20799 sqlite3_int64 res, mx;
20800 sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag);
20801 return mx;
 
 
20802 }
20803
20804 /*
20805 ** Trigger the alarm
20806 */
@@ -21287,23 +21328,15 @@
21328 }
21329 return zNew;
21330 }
21331
21332 /*
21333 ** Free any prior content in *pz and replace it with a copy of zNew.
 
 
21334 */
21335 SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){
 
 
 
 
 
 
21336 sqlite3DbFree(db, *pz);
21337 *pz = sqlite3DbStrDup(db, zNew);
21338 }
21339
21340 /*
21341 ** Take actions at the end of an API call to indicate an OOM error
21342 */
@@ -22271,28 +22304,10 @@
22304 z = sqlite3VMPrintf(db, zFormat, ap);
22305 va_end(ap);
22306 return z;
22307 }
22308
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22309 /*
22310 ** Print into memory obtained from sqlite3_malloc(). Omit the internal
22311 ** %-conversion extensions.
22312 */
22313 SQLITE_API char *SQLITE_STDCALL sqlite3_vmprintf(const char *zFormat, va_list ap){
@@ -36220,10 +36235,16 @@
36235 */
36236 if( pFile->locktype>=locktype ){
36237 OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h));
36238 return SQLITE_OK;
36239 }
36240
36241 /* Do not allow any kind of write-lock on a read-only database
36242 */
36243 if( (pFile->ctrlFlags & WINFILE_RDONLY)!=0 && locktype>=RESERVED_LOCK ){
36244 return SQLITE_IOERR_LOCK;
36245 }
36246
36247 /* Make sure the locking sequence is correct
36248 */
36249 assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK );
36250 assert( locktype!=PENDING_LOCK );
@@ -38617,18 +38638,18 @@
38638 #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && SQLITE_WIN32_USE_UUID
38639 if( sizeof(UUID)<=nBuf-n ){
38640 UUID id;
38641 memset(&id, 0, sizeof(UUID));
38642 osUuidCreate(&id);
38643 memcpy(&zBuf[n], &id, sizeof(UUID));
38644 n += sizeof(UUID);
38645 }
38646 if( sizeof(UUID)<=nBuf-n ){
38647 UUID id;
38648 memset(&id, 0, sizeof(UUID));
38649 osUuidCreateSequential(&id);
38650 memcpy(&zBuf[n], &id, sizeof(UUID));
38651 n += sizeof(UUID);
38652 }
38653 #endif
38654 #endif /* defined(SQLITE_TEST) || defined(SQLITE_ZERO_PRNG_SEED) */
38655 return n;
@@ -44777,15 +44798,14 @@
44798 */
44799 assert( pPager->eState==PAGER_OPEN );
44800 assert( pPager->eLock>=SHARED_LOCK );
44801 nPage = sqlite3WalDbsize(pPager->pWal);
44802
44803 /* If the number of pages in the database is not available from the
44804 ** WAL sub-system, determine the page counte based on the size of
44805 ** the database file. If the size of the database file is not an
44806 ** integer multiple of the page-size, round up the result.
 
44807 */
44808 if( nPage==0 ){
44809 i64 n = 0; /* Size of db file in bytes */
44810 assert( isOpen(pPager->fd) || pPager->tempFile );
44811 if( isOpen(pPager->fd) ){
@@ -54245,30 +54265,22 @@
54265 u8 *pAddr; /* The i-th cell pointer */
54266 pAddr = &data[cellOffset + i*2];
54267 pc = get2byte(pAddr);
54268 testcase( pc==iCellFirst );
54269 testcase( pc==iCellLast );
 
54270 /* These conditions have already been verified in btreeInitPage()
54271 ** if PRAGMA cell_size_check=ON.
54272 */
54273 if( pc<iCellFirst || pc>iCellLast ){
54274 return SQLITE_CORRUPT_BKPT;
54275 }
 
54276 assert( pc>=iCellFirst && pc<=iCellLast );
54277 size = cellSizePtr(pPage, &src[pc]);
54278 cbrk -= size;
 
 
 
 
 
54279 if( cbrk<iCellFirst || pc+size>usableSize ){
54280 return SQLITE_CORRUPT_BKPT;
54281 }
 
54282 assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
54283 testcase( cbrk+size==usableSize );
54284 testcase( pc+size==usableSize );
54285 put2byte(pAddr, cbrk);
54286 if( temp==0 ){
@@ -54340,11 +54352,11 @@
54352 }
54353 /* Remove the slot from the free-list. Update the number of
54354 ** fragmented bytes within the page. */
54355 memcpy(&aData[iAddr], &aData[pc], 2);
54356 aData[hdr+7] += (u8)x;
54357 }else if( pc < pPg->cellOffset+2*pPg->nCell || size+pc > usableSize ){
54358 *pRc = SQLITE_CORRUPT_BKPT;
54359 return 0;
54360 }else{
54361 /* The slot remains on the free-list. Reduce its size to account
54362 ** for the portion used by the new allocation. */
@@ -54392,11 +54404,15 @@
54404 ** and the reserved space is zero (the usual value for reserved space)
54405 ** then the cell content offset of an empty page wants to be 65536.
54406 ** However, that integer is too large to be stored in a 2-byte unsigned
54407 ** integer, so a value of 0 is used in its place. */
54408 top = get2byteNotZero(&data[hdr+5]);
54409 if( gap>top || NEVER((u32)top>pPage->pBt->usableSize) ){
54410 /* The NEVER() is because a oversize "top" value will be blocked from
54411 ** reaching this point by btreeInitPage() or btreeGetUnusedPage() */
54412 return SQLITE_CORRUPT_BKPT;
54413 }
54414
54415 /* If there is enough space between gap and top for one more cell pointer
54416 ** array entry offset, and if the freelist is not empty, then search the
54417 ** freelist looking for a free slot big enough to satisfy the request.
54418 */
@@ -54465,11 +54481,11 @@
54481 u32 iEnd = iStart + iSize; /* First byte past the iStart buffer */
54482 unsigned char *data = pPage->aData; /* Page content */
54483
54484 assert( pPage->pBt!=0 );
54485 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
54486 assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize );
54487 assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize );
54488 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
54489 assert( iSize>=4 ); /* Minimum cell size is 4 */
54490 assert( iStart<=iLast );
54491
@@ -54605,10 +54621,11 @@
54621 ** we failed to detect any corruption.
54622 */
54623 static int btreeInitPage(MemPage *pPage){
54624
54625 assert( pPage->pBt!=0 );
54626 assert( pPage->pBt->db!=0 );
54627 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
54628 assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
54629 assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
54630 assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
54631
@@ -54663,12 +54680,11 @@
54680 ** past the end of a page boundary and causes SQLITE_CORRUPT to be
54681 ** returned if it does.
54682 */
54683 iCellFirst = cellOffset + 2*pPage->nCell;
54684 iCellLast = usableSize - 4;
54685 if( pBt->db->flags & SQLITE_CellSizeCk ){
 
54686 int i; /* Index into the cell pointer array */
54687 int sz; /* Size of a cell */
54688
54689 if( !pPage->leaf ) iCellLast--;
54690 for(i=0; i<pPage->nCell; i++){
@@ -54684,11 +54700,10 @@
54700 return SQLITE_CORRUPT_BKPT;
54701 }
54702 }
54703 if( !pPage->leaf ) iCellLast++;
54704 }
 
54705
54706 /* Compute the total free space on the page
54707 ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
54708 ** start of the first freeblock on the page, or is zero if there are no
54709 ** freeblocks. */
@@ -54781,14 +54796,14 @@
54796 return pPage;
54797 }
54798
54799 /*
54800 ** Get a page from the pager. Initialize the MemPage.pBt and
54801 ** MemPage.aData elements if needed. See also: btreeGetUnusedPage().
54802 **
54803 ** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care
54804 ** about the content of the page at this time. So do not go to the disk
54805 ** to fetch the content. Just fill in the content with zeros for now.
54806 ** If in the future we call sqlite3PagerWrite() on this page, that
54807 ** means we have started to be concerned about content and the disk
54808 ** read should occur at that point.
54809 */
@@ -54885,10 +54900,40 @@
54900 assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData );
54901 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
54902 sqlite3PagerUnrefNotNull(pPage->pDbPage);
54903 }
54904 }
54905
54906 /*
54907 ** Get an unused page.
54908 **
54909 ** This works just like btreeGetPage() with the addition:
54910 **
54911 ** * If the page is already in use for some other purpose, immediately
54912 ** release it and return an SQLITE_CURRUPT error.
54913 ** * Make sure the isInit flag is clear
54914 */
54915 static int btreeGetUnusedPage(
54916 BtShared *pBt, /* The btree */
54917 Pgno pgno, /* Number of the page to fetch */
54918 MemPage **ppPage, /* Return the page in this parameter */
54919 int flags /* PAGER_GET_NOCONTENT or PAGER_GET_READONLY */
54920 ){
54921 int rc = btreeGetPage(pBt, pgno, ppPage, flags);
54922 if( rc==SQLITE_OK ){
54923 if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){
54924 releasePage(*ppPage);
54925 *ppPage = 0;
54926 return SQLITE_CORRUPT_BKPT;
54927 }
54928 (*ppPage)->isInit = 0;
54929 }else{
54930 *ppPage = 0;
54931 }
54932 return rc;
54933 }
54934
54935
54936 /*
54937 ** During a rollback, when the pager reloads information into the cache
54938 ** so that the cache is restored to its original state at the start of
54939 ** the transaction, for each page restored this routine is called.
@@ -56133,12 +56178,14 @@
56178 put4byte(pPage->aData, iTo);
56179 }else{
56180 u8 isInitOrig = pPage->isInit;
56181 int i;
56182 int nCell;
56183 int rc;
56184
56185 rc = btreeInitPage(pPage);
56186 if( rc ) return rc;
56187 nCell = pPage->nCell;
56188
56189 for(i=0; i<nCell; i++){
56190 u8 *pCell = findCell(pPage, i);
56191 if( eType==PTRMAP_OVERFLOW1 ){
@@ -56935,13 +56982,17 @@
56982 int wrFlag, /* 1 to write. 0 read-only */
56983 struct KeyInfo *pKeyInfo, /* First arg to xCompare() */
56984 BtCursor *pCur /* Write new cursor here */
56985 ){
56986 int rc;
56987 if( iTable<1 ){
56988 rc = SQLITE_CORRUPT_BKPT;
56989 }else{
56990 sqlite3BtreeEnter(p);
56991 rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur);
56992 sqlite3BtreeLeave(p);
56993 }
56994 return rc;
56995 }
56996
56997 /*
56998 ** Return the size of a BtCursor object in bytes.
@@ -57965,11 +58016,11 @@
58016 assert( lwr+upr>=0 );
58017 idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */
58018 }
58019 }else{
58020 for(;;){
58021 int nCell; /* Size of the pCell cell in bytes */
58022 pCell = findCell(pPage, idx) + pPage->childPtrSize;
58023
58024 /* The maximum supported page-size is 65536 bytes. This means that
58025 ** the maximum number of record bytes stored on an index B-Tree
58026 ** page is less than 16384 bytes and may be stored as a 2-byte
@@ -57994,16 +58045,29 @@
58045 c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey);
58046 }else{
58047 /* The record flows over onto one or more overflow pages. In
58048 ** this case the whole cell needs to be parsed, a buffer allocated
58049 ** and accessPayload() used to retrieve the record into the
58050 ** buffer before VdbeRecordCompare() can be called.
58051 **
58052 ** If the record is corrupt, the xRecordCompare routine may read
58053 ** up to two varints past the end of the buffer. An extra 18
58054 ** bytes of padding is allocated at the end of the buffer in
58055 ** case this happens. */
58056 void *pCellKey;
58057 u8 * const pCellBody = pCell - pPage->childPtrSize;
58058 btreeParseCellPtr(pPage, pCellBody, &pCur->info);
58059 nCell = (int)pCur->info.nKey;
58060 testcase( nCell<0 ); /* True if key size is 2^32 or more */
58061 testcase( nCell==0 ); /* Invalid key size: 0x80 0x80 0x00 */
58062 testcase( nCell==1 ); /* Invalid key size: 0x80 0x80 0x01 */
58063 testcase( nCell==2 ); /* Minimum legal index key size */
58064 if( nCell<2 ){
58065 rc = SQLITE_CORRUPT_BKPT;
58066 goto moveto_finish;
58067 }
58068 pCellKey = sqlite3Malloc( nCell+18 );
58069 if( pCellKey==0 ){
58070 rc = SQLITE_NOMEM;
58071 goto moveto_finish;
58072 }
58073 pCur->aiIdx[pCur->iPage] = (u16)idx;
@@ -58387,11 +58451,11 @@
58451 }
58452 testcase( iTrunk==mxPage );
58453 if( iTrunk>mxPage ){
58454 rc = SQLITE_CORRUPT_BKPT;
58455 }else{
58456 rc = btreeGetUnusedPage(pBt, iTrunk, &pTrunk, 0);
58457 }
58458 if( rc ){
58459 pTrunk = 0;
58460 goto end_allocate_page;
58461 }
@@ -58452,11 +58516,11 @@
58516 if( iNewTrunk>mxPage ){
58517 rc = SQLITE_CORRUPT_BKPT;
58518 goto end_allocate_page;
58519 }
58520 testcase( iNewTrunk==mxPage );
58521 rc = btreeGetUnusedPage(pBt, iNewTrunk, &pNewTrunk, 0);
58522 if( rc!=SQLITE_OK ){
58523 goto end_allocate_page;
58524 }
58525 rc = sqlite3PagerWrite(pNewTrunk->pDbPage);
58526 if( rc!=SQLITE_OK ){
@@ -58532,11 +58596,11 @@
58596 if( closest<k-1 ){
58597 memcpy(&aData[8+closest*4], &aData[4+k*4], 4);
58598 }
58599 put4byte(&aData[4], k-1);
58600 noContent = !btreeGetHasContent(pBt, *pPgno)? PAGER_GET_NOCONTENT : 0;
58601 rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, noContent);
58602 if( rc==SQLITE_OK ){
58603 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
58604 if( rc!=SQLITE_OK ){
58605 releasePage(*ppPage);
58606 }
@@ -58580,11 +58644,11 @@
58644 ** becomes a new pointer-map page, the second is used by the caller.
58645 */
58646 MemPage *pPg = 0;
58647 TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", pBt->nPage));
58648 assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) );
58649 rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent);
58650 if( rc==SQLITE_OK ){
58651 rc = sqlite3PagerWrite(pPg->pDbPage);
58652 releasePage(pPg);
58653 }
58654 if( rc ) return rc;
@@ -58594,35 +58658,27 @@
58658 #endif
58659 put4byte(28 + (u8*)pBt->pPage1->aData, pBt->nPage);
58660 *pPgno = pBt->nPage;
58661
58662 assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
58663 rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent);
58664 if( rc ) return rc;
58665 rc = sqlite3PagerWrite((*ppPage)->pDbPage);
58666 if( rc!=SQLITE_OK ){
58667 releasePage(*ppPage);
58668 *ppPage = 0;
58669 }
58670 TRACE(("ALLOCATE: %d from end of file\n", *pPgno));
58671 }
58672
58673 assert( *pPgno!=PENDING_BYTE_PAGE(pBt) );
58674
58675 end_allocate_page:
58676 releasePage(pTrunk);
58677 releasePage(pPrevTrunk);
58678 assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 );
58679 assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 );
 
 
 
 
 
 
 
 
 
58680 return rc;
58681 }
58682
58683 /*
58684 ** This function is used to add page iPage to the database file free-list.
@@ -58643,13 +58699,14 @@
58699 MemPage *pPage; /* Page being freed. May be NULL. */
58700 int rc; /* Return Code */
58701 int nFree; /* Initial number of pages on free-list */
58702
58703 assert( sqlite3_mutex_held(pBt->mutex) );
58704 assert( CORRUPT_DB || iPage>1 );
58705 assert( !pMemPage || pMemPage->pgno==iPage );
58706
58707 if( iPage<2 ) return SQLITE_CORRUPT_BKPT;
58708 if( pMemPage ){
58709 pPage = pMemPage;
58710 sqlite3PagerRef(pPage->pDbPage);
58711 }else{
58712 pPage = btreePageLookup(pBt, iPage);
@@ -58797,11 +58854,13 @@
58854 }
58855 ovflPgno = get4byte(&pCell[info.iOverflow]);
58856 assert( pBt->usableSize > 4 );
58857 ovflPageSize = pBt->usableSize - 4;
58858 nOvfl = (info.nPayload - info.nLocal + ovflPageSize - 1)/ovflPageSize;
58859 assert( nOvfl>0 ||
58860 (CORRUPT_DB && (info.nPayload + ovflPageSize)<ovflPageSize)
58861 );
58862 while( nOvfl-- ){
58863 Pgno iNext = 0;
58864 MemPage *pOvfl = 0;
58865 if( ovflPgno<2 || ovflPgno>btreePagecount(pBt) ){
58866 /* 0 is not a legal page number and page 1 cannot be an
@@ -59052,11 +59111,11 @@
59111 int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */
59112
59113 if( *pRC ) return;
59114
59115 assert( idx>=0 && idx<pPage->nCell );
59116 assert( CORRUPT_DB || sz==cellSize(pPage, idx) );
59117 assert( sqlite3PagerIswriteable(pPage->pDbPage) );
59118 assert( sqlite3_mutex_held(pPage->pBt->mutex) );
59119 data = pPage->aData;
59120 ptr = &pPage->aCellIdx[2*idx];
59121 pc = get2byte(ptr);
@@ -59216,11 +59275,12 @@
59275 }
59276 pData -= szCell[i];
59277 memcpy(pData, pCell, szCell[i]);
59278 put2byte(pCellptr, (pData - aData));
59279 pCellptr += 2;
59280 assert( szCell[i]==cellSizePtr(pPg, pCell) || CORRUPT_DB );
59281 testcase( szCell[i]==cellSizePtr(pPg,pCell) );
59282 }
59283
59284 /* The pPg->nFree field is now set incorrectly. The caller will fix it. */
59285 pPg->nCell = nCell;
59286 pPg->nOverflow = 0;
@@ -59893,10 +59953,18 @@
59953 leafCorrection = apOld[0]->leaf*4;
59954 leafData = apOld[0]->intKeyLeaf;
59955 for(i=0; i<nOld; i++){
59956 int limit;
59957 MemPage *pOld = apOld[i];
59958
59959 /* Verify that all sibling pages are of the same "type" (table-leaf,
59960 ** table-interior, index-leaf, or index-interior).
59961 */
59962 if( pOld->aData[0]!=apOld[0]->aData[0] ){
59963 rc = SQLITE_CORRUPT_BKPT;
59964 goto balance_cleanup;
59965 }
59966
59967 limit = pOld->nCell+pOld->nOverflow;
59968 if( pOld->nOverflow>0 ){
59969 for(j=0; j<limit; j++){
59970 assert( nCell<nMaxCells );
@@ -59935,17 +60003,17 @@
60003 /* The right pointer of the child page pOld becomes the left
60004 ** pointer of the divider cell */
60005 memcpy(apCell[nCell], &pOld->aData[8], 4);
60006 }else{
60007 assert( leafCorrection==4 );
60008 while( szCell[nCell]<4 ){
60009 /* Do not allow any cells smaller than 4 bytes. If a smaller cell
60010 ** does exist, pad it with 0x00 bytes. */
60011 assert( szCell[nCell]==3 || CORRUPT_DB );
60012 assert( apCell[nCell]==&aSpace1[iSpace1-3] || CORRUPT_DB );
60013 aSpace1[iSpace1++] = 0x00;
60014 szCell[nCell]++;
60015 }
60016 }
60017 nCell++;
60018 }
60019 }
@@ -60032,14 +60100,10 @@
60100 ));
60101
60102 /*
60103 ** Allocate k new pages. Reuse old pages where possible.
60104 */
 
 
 
 
60105 pageFlags = apOld[0]->aData[0];
60106 for(i=0; i<k; i++){
60107 MemPage *pNew;
60108 if( i<nOld ){
60109 pNew = apNew[i] = apOld[i];
@@ -60817,10 +60881,11 @@
60881 int nCell;
60882 Pgno n = pCur->apPage[iCellDepth+1]->pgno;
60883 unsigned char *pTmp;
60884
60885 pCell = findCell(pLeaf, pLeaf->nCell-1);
60886 if( pCell<&pLeaf->aData[4] ) return SQLITE_CORRUPT_BKPT;
60887 nCell = cellSizePtr(pLeaf, pCell);
60888 assert( MX_CELL_SIZE(pBt) >= nCell );
60889 pTmp = pBt->pTmpSpace;
60890 assert( pTmp!=0 );
60891 rc = sqlite3PagerWrite(pLeaf->pDbPage);
@@ -60909,11 +60974,12 @@
60974 */
60975 while( pgnoRoot==PTRMAP_PAGENO(pBt, pgnoRoot) ||
60976 pgnoRoot==PENDING_BYTE_PAGE(pBt) ){
60977 pgnoRoot++;
60978 }
60979 assert( pgnoRoot>=3 || CORRUPT_DB );
60980 testcase( pgnoRoot<3 );
60981
60982 /* Allocate a page. The page that currently resides at pgnoRoot will
60983 ** be moved to the allocated page (unless the allocated page happens
60984 ** to reside at pgnoRoot).
60985 */
@@ -61059,11 +61125,12 @@
61125 }
61126 if( !pPage->leaf ){
61127 rc = clearDatabasePage(pBt, get4byte(&pPage->aData[hdr+8]), 1, pnChange);
61128 if( rc ) goto cleardatabasepage_out;
61129 }else if( pnChange ){
61130 assert( pPage->intKey || CORRUPT_DB );
61131 testcase( !pPage->intKey );
61132 *pnChange += pPage->nCell;
61133 }
61134 if( freePageFlag ){
61135 freePage(pPage, &rc);
61136 }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){
@@ -63854,14 +63921,10 @@
63921 }
63922 pMem->pScopyFrom = 0;
63923 }
63924 #endif /* SQLITE_DEBUG */
63925
 
 
 
 
63926
63927 /*
63928 ** Make an shallow copy of pFrom into pTo. Prior contents of
63929 ** pTo are freed. The pFrom->z field is not duplicated. If
63930 ** pFrom->z is used, then pTo->z points to the same thing as pFrom->z
@@ -63884,11 +63947,14 @@
63947 ** freed before the copy is made.
63948 */
63949 SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){
63950 int rc = SQLITE_OK;
63951
63952 /* The pFrom==0 case in the following assert() is when an sqlite3_value
63953 ** from sqlite3_value_dup() is used as the argument
63954 ** to sqlite3_result_value(). */
63955 assert( pTo->db==pFrom->db || pFrom->db==0 );
63956 assert( (pFrom->flags & MEM_RowSet)==0 );
63957 if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo);
63958 memcpy(pTo, pFrom, MEMCELLSIZE);
63959 pTo->flags &= ~MEM_Dyn;
63960 if( pTo->flags&(MEM_Str|MEM_Blob) ){
@@ -64817,10 +64883,21 @@
64883 assert( pParse->aLabel==0 );
64884 assert( pParse->nLabel==0 );
64885 assert( pParse->nOpAlloc==0 );
64886 return p;
64887 }
64888
64889 /*
64890 ** Change the error string stored in Vdbe.zErrMsg
64891 */
64892 SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){
64893 va_list ap;
64894 sqlite3DbFree(p->db, p->zErrMsg);
64895 va_start(ap, zFormat);
64896 p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap);
64897 va_end(ap);
64898 }
64899
64900 /*
64901 ** Remember the SQL string for a prepared statement.
64902 */
64903 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, int isPrepareV2){
@@ -66174,11 +66251,11 @@
66251 p->rc = SQLITE_OK;
66252 rc = SQLITE_DONE;
66253 }else if( db->u1.isInterrupted ){
66254 p->rc = SQLITE_INTERRUPT;
66255 rc = SQLITE_ERROR;
66256 sqlite3VdbeError(p, sqlite3ErrStr(p->rc));
66257 }else{
66258 char *zP4;
66259 Op *pOp;
66260 if( i<p->nOp ){
66261 /* The output line number is small enough that we are still in the
@@ -67077,11 +67154,11 @@
67154 if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
67155 || (!deferred && p->nFkConstraint>0)
67156 ){
67157 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
67158 p->errorAction = OE_Abort;
67159 sqlite3VdbeError(p, "FOREIGN KEY constraint failed");
67160 return SQLITE_ERROR;
67161 }
67162 return SQLITE_OK;
67163 }
67164 #endif
@@ -68420,11 +68497,11 @@
68497
68498 /* RHS is an integer */
68499 if( pRhs->flags & MEM_Int ){
68500 serial_type = aKey1[idx1];
68501 testcase( serial_type==12 );
68502 if( serial_type>=10 ){
68503 rc = +1;
68504 }else if( serial_type==0 ){
68505 rc = -1;
68506 }else if( serial_type==7 ){
68507 double rhs = (double)pRhs->u.i;
@@ -68446,11 +68523,15 @@
68523 }
68524
68525 /* RHS is real */
68526 else if( pRhs->flags & MEM_Real ){
68527 serial_type = aKey1[idx1];
68528 if( serial_type>=10 ){
68529 /* Serial types 12 or greater are strings and blobs (greater than
68530 ** numbers). Types 10 and 11 are currently "reserved for future
68531 ** use", so it doesn't really matter what the results of comparing
68532 ** them to numberic values are. */
68533 rc = +1;
68534 }else if( serial_type==0 ){
68535 rc = -1;
68536 }else{
68537 double rhs = pRhs->u.r;
@@ -69184,10 +69265,40 @@
69265 SQLITE_INTEGER, /* 0x1e */
69266 SQLITE_NULL, /* 0x1f */
69267 };
69268 return aType[pVal->flags&MEM_AffMask];
69269 }
69270
69271 /* Make a copy of an sqlite3_value object
69272 */
69273 SQLITE_API sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value *pOrig){
69274 sqlite3_value *pNew;
69275 if( pOrig==0 ) return 0;
69276 pNew = sqlite3_malloc( sizeof(*pNew) );
69277 if( pNew==0 ) return 0;
69278 memset(pNew, 0, sizeof(*pNew));
69279 memcpy(pNew, pOrig, MEMCELLSIZE);
69280 pNew->flags &= ~MEM_Dyn;
69281 pNew->db = 0;
69282 if( pNew->flags&(MEM_Str|MEM_Blob) ){
69283 pNew->flags &= ~(MEM_Static|MEM_Dyn);
69284 pNew->flags |= MEM_Ephem;
69285 if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){
69286 sqlite3ValueFree(pNew);
69287 pNew = 0;
69288 }
69289 }
69290 return pNew;
69291 }
69292
69293 /* Destroy an sqlite3_value object previously obtained from
69294 ** sqlite3_value_dup().
69295 */
69296 SQLITE_API void SQLITE_STDCALL sqlite3_value_free(sqlite3_value *pOld){
69297 sqlite3ValueFree(pOld);
69298 }
69299
69300
69301 /**************************** sqlite3_result_ *******************************
69302 ** The following routines are used by user-defined functions to specify
69303 ** the function result.
69304 **
@@ -71037,10 +71148,11 @@
71148 ** representation.
71149 */
71150 if( 0==(pRec->flags&MEM_Str) && (pRec->flags&(MEM_Real|MEM_Int)) ){
71151 sqlite3VdbeMemStringify(pRec, enc, 1);
71152 }
71153 pRec->flags &= ~(MEM_Real|MEM_Int);
71154 }
71155 }
71156
71157 /*
71158 ** Try to convert the type of a function argument or a result column
@@ -71797,16 +71909,15 @@
71909 zType = 0;
71910 }
71911 assert( zType!=0 || pOp->p4.z!=0 );
71912 zLogFmt = "abort at %d in [%s]: %s";
71913 if( zType && pOp->p4.z ){
71914 sqlite3VdbeError(p, "%s constraint failed: %s", zType, pOp->p4.z);
 
71915 }else if( pOp->p4.z ){
71916 sqlite3VdbeError(p, "%s", pOp->p4.z);
71917 }else{
71918 sqlite3VdbeError(p, "%s constraint failed", zType);
71919 }
71920 sqlite3_log(pOp->p1, zLogFmt, pcx, p->zSql, p->zErrMsg);
71921 }
71922 rc = sqlite3VdbeHalt(p);
71923 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
@@ -72434,11 +72545,11 @@
72545 lastRowid = db->lastRowid; /* Remember rowid changes made by xFunc */
72546
72547 /* If the function returned an error, throw an exception */
72548 if( ctx.fErrorOrAux ){
72549 if( ctx.isError ){
72550 sqlite3VdbeError(p, "%s", sqlite3_value_text(ctx.pOut));
72551 rc = ctx.isError;
72552 }
72553 sqlite3VdbeDeleteAuxData(p, (int)(pOp - aOp), pOp->p1);
72554 }
72555
@@ -73621,12 +73732,11 @@
73732 if( p1==SAVEPOINT_BEGIN ){
73733 if( db->nVdbeWrite>0 ){
73734 /* A new savepoint cannot be created if there are active write
73735 ** statements (i.e. open read/write incremental blob handles).
73736 */
73737 sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress");
 
73738 rc = SQLITE_BUSY;
73739 }else{
73740 nName = sqlite3Strlen30(zName);
73741
73742 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -73673,19 +73783,18 @@
73783 pSavepoint = pSavepoint->pNext
73784 ){
73785 iSavepoint++;
73786 }
73787 if( !pSavepoint ){
73788 sqlite3VdbeError(p, "no such savepoint: %s", zName);
73789 rc = SQLITE_ERROR;
73790 }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){
73791 /* It is not possible to release (commit) a savepoint if there are
73792 ** active write statements.
73793 */
73794 sqlite3VdbeError(p, "cannot release savepoint - "
73795 "SQL statements in progress");
 
73796 rc = SQLITE_BUSY;
73797 }else{
73798
73799 /* Determine whether or not this is a transaction savepoint. If so,
73800 ** and this is a RELEASE command, then the current transaction
@@ -73787,27 +73896,16 @@
73896 assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
73897 assert( desiredAutoCommit==1 || iRollback==0 );
73898 assert( db->nVdbeActive>0 ); /* At least this one VM is active */
73899 assert( p->bIsReader );
73900
 
 
 
 
 
 
 
 
 
 
 
73901 if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
73902 /* If this instruction implements a COMMIT and other VMs are writing
73903 ** return an error indicating that the other VMs must complete first.
73904 */
73905 sqlite3VdbeError(p, "cannot commit transaction - "
73906 "SQL statements in progress");
73907 rc = SQLITE_BUSY;
73908 }else if( desiredAutoCommit!=db->autoCommit ){
73909 if( iRollback ){
73910 assert( desiredAutoCommit==1 );
73911 sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
@@ -73830,11 +73928,11 @@
73928 }else{
73929 rc = SQLITE_ERROR;
73930 }
73931 goto vdbe_return;
73932 }else{
73933 sqlite3VdbeError(p,
73934 (!desiredAutoCommit)?"cannot start a transaction within a transaction":(
73935 (iRollback)?"cannot rollback - no transaction is active":
73936 "cannot commit - no transaction is active"));
73937
73938 rc = SQLITE_ERROR;
@@ -76263,11 +76361,11 @@
76361 if( pFrame ) break;
76362 }
76363
76364 if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){
76365 rc = SQLITE_ERROR;
76366 sqlite3VdbeError(p, "too many levels of trigger recursion");
76367 break;
76368 }
76369
76370 /* Register pRt is used to store the memory required to save the state
76371 ** of the current program, and the memory required at runtime to execute
@@ -76566,11 +76664,11 @@
76664 ctx.pVdbe = p;
76665 ctx.iOp = (int)(pOp - aOp);
76666 ctx.skipFlag = 0;
76667 (ctx.pFunc->xStep)(&ctx, n, apVal); /* IMP: R-24505-23230 */
76668 if( ctx.isError ){
76669 sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
76670 rc = ctx.isError;
76671 }
76672 if( ctx.skipFlag ){
76673 assert( pOp[-1].opcode==OP_CollSeq );
76674 i = pOp[-1].p1;
@@ -76598,11 +76696,11 @@
76696 assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) );
76697 pMem = &aMem[pOp->p1];
76698 assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
76699 rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
76700 if( rc ){
76701 sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem));
76702 }
76703 sqlite3VdbeChangeEncoding(pMem, encoding);
76704 UPDATE_MAX_BLOBSIZE(pMem);
76705 if( sqlite3VdbeMemTooBig(pMem) ){
76706 goto too_big;
@@ -76703,11 +76801,11 @@
76801 if( (eNew!=eOld)
76802 && (eOld==PAGER_JOURNALMODE_WAL || eNew==PAGER_JOURNALMODE_WAL)
76803 ){
76804 if( !db->autoCommit || db->nVdbeRead>1 ){
76805 rc = SQLITE_ERROR;
76806 sqlite3VdbeError(p,
76807 "cannot change %s wal mode from within a transaction",
76808 (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of")
76809 );
76810 break;
76811 }else{
@@ -76834,11 +76932,11 @@
76932 assert( DbMaskTest(p->btreeMask, p1) );
76933 assert( isWriteLock==0 || isWriteLock==1 );
76934 rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
76935 if( (rc&0xFF)==SQLITE_LOCKED ){
76936 const char *z = pOp->p4.z;
76937 sqlite3VdbeError(p, "database table is locked: %s", z);
76938 }
76939 }
76940 break;
76941 }
76942 #endif /* SQLITE_OMIT_SHARED_CACHE */
@@ -77382,19 +77480,19 @@
77480
77481 /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
77482 ** is encountered.
77483 */
77484 too_big:
77485 sqlite3VdbeError(p, "string or blob too big");
77486 rc = SQLITE_TOOBIG;
77487 goto vdbe_error_halt;
77488
77489 /* Jump to here if a malloc() fails.
77490 */
77491 no_mem:
77492 db->mallocFailed = 1;
77493 sqlite3VdbeError(p, "out of memory");
77494 rc = SQLITE_NOMEM;
77495 goto vdbe_error_halt;
77496
77497 /* Jump to here for any other kind of fatal error. The "rc" variable
77498 ** should hold the error number.
@@ -77401,11 +77499,11 @@
77499 */
77500 abort_due_to_error:
77501 assert( p->zErrMsg==0 );
77502 if( db->mallocFailed ) rc = SQLITE_NOMEM;
77503 if( rc!=SQLITE_IOERR_NOMEM ){
77504 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
77505 }
77506 goto vdbe_error_halt;
77507
77508 /* Jump to here if the sqlite3_interrupt() API sets the interrupt
77509 ** flag.
@@ -77412,11 +77510,11 @@
77510 */
77511 abort_due_to_interrupt:
77512 assert( db->u1.isInterrupted );
77513 rc = SQLITE_INTERRUPT;
77514 p->rc = rc;
77515 sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
77516 goto vdbe_error_halt;
77517 }
77518
77519
77520 /************** End of vdbe.c ************************************************/
@@ -81651,11 +81749,11 @@
81749 iCol = -1;
81750 }
81751 break;
81752 }
81753 }
81754 if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){
81755 /* IMP: R-51414-32910 */
81756 /* IMP: R-44911-55124 */
81757 iCol = -1;
81758 }
81759 if( iCol<pTab->nCol ){
@@ -81681,11 +81779,11 @@
81779
81780 /*
81781 ** Perhaps the name is a reference to the ROWID
81782 */
81783 if( cnt==0 && cntTab==1 && pMatch && sqlite3IsRowid(zCol)
81784 && VisibleRowid(pMatch->pTab) ){
81785 cnt = 1;
81786 pExpr->iColumn = -1; /* IMP: R-44911-55124 */
81787 pExpr->affinity = SQLITE_AFF_INTEGER;
81788 }
81789
@@ -92125,18 +92223,15 @@
92223 #ifndef SQLITE_OMIT_AUTOINCREMENT
92224 sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
92225 "INTEGER PRIMARY KEY");
92226 #endif
92227 }else{
 
92228 Index *p;
 
92229 p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
92230 0, sortOrder, 0);
92231 if( p ){
92232 p->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
 
92233 }
92234 pList = 0;
92235 }
92236
92237 primary_key_exit:
@@ -92485,18 +92580,10 @@
92580 if( pParse->addrCrTab ){
92581 assert( v );
92582 sqlite3VdbeGetOp(v, pParse->addrCrTab)->opcode = OP_CreateIndex;
92583 }
92584
 
 
 
 
 
 
 
 
92585 /* Locate the PRIMARY KEY index. Or, if this table was originally
92586 ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index.
92587 */
92588 if( pTab->iPKey>=0 ){
92589 ExprList *pList;
@@ -92510,10 +92597,20 @@
92597 if( pPk==0 ) return;
92598 pPk->idxType = SQLITE_IDXTYPE_PRIMARYKEY;
92599 pTab->iPKey = -1;
92600 }else{
92601 pPk = sqlite3PrimaryKeyIndex(pTab);
92602
92603 /* Bypass the creation of the PRIMARY KEY btree and the sqlite_master
92604 ** table entry. This is only required if currently generating VDBE
92605 ** code for a CREATE TABLE (not when parsing one as part of reading
92606 ** a database schema). */
92607 if( v ){
92608 assert( db->init.busy==0 );
92609 sqlite3VdbeGetOp(v, pPk->tnum)->opcode = OP_Goto;
92610 }
92611
92612 /*
92613 ** Remove all redundant columns from the PRIMARY KEY. For example, change
92614 ** "PRIMARY KEY(a,b,a,b,c,b,c,d)" into just "PRIMARY KEY(a,b,c,d)". Later
92615 ** code assumes the PRIMARY KEY contains no repeated columns.
92616 */
@@ -92645,11 +92742,11 @@
92742 return;
92743 }
92744 if( (p->tabFlags & TF_HasPrimaryKey)==0 ){
92745 sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName);
92746 }else{
92747 p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid;
92748 convertToWithoutRowidTable(pParse, p);
92749 }
92750 }
92751
92752 iDb = sqlite3SchemaToIndex(db, p->pSchema);
@@ -92713,30 +92810,49 @@
92810 ** as a schema-lock must have already been obtained to create it. Since
92811 ** a schema-lock excludes all other database users, the write-lock would
92812 ** be redundant.
92813 */
92814 if( pSelect ){
92815 SelectDest dest; /* Where the SELECT should store results */
92816 int regYield; /* Register holding co-routine entry-point */
92817 int addrTop; /* Top of the co-routine */
92818 int regRec; /* A record to be insert into the new table */
92819 int regRowid; /* Rowid of the next row to insert */
92820 int addrInsLoop; /* Top of the loop for inserting rows */
92821 Table *pSelTab; /* A table that describes the SELECT results */
92822
92823 regYield = ++pParse->nMem;
92824 regRec = ++pParse->nMem;
92825 regRowid = ++pParse->nMem;
92826 assert(pParse->nTab==1);
92827 sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb);
92828 sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG);
92829 pParse->nTab = 2;
92830 addrTop = sqlite3VdbeCurrentAddr(v) + 1;
92831 sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
92832 sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
92833 sqlite3Select(pParse, pSelect, &dest);
92834 sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield);
92835 sqlite3VdbeJumpHere(v, addrTop - 1);
92836 if( pParse->nErr ) return;
92837 pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect);
92838 if( pSelTab==0 ) return;
92839 assert( p->aCol==0 );
92840 p->nCol = pSelTab->nCol;
92841 p->aCol = pSelTab->aCol;
92842 pSelTab->nCol = 0;
92843 pSelTab->aCol = 0;
92844 sqlite3DeleteTable(db, pSelTab);
92845 addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
92846 VdbeCoverage(v);
92847 sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec);
92848 sqlite3TableAffinity(v, p, 0);
92849 sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid);
92850 sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid);
92851 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrInsLoop);
92852 sqlite3VdbeJumpHere(v, addrInsLoop);
92853 sqlite3VdbeAddOp1(v, OP_Close, 1);
 
 
 
 
 
 
 
 
 
 
92854 }
92855
92856 /* Compute the complete text of the CREATE statement */
92857 if( pSelect ){
92858 zStmt = createTableStmt(db, p);
@@ -94031,14 +94147,19 @@
94147 int iMem = ++pParse->nMem;
94148
94149 v = sqlite3GetVdbe(pParse);
94150 if( v==0 ) goto exit_create_index;
94151
 
 
 
94152 sqlite3BeginWriteOperation(pParse, 1, iDb);
94153
94154 /* Create the rootpage for the index using CreateIndex. But before
94155 ** doing so, code a Noop instruction and store its address in
94156 ** Index.tnum. This is required in case this index is actually a
94157 ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In
94158 ** that case the convertToWithoutRowidTable() routine will replace
94159 ** the Noop with a Goto to jump over the VDBE code generated below. */
94160 pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop);
94161 sqlite3VdbeAddOp2(v, OP_CreateIndex, iDb, iMem);
94162
94163 /* Gather the complete text of the CREATE INDEX statement into
94164 ** the zStmt variable
94165 */
@@ -94074,10 +94195,12 @@
94195 sqlite3ChangeCookie(pParse, iDb);
94196 sqlite3VdbeAddParseSchemaOp(v, iDb,
94197 sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName));
94198 sqlite3VdbeAddOp1(v, OP_Expire, 0);
94199 }
94200
94201 sqlite3VdbeJumpHere(v, pIndex->tnum);
94202 }
94203
94204 /* When adding an index to the list of indices for a table, make
94205 ** sure all indices labeled OE_Replace come after all those labeled
94206 ** OE_Ignore. This is necessary for the correct constraint check
@@ -99669,11 +99792,11 @@
99792 sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nCol);
99793 VdbeComment((v, "%s", pTab->zName));
99794 }else{
99795 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
99796 assert( pPk!=0 );
99797 assert( pPk->tnum==pTab->tnum );
99798 sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb);
99799 sqlite3VdbeSetP4KeyInfo(pParse, pPk);
99800 VdbeComment((v, "%s", pTab->zName));
99801 }
99802 }
@@ -102119,10 +102242,12 @@
102242 void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64,
102243 void(*)(void*));
102244 void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64,
102245 void(*)(void*), unsigned char);
102246 int (*strglob)(const char*,const char*);
102247 sqlite3_value (*value_dup)(const sqlite3_value*);
102248 void (*value_free)(sqlite3_value*);
102249 };
102250
102251 /*
102252 ** The following macros redefine the API routines so that they are
102253 ** redirected through the global sqlite3_api structure.
@@ -102349,10 +102474,13 @@
102474 #define sqlite3_realloc64 sqlite3_api->realloc64
102475 #define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension
102476 #define sqlite3_result_blob64 sqlite3_api->result_blob64
102477 #define sqlite3_result_text64 sqlite3_api->result_text64
102478 #define sqlite3_strglob sqlite3_api->strglob
102479 /* Version 3.8.11 and later */
102480 #define sqlite3_value_dup sqlite3_api->value_dup
102481 #define sqlite3_value_free sqlite3_api->value_free
102482 #endif /* SQLITE_CORE */
102483
102484 #ifndef SQLITE_CORE
102485 /* This case when the file really is being compiled as a loadable
102486 ** extension */
@@ -103255,10 +103383,14 @@
103383 #endif
103384 { /* zName: */ "case_sensitive_like",
103385 /* ePragTyp: */ PragTyp_CASE_SENSITIVE_LIKE,
103386 /* ePragFlag: */ 0,
103387 /* iArg: */ 0 },
103388 { /* zName: */ "cell_size_check",
103389 /* ePragTyp: */ PragTyp_FLAG,
103390 /* ePragFlag: */ 0,
103391 /* iArg: */ SQLITE_CellSizeCk },
103392 #if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
103393 { /* zName: */ "checkpoint_fullfsync",
103394 /* ePragTyp: */ PragTyp_FLAG,
103395 /* ePragFlag: */ 0,
103396 /* iArg: */ SQLITE_CkptFullFSync },
@@ -103612,11 +103744,11 @@
103744 /* ePragTyp: */ PragTyp_FLAG,
103745 /* ePragFlag: */ 0,
103746 /* iArg: */ SQLITE_WriteSchema|SQLITE_RecoveryMode },
103747 #endif
103748 };
103749 /* Number of pragmas: 60 on by default, 73 total. */
103750
103751 /************** End of pragma.h **********************************************/
103752 /************** Continuing where we left off in pragma.c *********************/
103753
103754 /*
@@ -105595,17 +105727,17 @@
105727 const char *zObj, /* Object being parsed at the point of error */
105728 const char *zExtra /* Error information */
105729 ){
105730 sqlite3 *db = pData->db;
105731 if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){
105732 char *z;
105733 if( zObj==0 ) zObj = "?";
105734 z = sqlite3_mprintf("malformed database schema (%s)", zObj);
105735 if( z && zExtra ) z = sqlite3_mprintf("%z - %s", z, zExtra);
105736 sqlite3DbFree(db, *pData->pzErrMsg);
105737 *pData->pzErrMsg = z;
105738 if( z==0 ) db->mallocFailed = 1;
 
105739 }
105740 pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT_BKPT;
105741 }
105742
105743 /*
@@ -105793,11 +105925,11 @@
105925 ** will be closed before this function returns. */
105926 sqlite3BtreeEnter(pDb->pBt);
105927 if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){
105928 rc = sqlite3BtreeBeginTrans(pDb->pBt, 0);
105929 if( rc!=SQLITE_OK ){
105930 sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc));
105931 goto initone_error_out;
105932 }
105933 openedTransaction = 1;
105934 }
105935
@@ -107177,12 +107309,17 @@
107309 }
107310 }else if( eDest!=SRT_Exists ){
107311 /* If the destination is an EXISTS(...) expression, the actual
107312 ** values returned by the SELECT are not required.
107313 */
107314 u8 ecelFlags;
107315 if( eDest==SRT_Mem || eDest==SRT_Output || eDest==SRT_Coroutine ){
107316 ecelFlags = SQLITE_ECEL_DUP;
107317 }else{
107318 ecelFlags = 0;
107319 }
107320 sqlite3ExprCodeExprList(pParse, pEList, regResult, ecelFlags);
107321 }
107322
107323 /* If the DISTINCT keyword was present on the SELECT statement
107324 ** and this row has been seen before, then do not make this row
107325 ** part of the result.
@@ -107275,10 +107412,12 @@
107412 case SRT_Table:
107413 case SRT_EphemTab: {
107414 int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1);
107415 testcase( eDest==SRT_Table );
107416 testcase( eDest==SRT_EphemTab );
107417 testcase( eDest==SRT_Fifo );
107418 testcase( eDest==SRT_DistFifo );
107419 sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg);
107420 #ifndef SQLITE_OMIT_CTE
107421 if( eDest==SRT_DistFifo ){
107422 /* If the destination is DistFifo, then cursor (iParm+1) is open
107423 ** on an ephemeral index. If the current row is already present
@@ -107690,14 +107829,11 @@
107829 for(i=0; i<nSortData; i++){
107830 sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq+i, regRow+i);
107831 VdbeComment((v, "%s", aOutEx[i].zName ? aOutEx[i].zName : aOutEx[i].zSpan));
107832 }
107833 switch( eDest ){
 
107834 case SRT_EphemTab: {
 
 
107835 sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid);
107836 sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid);
107837 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
107838 break;
107839 }
@@ -109042,19 +109178,18 @@
109178
109179 /* Suppress the first OFFSET entries if there is an OFFSET clause
109180 */
109181 codeOffset(v, p->iOffset, iContinue);
109182
109183 assert( pDest->eDest!=SRT_Exists );
109184 assert( pDest->eDest!=SRT_Table );
109185 switch( pDest->eDest ){
109186 /* Store the result as data using a unique key.
109187 */
 
109188 case SRT_EphemTab: {
109189 int r1 = sqlite3GetTempReg(pParse);
109190 int r2 = sqlite3GetTempReg(pParse);
 
 
109191 sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1);
109192 sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2);
109193 sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2);
109194 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
109195 sqlite3ReleaseTempReg(pParse, r2);
@@ -109078,20 +109213,10 @@
109213 sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1);
109214 sqlite3ReleaseTempReg(pParse, r1);
109215 break;
109216 }
109217
 
 
 
 
 
 
 
 
 
 
109218 /* If this is a scalar select that is part of an expression, then
109219 ** store the results in the appropriate memory cell and break out
109220 ** of the scan loop.
109221 */
109222 case SRT_Mem: {
@@ -110462,11 +110587,11 @@
110587 if( pTab==0 ) return WRC_Abort;
110588 pTab->nRef = 1;
110589 pTab->zName = sqlite3DbStrDup(db, pCte->zName);
110590 pTab->iPKey = -1;
110591 pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
110592 pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
110593 pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0);
110594 if( db->mallocFailed ) return SQLITE_NOMEM;
110595 assert( pFrom->pSelect );
110596
110597 /* Check if this is a recursive CTE. */
@@ -110707,17 +110832,10 @@
110832 ExprList *pNew = 0;
110833 int flags = pParse->db->flags;
110834 int longNames = (flags & SQLITE_FullColNames)!=0
110835 && (flags & SQLITE_ShortColNames)==0;
110836
 
 
 
 
 
 
 
110837 for(k=0; k<pEList->nExpr; k++){
110838 pE = a[k].pExpr;
110839 pRight = pE->pRight;
110840 assert( pE->op!=TK_DOT || pRight!=0 );
110841 if( pE->op!=TK_ALL && (pE->op!=TK_DOT || pRight->op!=TK_ALL) ){
@@ -111295,10 +111413,11 @@
111413 isAgg = 1;
111414 p->selFlags |= SF_Aggregate;
111415 }
111416 i = -1;
111417 }else if( pTabList->nSrc==1
111418 && (p->selFlags & SF_All)==0
111419 && OptimizationEnabled(db, SQLITE_SubqCoroutine)
111420 ){
111421 /* Implement a co-routine that will return a single row of the result
111422 ** set on each invocation.
111423 */
@@ -111982,13 +112101,13 @@
112101 ** Generate a human-readable description of a the Select object.
112102 */
112103 SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){
112104 int n = 0;
112105 pView = sqlite3TreeViewPush(pView, moreToFollow);
112106 sqlite3TreeViewLine(pView, "SELECT%s%s (0x%p) selFlags=0x%x",
112107 ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""),
112108 ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), p, p->selFlags
112109 );
112110 if( p->pSrc && p->pSrc->nSrc ) n++;
112111 if( p->pWhere ) n++;
112112 if( p->pGroupBy ) n++;
112113 if( p->pHaving ) n++;
@@ -114138,16 +114257,14 @@
114257 /* Create the ephemeral table into which the update results will
114258 ** be stored.
114259 */
114260 assert( v );
114261 ephemTab = pParse->nTab++;
 
 
114262
114263 /* fill the ephemeral table
114264 */
114265 sqlite3SelectDestInit(&dest, SRT_EphemTab, ephemTab);
114266 sqlite3Select(pParse, pSelect, &dest);
114267
114268 /* Generate code to scan the ephemeral table and call VUpdate. */
114269 iReg = ++pParse->nMem;
114270 pParse->nMem += pTab->nCol+1;
@@ -115998,10 +116115,11 @@
116115 # define TERM_VNULL 0x00 /* Disabled if not using stat3 */
116116 #endif
116117 #define TERM_LIKEOPT 0x100 /* Virtual terms from the LIKE optimization */
116118 #define TERM_LIKECOND 0x200 /* Conditionally this LIKE operator term */
116119 #define TERM_LIKE 0x400 /* The original LIKE operator */
116120 #define TERM_IS 0x800 /* Term.pExpr is an IS operator */
116121
116122 /*
116123 ** An instance of the WhereScan object is used as an iterator for locating
116124 ** terms in the WHERE clause that are useful to the query planner.
116125 */
@@ -116146,25 +116264,26 @@
116264 ** Bitmasks for the operators on WhereTerm objects. These are all
116265 ** operators that are of interest to the query planner. An
116266 ** OR-ed combination of these values can be used when searching for
116267 ** particular WhereTerms within a WhereClause.
116268 */
116269 #define WO_IN 0x0001
116270 #define WO_EQ 0x0002
116271 #define WO_LT (WO_EQ<<(TK_LT-TK_EQ))
116272 #define WO_LE (WO_EQ<<(TK_LE-TK_EQ))
116273 #define WO_GT (WO_EQ<<(TK_GT-TK_EQ))
116274 #define WO_GE (WO_EQ<<(TK_GE-TK_EQ))
116275 #define WO_MATCH 0x0040
116276 #define WO_IS 0x0080
116277 #define WO_ISNULL 0x0100
116278 #define WO_OR 0x0200 /* Two or more OR-connected terms */
116279 #define WO_AND 0x0400 /* Two or more AND-connected terms */
116280 #define WO_EQUIV 0x0800 /* Of the form A==B, both columns */
116281 #define WO_NOOP 0x1000 /* This term does not restrict search space */
116282
116283 #define WO_ALL 0x1fff /* Mask of all possible WO_* values */
116284 #define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */
116285
116286 /*
116287 ** These are definitions of bits in the WhereLoop.wsFlags field.
116288 ** The particular combination of bits in each WhereLoop help to
116289 ** determine the algorithm that WhereLoop represents.
@@ -116534,11 +116653,11 @@
116653 static int allowedOp(int op){
116654 assert( TK_GT>TK_EQ && TK_GT<TK_GE );
116655 assert( TK_LT>TK_EQ && TK_LT<TK_GE );
116656 assert( TK_LE>TK_EQ && TK_LE<TK_GE );
116657 assert( TK_GE==TK_EQ+4 );
116658 return op==TK_IN || (op>=TK_EQ && op<=TK_GE) || op==TK_ISNULL || op==TK_IS;
116659 }
116660
116661 /*
116662 ** Commute a comparison operator. Expressions of the form "X op Y"
116663 ** are converted into "Y op X".
@@ -116587,10 +116706,12 @@
116706 assert( allowedOp(op) );
116707 if( op==TK_IN ){
116708 c = WO_IN;
116709 }else if( op==TK_ISNULL ){
116710 c = WO_ISNULL;
116711 }else if( op==TK_IS ){
116712 c = WO_IS;
116713 }else{
116714 assert( (WO_EQ<<(op-TK_EQ)) < 0x7fff );
116715 c = (u16)(WO_EQ<<(op-TK_EQ));
116716 }
116717 assert( op!=TK_ISNULL || c==WO_ISNULL );
@@ -116598,10 +116719,11 @@
116719 assert( op!=TK_EQ || c==WO_EQ );
116720 assert( op!=TK_LT || c==WO_LT );
116721 assert( op!=TK_LE || c==WO_LE );
116722 assert( op!=TK_GT || c==WO_GT );
116723 assert( op!=TK_GE || c==WO_GE );
116724 assert( op!=TK_IS || c==WO_IS );
116725 return c;
116726 }
116727
116728 /*
116729 ** Advance to the next WhereTerm that matches according to the criteria
@@ -116658,15 +116780,16 @@
116780 if( pColl==0 ) pColl = pParse->db->pDfltColl;
116781 if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){
116782 continue;
116783 }
116784 }
116785 if( (pTerm->eOperator & (WO_EQ|WO_IS))!=0
116786 && (pX = pTerm->pExpr->pRight)->op==TK_COLUMN
116787 && pX->iTable==pScan->aEquiv[0]
116788 && pX->iColumn==pScan->aEquiv[1]
116789 ){
116790 testcase( pTerm->eOperator & WO_IS );
116791 continue;
116792 }
116793 pScan->k = k+1;
116794 return pTerm;
116795 }
@@ -116764,13 +116887,15 @@
116887 WhereTerm *pResult = 0;
116888 WhereTerm *p;
116889 WhereScan scan;
116890
116891 p = whereScanInit(&scan, pWC, iCur, iColumn, op, pIdx);
116892 op &= WO_EQ|WO_IS;
116893 while( p ){
116894 if( (p->prereqRight & notReady)==0 ){
116895 if( p->prereqRight==0 && (p->eOperator&op)!=0 ){
116896 testcase( p->eOperator & WO_IS );
116897 return p;
116898 }
116899 if( pResult==0 ) pResult = p;
116900 }
116901 p = whereScanNext(&scan);
@@ -116801,11 +116926,11 @@
116926 ** so and false if not.
116927 **
116928 ** In order for the operator to be optimizible, the RHS must be a string
116929 ** literal that does not begin with a wildcard. The LHS must be a column
116930 ** that may only be NULL, a string, or a BLOB, never a number. (This means
116931 ** that virtual tables cannot participate in the LIKE optimization.) The
116932 ** collating sequence for the column on the LHS must be appropriate for
116933 ** the operator.
116934 */
116935 static int isLikeOrGlob(
116936 Parse *pParse, /* Parsing and code generating context */
@@ -117346,10 +117471,50 @@
117471 pTerm->eOperator = WO_NOOP; /* case 1 trumps case 3 */
117472 }
117473 }
117474 }
117475 #endif /* !SQLITE_OMIT_OR_OPTIMIZATION && !SQLITE_OMIT_SUBQUERY */
117476
117477 /*
117478 ** We already know that pExpr is a binary operator where both operands are
117479 ** column references. This routine checks to see if pExpr is an equivalence
117480 ** relation:
117481 ** 1. The SQLITE_Transitive optimization must be enabled
117482 ** 2. Must be either an == or an IS operator
117483 ** 3. Not originating the ON clause of an OUTER JOIN
117484 ** 4. The affinities of A and B must be compatible
117485 ** 5a. Both operands use the same collating sequence OR
117486 ** 5b. The overall collating sequence is BINARY
117487 ** If this routine returns TRUE, that means that the RHS can be substituted
117488 ** for the LHS anyplace else in the WHERE clause where the LHS column occurs.
117489 ** This is an optimization. No harm comes from returning 0. But if 1 is
117490 ** returned when it should not be, then incorrect answers might result.
117491 */
117492 static int termIsEquivalence(Parse *pParse, Expr *pExpr){
117493 char aff1, aff2;
117494 CollSeq *pColl;
117495 const char *zColl1, *zColl2;
117496 if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0;
117497 if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0;
117498 if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0;
117499 aff1 = sqlite3ExprAffinity(pExpr->pLeft);
117500 aff2 = sqlite3ExprAffinity(pExpr->pRight);
117501 if( aff1!=aff2
117502 && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2))
117503 ){
117504 return 0;
117505 }
117506 pColl = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight);
117507 if( pColl==0 || sqlite3StrICmp(pColl->zName, "BINARY")==0 ) return 1;
117508 pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
117509 /* Since pLeft and pRight are both a column references, their collating
117510 ** sequence should always be defined. */
117511 zColl1 = ALWAYS(pColl) ? pColl->zName : 0;
117512 pColl = sqlite3ExprCollSeq(pParse, pExpr->pRight);
117513 zColl2 = ALWAYS(pColl) ? pColl->zName : 0;
117514 return sqlite3StrICmp(zColl1, zColl2)==0;
117515 }
117516
117517 /*
117518 ** The input to this routine is an WhereTerm structure with only the
117519 ** "pExpr" field filled in. The job of this routine is to analyze the
117520 ** subexpression and populate all the other fields of the WhereTerm
@@ -117425,10 +117590,11 @@
117590 if( pLeft->op==TK_COLUMN ){
117591 pTerm->leftCursor = pLeft->iTable;
117592 pTerm->u.leftColumn = pLeft->iColumn;
117593 pTerm->eOperator = operatorMask(op) & opMask;
117594 }
117595 if( op==TK_IS ) pTerm->wtFlags |= TERM_IS;
117596 if( pRight && pRight->op==TK_COLUMN ){
117597 WhereTerm *pNew;
117598 Expr *pDup;
117599 u16 eExtraOp = 0; /* Extra bits for pNew->eOperator */
117600 if( pTerm->leftCursor>=0 ){
@@ -117440,16 +117606,15 @@
117606 }
117607 idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC);
117608 if( idxNew==0 ) return;
117609 pNew = &pWC->a[idxNew];
117610 markTermAsChild(pWC, idxNew, idxTerm);
117611 if( op==TK_IS ) pNew->wtFlags |= TERM_IS;
117612 pTerm = &pWC->a[idxTerm];
117613 pTerm->wtFlags |= TERM_COPIED;
117614
117615 if( termIsEquivalence(pParse, pDup) ){
 
 
117616 pTerm->eOperator |= WO_EQUIV;
117617 eExtraOp = WO_EQUIV;
117618 }
117619 }else{
117620 pDup = pExpr;
@@ -117639,14 +117804,11 @@
117804 /* When sqlite_stat3 histogram data is available an operator of the
117805 ** form "x IS NOT NULL" can sometimes be evaluated more efficiently
117806 ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a
117807 ** virtual term of that form.
117808 **
117809 ** Note that the virtual term must be tagged with TERM_VNULL.
 
 
 
117810 */
117811 if( pExpr->op==TK_NOTNULL
117812 && pExpr->pLeft->op==TK_COLUMN
117813 && pExpr->pLeft->iColumn>=0
117814 && OptimizationEnabled(db, SQLITE_Stat34)
@@ -117787,10 +117949,40 @@
117949 ** Estimate the logarithm of the input value to base 2.
117950 */
117951 static LogEst estLog(LogEst N){
117952 return N<=10 ? 0 : sqlite3LogEst(N) - 33;
117953 }
117954
117955 /*
117956 ** Convert OP_Column opcodes to OP_Copy in previously generated code.
117957 **
117958 ** This routine runs over generated VDBE code and translates OP_Column
117959 ** opcodes into OP_Copy, and OP_Rowid into OP_Null, when the table is being
117960 ** accessed via co-routine instead of via table lookup.
117961 */
117962 static void translateColumnToCopy(
117963 Vdbe *v, /* The VDBE containing code to translate */
117964 int iStart, /* Translate from this opcode to the end */
117965 int iTabCur, /* OP_Column/OP_Rowid references to this table */
117966 int iRegister /* The first column is in this register */
117967 ){
117968 VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart);
117969 int iEnd = sqlite3VdbeCurrentAddr(v);
117970 for(; iStart<iEnd; iStart++, pOp++){
117971 if( pOp->p1!=iTabCur ) continue;
117972 if( pOp->opcode==OP_Column ){
117973 pOp->opcode = OP_Copy;
117974 pOp->p1 = pOp->p2 + iRegister;
117975 pOp->p2 = pOp->p3;
117976 pOp->p3 = 0;
117977 }else if( pOp->opcode==OP_Rowid ){
117978 pOp->opcode = OP_Null;
117979 pOp->p1 = 0;
117980 pOp->p3 = 0;
117981 }
117982 }
117983 }
117984
117985 /*
117986 ** Two routines for printing the content of an sqlite3_index_info
117987 ** structure. Used for testing and debugging only. If neither
117988 ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines
@@ -117846,15 +118038,16 @@
118038 struct SrcList_item *pSrc, /* Table we are trying to access */
118039 Bitmask notReady /* Tables in outer loops of the join */
118040 ){
118041 char aff;
118042 if( pTerm->leftCursor!=pSrc->iCursor ) return 0;
118043 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) return 0;
118044 if( (pTerm->prereqRight & notReady)!=0 ) return 0;
118045 if( pTerm->u.leftColumn<0 ) return 0;
118046 aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity;
118047 if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0;
118048 testcase( pTerm->pExpr->op==TK_IS );
118049 return 1;
118050 }
118051 #endif
118052
118053
@@ -117889,10 +118082,11 @@
118082 Bitmask idxCols; /* Bitmap of columns used for indexing */
118083 Bitmask extraCols; /* Bitmap of additional columns */
118084 u8 sentWarning = 0; /* True if a warnning has been issued */
118085 Expr *pPartial = 0; /* Partial Index Expression */
118086 int iContinue = 0; /* Jump here to skip excluded rows */
118087 struct SrcList_item *pTabItem; /* FROM clause term being indexed */
118088
118089 /* Generate code to skip over the creation and initialization of the
118090 ** transient index on 2nd and subsequent iterations of the loop. */
118091 v = pParse->pVdbe;
118092 assert( v!=0 );
@@ -118014,11 +118208,20 @@
118208 sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
118209 VdbeComment((v, "for %s", pTable->zName));
118210
118211 /* Fill the automatic index with content */
118212 sqlite3ExprCachePush(pParse);
118213 pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom];
118214 if( pTabItem->viaCoroutine ){
118215 int regYield = pTabItem->regReturn;
118216 sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub);
118217 addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield);
118218 VdbeCoverage(v);
118219 VdbeComment((v, "next row of \"%s\"", pTabItem->pTab->zName));
118220 }else{
118221 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
118222 }
118223 if( pPartial ){
118224 iContinue = sqlite3VdbeMakeLabel(v);
118225 sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
118226 pLoop->wsFlags |= WHERE_PARTIALIDX;
118227 }
@@ -118025,11 +118228,17 @@
118228 regRecord = sqlite3GetTempReg(pParse);
118229 sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
118230 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
118231 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
118232 if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
118233 if( pTabItem->viaCoroutine ){
118234 translateColumnToCopy(v, addrTop, pLevel->iTabCur, pTabItem->regResult);
118235 sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
118236 pTabItem->viaCoroutine = 0;
118237 }else{
118238 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
118239 }
118240 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
118241 sqlite3VdbeJumpHere(v, addrTop);
118242 sqlite3ReleaseTempReg(pParse, regRecord);
118243 sqlite3ExprCachePop(pParse);
118244
@@ -118067,12 +118276,13 @@
118276 for(i=nTerm=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
118277 if( pTerm->leftCursor != pSrc->iCursor ) continue;
118278 assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
118279 testcase( pTerm->eOperator & WO_IN );
118280 testcase( pTerm->eOperator & WO_ISNULL );
118281 testcase( pTerm->eOperator & WO_IS );
118282 testcase( pTerm->eOperator & WO_ALL );
118283 if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
118284 if( pTerm->wtFlags & TERM_VNULL ) continue;
118285 nTerm++;
118286 }
118287
118288 /* If the ORDER BY clause contains only columns in the current
@@ -118119,13 +118329,14 @@
118329 for(i=j=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
118330 u8 op;
118331 if( pTerm->leftCursor != pSrc->iCursor ) continue;
118332 assert( IsPowerOfTwo(pTerm->eOperator & ~WO_EQUIV) );
118333 testcase( pTerm->eOperator & WO_IN );
118334 testcase( pTerm->eOperator & WO_IS );
118335 testcase( pTerm->eOperator & WO_ISNULL );
118336 testcase( pTerm->eOperator & WO_ALL );
118337 if( (pTerm->eOperator & ~(WO_ISNULL|WO_EQUIV|WO_IS))==0 ) continue;
118338 if( pTerm->wtFlags & TERM_VNULL ) continue;
118339 pIdxCons[j].iColumn = pTerm->u.leftColumn;
118340 pIdxCons[j].iTermOffset = i;
118341 op = (u8)pTerm->eOperator & WO_ALL;
118342 if( op==WO_IN ) op = WO_EQ;
@@ -118963,11 +119174,11 @@
119174 Expr *pX = pTerm->pExpr;
119175 Vdbe *v = pParse->pVdbe;
119176 int iReg; /* Register holding results */
119177
119178 assert( iTarget>0 );
119179 if( pX->op==TK_EQ || pX->op==TK_IS ){
119180 iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget);
119181 }else if( pX->op==TK_ISNULL ){
119182 iReg = iTarget;
119183 sqlite3VdbeAddOp2(v, OP_Null, 0, iReg);
119184 #ifndef SQLITE_OMIT_SUBQUERY
@@ -119148,11 +119359,11 @@
119359 }
119360 testcase( pTerm->eOperator & WO_ISNULL );
119361 testcase( pTerm->eOperator & WO_IN );
119362 if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){
119363 Expr *pRight = pTerm->pExpr->pRight;
119364 if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){
119365 sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk);
119366 VdbeCoverage(v);
119367 }
119368 if( zAff ){
119369 if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_NONE ){
@@ -120270,20 +120481,23 @@
120481 */
120482 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
120483 Expr *pE, *pEAlt;
120484 WhereTerm *pAlt;
120485 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
120486 if( (pTerm->eOperator & (WO_EQ|WO_IS))==0 ) continue;
120487 if( (pTerm->eOperator & WO_EQUIV)==0 ) continue;
120488 if( pTerm->leftCursor!=iCur ) continue;
120489 if( pLevel->iLeftJoin ) continue;
120490 pE = pTerm->pExpr;
120491 assert( !ExprHasProperty(pE, EP_FromJoin) );
120492 assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
120493 pAlt = findTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
120494 WO_EQ|WO_IN|WO_IS, 0);
120495 if( pAlt==0 ) continue;
120496 if( pAlt->wtFlags & (TERM_CODED) ) continue;
120497 testcase( pAlt->eOperator & WO_EQ );
120498 testcase( pAlt->eOperator & WO_IS );
120499 testcase( pAlt->eOperator & WO_IN );
120500 VdbeModuleComment((v, "begin transitive constraint"));
120501 pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
120502 if( pEAlt ){
120503 *pEAlt = *pAlt->pExpr;
@@ -120329,13 +120543,14 @@
120543 char zType[4];
120544 memcpy(zType, "...", 4);
120545 if( pTerm->wtFlags & TERM_VIRTUAL ) zType[0] = 'V';
120546 if( pTerm->eOperator & WO_EQUIV ) zType[1] = 'E';
120547 if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L';
120548 sqlite3DebugPrintf(
120549 "TERM-%-3d %p %s cursor=%-3d prob=%-3d op=0x%03x wtFlags=0x%04x\n",
120550 iTerm, pTerm, zType, pTerm->leftCursor, pTerm->truthProb,
120551 pTerm->eOperator, pTerm->wtFlags);
120552 sqlite3TreeViewExpr(0, pTerm->pExpr, 0);
120553 }
120554 }
120555 #endif
120556
@@ -120821,12 +121036,13 @@
121036 pLoop->nOut += pTerm->truthProb;
121037 }else{
121038 /* In the absence of explicit truth probabilities, use heuristics to
121039 ** guess a reasonable truth probability. */
121040 pLoop->nOut--;
121041 if( pTerm->eOperator&(WO_EQ|WO_IS) ){
121042 Expr *pRight = pTerm->pExpr->pRight;
121043 testcase( pTerm->pExpr->op==TK_IS );
121044 if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){
121045 k = 10;
121046 }else{
121047 k = 20;
121048 }
@@ -120890,14 +121106,14 @@
121106
121107 assert( (pNew->wsFlags & WHERE_VIRTUALTABLE)==0 );
121108 assert( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 );
121109 if( pNew->wsFlags & WHERE_BTM_LIMIT ){
121110 opMask = WO_LT|WO_LE;
121111 }else if( /*pProbe->tnum<=0 ||*/ (pSrc->jointype & JT_LEFT)!=0 ){
121112 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE;
121113 }else{
121114 opMask = WO_EQ|WO_IN|WO_GT|WO_GE|WO_LT|WO_LE|WO_ISNULL|WO_IS;
121115 }
121116 if( pProbe->bUnordered ) opMask &= ~(WO_GT|WO_GE|WO_LT|WO_LE);
121117
121118 assert( pNew->u.btree.nEq<pProbe->nColumn );
121119 iCol = pProbe->aiColumn[pNew->u.btree.nEq];
@@ -120956,11 +121172,11 @@
121172 nIn = sqlite3LogEst(pExpr->x.pList->nExpr);
121173 }
121174 assert( nIn>0 ); /* RHS always has 2 or more terms... The parser
121175 ** changes "x IN (?)" into "x=?". */
121176
121177 }else if( eOp & (WO_EQ|WO_IS) ){
121178 pNew->wsFlags |= WHERE_COLUMN_EQ;
121179 if( iCol<0 || (nInMul==0 && pNew->u.btree.nEq==pProbe->nKeyCol-1) ){
121180 if( iCol>=0 && pProbe->uniqNotNull==0 ){
121181 pNew->wsFlags |= WHERE_UNQ_WANTED;
121182 }else{
@@ -121006,11 +121222,11 @@
121222 /* Adjust nOut using stat3/stat4 data. Or, if there is no stat3/stat4
121223 ** data, using some other estimate. */
121224 whereRangeScanEst(pParse, pBuilder, pBtm, pTop, pNew);
121225 }else{
121226 int nEq = ++pNew->u.btree.nEq;
121227 assert( eOp & (WO_ISNULL|WO_EQ|WO_IN|WO_IS) );
121228
121229 assert( pNew->nOut==saved_nOut );
121230 if( pTerm->truthProb<=0 && iCol>=0 ){
121231 assert( (eOp & WO_IN) || nIn==0 );
121232 testcase( eOp & WO_IN );
@@ -121023,12 +121239,13 @@
121239 && pProbe->nSample
121240 && pNew->u.btree.nEq<=pProbe->nSampleCol
121241 && ((eOp & WO_IN)==0 || !ExprHasProperty(pTerm->pExpr, EP_xIsSelect))
121242 ){
121243 Expr *pExpr = pTerm->pExpr;
121244 if( (eOp & (WO_EQ|WO_ISNULL|WO_IS))!=0 ){
121245 testcase( eOp & WO_EQ );
121246 testcase( eOp & WO_IS );
121247 testcase( eOp & WO_ISNULL );
121248 rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut);
121249 }else{
121250 rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut);
121251 }
@@ -121293,19 +121510,18 @@
121510 rSize = pTab->nRowLogEst;
121511 rLogSize = estLog(rSize);
121512
121513 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
121514 /* Automatic indexes */
121515 if( !pBuilder->pOrSet /* Not part of an OR optimization */
121516 && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
121517 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
121518 && pSrc->pIndex==0 /* Has no INDEXED BY clause */
121519 && !pSrc->notIndexed /* Has no NOT INDEXED clause */
121520 && HasRowid(pTab) /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */
121521 && !pSrc->isCorrelated /* Not a correlated subquery */
121522 && !pSrc->isRecursive /* Not a recursive common table expression. */
 
121523 ){
121524 /* Generate auto-index WhereLoops */
121525 WhereTerm *pTerm;
121526 WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
121527 for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
@@ -121861,21 +122077,22 @@
122077 if( MASKBIT(i) & obSat ) continue;
122078 pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
122079 if( pOBExpr->op!=TK_COLUMN ) continue;
122080 if( pOBExpr->iTable!=iCur ) continue;
122081 pTerm = findTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn,
122082 ~ready, WO_EQ|WO_ISNULL|WO_IS, 0);
122083 if( pTerm==0 ) continue;
122084 if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){
122085 const char *z1, *z2;
122086 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
122087 if( !pColl ) pColl = db->pDfltColl;
122088 z1 = pColl->zName;
122089 pColl = sqlite3ExprCollSeq(pWInfo->pParse, pTerm->pExpr);
122090 if( !pColl ) pColl = db->pDfltColl;
122091 z2 = pColl->zName;
122092 if( sqlite3StrICmp(z1, z2)!=0 ) continue;
122093 testcase( pTerm->pExpr->op==TK_IS );
122094 }
122095 obSat |= MASKBIT(i);
122096 }
122097
122098 if( (pLoop->wsFlags & WHERE_ONEROW)==0 ){
@@ -121902,11 +122119,11 @@
122119 u8 bOnce; /* True to run the ORDER BY search loop */
122120
122121 /* Skip over == and IS NULL terms */
122122 if( j<pLoop->u.btree.nEq
122123 && pLoop->nSkip==0
122124 && ((i = pLoop->aLTerm[j]->eOperator) & (WO_EQ|WO_ISNULL|WO_IS))!=0
122125 ){
122126 if( i & WO_ISNULL ){
122127 testcase( isOrderDistinct );
122128 isOrderDistinct = 0;
122129 }
@@ -122475,28 +122692,32 @@
122692 iCur = pItem->iCursor;
122693 pWC = &pWInfo->sWC;
122694 pLoop = pBuilder->pNew;
122695 pLoop->wsFlags = 0;
122696 pLoop->nSkip = 0;
122697 pTerm = findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0);
122698 if( pTerm ){
122699 testcase( pTerm->eOperator & WO_IS );
122700 pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
122701 pLoop->aLTerm[0] = pTerm;
122702 pLoop->nLTerm = 1;
122703 pLoop->u.btree.nEq = 1;
122704 /* TUNING: Cost of a rowid lookup is 10 */
122705 pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */
122706 }else{
122707 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
122708 int opMask;
122709 assert( pLoop->aLTermSpace==pLoop->aLTerm );
122710 if( !IsUniqueIndex(pIdx)
122711 || pIdx->pPartIdxWhere!=0
122712 || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace)
122713 ) continue;
122714 opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
122715 for(j=0; j<pIdx->nKeyCol; j++){
122716 pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, opMask, pIdx);
122717 if( pTerm==0 ) break;
122718 testcase( pTerm->eOperator & WO_IS );
122719 pLoop->aLTerm[j] = pTerm;
122720 }
122721 if( j!=pIdx->nKeyCol ) continue;
122722 pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
122723 if( pIdx->isCovering || (pItem->colUsed & ~columnsInIndex(pIdx))==0 ){
@@ -123131,30 +123352,16 @@
123352 Table *pTab = pTabItem->pTab;
123353 assert( pTab!=0 );
123354 pLoop = pLevel->pWLoop;
123355
123356 /* For a co-routine, change all OP_Column references to the table of
123357 ** the co-routine into OP_Copy of result contained in a register.
123358 ** OP_Rowid becomes OP_Null.
123359 */
123360 if( pTabItem->viaCoroutine && !db->mallocFailed ){
123361 translateColumnToCopy(v, pLevel->addrBody, pLevel->iTabCur,
123362 pTabItem->regResult);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123363 continue;
123364 }
123365
123366 /* Close all of the cursors that were opened by sqlite3WhereBegin.
123367 ** Except, do not close cursors that will be reused by the OR optimization
@@ -125418,11 +125625,11 @@
125625 {yygotominor.yy186 = 0;}
125626 break;
125627 case 35: /* table_options ::= WITHOUT nm */
125628 {
125629 if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){
125630 yygotominor.yy186 = TF_WithoutRowid | TF_NoVisibleRowid;
125631 }else{
125632 yygotominor.yy186 = 0;
125633 sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z);
125634 }
125635 }
@@ -125642,10 +125849,11 @@
125849 {yygotominor.yy3 = yymsp[0].minor.yy3;}
125850 break;
125851 case 114: /* selectnowith ::= selectnowith multiselect_op oneselect */
125852 {
125853 Select *pRhs = yymsp[0].minor.yy3;
125854 Select *pLhs = yymsp[-2].minor.yy3;
125855 if( pRhs && pRhs->pPrior ){
125856 SrcList *pFrom;
125857 Token x;
125858 x.n = 0;
125859 parserDoubleLinkSelect(pParse, pRhs);
@@ -125652,15 +125860,16 @@
125860 pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0);
125861 pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0,0);
125862 }
125863 if( pRhs ){
125864 pRhs->op = (u8)yymsp[-1].minor.yy328;
125865 pRhs->pPrior = pLhs;
125866 if( ALWAYS(pLhs) ) pLhs->selFlags &= ~SF_MultiValue;
125867 pRhs->selFlags &= ~SF_MultiValue;
125868 if( yymsp[-1].minor.yy328!=TK_ALL ) pParse->hasCompound = 1;
125869 }else{
125870 sqlite3SelectDelete(pParse->db, pLhs);
125871 }
125872 yygotominor.yy3 = pRhs;
125873 }
125874 break;
125875 case 116: /* multiselect_op ::= UNION ALL */
@@ -125717,11 +125926,13 @@
125926 break;
125927 case 122: /* distinct ::= DISTINCT */
125928 {yygotominor.yy381 = SF_Distinct;}
125929 break;
125930 case 123: /* distinct ::= ALL */
125931 {yygotominor.yy381 = SF_All;}
125932 break;
125933 case 124: /* distinct ::= */
125934 {yygotominor.yy381 = 0;}
125935 break;
125936 case 125: /* sclp ::= selcollist COMMA */
125937 case 243: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==243);
125938 {yygotominor.yy14 = yymsp[-1].minor.yy14;}
@@ -126012,11 +126223,11 @@
126223 if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
126224 sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0);
126225 }
126226 yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0);
126227 spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0);
126228 if( yymsp[-2].minor.yy381==SF_Distinct && yygotominor.yy346.pExpr ){
126229 yygotominor.yy346.pExpr->flags |= EP_Distinct;
126230 }
126231 }
126232 break;
126233 case 196: /* expr ::= ID|INDEXED LP STAR RP */
@@ -127533,11 +127744,12 @@
127744 }
127745 }
127746 }
127747 abort_parse:
127748 assert( nErr==0 );
127749 if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
127750 assert( zSql[i]==0 );
127751 if( lastTokenParsed!=TK_SEMI ){
127752 sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
127753 pParse->zTail = &zSql[i];
127754 }
127755 if( pParse->rc==SQLITE_OK && db->mallocFailed==0 ){
@@ -127555,11 +127767,11 @@
127767 db->lookaside.bEnabled = enableLookaside;
127768 if( db->mallocFailed ){
127769 pParse->rc = SQLITE_NOMEM;
127770 }
127771 if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
127772 pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc));
127773 }
127774 assert( pzErrMsg!=0 );
127775 if( pParse->zErrMsg ){
127776 *pzErrMsg = pParse->zErrMsg;
127777 sqlite3_log(pParse->rc, "%s", *pzErrMsg);
@@ -130747,10 +130959,13 @@
130959 | SQLITE_ForeignKeys
130960 #endif
130961 #if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
130962 | SQLITE_ReverseOrder
130963 #endif
130964 #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
130965 | SQLITE_CellSizeCk
130966 #endif
130967 ;
130968 sqlite3HashInit(&db->aCollSeq);
130969 #ifndef SQLITE_OMIT_VIRTUALTABLE
130970 sqlite3HashInit(&db->aModule);
130971 #endif
@@ -130866,12 +131081,11 @@
131081 }
131082 #endif
131083
131084 #ifdef SQLITE_ENABLE_DBSTAT_VTAB
131085 if( !db->mallocFailed && rc==SQLITE_OK){
131086 rc = sqlite3DbstatRegister(db);
 
131087 }
131088 #endif
131089
131090 /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
131091 ** mode. -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
@@ -132871,10 +133085,12 @@
133085 typedef struct Fts3SegFilter Fts3SegFilter;
133086 typedef struct Fts3DeferredToken Fts3DeferredToken;
133087 typedef struct Fts3SegReader Fts3SegReader;
133088 typedef struct Fts3MultiSegReader Fts3MultiSegReader;
133089
133090 typedef struct MatchinfoBuffer MatchinfoBuffer;
133091
133092 /*
133093 ** A connection to a fulltext index is an instance of the following
133094 ** structure. The xCreate and xConnect methods create an instance
133095 ** of this structure and xDestroy and xDisconnect free that instance.
133096 ** All other methods receive a pointer to the structure as one of their
@@ -132980,13 +133196,11 @@
133196 int nRowAvg; /* Average size of database rows, in pages */
133197 sqlite3_int64 nDoc; /* Documents in table */
133198 i64 iMinDocid; /* Minimum docid to return */
133199 i64 iMaxDocid; /* Maximum docid to return */
133200 int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */
133201 MatchinfoBuffer *pMIBuffer; /* Buffer for matchinfo data */
 
 
133202 };
133203
133204 #define FTS3_EVAL_FILTER 0
133205 #define FTS3_EVAL_NEXT 1
133206 #define FTS3_EVAL_MATCHINFO 2
@@ -133102,11 +133316,13 @@
133316 sqlite3_int64 iDocid; /* Current docid */
133317 u8 bEof; /* True this expression is at EOF already */
133318 u8 bStart; /* True if iDocid is valid */
133319 u8 bDeferred; /* True if this expression is entirely deferred */
133320
133321 /* The following are used by the fts3_snippet.c module. */
133322 int iPhrase; /* Index of this phrase in matchinfo() results */
133323 u32 *aMI; /* See above */
133324 };
133325
133326 /*
133327 ** Candidate values for Fts3Query.eType. Note that the order of the first
133328 ** four values is in order of precedence when parsing expressions. For
@@ -133223,10 +133439,11 @@
133439 SQLITE_PRIVATE void sqlite3Fts3Dequote(char *);
133440 SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*);
133441 SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *);
133442 SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *);
133443 SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*);
133444 SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc);
133445
133446 /* fts3_tokenizer.c */
133447 SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *);
133448 SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
133449 SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
@@ -133238,10 +133455,11 @@
133455 SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*);
133456 SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
133457 const char *, const char *, int, int
133458 );
133459 SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
133460 SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p);
133461
133462 /* fts3_expr.c */
133463 SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
133464 char **, int, int, int, const char *, int, Fts3Expr **, char **
133465 );
@@ -134665,11 +134883,11 @@
134883 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
134884 sqlite3_finalize(pCsr->pStmt);
134885 sqlite3Fts3ExprFree(pCsr->pExpr);
134886 sqlite3Fts3FreeDeferredTokens(pCsr);
134887 sqlite3_free(pCsr->aDoclist);
134888 sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
134889 assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 );
134890 sqlite3_free(pCsr);
134891 return SQLITE_OK;
134892 }
134893
@@ -136166,11 +136384,11 @@
136384 assert( iIdx==nVal );
136385
136386 /* In case the cursor has been used before, clear it now. */
136387 sqlite3_finalize(pCsr->pStmt);
136388 sqlite3_free(pCsr->aDoclist);
136389 sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
136390 sqlite3Fts3ExprFree(pCsr->pExpr);
136391 memset(&pCursor[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor));
136392
136393 /* Set the lower and upper bounds on docids to return */
136394 pCsr->iMinDocid = fts3DocidRange(pDocidGe, SMALLEST_INT64);
@@ -138064,11 +138282,11 @@
138282 ** is populated as for "A * C" before returning.
138283 **
138284 ** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is
138285 ** advanced to point to the next row that matches "x AND y".
138286 **
138287 ** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is
138288 ** really a match, taking into account deferred tokens and NEAR operators.
138289 */
138290 static void fts3EvalNextRow(
138291 Fts3Cursor *pCsr, /* FTS Cursor handle */
138292 Fts3Expr *pExpr, /* Expr. to advance to next matching row */
@@ -138284,11 +138502,11 @@
138502
138503 return res;
138504 }
138505
138506 /*
138507 ** This function is a helper function for sqlite3Fts3EvalTestDeferred().
138508 ** Assuming no error occurs or has occurred, It returns non-zero if the
138509 ** expression passed as the second argument matches the row that pCsr
138510 ** currently points to, or zero if it does not.
138511 **
138512 ** If *pRc is not SQLITE_OK when this function is called, it is a no-op.
@@ -138405,11 +138623,11 @@
138623 ** it is determined that the row does *not* match the query.
138624 **
138625 ** Or, if no error occurs and it seems the current row does match the FTS
138626 ** query, return 0.
138627 */
138628 SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){
138629 int rc = *pRc;
138630 int bMiss = 0;
138631 if( rc==SQLITE_OK ){
138632
138633 /* If there are one or more deferred tokens, load the current row into
@@ -138452,11 +138670,11 @@
138670 fts3EvalNextRow(pCsr, pExpr, &rc);
138671 pCsr->isEof = pExpr->bEof;
138672 pCsr->isRequireSeek = 1;
138673 pCsr->isMatchinfoNeeded = 1;
138674 pCsr->iPrevId = pExpr->iDocid;
138675 }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) );
138676 }
138677
138678 /* Check if the cursor is past the end of the docid range specified
138679 ** by Fts3Cursor.iMinDocid/iMaxDocid. If so, set the EOF flag. */
138680 if( rc==SQLITE_OK && (
@@ -138613,11 +138831,11 @@
138831 pCsr->isRequireSeek = 1;
138832 pCsr->isMatchinfoNeeded = 1;
138833 pCsr->iPrevId = pRoot->iDocid;
138834 }while( pCsr->isEof==0
138835 && pRoot->eType==FTSQUERY_NEAR
138836 && sqlite3Fts3EvalTestDeferred(pCsr, &rc)
138837 );
138838
138839 if( rc==SQLITE_OK && pCsr->isEof==0 ){
138840 fts3EvalUpdateCounts(pRoot);
138841 }
@@ -138638,11 +138856,10 @@
138856 fts3EvalRestart(pCsr, pRoot, &rc);
138857 do {
138858 fts3EvalNextRow(pCsr, pRoot, &rc);
138859 assert( pRoot->bEof==0 );
138860 }while( pRoot->iDocid!=iDocid && rc==SQLITE_OK );
 
138861 }
138862 }
138863 return rc;
138864 }
138865
@@ -148650,10 +148867,11 @@
148867 #define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */
148868 #define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
148869 #define FTS3_MATCHINFO_LCS 's' /* nCol values */
148870 #define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
148871 #define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
148872 #define FTS3_MATCHINFO_LHITS_BM 'b' /* nCol*nPhrase values */
148873
148874 /*
148875 ** The default value for the second argument to matchinfo().
148876 */
148877 #define FTS3_MATCHINFO_DEFAULT "pcx"
@@ -148711,13 +148929,26 @@
148929 struct MatchInfo {
148930 Fts3Cursor *pCursor; /* FTS3 Cursor */
148931 int nCol; /* Number of columns in table */
148932 int nPhrase; /* Number of matchable phrases in query */
148933 sqlite3_int64 nDoc; /* Number of docs in database */
148934 char flag;
148935 u32 *aMatchinfo; /* Pre-allocated buffer */
148936 };
148937
148938 /*
148939 ** An instance of this structure is used to manage a pair of buffers, each
148940 ** (nElem * sizeof(u32)) bytes in size. See the MatchinfoBuffer code below
148941 ** for details.
148942 */
148943 struct MatchinfoBuffer {
148944 u8 aRef[3];
148945 int nElem;
148946 int bGlobal; /* Set if global data is loaded */
148947 char *zMatchinfo;
148948 u32 aMatchinfo[1];
148949 };
148950
148951
148952 /*
148953 ** The snippet() and offsets() functions both return text values. An instance
148954 ** of the following structure is used to accumulate those values while the
@@ -148728,10 +148959,101 @@
148959 char *z; /* Pointer to buffer containing string */
148960 int n; /* Length of z in bytes (excl. nul-term) */
148961 int nAlloc; /* Allocated size of buffer z in bytes */
148962 };
148963
148964
148965 /*************************************************************************
148966 ** Start of MatchinfoBuffer code.
148967 */
148968
148969 /*
148970 ** Allocate a two-slot MatchinfoBuffer object.
148971 */
148972 static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
148973 MatchinfoBuffer *pRet;
148974 int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
148975 int nStr = (int)strlen(zMatchinfo);
148976
148977 pRet = sqlite3_malloc(nByte + nStr+1);
148978 if( pRet ){
148979 memset(pRet, 0, nByte);
148980 pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
148981 pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
148982 pRet->nElem = nElem;
148983 pRet->zMatchinfo = ((char*)pRet) + nByte;
148984 memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
148985 pRet->aRef[0] = 1;
148986 }
148987
148988 return pRet;
148989 }
148990
148991 static void fts3MIBufferFree(void *p){
148992 MatchinfoBuffer *pBuf = (MatchinfoBuffer*)((u8*)p - ((u32*)p)[-1]);
148993
148994 assert( (u32*)p==&pBuf->aMatchinfo[1]
148995 || (u32*)p==&pBuf->aMatchinfo[pBuf->nElem+2]
148996 );
148997 if( (u32*)p==&pBuf->aMatchinfo[1] ){
148998 pBuf->aRef[1] = 0;
148999 }else{
149000 pBuf->aRef[2] = 0;
149001 }
149002
149003 if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){
149004 sqlite3_free(pBuf);
149005 }
149006 }
149007
149008 static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){
149009 void (*xRet)(void*) = 0;
149010 u32 *aOut = 0;
149011
149012 if( p->aRef[1]==0 ){
149013 p->aRef[1] = 1;
149014 aOut = &p->aMatchinfo[1];
149015 xRet = fts3MIBufferFree;
149016 }
149017 else if( p->aRef[2]==0 ){
149018 p->aRef[2] = 1;
149019 aOut = &p->aMatchinfo[p->nElem+2];
149020 xRet = fts3MIBufferFree;
149021 }else{
149022 aOut = (u32*)sqlite3_malloc(p->nElem * sizeof(u32));
149023 if( aOut ){
149024 xRet = sqlite3_free;
149025 if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32));
149026 }
149027 }
149028
149029 *paOut = aOut;
149030 return xRet;
149031 }
149032
149033 static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){
149034 p->bGlobal = 1;
149035 memcpy(&p->aMatchinfo[2+p->nElem], &p->aMatchinfo[1], p->nElem*sizeof(u32));
149036 }
149037
149038 /*
149039 ** Free a MatchinfoBuffer object allocated using fts3MIBufferNew()
149040 */
149041 SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){
149042 if( p ){
149043 assert( p->aRef[0]==1 );
149044 p->aRef[0] = 0;
149045 if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){
149046 sqlite3_free(p);
149047 }
149048 }
149049 }
149050
149051 /*
149052 ** End of MatchinfoBuffer code.
149053 *************************************************************************/
149054
149055
149056 /*
149057 ** This function is used to help iterate through a position-list. A position
149058 ** list is a list of unique integers, sorted from smallest to largest. Each
149059 ** element of the list is represented by an FTS3 varint that takes the value
@@ -148765,11 +149087,11 @@
149087 int *piPhrase, /* Pointer to phrase counter */
149088 int (*x)(Fts3Expr*,int,void*), /* Callback function to invoke for phrases */
149089 void *pCtx /* Second argument to pass to callback */
149090 ){
149091 int rc; /* Return code */
149092 int eType = pExpr->eType; /* Type of expression node pExpr */
149093
149094 if( eType!=FTSQUERY_PHRASE ){
149095 assert( pExpr->pLeft && pExpr->pRight );
149096 rc = fts3ExprIterate2(pExpr->pLeft, piPhrase, x, pCtx);
149097 if( rc==SQLITE_OK && eType!=FTSQUERY_NOT ){
@@ -148798,10 +149120,11 @@
149120 void *pCtx /* Second argument to pass to callback */
149121 ){
149122 int iPhrase = 0; /* Variable used as the phrase counter */
149123 return fts3ExprIterate2(pExpr, &iPhrase, x, pCtx);
149124 }
149125
149126
149127 /*
149128 ** This is an fts3ExprIterate() callback used while loading the doclists
149129 ** for each phrase into Fts3Expr.aDoclist[]/nDoclist. See also
149130 ** fts3ExprLoadDoclists().
@@ -148843,12 +149166,11 @@
149166 return rc;
149167 }
149168
149169 static int fts3ExprPhraseCountCb(Fts3Expr *pExpr, int iPhrase, void *ctx){
149170 (*(int *)ctx)++;
149171 pExpr->iPhrase = iPhrase;
 
149172 return SQLITE_OK;
149173 }
149174 static int fts3ExprPhraseCount(Fts3Expr *pExpr){
149175 int nPhrase = 0;
149176 (void)fts3ExprIterate(pExpr, fts3ExprPhraseCountCb, (void *)&nPhrase);
@@ -149065,11 +149387,11 @@
149387 sIter.pCsr = pCsr;
149388 sIter.iCol = iCol;
149389 sIter.nSnippet = nSnippet;
149390 sIter.nPhrase = nList;
149391 sIter.iCurrent = -1;
149392 rc = fts3ExprIterate(pCsr->pExpr, fts3SnippetFindPositions, (void*)&sIter);
149393 if( rc==SQLITE_OK ){
149394
149395 /* Set the *pmSeen output variable. */
149396 for(i=0; i<nList; i++){
149397 if( sIter.aPhrase[i].pHead ){
@@ -149365,10 +149687,64 @@
149687 }
149688
149689 *ppCollist = pEnd;
149690 return nEntry;
149691 }
149692
149693 /*
149694 ** This function gathers 'y' or 'b' data for a single phrase.
149695 */
149696 static void fts3ExprLHits(
149697 Fts3Expr *pExpr, /* Phrase expression node */
149698 MatchInfo *p /* Matchinfo context */
149699 ){
149700 Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
149701 int iStart;
149702 Fts3Phrase *pPhrase = pExpr->pPhrase;
149703 char *pIter = pPhrase->doclist.pList;
149704 int iCol = 0;
149705
149706 assert( p->flag==FTS3_MATCHINFO_LHITS_BM || p->flag==FTS3_MATCHINFO_LHITS );
149707 if( p->flag==FTS3_MATCHINFO_LHITS ){
149708 iStart = pExpr->iPhrase * p->nCol;
149709 }else{
149710 iStart = pExpr->iPhrase * ((p->nCol + 31) / 32);
149711 }
149712
149713 while( 1 ){
149714 int nHit = fts3ColumnlistCount(&pIter);
149715 if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
149716 if( p->flag==FTS3_MATCHINFO_LHITS ){
149717 p->aMatchinfo[iStart + iCol] = (u32)nHit;
149718 }else if( nHit ){
149719 p->aMatchinfo[iStart + (iCol+1)/32] |= (1 << (iCol&0x1F));
149720 }
149721 }
149722 assert( *pIter==0x00 || *pIter==0x01 );
149723 if( *pIter!=0x01 ) break;
149724 pIter++;
149725 pIter += fts3GetVarint32(pIter, &iCol);
149726 }
149727 }
149728
149729 /*
149730 ** Gather the results for matchinfo directives 'y' and 'b'.
149731 */
149732 static void fts3ExprLHitGather(
149733 Fts3Expr *pExpr,
149734 MatchInfo *p
149735 ){
149736 assert( (pExpr->pLeft==0)==(pExpr->pRight==0) );
149737 if( pExpr->bEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
149738 if( pExpr->pLeft ){
149739 fts3ExprLHitGather(pExpr->pLeft, p);
149740 fts3ExprLHitGather(pExpr->pRight, p);
149741 }else{
149742 fts3ExprLHits(pExpr, p);
149743 }
149744 }
149745 }
149746
149747 /*
149748 ** fts3ExprIterate() callback used to collect the "global" matchinfo stats
149749 ** for a single query.
149750 **
@@ -149432,55 +149808,10 @@
149808 }
149809
149810 return rc;
149811 }
149812
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149813 static int fts3MatchinfoCheck(
149814 Fts3Table *pTab,
149815 char cArg,
149816 char **pzErr
149817 ){
@@ -149490,10 +149821,11 @@
149821 || (cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bFts4)
149822 || (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
149823 || (cArg==FTS3_MATCHINFO_LCS)
149824 || (cArg==FTS3_MATCHINFO_HITS)
149825 || (cArg==FTS3_MATCHINFO_LHITS)
149826 || (cArg==FTS3_MATCHINFO_LHITS_BM)
149827 ){
149828 return SQLITE_OK;
149829 }
149830 sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
149831 return SQLITE_ERROR;
@@ -149516,10 +149848,14 @@
149848 break;
149849
149850 case FTS3_MATCHINFO_LHITS:
149851 nVal = pInfo->nCol * pInfo->nPhrase;
149852 break;
149853
149854 case FTS3_MATCHINFO_LHITS_BM:
149855 nVal = pInfo->nPhrase * ((pInfo->nCol + 31) / 32);
149856 break;
149857
149858 default:
149859 assert( cArg==FTS3_MATCHINFO_HITS );
149860 nVal = pInfo->nCol * pInfo->nPhrase * 3;
149861 break;
@@ -149711,11 +150047,11 @@
150047 int i;
150048 Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
150049 sqlite3_stmt *pSelect = 0;
150050
150051 for(i=0; rc==SQLITE_OK && zArg[i]; i++){
150052 pInfo->flag = zArg[i];
150053 switch( zArg[i] ){
150054 case FTS3_MATCHINFO_NPHRASE:
150055 if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase;
150056 break;
150057
@@ -149771,13 +150107,17 @@
150107 if( rc==SQLITE_OK ){
150108 rc = fts3MatchinfoLcs(pCsr, pInfo);
150109 }
150110 break;
150111
150112 case FTS3_MATCHINFO_LHITS_BM:
150113 case FTS3_MATCHINFO_LHITS: {
150114 int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
150115 memset(pInfo->aMatchinfo, 0, nZero);
150116 fts3ExprLHitGather(pCsr->pExpr, pInfo);
150117 break;
150118 }
150119
150120 default: {
150121 Fts3Expr *pExpr;
150122 assert( zArg[i]==FTS3_MATCHINFO_HITS );
150123 pExpr = pCsr->pExpr;
@@ -149787,10 +150127,11 @@
150127 if( pCsr->pDeferred ){
150128 rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0);
150129 if( rc!=SQLITE_OK ) break;
150130 }
150131 rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo);
150132 sqlite3Fts3EvalTestDeferred(pCsr, &rc);
150133 if( rc!=SQLITE_OK ) break;
150134 }
150135 (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo);
150136 break;
150137 }
@@ -149806,73 +150147,90 @@
150147
150148 /*
150149 ** Populate pCsr->aMatchinfo[] with data for the current row. The
150150 ** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32).
150151 */
150152 static void fts3GetMatchinfo(
150153 sqlite3_context *pCtx, /* Return results here */
150154 Fts3Cursor *pCsr, /* FTS3 Cursor object */
150155 const char *zArg /* Second argument to matchinfo() function */
150156 ){
150157 MatchInfo sInfo;
150158 Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
150159 int rc = SQLITE_OK;
150160 int bGlobal = 0; /* Collect 'global' stats as well as local */
150161
150162 u32 *aOut = 0;
150163 void (*xDestroyOut)(void*) = 0;
150164
150165 memset(&sInfo, 0, sizeof(MatchInfo));
150166 sInfo.pCursor = pCsr;
150167 sInfo.nCol = pTab->nColumn;
150168
150169 /* If there is cached matchinfo() data, but the format string for the
150170 ** cache does not match the format string for this request, discard
150171 ** the cached data. */
150172 if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){
150173 sqlite3Fts3MIBufferFree(pCsr->pMIBuffer);
150174 pCsr->pMIBuffer = 0;
 
 
150175 }
150176
150177 /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the
150178 ** matchinfo function has been called for this query. In this case
150179 ** allocate the array used to accumulate the matchinfo data and
150180 ** initialize those elements that are constant for every row.
150181 */
150182 if( pCsr->pMIBuffer==0 ){
150183 int nMatchinfo = 0; /* Number of u32 elements in match-info */
 
150184 int i; /* Used to iterate through zArg */
150185
150186 /* Determine the number of phrases in the query */
150187 pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr);
150188 sInfo.nPhrase = pCsr->nPhrase;
150189
150190 /* Determine the number of integers in the buffer returned by this call. */
150191 for(i=0; zArg[i]; i++){
150192 char *zErr = 0;
150193 if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){
150194 sqlite3_result_error(pCtx, zErr, -1);
150195 sqlite3_free(zErr);
150196 return;
150197 }
150198 nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]);
150199 }
150200
150201 /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */
150202 pCsr->pMIBuffer = fts3MIBufferNew(nMatchinfo, zArg);
150203 if( !pCsr->pMIBuffer ) rc = SQLITE_NOMEM;
150204
 
 
 
 
 
150205 pCsr->isMatchinfoNeeded = 1;
150206 bGlobal = 1;
150207 }
150208
150209 if( rc==SQLITE_OK ){
150210 xDestroyOut = fts3MIBufferAlloc(pCsr->pMIBuffer, &aOut);
150211 if( xDestroyOut==0 ){
150212 rc = SQLITE_NOMEM;
150213 }
150214 }
150215
150216 if( rc==SQLITE_OK ){
150217 sInfo.aMatchinfo = aOut;
150218 sInfo.nPhrase = pCsr->nPhrase;
150219 rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg);
150220 if( bGlobal ){
150221 fts3MIBufferSetGlobal(pCsr->pMIBuffer);
150222 }
150223 }
150224
150225 if( rc!=SQLITE_OK ){
150226 sqlite3_result_error_code(pCtx, rc);
150227 if( xDestroyOut ) xDestroyOut(aOut);
150228 }else{
150229 int n = pCsr->pMIBuffer->nElem * sizeof(u32);
150230 sqlite3_result_blob(pCtx, aOut, n, xDestroyOut);
150231 }
150232 }
150233
150234 /*
150235 ** Implementation of snippet() function.
150236 */
@@ -150074,11 +150432,11 @@
150432 ** no way that this operation can fail, so the return code from
150433 ** fts3ExprIterate() can be discarded.
150434 */
150435 sCtx.iCol = iCol;
150436 sCtx.iTerm = 0;
150437 (void)fts3ExprIterate(pCsr->pExpr, fts3ExprTermOffsetInit, (void*)&sCtx);
150438
150439 /* Retreive the text stored in column iCol. If an SQL NULL is stored
150440 ** in column iCol, jump immediately to the next iteration of the loop.
150441 ** If an OOM occurs while retrieving the data (this can happen if SQLite
150442 ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM
@@ -150166,42 +150524,25 @@
150524 sqlite3_context *pContext, /* Function call context */
150525 Fts3Cursor *pCsr, /* FTS3 table cursor */
150526 const char *zArg /* Second arg to matchinfo() function */
150527 ){
150528 Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab;
 
 
150529 const char *zFormat;
150530
150531 if( zArg ){
 
 
 
 
 
 
 
 
150532 zFormat = zArg;
150533 }else{
150534 zFormat = FTS3_MATCHINFO_DEFAULT;
150535 }
150536
150537 if( !pCsr->pExpr ){
150538 sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC);
150539 return;
 
 
 
 
 
 
 
 
150540 }else{
150541 /* Retrieve matchinfo() data. */
150542 fts3GetMatchinfo(pContext, pCsr, zFormat);
150543 sqlite3Fts3SegmentsClose(pTab);
150544 }
150545 }
150546
150547 #endif
150548
@@ -151318,10 +151659,11 @@
151659 */
151660 struct RtreeMatchArg {
151661 u32 magic; /* Always RTREE_GEOMETRY_MAGIC */
151662 RtreeGeomCallback cb; /* Info about the callback functions */
151663 int nParam; /* Number of parameters to the SQL function */
151664 sqlite3_value **apSqlParam; /* Original SQL parameter values */
151665 RtreeDValue aParam[1]; /* Values for parameters to the SQL function */
151666 };
151667
151668 #ifndef MAX
151669 # define MAX(x,y) ((x) < (y) ? (y) : (x))
@@ -152449,13 +152791,11 @@
152791 /* Check that value is actually a blob. */
152792 if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
152793
152794 /* Check that the blob is roughly the right size. */
152795 nBlob = sqlite3_value_bytes(pValue);
152796 if( nBlob<(int)sizeof(RtreeMatchArg) ){
 
 
152797 return SQLITE_ERROR;
152798 }
152799
152800 pInfo = (sqlite3_rtree_query_info*)sqlite3_malloc( sizeof(*pInfo)+nBlob );
152801 if( !pInfo ) return SQLITE_NOMEM;
@@ -152462,18 +152802,20 @@
152802 memset(pInfo, 0, sizeof(*pInfo));
152803 pBlob = (RtreeMatchArg*)&pInfo[1];
152804
152805 memcpy(pBlob, sqlite3_value_blob(pValue), nBlob);
152806 nExpected = (int)(sizeof(RtreeMatchArg) +
152807 pBlob->nParam*sizeof(sqlite3_value*) +
152808 (pBlob->nParam-1)*sizeof(RtreeDValue));
152809 if( pBlob->magic!=RTREE_GEOMETRY_MAGIC || nBlob!=nExpected ){
152810 sqlite3_free(pInfo);
152811 return SQLITE_ERROR;
152812 }
152813 pInfo->pContext = pBlob->cb.pContext;
152814 pInfo->nParam = pBlob->nParam;
152815 pInfo->aParam = pBlob->aParam;
152816 pInfo->apSqlParam = pBlob->apSqlParam;
152817
152818 if( pBlob->cb.xGeom ){
152819 pCons->u.xGeom = pBlob->cb.xGeom;
152820 }else{
152821 pCons->op = RTREE_QUERY;
@@ -152636,21 +152978,34 @@
152978 */
152979 static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
152980 Rtree *pRtree = (Rtree*)tab;
152981 int rc = SQLITE_OK;
152982 int ii;
152983 int bMatch = 0; /* True if there exists a MATCH constraint */
152984 i64 nRow; /* Estimated rows returned by this scan */
152985
152986 int iIdx = 0;
152987 char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
152988 memset(zIdxStr, 0, sizeof(zIdxStr));
152989
152990 /* Check if there exists a MATCH constraint - even an unusable one. If there
152991 ** is, do not consider the lookup-by-rowid plan as using such a plan would
152992 ** require the VDBE to evaluate the MATCH constraint, which is not currently
152993 ** possible. */
152994 for(ii=0; ii<pIdxInfo->nConstraint; ii++){
152995 if( pIdxInfo->aConstraint[ii].op==SQLITE_INDEX_CONSTRAINT_MATCH ){
152996 bMatch = 1;
152997 }
152998 }
152999
153000 assert( pIdxInfo->idxStr==0 );
153001 for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
153002 struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
153003
153004 if( bMatch==0 && p->usable
153005 && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ
153006 ){
153007 /* We have an equality constraint on the rowid. Use strategy 1. */
153008 int jj;
153009 for(jj=0; jj<ii; jj++){
153010 pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
153011 pIdxInfo->aConstraintUsage[jj].omit = 0;
@@ -154338,10 +154693,22 @@
154693 static void rtreeFreeCallback(void *p){
154694 RtreeGeomCallback *pInfo = (RtreeGeomCallback*)p;
154695 if( pInfo->xDestructor ) pInfo->xDestructor(pInfo->pContext);
154696 sqlite3_free(p);
154697 }
154698
154699 /*
154700 ** This routine frees the BLOB that is returned by geomCallback().
154701 */
154702 static void rtreeMatchArgFree(void *pArg){
154703 int i;
154704 RtreeMatchArg *p = (RtreeMatchArg*)pArg;
154705 for(i=0; i<p->nParam; i++){
154706 sqlite3_value_free(p->apSqlParam[i]);
154707 }
154708 sqlite3_free(p);
154709 }
154710
154711 /*
154712 ** Each call to sqlite3_rtree_geometry_callback() or
154713 ** sqlite3_rtree_query_callback() creates an ordinary SQLite
154714 ** scalar function that is implemented by this routine.
@@ -154357,28 +154724,38 @@
154724 */
154725 static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){
154726 RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx);
154727 RtreeMatchArg *pBlob;
154728 int nBlob;
154729 int memErr = 0;
154730
154731 nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue)
154732 + nArg*sizeof(sqlite3_value*);
154733 pBlob = (RtreeMatchArg *)sqlite3_malloc(nBlob);
154734 if( !pBlob ){
154735 sqlite3_result_error_nomem(ctx);
154736 }else{
154737 int i;
154738 pBlob->magic = RTREE_GEOMETRY_MAGIC;
154739 pBlob->cb = pGeomCtx[0];
154740 pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg];
154741 pBlob->nParam = nArg;
154742 for(i=0; i<nArg; i++){
154743 pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]);
154744 if( pBlob->apSqlParam[i]==0 ) memErr = 1;
154745 #ifdef SQLITE_RTREE_INT_ONLY
154746 pBlob->aParam[i] = sqlite3_value_int64(aArg[i]);
154747 #else
154748 pBlob->aParam[i] = sqlite3_value_double(aArg[i]);
154749 #endif
154750 }
154751 if( memErr ){
154752 sqlite3_result_error_nomem(ctx);
154753 rtreeMatchArgFree(pBlob);
154754 }else{
154755 sqlite3_result_blob(ctx, pBlob, nBlob, rtreeMatchArgFree);
154756 }
154757 }
154758 }
154759
154760 /*
154761 ** Register a new geometry function for use with the r-tree MATCH operator.
@@ -155210,10 +155587,4095 @@
155587
155588 #endif /* defined(SQLITE_ENABLE_ICU) */
155589 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
155590
155591 /************** End of fts3_icu.c ********************************************/
155592 /************** Begin file sqlite3ota.c **************************************/
155593 /*
155594 ** 2014 August 30
155595 **
155596 ** The author disclaims copyright to this source code. In place of
155597 ** a legal notice, here is a blessing:
155598 **
155599 ** May you do good and not evil.
155600 ** May you find forgiveness for yourself and forgive others.
155601 ** May you share freely, never taking more than you give.
155602 **
155603 *************************************************************************
155604 **
155605 **
155606 ** OVERVIEW
155607 **
155608 ** The OTA extension requires that the OTA update be packaged as an
155609 ** SQLite database. The tables it expects to find are described in
155610 ** sqlite3ota.h. Essentially, for each table xyz in the target database
155611 ** that the user wishes to write to, a corresponding data_xyz table is
155612 ** created in the OTA database and populated with one row for each row to
155613 ** update, insert or delete from the target table.
155614 **
155615 ** The update proceeds in three stages:
155616 **
155617 ** 1) The database is updated. The modified database pages are written
155618 ** to a *-oal file. A *-oal file is just like a *-wal file, except
155619 ** that it is named "<database>-oal" instead of "<database>-wal".
155620 ** Because regular SQLite clients do not look for file named
155621 ** "<database>-oal", they go on using the original database in
155622 ** rollback mode while the *-oal file is being generated.
155623 **
155624 ** During this stage OTA does not update the database by writing
155625 ** directly to the target tables. Instead it creates "imposter"
155626 ** tables using the SQLITE_TESTCTRL_IMPOSTER interface that it uses
155627 ** to update each b-tree individually. All updates required by each
155628 ** b-tree are completed before moving on to the next, and all
155629 ** updates are done in sorted key order.
155630 **
155631 ** 2) The "<database>-oal" file is moved to the equivalent "<database>-wal"
155632 ** location using a call to rename(2). Before doing this the OTA
155633 ** module takes an EXCLUSIVE lock on the database file, ensuring
155634 ** that there are no other active readers.
155635 **
155636 ** Once the EXCLUSIVE lock is released, any other database readers
155637 ** detect the new *-wal file and read the database in wal mode. At
155638 ** this point they see the new version of the database - including
155639 ** the updates made as part of the OTA update.
155640 **
155641 ** 3) The new *-wal file is checkpointed. This proceeds in the same way
155642 ** as a regular database checkpoint, except that a single frame is
155643 ** checkpointed each time sqlite3ota_step() is called. If the OTA
155644 ** handle is closed before the entire *-wal file is checkpointed,
155645 ** the checkpoint progress is saved in the OTA database and the
155646 ** checkpoint can be resumed by another OTA client at some point in
155647 ** the future.
155648 **
155649 ** POTENTIAL PROBLEMS
155650 **
155651 ** The rename() call might not be portable. And OTA is not currently
155652 ** syncing the directory after renaming the file.
155653 **
155654 ** When state is saved, any commit to the *-oal file and the commit to
155655 ** the OTA update database are not atomic. So if the power fails at the
155656 ** wrong moment they might get out of sync. As the main database will be
155657 ** committed before the OTA update database this will likely either just
155658 ** pass unnoticed, or result in SQLITE_CONSTRAINT errors (due to UNIQUE
155659 ** constraint violations).
155660 **
155661 ** If some client does modify the target database mid OTA update, or some
155662 ** other error occurs, the OTA extension will keep throwing errors. It's
155663 ** not really clear how to get out of this state. The system could just
155664 ** by delete the OTA update database and *-oal file and have the device
155665 ** download the update again and start over.
155666 **
155667 ** At present, for an UPDATE, both the new.* and old.* records are
155668 ** collected in the ota_xyz table. And for both UPDATEs and DELETEs all
155669 ** fields are collected. This means we're probably writing a lot more
155670 ** data to disk when saving the state of an ongoing update to the OTA
155671 ** update database than is strictly necessary.
155672 **
155673 */
155674
155675 /* #include <assert.h> */
155676 /* #include <string.h> */
155677 /* #include <stdio.h> */
155678 /* #include <unistd.h> */
155679
155680
155681 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA)
155682 /************** Include sqlite3ota.h in the middle of sqlite3ota.c ***********/
155683 /************** Begin file sqlite3ota.h **************************************/
155684 /*
155685 ** 2014 August 30
155686 **
155687 ** The author disclaims copyright to this source code. In place of
155688 ** a legal notice, here is a blessing:
155689 **
155690 ** May you do good and not evil.
155691 ** May you find forgiveness for yourself and forgive others.
155692 ** May you share freely, never taking more than you give.
155693 **
155694 *************************************************************************
155695 **
155696 ** This file contains the public interface for the OTA extension.
155697 */
155698
155699 /*
155700 ** SUMMARY
155701 **
155702 ** Writing a transaction containing a large number of operations on
155703 ** b-tree indexes that are collectively larger than the available cache
155704 ** memory can be very inefficient.
155705 **
155706 ** The problem is that in order to update a b-tree, the leaf page (at least)
155707 ** containing the entry being inserted or deleted must be modified. If the
155708 ** working set of leaves is larger than the available cache memory, then a
155709 ** single leaf that is modified more than once as part of the transaction
155710 ** may be loaded from or written to the persistent media multiple times.
155711 ** Additionally, because the index updates are likely to be applied in
155712 ** random order, access to pages within the database is also likely to be in
155713 ** random order, which is itself quite inefficient.
155714 **
155715 ** One way to improve the situation is to sort the operations on each index
155716 ** by index key before applying them to the b-tree. This leads to an IO
155717 ** pattern that resembles a single linear scan through the index b-tree,
155718 ** and all but guarantees each modified leaf page is loaded and stored
155719 ** exactly once. SQLite uses this trick to improve the performance of
155720 ** CREATE INDEX commands. This extension allows it to be used to improve
155721 ** the performance of large transactions on existing databases.
155722 **
155723 ** Additionally, this extension allows the work involved in writing the
155724 ** large transaction to be broken down into sub-transactions performed
155725 ** sequentially by separate processes. This is useful if the system cannot
155726 ** guarantee that a single update process will run for long enough to apply
155727 ** the entire update, for example because the update is being applied on a
155728 ** mobile device that is frequently rebooted. Even after the writer process
155729 ** has committed one or more sub-transactions, other database clients continue
155730 ** to read from the original database snapshot. In other words, partially
155731 ** applied transactions are not visible to other clients.
155732 **
155733 ** "OTA" stands for "Over The Air" update. As in a large database update
155734 ** transmitted via a wireless network to a mobile device. A transaction
155735 ** applied using this extension is hence refered to as an "OTA update".
155736 **
155737 **
155738 ** LIMITATIONS
155739 **
155740 ** An "OTA update" transaction is subject to the following limitations:
155741 **
155742 ** * The transaction must consist of INSERT, UPDATE and DELETE operations
155743 ** only.
155744 **
155745 ** * INSERT statements may not use any default values.
155746 **
155747 ** * UPDATE and DELETE statements must identify their target rows by
155748 ** non-NULL PRIMARY KEY values. Rows with NULL values stored in PRIMARY
155749 ** KEY fields may not be updated or deleted. If the table being written
155750 ** has no PRIMARY KEY, affected rows must be identified by rowid.
155751 **
155752 ** * UPDATE statements may not modify PRIMARY KEY columns.
155753 **
155754 ** * No triggers will be fired.
155755 **
155756 ** * No foreign key violations are detected or reported.
155757 **
155758 ** * CHECK constraints are not enforced.
155759 **
155760 ** * No constraint handling mode except for "OR ROLLBACK" is supported.
155761 **
155762 **
155763 ** PREPARATION
155764 **
155765 ** An "OTA update" is stored as a separate SQLite database. A database
155766 ** containing an OTA update is an "OTA database". For each table in the
155767 ** target database to be updated, the OTA database should contain a table
155768 ** named "data_<target name>" containing the same set of columns as the
155769 ** target table, and one more - "ota_control". The data_% table should
155770 ** have no PRIMARY KEY or UNIQUE constraints, but each column should have
155771 ** the same type as the corresponding column in the target database.
155772 ** The "ota_control" column should have no type at all. For example, if
155773 ** the target database contains:
155774 **
155775 ** CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c UNIQUE);
155776 **
155777 ** Then the OTA database should contain:
155778 **
155779 ** CREATE TABLE data_t1(a INTEGER, b TEXT, c, ota_control);
155780 **
155781 ** The order of the columns in the data_% table does not matter.
155782 **
155783 ** If the target database table is a virtual table or a table that has no
155784 ** PRIMARY KEY declaration, the data_% table must also contain a column
155785 ** named "ota_rowid". This column is mapped to the tables implicit primary
155786 ** key column - "rowid". Virtual tables for which the "rowid" column does
155787 ** not function like a primary key value cannot be updated using OTA. For
155788 ** example, if the target db contains either of the following:
155789 **
155790 ** CREATE VIRTUAL TABLE x1 USING fts3(a, b);
155791 ** CREATE TABLE x1(a, b)
155792 **
155793 ** then the OTA database should contain:
155794 **
155795 ** CREATE TABLE data_x1(a, b, ota_rowid, ota_control);
155796 **
155797 ** All non-hidden columns (i.e. all columns matched by "SELECT *") of the
155798 ** target table must be present in the input table. For virtual tables,
155799 ** hidden columns are optional - they are updated by OTA if present in
155800 ** the input table, or not otherwise. For example, to write to an fts4
155801 ** table with a hidden languageid column such as:
155802 **
155803 ** CREATE VIRTUAL TABLE ft1 USING fts4(a, b, languageid='langid');
155804 **
155805 ** Either of the following input table schemas may be used:
155806 **
155807 ** CREATE TABLE data_ft1(a, b, langid, ota_rowid, ota_control);
155808 ** CREATE TABLE data_ft1(a, b, ota_rowid, ota_control);
155809 **
155810 ** For each row to INSERT into the target database as part of the OTA
155811 ** update, the corresponding data_% table should contain a single record
155812 ** with the "ota_control" column set to contain integer value 0. The
155813 ** other columns should be set to the values that make up the new record
155814 ** to insert.
155815 **
155816 ** If the target database table has an INTEGER PRIMARY KEY, it is not
155817 ** possible to insert a NULL value into the IPK column. Attempting to
155818 ** do so results in an SQLITE_MISMATCH error.
155819 **
155820 ** For each row to DELETE from the target database as part of the OTA
155821 ** update, the corresponding data_% table should contain a single record
155822 ** with the "ota_control" column set to contain integer value 1. The
155823 ** real primary key values of the row to delete should be stored in the
155824 ** corresponding columns of the data_% table. The values stored in the
155825 ** other columns are not used.
155826 **
155827 ** For each row to UPDATE from the target database as part of the OTA
155828 ** update, the corresponding data_% table should contain a single record
155829 ** with the "ota_control" column set to contain a value of type text.
155830 ** The real primary key values identifying the row to update should be
155831 ** stored in the corresponding columns of the data_% table row, as should
155832 ** the new values of all columns being update. The text value in the
155833 ** "ota_control" column must contain the same number of characters as
155834 ** there are columns in the target database table, and must consist entirely
155835 ** of 'x' and '.' characters (or in some special cases 'd' - see below). For
155836 ** each column that is being updated, the corresponding character is set to
155837 ** 'x'. For those that remain as they are, the corresponding character of the
155838 ** ota_control value should be set to '.'. For example, given the tables
155839 ** above, the update statement:
155840 **
155841 ** UPDATE t1 SET c = 'usa' WHERE a = 4;
155842 **
155843 ** is represented by the data_t1 row created by:
155844 **
155845 ** INSERT INTO data_t1(a, b, c, ota_control) VALUES(4, NULL, 'usa', '..x');
155846 **
155847 ** Instead of an 'x' character, characters of the ota_control value specified
155848 ** for UPDATEs may also be set to 'd'. In this case, instead of updating the
155849 ** target table with the value stored in the corresponding data_% column, the
155850 ** user-defined SQL function "ota_delta()" is invoked and the result stored in
155851 ** the target table column. ota_delta() is invoked with two arguments - the
155852 ** original value currently stored in the target table column and the
155853 ** value specified in the data_xxx table.
155854 **
155855 ** For example, this row:
155856 **
155857 ** INSERT INTO data_t1(a, b, c, ota_control) VALUES(4, NULL, 'usa', '..d');
155858 **
155859 ** is similar to an UPDATE statement such as:
155860 **
155861 ** UPDATE t1 SET c = ota_delta(c, 'usa') WHERE a = 4;
155862 **
155863 ** If the target database table is a virtual table or a table with no PRIMARY
155864 ** KEY, the ota_control value should not include a character corresponding
155865 ** to the ota_rowid value. For example, this:
155866 **
155867 ** INSERT INTO data_ft1(a, b, ota_rowid, ota_control)
155868 ** VALUES(NULL, 'usa', 12, '.x');
155869 **
155870 ** causes a result similar to:
155871 **
155872 ** UPDATE ft1 SET b = 'usa' WHERE rowid = 12;
155873 **
155874 ** The data_xxx tables themselves should have no PRIMARY KEY declarations.
155875 ** However, OTA is more efficient if reading the rows in from each data_xxx
155876 ** table in "rowid" order is roughly the same as reading them sorted by
155877 ** the PRIMARY KEY of the corresponding target database table. In other
155878 ** words, rows should be sorted using the destination table PRIMARY KEY
155879 ** fields before they are inserted into the data_xxx tables.
155880 **
155881 ** USAGE
155882 **
155883 ** The API declared below allows an application to apply an OTA update
155884 ** stored on disk to an existing target database. Essentially, the
155885 ** application:
155886 **
155887 ** 1) Opens an OTA handle using the sqlite3ota_open() function.
155888 **
155889 ** 2) Registers any required virtual table modules with the database
155890 ** handle returned by sqlite3ota_db(). Also, if required, register
155891 ** the ota_delta() implementation.
155892 **
155893 ** 3) Calls the sqlite3ota_step() function one or more times on
155894 ** the new handle. Each call to sqlite3ota_step() performs a single
155895 ** b-tree operation, so thousands of calls may be required to apply
155896 ** a complete update.
155897 **
155898 ** 4) Calls sqlite3ota_close() to close the OTA update handle. If
155899 ** sqlite3ota_step() has been called enough times to completely
155900 ** apply the update to the target database, then the OTA database
155901 ** is marked as fully applied. Otherwise, the state of the OTA
155902 ** update application is saved in the OTA database for later
155903 ** resumption.
155904 **
155905 ** See comments below for more detail on APIs.
155906 **
155907 ** If an update is only partially applied to the target database by the
155908 ** time sqlite3ota_close() is called, various state information is saved
155909 ** within the OTA database. This allows subsequent processes to automatically
155910 ** resume the OTA update from where it left off.
155911 **
155912 ** To remove all OTA extension state information, returning an OTA database
155913 ** to its original contents, it is sufficient to drop all tables that begin
155914 ** with the prefix "ota_"
155915 **
155916 ** DATABASE LOCKING
155917 **
155918 ** An OTA update may not be applied to a database in WAL mode. Attempting
155919 ** to do so is an error (SQLITE_ERROR).
155920 **
155921 ** While an OTA handle is open, a SHARED lock may be held on the target
155922 ** database file. This means it is possible for other clients to read the
155923 ** database, but not to write it.
155924 **
155925 ** If an OTA update is started and then suspended before it is completed,
155926 ** then an external client writes to the database, then attempting to resume
155927 ** the suspended OTA update is also an error (SQLITE_BUSY).
155928 */
155929
155930 #ifndef _SQLITE3OTA_H
155931 #define _SQLITE3OTA_H
155932
155933
155934 typedef struct sqlite3ota sqlite3ota;
155935
155936 /*
155937 ** Open an OTA handle.
155938 **
155939 ** Argument zTarget is the path to the target database. Argument zOta is
155940 ** the path to the OTA database. Each call to this function must be matched
155941 ** by a call to sqlite3ota_close(). When opening the databases, OTA passes
155942 ** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget
155943 ** or zOta begin with "file:", it will be interpreted as an SQLite
155944 ** database URI, not a regular file name.
155945 **
155946 ** If the zState argument is passed a NULL value, the OTA extension stores
155947 ** the current state of the update (how many rows have been updated, which
155948 ** indexes are yet to be updated etc.) within the OTA database itself. This
155949 ** can be convenient, as it means that the OTA application does not need to
155950 ** organize removing a separate state file after the update is concluded.
155951 ** Or, if zState is non-NULL, it must be a path to a database file in which
155952 ** the OTA extension can store the state of the update.
155953 **
155954 ** When resuming an OTA update, the zState argument must be passed the same
155955 ** value as when the OTA update was started.
155956 **
155957 ** Once the OTA update is finished, the OTA extension does not
155958 ** automatically remove any zState database file, even if it created it.
155959 **
155960 ** By default, OTA uses the default VFS to access the files on disk. To
155961 ** use a VFS other than the default, an SQLite "file:" URI containing a
155962 ** "vfs=..." option may be passed as the zTarget option.
155963 **
155964 ** IMPORTANT NOTE FOR ZIPVFS USERS: The OTA extension works with all of
155965 ** SQLite's built-in VFSs, including the multiplexor VFS. However it does
155966 ** not work out of the box with zipvfs. Refer to the comment describing
155967 ** the zipvfs_create_vfs() API below for details on using OTA with zipvfs.
155968 */
155969 SQLITE_API sqlite3ota *SQLITE_STDCALL sqlite3ota_open(
155970 const char *zTarget,
155971 const char *zOta,
155972 const char *zState
155973 );
155974
155975 /*
155976 ** Internally, each OTA connection uses a separate SQLite database
155977 ** connection to access the target and ota update databases. This
155978 ** API allows the application direct access to these database handles.
155979 **
155980 ** The first argument passed to this function must be a valid, open, OTA
155981 ** handle. The second argument should be passed zero to access the target
155982 ** database handle, or non-zero to access the ota update database handle.
155983 ** Accessing the underlying database handles may be useful in the
155984 ** following scenarios:
155985 **
155986 ** * If any target tables are virtual tables, it may be necessary to
155987 ** call sqlite3_create_module() on the target database handle to
155988 ** register the required virtual table implementations.
155989 **
155990 ** * If the data_xxx tables in the OTA source database are virtual
155991 ** tables, the application may need to call sqlite3_create_module() on
155992 ** the ota update db handle to any required virtual table
155993 ** implementations.
155994 **
155995 ** * If the application uses the "ota_delta()" feature described above,
155996 ** it must use sqlite3_create_function() or similar to register the
155997 ** ota_delta() implementation with the target database handle.
155998 **
155999 ** If an error has occurred, either while opening or stepping the OTA object,
156000 ** this function may return NULL. The error code and message may be collected
156001 ** when sqlite3ota_close() is called.
156002 */
156003 SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3ota_db(sqlite3ota*, int bOta);
156004
156005 /*
156006 ** Do some work towards applying the OTA update to the target db.
156007 **
156008 ** Return SQLITE_DONE if the update has been completely applied, or
156009 ** SQLITE_OK if no error occurs but there remains work to do to apply
156010 ** the OTA update. If an error does occur, some other error code is
156011 ** returned.
156012 **
156013 ** Once a call to sqlite3ota_step() has returned a value other than
156014 ** SQLITE_OK, all subsequent calls on the same OTA handle are no-ops
156015 ** that immediately return the same value.
156016 */
156017 SQLITE_API int SQLITE_STDCALL sqlite3ota_step(sqlite3ota *pOta);
156018
156019 /*
156020 ** Close an OTA handle.
156021 **
156022 ** If the OTA update has been completely applied, mark the OTA database
156023 ** as fully applied. Otherwise, assuming no error has occurred, save the
156024 ** current state of the OTA update appliation to the OTA database.
156025 **
156026 ** If an error has already occurred as part of an sqlite3ota_step()
156027 ** or sqlite3ota_open() call, or if one occurs within this function, an
156028 ** SQLite error code is returned. Additionally, *pzErrmsg may be set to
156029 ** point to a buffer containing a utf-8 formatted English language error
156030 ** message. It is the responsibility of the caller to eventually free any
156031 ** such buffer using sqlite3_free().
156032 **
156033 ** Otherwise, if no error occurs, this function returns SQLITE_OK if the
156034 ** update has been partially applied, or SQLITE_DONE if it has been
156035 ** completely applied.
156036 */
156037 SQLITE_API int SQLITE_STDCALL sqlite3ota_close(sqlite3ota *pOta, char **pzErrmsg);
156038
156039 /*
156040 ** Return the total number of key-value operations (inserts, deletes or
156041 ** updates) that have been performed on the target database since the
156042 ** current OTA update was started.
156043 */
156044 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3ota_progress(sqlite3ota *pOta);
156045
156046 /*
156047 ** Create an OTA VFS named zName that accesses the underlying file-system
156048 ** via existing VFS zParent. Or, if the zParent parameter is passed NULL,
156049 ** then the new OTA VFS uses the default system VFS to access the file-system.
156050 ** The new object is registered as a non-default VFS with SQLite before
156051 ** returning.
156052 **
156053 ** Part of the OTA implementation uses a custom VFS object. Usually, this
156054 ** object is created and deleted automatically by OTA.
156055 **
156056 ** The exception is for applications that also use zipvfs. In this case,
156057 ** the custom VFS must be explicitly created by the user before the OTA
156058 ** handle is opened. The OTA VFS should be installed so that the zipvfs
156059 ** VFS uses the OTA VFS, which in turn uses any other VFS layers in use
156060 ** (for example multiplexor) to access the file-system. For example,
156061 ** to assemble an OTA enabled VFS stack that uses both zipvfs and
156062 ** multiplexor (error checking omitted):
156063 **
156064 ** // Create a VFS named "multiplex" (not the default).
156065 ** sqlite3_multiplex_initialize(0, 0);
156066 **
156067 ** // Create an ota VFS named "ota" that uses multiplexor. If the
156068 ** // second argument were replaced with NULL, the "ota" VFS would
156069 ** // access the file-system via the system default VFS, bypassing the
156070 ** // multiplexor.
156071 ** sqlite3ota_create_vfs("ota", "multiplex");
156072 **
156073 ** // Create a zipvfs VFS named "zipvfs" that uses ota.
156074 ** zipvfs_create_vfs_v3("zipvfs", "ota", 0, xCompressorAlgorithmDetector);
156075 **
156076 ** // Make zipvfs the default VFS.
156077 ** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1);
156078 **
156079 ** Because the default VFS created above includes a OTA functionality, it
156080 ** may be used by OTA clients. Attempting to use OTA with a zipvfs VFS stack
156081 ** that does not include the OTA layer results in an error.
156082 **
156083 ** The overhead of adding the "ota" VFS to the system is negligible for
156084 ** non-OTA users. There is no harm in an application accessing the
156085 ** file-system via "ota" all the time, even if it only uses OTA functionality
156086 ** occasionally.
156087 */
156088 SQLITE_API int SQLITE_STDCALL sqlite3ota_create_vfs(const char *zName, const char *zParent);
156089
156090 /*
156091 ** Deregister and destroy an OTA vfs created by an earlier call to
156092 ** sqlite3ota_create_vfs().
156093 **
156094 ** VFS objects are not reference counted. If a VFS object is destroyed
156095 ** before all database handles that use it have been closed, the results
156096 ** are undefined.
156097 */
156098 SQLITE_API void SQLITE_STDCALL sqlite3ota_destroy_vfs(const char *zName);
156099
156100 #endif /* _SQLITE3OTA_H */
156101
156102
156103 /************** End of sqlite3ota.h ******************************************/
156104 /************** Continuing where we left off in sqlite3ota.c *****************/
156105
156106 /* Maximum number of prepared UPDATE statements held by this module */
156107 #define SQLITE_OTA_UPDATE_CACHESIZE 16
156108
156109 /*
156110 ** Swap two objects of type TYPE.
156111 */
156112 #if !defined(SQLITE_AMALGAMATION)
156113 # define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
156114 #endif
156115
156116 /*
156117 ** The ota_state table is used to save the state of a partially applied
156118 ** update so that it can be resumed later. The table consists of integer
156119 ** keys mapped to values as follows:
156120 **
156121 ** OTA_STATE_STAGE:
156122 ** May be set to integer values 1, 2, 4 or 5. As follows:
156123 ** 1: the *-ota file is currently under construction.
156124 ** 2: the *-ota file has been constructed, but not yet moved
156125 ** to the *-wal path.
156126 ** 4: the checkpoint is underway.
156127 ** 5: the ota update has been checkpointed.
156128 **
156129 ** OTA_STATE_TBL:
156130 ** Only valid if STAGE==1. The target database name of the table
156131 ** currently being written.
156132 **
156133 ** OTA_STATE_IDX:
156134 ** Only valid if STAGE==1. The target database name of the index
156135 ** currently being written, or NULL if the main table is currently being
156136 ** updated.
156137 **
156138 ** OTA_STATE_ROW:
156139 ** Only valid if STAGE==1. Number of rows already processed for the current
156140 ** table/index.
156141 **
156142 ** OTA_STATE_PROGRESS:
156143 ** Total number of sqlite3ota_step() calls made so far as part of this
156144 ** ota update.
156145 **
156146 ** OTA_STATE_CKPT:
156147 ** Valid if STAGE==4. The 64-bit checksum associated with the wal-index
156148 ** header created by recovering the *-wal file. This is used to detect
156149 ** cases when another client appends frames to the *-wal file in the
156150 ** middle of an incremental checkpoint (an incremental checkpoint cannot
156151 ** be continued if this happens).
156152 **
156153 ** OTA_STATE_COOKIE:
156154 ** Valid if STAGE==1. The current change-counter cookie value in the
156155 ** target db file.
156156 **
156157 ** OTA_STATE_OALSZ:
156158 ** Valid if STAGE==1. The size in bytes of the *-oal file.
156159 */
156160 #define OTA_STATE_STAGE 1
156161 #define OTA_STATE_TBL 2
156162 #define OTA_STATE_IDX 3
156163 #define OTA_STATE_ROW 4
156164 #define OTA_STATE_PROGRESS 5
156165 #define OTA_STATE_CKPT 6
156166 #define OTA_STATE_COOKIE 7
156167 #define OTA_STATE_OALSZ 8
156168
156169 #define OTA_STAGE_OAL 1
156170 #define OTA_STAGE_MOVE 2
156171 #define OTA_STAGE_CAPTURE 3
156172 #define OTA_STAGE_CKPT 4
156173 #define OTA_STAGE_DONE 5
156174
156175
156176 #define OTA_CREATE_STATE \
156177 "CREATE TABLE IF NOT EXISTS %s.ota_state(k INTEGER PRIMARY KEY, v)"
156178
156179 typedef struct OtaFrame OtaFrame;
156180 typedef struct OtaObjIter OtaObjIter;
156181 typedef struct OtaState OtaState;
156182 typedef struct ota_vfs ota_vfs;
156183 typedef struct ota_file ota_file;
156184 typedef struct OtaUpdateStmt OtaUpdateStmt;
156185
156186 #if !defined(SQLITE_AMALGAMATION)
156187 typedef unsigned int u32;
156188 typedef unsigned char u8;
156189 typedef sqlite3_int64 i64;
156190 #endif
156191
156192 /*
156193 ** These values must match the values defined in wal.c for the equivalent
156194 ** locks. These are not magic numbers as they are part of the SQLite file
156195 ** format.
156196 */
156197 #define WAL_LOCK_WRITE 0
156198 #define WAL_LOCK_CKPT 1
156199 #define WAL_LOCK_READ0 3
156200
156201 /*
156202 ** A structure to store values read from the ota_state table in memory.
156203 */
156204 struct OtaState {
156205 int eStage;
156206 char *zTbl;
156207 char *zIdx;
156208 i64 iWalCksum;
156209 int nRow;
156210 i64 nProgress;
156211 u32 iCookie;
156212 i64 iOalSz;
156213 };
156214
156215 struct OtaUpdateStmt {
156216 char *zMask; /* Copy of update mask used with pUpdate */
156217 sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */
156218 OtaUpdateStmt *pNext;
156219 };
156220
156221 /*
156222 ** An iterator of this type is used to iterate through all objects in
156223 ** the target database that require updating. For each such table, the
156224 ** iterator visits, in order:
156225 **
156226 ** * the table itself,
156227 ** * each index of the table (zero or more points to visit), and
156228 ** * a special "cleanup table" state.
156229 **
156230 ** abIndexed:
156231 ** If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
156232 ** it points to an array of flags nTblCol elements in size. The flag is
156233 ** set for each column that is either a part of the PK or a part of an
156234 ** index. Or clear otherwise.
156235 **
156236 */
156237 struct OtaObjIter {
156238 sqlite3_stmt *pTblIter; /* Iterate through tables */
156239 sqlite3_stmt *pIdxIter; /* Index iterator */
156240 int nTblCol; /* Size of azTblCol[] array */
156241 char **azTblCol; /* Array of unquoted target column names */
156242 char **azTblType; /* Array of target column types */
156243 int *aiSrcOrder; /* src table col -> target table col */
156244 u8 *abTblPk; /* Array of flags, set on target PK columns */
156245 u8 *abNotNull; /* Array of flags, set on NOT NULL columns */
156246 u8 *abIndexed; /* Array of flags, set on indexed & PK cols */
156247 int eType; /* Table type - an OTA_PK_XXX value */
156248
156249 /* Output variables. zTbl==0 implies EOF. */
156250 int bCleanup; /* True in "cleanup" state */
156251 const char *zTbl; /* Name of target db table */
156252 const char *zIdx; /* Name of target db index (or null) */
156253 int iTnum; /* Root page of current object */
156254 int iPkTnum; /* If eType==EXTERNAL, root of PK index */
156255 int bUnique; /* Current index is unique */
156256
156257 /* Statements created by otaObjIterPrepareAll() */
156258 int nCol; /* Number of columns in current object */
156259 sqlite3_stmt *pSelect; /* Source data */
156260 sqlite3_stmt *pInsert; /* Statement for INSERT operations */
156261 sqlite3_stmt *pDelete; /* Statement for DELETE ops */
156262 sqlite3_stmt *pTmpInsert; /* Insert into ota_tmp_$zTbl */
156263
156264 /* Last UPDATE used (for PK b-tree updates only), or NULL. */
156265 OtaUpdateStmt *pOtaUpdate;
156266 };
156267
156268 /*
156269 ** Values for OtaObjIter.eType
156270 **
156271 ** 0: Table does not exist (error)
156272 ** 1: Table has an implicit rowid.
156273 ** 2: Table has an explicit IPK column.
156274 ** 3: Table has an external PK index.
156275 ** 4: Table is WITHOUT ROWID.
156276 ** 5: Table is a virtual table.
156277 */
156278 #define OTA_PK_NOTABLE 0
156279 #define OTA_PK_NONE 1
156280 #define OTA_PK_IPK 2
156281 #define OTA_PK_EXTERNAL 3
156282 #define OTA_PK_WITHOUT_ROWID 4
156283 #define OTA_PK_VTAB 5
156284
156285
156286 /*
156287 ** Within the OTA_STAGE_OAL stage, each call to sqlite3ota_step() performs
156288 ** one of the following operations.
156289 */
156290 #define OTA_INSERT 1 /* Insert on a main table b-tree */
156291 #define OTA_DELETE 2 /* Delete a row from a main table b-tree */
156292 #define OTA_IDX_DELETE 3 /* Delete a row from an aux. index b-tree */
156293 #define OTA_IDX_INSERT 4 /* Insert on an aux. index b-tree */
156294 #define OTA_UPDATE 5 /* Update a row in a main table b-tree */
156295
156296
156297 /*
156298 ** A single step of an incremental checkpoint - frame iWalFrame of the wal
156299 ** file should be copied to page iDbPage of the database file.
156300 */
156301 struct OtaFrame {
156302 u32 iDbPage;
156303 u32 iWalFrame;
156304 };
156305
156306 /*
156307 ** OTA handle.
156308 */
156309 struct sqlite3ota {
156310 int eStage; /* Value of OTA_STATE_STAGE field */
156311 sqlite3 *dbMain; /* target database handle */
156312 sqlite3 *dbOta; /* ota database handle */
156313 char *zTarget; /* Path to target db */
156314 char *zOta; /* Path to ota db */
156315 char *zState; /* Path to state db (or NULL if zOta) */
156316 char zStateDb[5]; /* Db name for state ("stat" or "main") */
156317 int rc; /* Value returned by last ota_step() call */
156318 char *zErrmsg; /* Error message if rc!=SQLITE_OK */
156319 int nStep; /* Rows processed for current object */
156320 int nProgress; /* Rows processed for all objects */
156321 OtaObjIter objiter; /* Iterator for skipping through tbl/idx */
156322 const char *zVfsName; /* Name of automatically created ota vfs */
156323 ota_file *pTargetFd; /* File handle open on target db */
156324 i64 iOalSz;
156325
156326 /* The following state variables are used as part of the incremental
156327 ** checkpoint stage (eStage==OTA_STAGE_CKPT). See comments surrounding
156328 ** function otaSetupCheckpoint() for details. */
156329 u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */
156330 u32 mLock;
156331 int nFrame; /* Entries in aFrame[] array */
156332 int nFrameAlloc; /* Allocated size of aFrame[] array */
156333 OtaFrame *aFrame;
156334 int pgsz;
156335 u8 *aBuf;
156336 i64 iWalCksum;
156337 };
156338
156339 /*
156340 ** An ota VFS is implemented using an instance of this structure.
156341 */
156342 struct ota_vfs {
156343 sqlite3_vfs base; /* ota VFS shim methods */
156344 sqlite3_vfs *pRealVfs; /* Underlying VFS */
156345 sqlite3_mutex *mutex; /* Mutex to protect pMain */
156346 ota_file *pMain; /* Linked list of main db files */
156347 };
156348
156349 /*
156350 ** Each file opened by an ota VFS is represented by an instance of
156351 ** the following structure.
156352 */
156353 struct ota_file {
156354 sqlite3_file base; /* sqlite3_file methods */
156355 sqlite3_file *pReal; /* Underlying file handle */
156356 ota_vfs *pOtaVfs; /* Pointer to the ota_vfs object */
156357 sqlite3ota *pOta; /* Pointer to ota object (ota target only) */
156358
156359 int openFlags; /* Flags this file was opened with */
156360 u32 iCookie; /* Cookie value for main db files */
156361 u8 iWriteVer; /* "write-version" value for main db files */
156362
156363 int nShm; /* Number of entries in apShm[] array */
156364 char **apShm; /* Array of mmap'd *-shm regions */
156365 char *zDel; /* Delete this when closing file */
156366
156367 const char *zWal; /* Wal filename for this main db file */
156368 ota_file *pWalFd; /* Wal file descriptor for this main db */
156369 ota_file *pMainNext; /* Next MAIN_DB file */
156370 };
156371
156372
156373 /*
156374 ** Prepare the SQL statement in buffer zSql against database handle db.
156375 ** If successful, set *ppStmt to point to the new statement and return
156376 ** SQLITE_OK.
156377 **
156378 ** Otherwise, if an error does occur, set *ppStmt to NULL and return
156379 ** an SQLite error code. Additionally, set output variable *pzErrmsg to
156380 ** point to a buffer containing an error message. It is the responsibility
156381 ** of the caller to (eventually) free this buffer using sqlite3_free().
156382 */
156383 static int prepareAndCollectError(
156384 sqlite3 *db,
156385 sqlite3_stmt **ppStmt,
156386 char **pzErrmsg,
156387 const char *zSql
156388 ){
156389 int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
156390 if( rc!=SQLITE_OK ){
156391 *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
156392 *ppStmt = 0;
156393 }
156394 return rc;
156395 }
156396
156397 /*
156398 ** Reset the SQL statement passed as the first argument. Return a copy
156399 ** of the value returned by sqlite3_reset().
156400 **
156401 ** If an error has occurred, then set *pzErrmsg to point to a buffer
156402 ** containing an error message. It is the responsibility of the caller
156403 ** to eventually free this buffer using sqlite3_free().
156404 */
156405 static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){
156406 int rc = sqlite3_reset(pStmt);
156407 if( rc!=SQLITE_OK ){
156408 *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt)));
156409 }
156410 return rc;
156411 }
156412
156413 /*
156414 ** Unless it is NULL, argument zSql points to a buffer allocated using
156415 ** sqlite3_malloc containing an SQL statement. This function prepares the SQL
156416 ** statement against database db and frees the buffer. If statement
156417 ** compilation is successful, *ppStmt is set to point to the new statement
156418 ** handle and SQLITE_OK is returned.
156419 **
156420 ** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code
156421 ** returned. In this case, *pzErrmsg may also be set to point to an error
156422 ** message. It is the responsibility of the caller to free this error message
156423 ** buffer using sqlite3_free().
156424 **
156425 ** If argument zSql is NULL, this function assumes that an OOM has occurred.
156426 ** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL.
156427 */
156428 static int prepareFreeAndCollectError(
156429 sqlite3 *db,
156430 sqlite3_stmt **ppStmt,
156431 char **pzErrmsg,
156432 char *zSql
156433 ){
156434 int rc;
156435 assert( *pzErrmsg==0 );
156436 if( zSql==0 ){
156437 rc = SQLITE_NOMEM;
156438 *ppStmt = 0;
156439 }else{
156440 rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql);
156441 sqlite3_free(zSql);
156442 }
156443 return rc;
156444 }
156445
156446 /*
156447 ** Free the OtaObjIter.azTblCol[] and OtaObjIter.abTblPk[] arrays allocated
156448 ** by an earlier call to otaObjIterCacheTableInfo().
156449 */
156450 static void otaObjIterFreeCols(OtaObjIter *pIter){
156451 int i;
156452 for(i=0; i<pIter->nTblCol; i++){
156453 sqlite3_free(pIter->azTblCol[i]);
156454 sqlite3_free(pIter->azTblType[i]);
156455 }
156456 sqlite3_free(pIter->azTblCol);
156457 pIter->azTblCol = 0;
156458 pIter->azTblType = 0;
156459 pIter->aiSrcOrder = 0;
156460 pIter->abTblPk = 0;
156461 pIter->abNotNull = 0;
156462 pIter->nTblCol = 0;
156463 pIter->eType = 0; /* Invalid value */
156464 }
156465
156466 /*
156467 ** Finalize all statements and free all allocations that are specific to
156468 ** the current object (table/index pair).
156469 */
156470 static void otaObjIterClearStatements(OtaObjIter *pIter){
156471 OtaUpdateStmt *pUp;
156472
156473 sqlite3_finalize(pIter->pSelect);
156474 sqlite3_finalize(pIter->pInsert);
156475 sqlite3_finalize(pIter->pDelete);
156476 sqlite3_finalize(pIter->pTmpInsert);
156477 pUp = pIter->pOtaUpdate;
156478 while( pUp ){
156479 OtaUpdateStmt *pTmp = pUp->pNext;
156480 sqlite3_finalize(pUp->pUpdate);
156481 sqlite3_free(pUp);
156482 pUp = pTmp;
156483 }
156484
156485 pIter->pSelect = 0;
156486 pIter->pInsert = 0;
156487 pIter->pDelete = 0;
156488 pIter->pOtaUpdate = 0;
156489 pIter->pTmpInsert = 0;
156490 pIter->nCol = 0;
156491 }
156492
156493 /*
156494 ** Clean up any resources allocated as part of the iterator object passed
156495 ** as the only argument.
156496 */
156497 static void otaObjIterFinalize(OtaObjIter *pIter){
156498 otaObjIterClearStatements(pIter);
156499 sqlite3_finalize(pIter->pTblIter);
156500 sqlite3_finalize(pIter->pIdxIter);
156501 otaObjIterFreeCols(pIter);
156502 memset(pIter, 0, sizeof(OtaObjIter));
156503 }
156504
156505 /*
156506 ** Advance the iterator to the next position.
156507 **
156508 ** If no error occurs, SQLITE_OK is returned and the iterator is left
156509 ** pointing to the next entry. Otherwise, an error code and message is
156510 ** left in the OTA handle passed as the first argument. A copy of the
156511 ** error code is returned.
156512 */
156513 static int otaObjIterNext(sqlite3ota *p, OtaObjIter *pIter){
156514 int rc = p->rc;
156515 if( rc==SQLITE_OK ){
156516
156517 /* Free any SQLite statements used while processing the previous object */
156518 otaObjIterClearStatements(pIter);
156519 if( pIter->zIdx==0 ){
156520 rc = sqlite3_exec(p->dbMain,
156521 "DROP TRIGGER IF EXISTS temp.ota_insert_tr;"
156522 "DROP TRIGGER IF EXISTS temp.ota_update1_tr;"
156523 "DROP TRIGGER IF EXISTS temp.ota_update2_tr;"
156524 "DROP TRIGGER IF EXISTS temp.ota_delete_tr;"
156525 , 0, 0, &p->zErrmsg
156526 );
156527 }
156528
156529 if( rc==SQLITE_OK ){
156530 if( pIter->bCleanup ){
156531 otaObjIterFreeCols(pIter);
156532 pIter->bCleanup = 0;
156533 rc = sqlite3_step(pIter->pTblIter);
156534 if( rc!=SQLITE_ROW ){
156535 rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
156536 pIter->zTbl = 0;
156537 }else{
156538 pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
156539 rc = pIter->zTbl ? SQLITE_OK : SQLITE_NOMEM;
156540 }
156541 }else{
156542 if( pIter->zIdx==0 ){
156543 sqlite3_stmt *pIdx = pIter->pIdxIter;
156544 rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC);
156545 }
156546 if( rc==SQLITE_OK ){
156547 rc = sqlite3_step(pIter->pIdxIter);
156548 if( rc!=SQLITE_ROW ){
156549 rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg);
156550 pIter->bCleanup = 1;
156551 pIter->zIdx = 0;
156552 }else{
156553 pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0);
156554 pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1);
156555 pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2);
156556 rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM;
156557 }
156558 }
156559 }
156560 }
156561 }
156562
156563 if( rc!=SQLITE_OK ){
156564 otaObjIterFinalize(pIter);
156565 p->rc = rc;
156566 }
156567 return rc;
156568 }
156569
156570 /*
156571 ** Initialize the iterator structure passed as the second argument.
156572 **
156573 ** If no error occurs, SQLITE_OK is returned and the iterator is left
156574 ** pointing to the first entry. Otherwise, an error code and message is
156575 ** left in the OTA handle passed as the first argument. A copy of the
156576 ** error code is returned.
156577 */
156578 static int otaObjIterFirst(sqlite3ota *p, OtaObjIter *pIter){
156579 int rc;
156580 memset(pIter, 0, sizeof(OtaObjIter));
156581
156582 rc = prepareAndCollectError(p->dbOta, &pIter->pTblIter, &p->zErrmsg,
156583 "SELECT substr(name, 6) FROM sqlite_master "
156584 "WHERE type='table' AND name LIKE 'data_%'"
156585 );
156586
156587 if( rc==SQLITE_OK ){
156588 rc = prepareAndCollectError(p->dbMain, &pIter->pIdxIter, &p->zErrmsg,
156589 "SELECT name, rootpage, sql IS NULL OR substr(8, 6)=='UNIQUE' "
156590 " FROM main.sqlite_master "
156591 " WHERE type='index' AND tbl_name = ?"
156592 );
156593 }
156594
156595 pIter->bCleanup = 1;
156596 p->rc = rc;
156597 return otaObjIterNext(p, pIter);
156598 }
156599
156600 /*
156601 ** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs,
156602 ** an error code is stored in the OTA handle passed as the first argument.
156603 **
156604 ** If an error has already occurred (p->rc is already set to something other
156605 ** than SQLITE_OK), then this function returns NULL without modifying the
156606 ** stored error code. In this case it still calls sqlite3_free() on any
156607 ** printf() parameters associated with %z conversions.
156608 */
156609 static char *otaMPrintf(sqlite3ota *p, const char *zFmt, ...){
156610 char *zSql = 0;
156611 va_list ap;
156612 va_start(ap, zFmt);
156613 zSql = sqlite3_vmprintf(zFmt, ap);
156614 if( p->rc==SQLITE_OK ){
156615 if( zSql==0 ) p->rc = SQLITE_NOMEM;
156616 }else{
156617 sqlite3_free(zSql);
156618 zSql = 0;
156619 }
156620 va_end(ap);
156621 return zSql;
156622 }
156623
156624 /*
156625 ** Argument zFmt is a sqlite3_mprintf() style format string. The trailing
156626 ** arguments are the usual subsitution values. This function performs
156627 ** the printf() style substitutions and executes the result as an SQL
156628 ** statement on the OTA handles database.
156629 **
156630 ** If an error occurs, an error code and error message is stored in the
156631 ** OTA handle. If an error has already occurred when this function is
156632 ** called, it is a no-op.
156633 */
156634 static int otaMPrintfExec(sqlite3ota *p, sqlite3 *db, const char *zFmt, ...){
156635 va_list ap;
156636 va_start(ap, zFmt);
156637 char *zSql = sqlite3_vmprintf(zFmt, ap);
156638 if( p->rc==SQLITE_OK ){
156639 if( zSql==0 ){
156640 p->rc = SQLITE_NOMEM;
156641 }else{
156642 p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg);
156643 }
156644 }
156645 sqlite3_free(zSql);
156646 va_end(ap);
156647 return p->rc;
156648 }
156649
156650 /*
156651 ** Attempt to allocate and return a pointer to a zeroed block of nByte
156652 ** bytes.
156653 **
156654 ** If an error (i.e. an OOM condition) occurs, return NULL and leave an
156655 ** error code in the ota handle passed as the first argument. Or, if an
156656 ** error has already occurred when this function is called, return NULL
156657 ** immediately without attempting the allocation or modifying the stored
156658 ** error code.
156659 */
156660 static void *otaMalloc(sqlite3ota *p, int nByte){
156661 void *pRet = 0;
156662 if( p->rc==SQLITE_OK ){
156663 assert( nByte>0 );
156664 pRet = sqlite3_malloc(nByte);
156665 if( pRet==0 ){
156666 p->rc = SQLITE_NOMEM;
156667 }else{
156668 memset(pRet, 0, nByte);
156669 }
156670 }
156671 return pRet;
156672 }
156673
156674
156675 /*
156676 ** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that
156677 ** there is room for at least nCol elements. If an OOM occurs, store an
156678 ** error code in the OTA handle passed as the first argument.
156679 */
156680 static void otaAllocateIterArrays(sqlite3ota *p, OtaObjIter *pIter, int nCol){
156681 int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
156682 char **azNew;
156683
156684 azNew = (char**)otaMalloc(p, nByte);
156685 if( azNew ){
156686 pIter->azTblCol = azNew;
156687 pIter->azTblType = &azNew[nCol];
156688 pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol];
156689 pIter->abTblPk = (u8*)&pIter->aiSrcOrder[nCol];
156690 pIter->abNotNull = (u8*)&pIter->abTblPk[nCol];
156691 pIter->abIndexed = (u8*)&pIter->abNotNull[nCol];
156692 }
156693 }
156694
156695 /*
156696 ** The first argument must be a nul-terminated string. This function
156697 ** returns a copy of the string in memory obtained from sqlite3_malloc().
156698 ** It is the responsibility of the caller to eventually free this memory
156699 ** using sqlite3_free().
156700 **
156701 ** If an OOM condition is encountered when attempting to allocate memory,
156702 ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise,
156703 ** if the allocation succeeds, (*pRc) is left unchanged.
156704 */
156705 static char *otaStrndup(const char *zStr, int *pRc){
156706 char *zRet = 0;
156707
156708 assert( *pRc==SQLITE_OK );
156709 if( zStr ){
156710 int nCopy = strlen(zStr) + 1;
156711 zRet = (char*)sqlite3_malloc(nCopy);
156712 if( zRet ){
156713 memcpy(zRet, zStr, nCopy);
156714 }else{
156715 *pRc = SQLITE_NOMEM;
156716 }
156717 }
156718
156719 return zRet;
156720 }
156721
156722 /*
156723 ** Finalize the statement passed as the second argument.
156724 **
156725 ** If the sqlite3_finalize() call indicates that an error occurs, and the
156726 ** ota handle error code is not already set, set the error code and error
156727 ** message accordingly.
156728 */
156729 static void otaFinalize(sqlite3ota *p, sqlite3_stmt *pStmt){
156730 sqlite3 *db = sqlite3_db_handle(pStmt);
156731 int rc = sqlite3_finalize(pStmt);
156732 if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){
156733 p->rc = rc;
156734 p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
156735 }
156736 }
156737
156738 /* Determine the type of a table.
156739 **
156740 ** peType is of type (int*), a pointer to an output parameter of type
156741 ** (int). This call sets the output parameter as follows, depending
156742 ** on the type of the table specified by parameters dbName and zTbl.
156743 **
156744 ** OTA_PK_NOTABLE: No such table.
156745 ** OTA_PK_NONE: Table has an implicit rowid.
156746 ** OTA_PK_IPK: Table has an explicit IPK column.
156747 ** OTA_PK_EXTERNAL: Table has an external PK index.
156748 ** OTA_PK_WITHOUT_ROWID: Table is WITHOUT ROWID.
156749 ** OTA_PK_VTAB: Table is a virtual table.
156750 **
156751 ** Argument *piPk is also of type (int*), and also points to an output
156752 ** parameter. Unless the table has an external primary key index
156753 ** (i.e. unless *peType is set to 3), then *piPk is set to zero. Or,
156754 ** if the table does have an external primary key index, then *piPk
156755 ** is set to the root page number of the primary key index before
156756 ** returning.
156757 **
156758 ** ALGORITHM:
156759 **
156760 ** if( no entry exists in sqlite_master ){
156761 ** return OTA_PK_NOTABLE
156762 ** }else if( sql for the entry starts with "CREATE VIRTUAL" ){
156763 ** return OTA_PK_VTAB
156764 ** }else if( "PRAGMA index_list()" for the table contains a "pk" index ){
156765 ** if( the index that is the pk exists in sqlite_master ){
156766 ** *piPK = rootpage of that index.
156767 ** return OTA_PK_EXTERNAL
156768 ** }else{
156769 ** return OTA_PK_WITHOUT_ROWID
156770 ** }
156771 ** }else if( "PRAGMA table_info()" lists one or more "pk" columns ){
156772 ** return OTA_PK_IPK
156773 ** }else{
156774 ** return OTA_PK_NONE
156775 ** }
156776 */
156777 static void otaTableType(
156778 sqlite3ota *p,
156779 const char *zTab,
156780 int *peType,
156781 int *piTnum,
156782 int *piPk
156783 ){
156784 /*
156785 ** 0) SELECT count(*) FROM sqlite_master where name=%Q AND IsVirtual(%Q)
156786 ** 1) PRAGMA index_list = ?
156787 ** 2) SELECT count(*) FROM sqlite_master where name=%Q
156788 ** 3) PRAGMA table_info = ?
156789 */
156790 sqlite3_stmt *aStmt[4] = {0, 0, 0, 0};
156791
156792 *peType = OTA_PK_NOTABLE;
156793 *piPk = 0;
156794
156795 assert( p->rc==SQLITE_OK );
156796 p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg,
156797 sqlite3_mprintf(
156798 "SELECT (sql LIKE 'create virtual%%'), rootpage"
156799 " FROM sqlite_master"
156800 " WHERE name=%Q", zTab
156801 ));
156802 if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){
156803 /* Either an error, or no such table. */
156804 goto otaTableType_end;
156805 }
156806 if( sqlite3_column_int(aStmt[0], 0) ){
156807 *peType = OTA_PK_VTAB; /* virtual table */
156808 goto otaTableType_end;
156809 }
156810 *piTnum = sqlite3_column_int(aStmt[0], 1);
156811
156812 p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg,
156813 sqlite3_mprintf("PRAGMA index_list=%Q",zTab)
156814 );
156815 if( p->rc ) goto otaTableType_end;
156816 while( sqlite3_step(aStmt[1])==SQLITE_ROW ){
156817 const u8 *zOrig = sqlite3_column_text(aStmt[1], 3);
156818 const u8 *zIdx = sqlite3_column_text(aStmt[1], 1);
156819 if( zOrig && zIdx && zOrig[0]=='p' ){
156820 p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg,
156821 sqlite3_mprintf(
156822 "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx
156823 ));
156824 if( p->rc==SQLITE_OK ){
156825 if( sqlite3_step(aStmt[2])==SQLITE_ROW ){
156826 *piPk = sqlite3_column_int(aStmt[2], 0);
156827 *peType = OTA_PK_EXTERNAL;
156828 }else{
156829 *peType = OTA_PK_WITHOUT_ROWID;
156830 }
156831 }
156832 goto otaTableType_end;
156833 }
156834 }
156835
156836 p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg,
156837 sqlite3_mprintf("PRAGMA table_info=%Q",zTab)
156838 );
156839 if( p->rc==SQLITE_OK ){
156840 while( sqlite3_step(aStmt[3])==SQLITE_ROW ){
156841 if( sqlite3_column_int(aStmt[3],5)>0 ){
156842 *peType = OTA_PK_IPK; /* explicit IPK column */
156843 goto otaTableType_end;
156844 }
156845 }
156846 *peType = OTA_PK_NONE;
156847 }
156848
156849 otaTableType_end: {
156850 int i;
156851 for(i=0; i<sizeof(aStmt)/sizeof(aStmt[0]); i++){
156852 otaFinalize(p, aStmt[i]);
156853 }
156854 }
156855 }
156856
156857 /*
156858 ** This is a helper function for otaObjIterCacheTableInfo(). It populates
156859 ** the pIter->abIndexed[] array.
156860 */
156861 static void otaObjIterCacheIndexedCols(sqlite3ota *p, OtaObjIter *pIter){
156862 sqlite3_stmt *pList = 0;
156863 int bIndex = 0;
156864
156865 if( p->rc==SQLITE_OK ){
156866 memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol);
156867 p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg,
156868 sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
156869 );
156870 }
156871
156872 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
156873 const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
156874 sqlite3_stmt *pXInfo = 0;
156875 if( zIdx==0 ) break;
156876 p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
156877 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
156878 );
156879 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
156880 int iCid = sqlite3_column_int(pXInfo, 1);
156881 if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
156882 }
156883 otaFinalize(p, pXInfo);
156884 bIndex = 1;
156885 }
156886
156887 otaFinalize(p, pList);
156888 if( bIndex==0 ) pIter->abIndexed = 0;
156889 }
156890
156891
156892 /*
156893 ** If they are not already populated, populate the pIter->azTblCol[],
156894 ** pIter->abTblPk[], pIter->nTblCol and pIter->bRowid variables according to
156895 ** the table (not index) that the iterator currently points to.
156896 **
156897 ** Return SQLITE_OK if successful, or an SQLite error code otherwise. If
156898 ** an error does occur, an error code and error message are also left in
156899 ** the OTA handle.
156900 */
156901 static int otaObjIterCacheTableInfo(sqlite3ota *p, OtaObjIter *pIter){
156902 if( pIter->azTblCol==0 ){
156903 sqlite3_stmt *pStmt = 0;
156904 int nCol = 0;
156905 int i; /* for() loop iterator variable */
156906 int bOtaRowid = 0; /* If input table has column "ota_rowid" */
156907 int iOrder = 0;
156908 int iTnum = 0;
156909
156910 /* Figure out the type of table this step will deal with. */
156911 assert( pIter->eType==0 );
156912 otaTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum);
156913 if( p->rc==SQLITE_OK && pIter->eType==OTA_PK_NOTABLE ){
156914 p->rc = SQLITE_ERROR;
156915 p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl);
156916 }
156917 if( p->rc ) return p->rc;
156918 if( pIter->zIdx==0 ) pIter->iTnum = iTnum;
156919
156920 assert( pIter->eType==OTA_PK_NONE || pIter->eType==OTA_PK_IPK
156921 || pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_WITHOUT_ROWID
156922 || pIter->eType==OTA_PK_VTAB
156923 );
156924
156925 /* Populate the azTblCol[] and nTblCol variables based on the columns
156926 ** of the input table. Ignore any input table columns that begin with
156927 ** "ota_". */
156928 p->rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg,
156929 sqlite3_mprintf("SELECT * FROM 'data_%q'", pIter->zTbl)
156930 );
156931 if( p->rc==SQLITE_OK ){
156932 nCol = sqlite3_column_count(pStmt);
156933 otaAllocateIterArrays(p, pIter, nCol);
156934 }
156935 for(i=0; p->rc==SQLITE_OK && i<nCol; i++){
156936 const char *zName = (const char*)sqlite3_column_name(pStmt, i);
156937 if( sqlite3_strnicmp("ota_", zName, 4) ){
156938 char *zCopy = otaStrndup(zName, &p->rc);
156939 pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol;
156940 pIter->azTblCol[pIter->nTblCol++] = zCopy;
156941 }
156942 else if( 0==sqlite3_stricmp("ota_rowid", zName) ){
156943 bOtaRowid = 1;
156944 }
156945 }
156946 sqlite3_finalize(pStmt);
156947 pStmt = 0;
156948
156949 if( p->rc==SQLITE_OK
156950 && bOtaRowid!=(pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
156951 ){
156952 p->rc = SQLITE_ERROR;
156953 p->zErrmsg = sqlite3_mprintf(
156954 "table data_%q %s ota_rowid column", pIter->zTbl,
156955 (bOtaRowid ? "may not have" : "requires")
156956 );
156957 }
156958
156959 /* Check that all non-HIDDEN columns in the destination table are also
156960 ** present in the input table. Populate the abTblPk[], azTblType[] and
156961 ** aiTblOrder[] arrays at the same time. */
156962 if( p->rc==SQLITE_OK ){
156963 p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
156964 sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl)
156965 );
156966 }
156967 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
156968 const char *zName = (const char*)sqlite3_column_text(pStmt, 1);
156969 if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */
156970 for(i=iOrder; i<pIter->nTblCol; i++){
156971 if( 0==strcmp(zName, pIter->azTblCol[i]) ) break;
156972 }
156973 if( i==pIter->nTblCol ){
156974 p->rc = SQLITE_ERROR;
156975 p->zErrmsg = sqlite3_mprintf("column missing from data_%q: %s",
156976 pIter->zTbl, zName
156977 );
156978 }else{
156979 int iPk = sqlite3_column_int(pStmt, 5);
156980 int bNotNull = sqlite3_column_int(pStmt, 3);
156981 const char *zType = (const char*)sqlite3_column_text(pStmt, 2);
156982
156983 if( i!=iOrder ){
156984 SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]);
156985 SWAP(char*, pIter->azTblCol[i], pIter->azTblCol[iOrder]);
156986 }
156987
156988 pIter->azTblType[iOrder] = otaStrndup(zType, &p->rc);
156989 pIter->abTblPk[iOrder] = (iPk!=0);
156990 pIter->abNotNull[iOrder] = (u8)bNotNull || (iPk!=0);
156991 iOrder++;
156992 }
156993 }
156994
156995 otaFinalize(p, pStmt);
156996 otaObjIterCacheIndexedCols(p, pIter);
156997 assert( pIter->eType!=OTA_PK_VTAB || pIter->abIndexed==0 );
156998 }
156999
157000 return p->rc;
157001 }
157002
157003 /*
157004 ** This function constructs and returns a pointer to a nul-terminated
157005 ** string containing some SQL clause or list based on one or more of the
157006 ** column names currently stored in the pIter->azTblCol[] array.
157007 */
157008 static char *otaObjIterGetCollist(
157009 sqlite3ota *p, /* OTA object */
157010 OtaObjIter *pIter /* Object iterator for column names */
157011 ){
157012 char *zList = 0;
157013 const char *zSep = "";
157014 int i;
157015 for(i=0; i<pIter->nTblCol; i++){
157016 const char *z = pIter->azTblCol[i];
157017 zList = otaMPrintf(p, "%z%s\"%w\"", zList, zSep, z);
157018 zSep = ", ";
157019 }
157020 return zList;
157021 }
157022
157023 /*
157024 ** This function is used to create a SELECT list (the list of SQL
157025 ** expressions that follows a SELECT keyword) for a SELECT statement
157026 ** used to read from an data_xxx or ota_tmp_xxx table while updating the
157027 ** index object currently indicated by the iterator object passed as the
157028 ** second argument. A "PRAGMA index_xinfo = <idxname>" statement is used
157029 ** to obtain the required information.
157030 **
157031 ** If the index is of the following form:
157032 **
157033 ** CREATE INDEX i1 ON t1(c, b COLLATE nocase);
157034 **
157035 ** and "t1" is a table with an explicit INTEGER PRIMARY KEY column
157036 ** "ipk", the returned string is:
157037 **
157038 ** "`c` COLLATE 'BINARY', `b` COLLATE 'NOCASE', `ipk` COLLATE 'BINARY'"
157039 **
157040 ** As well as the returned string, three other malloc'd strings are
157041 ** returned via output parameters. As follows:
157042 **
157043 ** pzImposterCols: ...
157044 ** pzImposterPk: ...
157045 ** pzWhere: ...
157046 */
157047 static char *otaObjIterGetIndexCols(
157048 sqlite3ota *p, /* OTA object */
157049 OtaObjIter *pIter, /* Object iterator for column names */
157050 char **pzImposterCols, /* OUT: Columns for imposter table */
157051 char **pzImposterPk, /* OUT: Imposter PK clause */
157052 char **pzWhere, /* OUT: WHERE clause */
157053 int *pnBind /* OUT: Total number of columns */
157054 ){
157055 int rc = p->rc; /* Error code */
157056 int rc2; /* sqlite3_finalize() return code */
157057 char *zRet = 0; /* String to return */
157058 char *zImpCols = 0; /* String to return via *pzImposterCols */
157059 char *zImpPK = 0; /* String to return via *pzImposterPK */
157060 char *zWhere = 0; /* String to return via *pzWhere */
157061 int nBind = 0; /* Value to return via *pnBind */
157062 const char *zCom = ""; /* Set to ", " later on */
157063 const char *zAnd = ""; /* Set to " AND " later on */
157064 sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */
157065
157066 if( rc==SQLITE_OK ){
157067 assert( p->zErrmsg==0 );
157068 rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
157069 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx)
157070 );
157071 }
157072
157073 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
157074 int iCid = sqlite3_column_int(pXInfo, 1);
157075 int bDesc = sqlite3_column_int(pXInfo, 3);
157076 const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
157077 const char *zCol;
157078 const char *zType;
157079
157080 if( iCid<0 ){
157081 /* An integer primary key. If the table has an explicit IPK, use
157082 ** its name. Otherwise, use "ota_rowid". */
157083 if( pIter->eType==OTA_PK_IPK ){
157084 int i;
157085 for(i=0; pIter->abTblPk[i]==0; i++);
157086 assert( i<pIter->nTblCol );
157087 zCol = pIter->azTblCol[i];
157088 }else{
157089 zCol = "ota_rowid";
157090 }
157091 zType = "INTEGER";
157092 }else{
157093 zCol = pIter->azTblCol[iCid];
157094 zType = pIter->azTblType[iCid];
157095 }
157096
157097 zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
157098 if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
157099 const char *zOrder = (bDesc ? " DESC" : "");
157100 zImpPK = sqlite3_mprintf("%z%s\"ota_imp_%d%w\"%s",
157101 zImpPK, zCom, nBind, zCol, zOrder
157102 );
157103 }
157104 zImpCols = sqlite3_mprintf("%z%s\"ota_imp_%d%w\" %s COLLATE %Q",
157105 zImpCols, zCom, nBind, zCol, zType, zCollate
157106 );
157107 zWhere = sqlite3_mprintf(
157108 "%z%s\"ota_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol
157109 );
157110 if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM;
157111 zCom = ", ";
157112 zAnd = " AND ";
157113 nBind++;
157114 }
157115
157116 rc2 = sqlite3_finalize(pXInfo);
157117 if( rc==SQLITE_OK ) rc = rc2;
157118
157119 if( rc!=SQLITE_OK ){
157120 sqlite3_free(zRet);
157121 sqlite3_free(zImpCols);
157122 sqlite3_free(zImpPK);
157123 sqlite3_free(zWhere);
157124 zRet = 0;
157125 zImpCols = 0;
157126 zImpPK = 0;
157127 zWhere = 0;
157128 p->rc = rc;
157129 }
157130
157131 *pzImposterCols = zImpCols;
157132 *pzImposterPk = zImpPK;
157133 *pzWhere = zWhere;
157134 *pnBind = nBind;
157135 return zRet;
157136 }
157137
157138 /*
157139 ** Assuming the current table columns are "a", "b" and "c", and the zObj
157140 ** paramter is passed "old", return a string of the form:
157141 **
157142 ** "old.a, old.b, old.b"
157143 **
157144 ** With the column names escaped.
157145 **
157146 ** For tables with implicit rowids - OTA_PK_EXTERNAL and OTA_PK_NONE, append
157147 ** the text ", old._rowid_" to the returned value.
157148 */
157149 static char *otaObjIterGetOldlist(
157150 sqlite3ota *p,
157151 OtaObjIter *pIter,
157152 const char *zObj
157153 ){
157154 char *zList = 0;
157155 if( p->rc==SQLITE_OK && pIter->abIndexed ){
157156 const char *zS = "";
157157 int i;
157158 for(i=0; i<pIter->nTblCol; i++){
157159 if( pIter->abIndexed[i] ){
157160 const char *zCol = pIter->azTblCol[i];
157161 zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol);
157162 }else{
157163 zList = sqlite3_mprintf("%z%sNULL", zList, zS);
157164 }
157165 zS = ", ";
157166 if( zList==0 ){
157167 p->rc = SQLITE_NOMEM;
157168 break;
157169 }
157170 }
157171
157172 /* For a table with implicit rowids, append "old._rowid_" to the list. */
157173 if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157174 zList = otaMPrintf(p, "%z, %s._rowid_", zList, zObj);
157175 }
157176 }
157177 return zList;
157178 }
157179
157180 /*
157181 ** Return an expression that can be used in a WHERE clause to match the
157182 ** primary key of the current table. For example, if the table is:
157183 **
157184 ** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, c));
157185 **
157186 ** Return the string:
157187 **
157188 ** "b = ?1 AND c = ?2"
157189 */
157190 static char *otaObjIterGetWhere(
157191 sqlite3ota *p,
157192 OtaObjIter *pIter
157193 ){
157194 char *zList = 0;
157195 if( pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE ){
157196 zList = otaMPrintf(p, "_rowid_ = ?%d", pIter->nTblCol+1);
157197 }else if( pIter->eType==OTA_PK_EXTERNAL ){
157198 const char *zSep = "";
157199 int i;
157200 for(i=0; i<pIter->nTblCol; i++){
157201 if( pIter->abTblPk[i] ){
157202 zList = otaMPrintf(p, "%z%sc%d=?%d", zList, zSep, i, i+1);
157203 zSep = " AND ";
157204 }
157205 }
157206 zList = otaMPrintf(p,
157207 "_rowid_ = (SELECT id FROM ota_imposter2 WHERE %z)", zList
157208 );
157209
157210 }else{
157211 const char *zSep = "";
157212 int i;
157213 for(i=0; i<pIter->nTblCol; i++){
157214 if( pIter->abTblPk[i] ){
157215 const char *zCol = pIter->azTblCol[i];
157216 zList = otaMPrintf(p, "%z%s\"%w\"=?%d", zList, zSep, zCol, i+1);
157217 zSep = " AND ";
157218 }
157219 }
157220 }
157221 return zList;
157222 }
157223
157224 /*
157225 ** The SELECT statement iterating through the keys for the current object
157226 ** (p->objiter.pSelect) currently points to a valid row. However, there
157227 ** is something wrong with the ota_control value in the ota_control value
157228 ** stored in the (p->nCol+1)'th column. Set the error code and error message
157229 ** of the OTA handle to something reflecting this.
157230 */
157231 static void otaBadControlError(sqlite3ota *p){
157232 p->rc = SQLITE_ERROR;
157233 p->zErrmsg = sqlite3_mprintf("invalid ota_control value");
157234 }
157235
157236
157237 /*
157238 ** Return a nul-terminated string containing the comma separated list of
157239 ** assignments that should be included following the "SET" keyword of
157240 ** an UPDATE statement used to update the table object that the iterator
157241 ** passed as the second argument currently points to if the ota_control
157242 ** column of the data_xxx table entry is set to zMask.
157243 **
157244 ** The memory for the returned string is obtained from sqlite3_malloc().
157245 ** It is the responsibility of the caller to eventually free it using
157246 ** sqlite3_free().
157247 **
157248 ** If an OOM error is encountered when allocating space for the new
157249 ** string, an error code is left in the ota handle passed as the first
157250 ** argument and NULL is returned. Or, if an error has already occurred
157251 ** when this function is called, NULL is returned immediately, without
157252 ** attempting the allocation or modifying the stored error code.
157253 */
157254 static char *otaObjIterGetSetlist(
157255 sqlite3ota *p,
157256 OtaObjIter *pIter,
157257 const char *zMask
157258 ){
157259 char *zList = 0;
157260 if( p->rc==SQLITE_OK ){
157261 int i;
157262
157263 if( strlen(zMask)!=pIter->nTblCol ){
157264 otaBadControlError(p);
157265 }else{
157266 const char *zSep = "";
157267 for(i=0; i<pIter->nTblCol; i++){
157268 char c = zMask[pIter->aiSrcOrder[i]];
157269 if( c=='x' ){
157270 zList = otaMPrintf(p, "%z%s\"%w\"=?%d",
157271 zList, zSep, pIter->azTblCol[i], i+1
157272 );
157273 zSep = ", ";
157274 }
157275 if( c=='d' ){
157276 zList = otaMPrintf(p, "%z%s\"%w\"=ota_delta(\"%w\", ?%d)",
157277 zList, zSep, pIter->azTblCol[i], pIter->azTblCol[i], i+1
157278 );
157279 zSep = ", ";
157280 }
157281 }
157282 }
157283 }
157284 return zList;
157285 }
157286
157287 /*
157288 ** Return a nul-terminated string consisting of nByte comma separated
157289 ** "?" expressions. For example, if nByte is 3, return a pointer to
157290 ** a buffer containing the string "?,?,?".
157291 **
157292 ** The memory for the returned string is obtained from sqlite3_malloc().
157293 ** It is the responsibility of the caller to eventually free it using
157294 ** sqlite3_free().
157295 **
157296 ** If an OOM error is encountered when allocating space for the new
157297 ** string, an error code is left in the ota handle passed as the first
157298 ** argument and NULL is returned. Or, if an error has already occurred
157299 ** when this function is called, NULL is returned immediately, without
157300 ** attempting the allocation or modifying the stored error code.
157301 */
157302 static char *otaObjIterGetBindlist(sqlite3ota *p, int nBind){
157303 char *zRet = 0;
157304 int nByte = nBind*2 + 1;
157305
157306 zRet = (char*)otaMalloc(p, nByte);
157307 if( zRet ){
157308 int i;
157309 for(i=0; i<nBind; i++){
157310 zRet[i*2] = '?';
157311 zRet[i*2+1] = (i+1==nBind) ? '\0' : ',';
157312 }
157313 }
157314 return zRet;
157315 }
157316
157317 /*
157318 ** The iterator currently points to a table (not index) of type
157319 ** OTA_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY
157320 ** declaration for the corresponding imposter table. For example,
157321 ** if the iterator points to a table created as:
157322 **
157323 ** CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
157324 **
157325 ** this function returns:
157326 **
157327 ** PRIMARY KEY("b", "a" DESC)
157328 */
157329 static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){
157330 char *z = 0;
157331 assert( pIter->zIdx==0 );
157332 if( p->rc==SQLITE_OK ){
157333 const char *zSep = "PRIMARY KEY(";
157334 sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */
157335 sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = <pk-index> */
157336
157337 p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg,
157338 sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
157339 );
157340 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){
157341 const char *zOrig = (const char*)sqlite3_column_text(pXList,3);
157342 if( zOrig && strcmp(zOrig, "pk")==0 ){
157343 const char *zIdx = (const char*)sqlite3_column_text(pXList,1);
157344 if( zIdx ){
157345 p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
157346 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
157347 );
157348 }
157349 break;
157350 }
157351 }
157352 otaFinalize(p, pXList);
157353
157354 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
157355 if( sqlite3_column_int(pXInfo, 5) ){
157356 /* int iCid = sqlite3_column_int(pXInfo, 0); */
157357 const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
157358 const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
157359 z = otaMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
157360 zSep = ", ";
157361 }
157362 }
157363 z = otaMPrintf(p, "%z)", z);
157364 otaFinalize(p, pXInfo);
157365 }
157366 return z;
157367 }
157368
157369 /*
157370 ** This function creates the second imposter table used when writing to
157371 ** a table b-tree where the table has an external primary key. If the
157372 ** iterator passed as the second argument does not currently point to
157373 ** a table (not index) with an external primary key, this function is a
157374 ** no-op.
157375 **
157376 ** Assuming the iterator does point to a table with an external PK, this
157377 ** function creates a WITHOUT ROWID imposter table named "ota_imposter2"
157378 ** used to access that PK index. For example, if the target table is
157379 ** declared as follows:
157380 **
157381 ** CREATE TABLE t1(a, b TEXT, c REAL, PRIMARY KEY(b, c));
157382 **
157383 ** then the imposter table schema is:
157384 **
157385 ** CREATE TABLE ota_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID;
157386 **
157387 */
157388 static void otaCreateImposterTable2(sqlite3ota *p, OtaObjIter *pIter){
157389 if( p->rc==SQLITE_OK && pIter->eType==OTA_PK_EXTERNAL ){
157390 int tnum = pIter->iPkTnum; /* Root page of PK index */
157391 sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */
157392 const char *zIdx = 0; /* Name of PK index */
157393 sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */
157394 const char *zComma = "";
157395 char *zCols = 0; /* Used to build up list of table cols */
157396 char *zPk = 0; /* Used to build up table PK declaration */
157397
157398 /* Figure out the name of the primary key index for the current table.
157399 ** This is needed for the argument to "PRAGMA index_xinfo". Set
157400 ** zIdx to point to a nul-terminated string containing this name. */
157401 p->rc = prepareAndCollectError(p->dbMain, &pQuery, &p->zErrmsg,
157402 "SELECT name FROM sqlite_master WHERE rootpage = ?"
157403 );
157404 if( p->rc==SQLITE_OK ){
157405 sqlite3_bind_int(pQuery, 1, tnum);
157406 if( SQLITE_ROW==sqlite3_step(pQuery) ){
157407 zIdx = (const char*)sqlite3_column_text(pQuery, 0);
157408 }
157409 }
157410 if( zIdx ){
157411 p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
157412 sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
157413 );
157414 }
157415 otaFinalize(p, pQuery);
157416
157417 while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
157418 int bKey = sqlite3_column_int(pXInfo, 5);
157419 if( bKey ){
157420 int iCid = sqlite3_column_int(pXInfo, 1);
157421 int bDesc = sqlite3_column_int(pXInfo, 3);
157422 const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
157423 zCols = otaMPrintf(p, "%z%sc%d %s COLLATE %s", zCols, zComma,
157424 iCid, pIter->azTblType[iCid], zCollate
157425 );
157426 zPk = otaMPrintf(p, "%z%sc%d%s", zPk, zComma, iCid, bDesc?" DESC":"");
157427 zComma = ", ";
157428 }
157429 }
157430 zCols = otaMPrintf(p, "%z, id INTEGER", zCols);
157431 otaFinalize(p, pXInfo);
157432
157433 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
157434 otaMPrintfExec(p, p->dbMain,
157435 "CREATE TABLE ota_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID",
157436 zCols, zPk
157437 );
157438 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
157439 }
157440 }
157441
157442 /*
157443 ** If an error has already occurred when this function is called, it
157444 ** immediately returns zero (without doing any work). Or, if an error
157445 ** occurs during the execution of this function, it sets the error code
157446 ** in the sqlite3ota object indicated by the first argument and returns
157447 ** zero.
157448 **
157449 ** The iterator passed as the second argument is guaranteed to point to
157450 ** a table (not an index) when this function is called. This function
157451 ** attempts to create any imposter table required to write to the main
157452 ** table b-tree of the table before returning. Non-zero is returned if
157453 ** an imposter table are created, or zero otherwise.
157454 **
157455 ** An imposter table is required in all cases except OTA_PK_VTAB. Only
157456 ** virtual tables are written to directly. The imposter table has the
157457 ** same schema as the actual target table (less any UNIQUE constraints).
157458 ** More precisely, the "same schema" means the same columns, types,
157459 ** collation sequences. For tables that do not have an external PRIMARY
157460 ** KEY, it also means the same PRIMARY KEY declaration.
157461 */
157462 static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){
157463 if( p->rc==SQLITE_OK && pIter->eType!=OTA_PK_VTAB ){
157464 int tnum = pIter->iTnum;
157465 const char *zComma = "";
157466 char *zSql = 0;
157467 int iCol;
157468 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
157469
157470 for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){
157471 const char *zPk = "";
157472 const char *zCol = pIter->azTblCol[iCol];
157473 const char *zColl = 0;
157474
157475 p->rc = sqlite3_table_column_metadata(
157476 p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0
157477 );
157478
157479 if( pIter->eType==OTA_PK_IPK && pIter->abTblPk[iCol] ){
157480 /* If the target table column is an "INTEGER PRIMARY KEY", add
157481 ** "PRIMARY KEY" to the imposter table column declaration. */
157482 zPk = "PRIMARY KEY ";
157483 }
157484 zSql = otaMPrintf(p, "%z%s\"%w\" %s %sCOLLATE %s%s",
157485 zSql, zComma, zCol, pIter->azTblType[iCol], zPk, zColl,
157486 (pIter->abNotNull[iCol] ? " NOT NULL" : "")
157487 );
157488 zComma = ", ";
157489 }
157490
157491 if( pIter->eType==OTA_PK_WITHOUT_ROWID ){
157492 char *zPk = otaWithoutRowidPK(p, pIter);
157493 if( zPk ){
157494 zSql = otaMPrintf(p, "%z, %z", zSql, zPk);
157495 }
157496 }
157497
157498 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum);
157499 otaMPrintfExec(p, p->dbMain, "CREATE TABLE \"ota_imp_%w\"(%z)%s",
157500 pIter->zTbl, zSql,
157501 (pIter->eType==OTA_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "")
157502 );
157503 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
157504 }
157505 }
157506
157507 /*
157508 ** Prepare a statement used to insert rows into the "ota_tmp_xxx" table.
157509 ** Specifically a statement of the form:
157510 **
157511 ** INSERT INTO ota_tmp_xxx VALUES(?, ?, ? ...);
157512 **
157513 ** The number of bound variables is equal to the number of columns in
157514 ** the target table, plus one (for the ota_control column), plus one more
157515 ** (for the ota_rowid column) if the target table is an implicit IPK or
157516 ** virtual table.
157517 */
157518 static void otaObjIterPrepareTmpInsert(
157519 sqlite3ota *p,
157520 OtaObjIter *pIter,
157521 const char *zCollist,
157522 const char *zOtaRowid
157523 ){
157524 int bOtaRowid = (pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE);
157525 char *zBind = otaObjIterGetBindlist(p, pIter->nTblCol + 1 + bOtaRowid);
157526 if( zBind ){
157527 assert( pIter->pTmpInsert==0 );
157528 p->rc = prepareFreeAndCollectError(
157529 p->dbOta, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf(
157530 "INSERT INTO %s.'ota_tmp_%q'(ota_control,%s%s) VALUES(%z)",
157531 p->zStateDb, pIter->zTbl, zCollist, zOtaRowid, zBind
157532 ));
157533 }
157534 }
157535
157536 static void otaTmpInsertFunc(
157537 sqlite3_context *pCtx,
157538 int nVal,
157539 sqlite3_value **apVal
157540 ){
157541 sqlite3ota *p = sqlite3_user_data(pCtx);
157542 int rc = SQLITE_OK;
157543 int i;
157544
157545 for(i=0; rc==SQLITE_OK && i<nVal; i++){
157546 rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]);
157547 }
157548 if( rc==SQLITE_OK ){
157549 sqlite3_step(p->objiter.pTmpInsert);
157550 rc = sqlite3_reset(p->objiter.pTmpInsert);
157551 }
157552
157553 if( rc!=SQLITE_OK ){
157554 sqlite3_result_error_code(pCtx, rc);
157555 }
157556 }
157557
157558 /*
157559 ** Ensure that the SQLite statement handles required to update the
157560 ** target database object currently indicated by the iterator passed
157561 ** as the second argument are available.
157562 */
157563 static int otaObjIterPrepareAll(
157564 sqlite3ota *p,
157565 OtaObjIter *pIter,
157566 int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */
157567 ){
157568 assert( pIter->bCleanup==0 );
157569 if( pIter->pSelect==0 && otaObjIterCacheTableInfo(p, pIter)==SQLITE_OK ){
157570 const int tnum = pIter->iTnum;
157571 char *zCollist = 0; /* List of indexed columns */
157572 char **pz = &p->zErrmsg;
157573 const char *zIdx = pIter->zIdx;
157574 char *zLimit = 0;
157575
157576 if( nOffset ){
157577 zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset);
157578 if( !zLimit ) p->rc = SQLITE_NOMEM;
157579 }
157580
157581 if( zIdx ){
157582 const char *zTbl = pIter->zTbl;
157583 char *zImposterCols = 0; /* Columns for imposter table */
157584 char *zImposterPK = 0; /* Primary key declaration for imposter */
157585 char *zWhere = 0; /* WHERE clause on PK columns */
157586 char *zBind = 0;
157587 int nBind = 0;
157588
157589 assert( pIter->eType!=OTA_PK_VTAB );
157590 zCollist = otaObjIterGetIndexCols(
157591 p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
157592 );
157593 zBind = otaObjIterGetBindlist(p, nBind);
157594
157595 /* Create the imposter table used to write to this index. */
157596 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
157597 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
157598 otaMPrintfExec(p, p->dbMain,
157599 "CREATE TABLE \"ota_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
157600 zTbl, zImposterCols, zImposterPK
157601 );
157602 sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0);
157603
157604 /* Create the statement to insert index entries */
157605 pIter->nCol = nBind;
157606 if( p->rc==SQLITE_OK ){
157607 p->rc = prepareFreeAndCollectError(
157608 p->dbMain, &pIter->pInsert, &p->zErrmsg,
157609 sqlite3_mprintf("INSERT INTO \"ota_imp_%w\" VALUES(%s)", zTbl, zBind)
157610 );
157611 }
157612
157613 /* And to delete index entries */
157614 if( p->rc==SQLITE_OK ){
157615 p->rc = prepareFreeAndCollectError(
157616 p->dbMain, &pIter->pDelete, &p->zErrmsg,
157617 sqlite3_mprintf("DELETE FROM \"ota_imp_%w\" WHERE %s", zTbl, zWhere)
157618 );
157619 }
157620
157621 /* Create the SELECT statement to read keys in sorted order */
157622 if( p->rc==SQLITE_OK ){
157623 char *zSql;
157624 if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157625 zSql = sqlite3_mprintf(
157626 "SELECT %s, ota_control FROM %s.'ota_tmp_%q' ORDER BY %s%s",
157627 zCollist, p->zStateDb, pIter->zTbl,
157628 zCollist, zLimit
157629 );
157630 }else{
157631 zSql = sqlite3_mprintf(
157632 "SELECT %s, ota_control FROM 'data_%q' "
157633 "WHERE typeof(ota_control)='integer' AND ota_control!=1 "
157634 "UNION ALL "
157635 "SELECT %s, ota_control FROM %s.'ota_tmp_%q' "
157636 "ORDER BY %s%s",
157637 zCollist, pIter->zTbl,
157638 zCollist, p->zStateDb, pIter->zTbl,
157639 zCollist, zLimit
157640 );
157641 }
157642 p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz, zSql);
157643 }
157644
157645 sqlite3_free(zImposterCols);
157646 sqlite3_free(zImposterPK);
157647 sqlite3_free(zWhere);
157648 sqlite3_free(zBind);
157649 }else{
157650 int bOtaRowid = (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE);
157651 const char *zTbl = pIter->zTbl; /* Table this step applies to */
157652 const char *zWrite; /* Imposter table name */
157653
157654 char *zBindings = otaObjIterGetBindlist(p, pIter->nTblCol + bOtaRowid);
157655 char *zWhere = otaObjIterGetWhere(p, pIter);
157656 char *zOldlist = otaObjIterGetOldlist(p, pIter, "old");
157657 char *zNewlist = otaObjIterGetOldlist(p, pIter, "new");
157658
157659 zCollist = otaObjIterGetCollist(p, pIter);
157660 pIter->nCol = pIter->nTblCol;
157661
157662 /* Create the SELECT statement to read keys from data_xxx */
157663 if( p->rc==SQLITE_OK ){
157664 p->rc = prepareFreeAndCollectError(p->dbOta, &pIter->pSelect, pz,
157665 sqlite3_mprintf(
157666 "SELECT %s, ota_control%s FROM 'data_%q'%s",
157667 zCollist, (bOtaRowid ? ", ota_rowid" : ""), zTbl, zLimit
157668 )
157669 );
157670 }
157671
157672 /* Create the imposter table or tables (if required). */
157673 otaCreateImposterTable(p, pIter);
157674 otaCreateImposterTable2(p, pIter);
157675 zWrite = (pIter->eType==OTA_PK_VTAB ? "" : "ota_imp_");
157676
157677 /* Create the INSERT statement to write to the target PK b-tree */
157678 if( p->rc==SQLITE_OK ){
157679 p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz,
157680 sqlite3_mprintf(
157681 "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)",
157682 zWrite, zTbl, zCollist, (bOtaRowid ? ", _rowid_" : ""), zBindings
157683 )
157684 );
157685 }
157686
157687 /* Create the DELETE statement to write to the target PK b-tree */
157688 if( p->rc==SQLITE_OK ){
157689 p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz,
157690 sqlite3_mprintf(
157691 "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere
157692 )
157693 );
157694 }
157695
157696 if( pIter->abIndexed ){
157697 const char *zOtaRowid = "";
157698 if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157699 zOtaRowid = ", ota_rowid";
157700 }
157701
157702 /* Create the ota_tmp_xxx table and the triggers to populate it. */
157703 otaMPrintfExec(p, p->dbOta,
157704 "CREATE TABLE IF NOT EXISTS %s.'ota_tmp_%q' AS "
157705 "SELECT *%s FROM 'data_%q' WHERE 0;"
157706 , p->zStateDb
157707 , zTbl, (pIter->eType==OTA_PK_EXTERNAL ? ", 0 AS ota_rowid" : "")
157708 , zTbl
157709 );
157710
157711 otaMPrintfExec(p, p->dbMain,
157712 "CREATE TEMP TRIGGER ota_delete_tr BEFORE DELETE ON \"%s%w\" "
157713 "BEGIN "
157714 " SELECT ota_tmp_insert(2, %s);"
157715 "END;"
157716
157717 "CREATE TEMP TRIGGER ota_update1_tr BEFORE UPDATE ON \"%s%w\" "
157718 "BEGIN "
157719 " SELECT ota_tmp_insert(2, %s);"
157720 "END;"
157721
157722 "CREATE TEMP TRIGGER ota_update2_tr AFTER UPDATE ON \"%s%w\" "
157723 "BEGIN "
157724 " SELECT ota_tmp_insert(3, %s);"
157725 "END;",
157726 zWrite, zTbl, zOldlist,
157727 zWrite, zTbl, zOldlist,
157728 zWrite, zTbl, zNewlist
157729 );
157730
157731 if( pIter->eType==OTA_PK_EXTERNAL || pIter->eType==OTA_PK_NONE ){
157732 otaMPrintfExec(p, p->dbMain,
157733 "CREATE TEMP TRIGGER ota_insert_tr AFTER INSERT ON \"%s%w\" "
157734 "BEGIN "
157735 " SELECT ota_tmp_insert(0, %s);"
157736 "END;",
157737 zWrite, zTbl, zNewlist
157738 );
157739 }
157740
157741 otaObjIterPrepareTmpInsert(p, pIter, zCollist, zOtaRowid);
157742 }
157743
157744 sqlite3_free(zWhere);
157745 sqlite3_free(zOldlist);
157746 sqlite3_free(zNewlist);
157747 sqlite3_free(zBindings);
157748 }
157749 sqlite3_free(zCollist);
157750 sqlite3_free(zLimit);
157751 }
157752
157753 return p->rc;
157754 }
157755
157756 /*
157757 ** Set output variable *ppStmt to point to an UPDATE statement that may
157758 ** be used to update the imposter table for the main table b-tree of the
157759 ** table object that pIter currently points to, assuming that the
157760 ** ota_control column of the data_xyz table contains zMask.
157761 **
157762 ** If the zMask string does not specify any columns to update, then this
157763 ** is not an error. Output variable *ppStmt is set to NULL in this case.
157764 */
157765 static int otaGetUpdateStmt(
157766 sqlite3ota *p, /* OTA handle */
157767 OtaObjIter *pIter, /* Object iterator */
157768 const char *zMask, /* ota_control value ('x.x.') */
157769 sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */
157770 ){
157771 OtaUpdateStmt **pp;
157772 OtaUpdateStmt *pUp = 0;
157773 int nUp = 0;
157774
157775 /* In case an error occurs */
157776 *ppStmt = 0;
157777
157778 /* Search for an existing statement. If one is found, shift it to the front
157779 ** of the LRU queue and return immediately. Otherwise, leave nUp pointing
157780 ** to the number of statements currently in the cache and pUp to the
157781 ** last object in the list. */
157782 for(pp=&pIter->pOtaUpdate; *pp; pp=&((*pp)->pNext)){
157783 pUp = *pp;
157784 if( strcmp(pUp->zMask, zMask)==0 ){
157785 *pp = pUp->pNext;
157786 pUp->pNext = pIter->pOtaUpdate;
157787 pIter->pOtaUpdate = pUp;
157788 *ppStmt = pUp->pUpdate;
157789 return SQLITE_OK;
157790 }
157791 nUp++;
157792 }
157793 assert( pUp==0 || pUp->pNext==0 );
157794
157795 if( nUp>=SQLITE_OTA_UPDATE_CACHESIZE ){
157796 for(pp=&pIter->pOtaUpdate; *pp!=pUp; pp=&((*pp)->pNext));
157797 *pp = 0;
157798 sqlite3_finalize(pUp->pUpdate);
157799 pUp->pUpdate = 0;
157800 }else{
157801 pUp = (OtaUpdateStmt*)otaMalloc(p, sizeof(OtaUpdateStmt)+pIter->nTblCol+1);
157802 }
157803
157804 if( pUp ){
157805 char *zWhere = otaObjIterGetWhere(p, pIter);
157806 char *zSet = otaObjIterGetSetlist(p, pIter, zMask);
157807 char *zUpdate = 0;
157808
157809 pUp->zMask = (char*)&pUp[1];
157810 memcpy(pUp->zMask, zMask, pIter->nTblCol);
157811 pUp->pNext = pIter->pOtaUpdate;
157812 pIter->pOtaUpdate = pUp;
157813
157814 if( zSet ){
157815 const char *zPrefix = "";
157816
157817 if( pIter->eType!=OTA_PK_VTAB ) zPrefix = "ota_imp_";
157818 zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s",
157819 zPrefix, pIter->zTbl, zSet, zWhere
157820 );
157821 p->rc = prepareFreeAndCollectError(
157822 p->dbMain, &pUp->pUpdate, &p->zErrmsg, zUpdate
157823 );
157824 *ppStmt = pUp->pUpdate;
157825 }
157826 sqlite3_free(zWhere);
157827 sqlite3_free(zSet);
157828 }
157829
157830 return p->rc;
157831 }
157832
157833 static sqlite3 *otaOpenDbhandle(sqlite3ota *p, const char *zName){
157834 sqlite3 *db = 0;
157835 if( p->rc==SQLITE_OK ){
157836 const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI;
157837 p->rc = sqlite3_open_v2(zName, &db, flags, p->zVfsName);
157838 if( p->rc ){
157839 p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
157840 sqlite3_close(db);
157841 db = 0;
157842 }
157843 }
157844 return db;
157845 }
157846
157847 /*
157848 ** Open the database handle and attach the OTA database as "ota". If an
157849 ** error occurs, leave an error code and message in the OTA handle.
157850 */
157851 static void otaOpenDatabase(sqlite3ota *p){
157852 assert( p->rc==SQLITE_OK );
157853 assert( p->dbMain==0 && p->dbOta==0 );
157854
157855 p->eStage = 0;
157856 p->dbMain = otaOpenDbhandle(p, p->zTarget);
157857 p->dbOta = otaOpenDbhandle(p, p->zOta);
157858
157859 /* If using separate OTA and state databases, attach the state database to
157860 ** the OTA db handle now. */
157861 if( p->zState ){
157862 otaMPrintfExec(p, p->dbOta, "ATTACH %Q AS stat", p->zState);
157863 memcpy(p->zStateDb, "stat", 4);
157864 }else{
157865 memcpy(p->zStateDb, "main", 4);
157866 }
157867
157868 if( p->rc==SQLITE_OK ){
157869 p->rc = sqlite3_create_function(p->dbMain,
157870 "ota_tmp_insert", -1, SQLITE_UTF8, (void*)p, otaTmpInsertFunc, 0, 0
157871 );
157872 }
157873
157874 if( p->rc==SQLITE_OK ){
157875 p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_OTA, (void*)p);
157876 }
157877 otaMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master");
157878
157879 /* Mark the database file just opened as an OTA target database. If
157880 ** this call returns SQLITE_NOTFOUND, then the OTA vfs is not in use.
157881 ** This is an error. */
157882 if( p->rc==SQLITE_OK ){
157883 p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_OTA, (void*)p);
157884 }
157885
157886 if( p->rc==SQLITE_NOTFOUND ){
157887 p->rc = SQLITE_ERROR;
157888 p->zErrmsg = sqlite3_mprintf("ota vfs not found");
157889 }
157890 }
157891
157892 /*
157893 ** This routine is a copy of the sqlite3FileSuffix3() routine from the core.
157894 ** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined.
157895 **
157896 ** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database
157897 ** filename in zBaseFilename is a URI with the "8_3_names=1" parameter and
157898 ** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
157899 ** three characters, then shorten the suffix on z[] to be the last three
157900 ** characters of the original suffix.
157901 **
157902 ** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
157903 ** do the suffix shortening regardless of URI parameter.
157904 **
157905 ** Examples:
157906 **
157907 ** test.db-journal => test.nal
157908 ** test.db-wal => test.wal
157909 ** test.db-shm => test.shm
157910 ** test.db-mj7f3319fa => test.9fa
157911 */
157912 static void otaFileSuffix3(const char *zBase, char *z){
157913 #ifdef SQLITE_ENABLE_8_3_NAMES
157914 #if SQLITE_ENABLE_8_3_NAMES<2
157915 if( sqlite3_uri_boolean(zBase, "8_3_names", 0) )
157916 #endif
157917 {
157918 int i, sz;
157919 sz = sqlite3Strlen30(z);
157920 for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
157921 if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
157922 }
157923 #endif
157924 }
157925
157926 /*
157927 ** Return the current wal-index header checksum for the target database
157928 ** as a 64-bit integer.
157929 **
157930 ** The checksum is store in the first page of xShmMap memory as an 8-byte
157931 ** blob starting at byte offset 40.
157932 */
157933 static i64 otaShmChecksum(sqlite3ota *p){
157934 i64 iRet = 0;
157935 if( p->rc==SQLITE_OK ){
157936 sqlite3_file *pDb = p->pTargetFd->pReal;
157937 u32 volatile *ptr;
157938 p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
157939 if( p->rc==SQLITE_OK ){
157940 iRet = ((i64)ptr[10] << 32) + ptr[11];
157941 }
157942 }
157943 return iRet;
157944 }
157945
157946 /*
157947 ** This function is called as part of initializing or reinitializing an
157948 ** incremental checkpoint.
157949 **
157950 ** It populates the sqlite3ota.aFrame[] array with the set of
157951 ** (wal frame -> db page) copy operations required to checkpoint the
157952 ** current wal file, and obtains the set of shm locks required to safely
157953 ** perform the copy operations directly on the file-system.
157954 **
157955 ** If argument pState is not NULL, then the incremental checkpoint is
157956 ** being resumed. In this case, if the checksum of the wal-index-header
157957 ** following recovery is not the same as the checksum saved in the OtaState
157958 ** object, then the ota handle is set to DONE state. This occurs if some
157959 ** other client appends a transaction to the wal file in the middle of
157960 ** an incremental checkpoint.
157961 */
157962 static void otaSetupCheckpoint(sqlite3ota *p, OtaState *pState){
157963
157964 /* If pState is NULL, then the wal file may not have been opened and
157965 ** recovered. Running a read-statement here to ensure that doing so
157966 ** does not interfere with the "capture" process below. */
157967 if( pState==0 ){
157968 p->eStage = 0;
157969 if( p->rc==SQLITE_OK ){
157970 p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0);
157971 }
157972 }
157973
157974 /* Assuming no error has occurred, run a "restart" checkpoint with the
157975 ** sqlite3ota.eStage variable set to CAPTURE. This turns on the following
157976 ** special behaviour in the ota VFS:
157977 **
157978 ** * If the exclusive shm WRITER or READ0 lock cannot be obtained,
157979 ** the checkpoint fails with SQLITE_BUSY (normally SQLite would
157980 ** proceed with running a passive checkpoint instead of failing).
157981 **
157982 ** * Attempts to read from the *-wal file or write to the database file
157983 ** do not perform any IO. Instead, the frame/page combinations that
157984 ** would be read/written are recorded in the sqlite3ota.aFrame[]
157985 ** array.
157986 **
157987 ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER,
157988 ** READ0 and CHECKPOINT locks taken as part of the checkpoint are
157989 ** no-ops. These locks will not be released until the connection
157990 ** is closed.
157991 **
157992 ** * Attempting to xSync() the database file causes an SQLITE_INTERNAL
157993 ** error.
157994 **
157995 ** As a result, unless an error (i.e. OOM or SQLITE_BUSY) occurs, the
157996 ** checkpoint below fails with SQLITE_INTERNAL, and leaves the aFrame[]
157997 ** array populated with a set of (frame -> page) mappings. Because the
157998 ** WRITER, CHECKPOINT and READ0 locks are still held, it is safe to copy
157999 ** data from the wal file into the database file according to the
158000 ** contents of aFrame[].
158001 */
158002 if( p->rc==SQLITE_OK ){
158003 int rc2;
158004 p->eStage = OTA_STAGE_CAPTURE;
158005 rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0);
158006 if( rc2!=SQLITE_INTERNAL ) p->rc = rc2;
158007 }
158008
158009 if( p->rc==SQLITE_OK ){
158010 p->eStage = OTA_STAGE_CKPT;
158011 p->nStep = (pState ? pState->nRow : 0);
158012 p->aBuf = otaMalloc(p, p->pgsz);
158013 p->iWalCksum = otaShmChecksum(p);
158014 }
158015
158016 if( p->rc==SQLITE_OK && pState && pState->iWalCksum!=p->iWalCksum ){
158017 p->rc = SQLITE_DONE;
158018 p->eStage = OTA_STAGE_DONE;
158019 }
158020 }
158021
158022 /*
158023 ** Called when iAmt bytes are read from offset iOff of the wal file while
158024 ** the ota object is in capture mode. Record the frame number of the frame
158025 ** being read in the aFrame[] array.
158026 */
158027 static int otaCaptureWalRead(sqlite3ota *pOta, i64 iOff, int iAmt){
158028 const u32 mReq = (1<<WAL_LOCK_WRITE)|(1<<WAL_LOCK_CKPT)|(1<<WAL_LOCK_READ0);
158029 u32 iFrame;
158030
158031 if( pOta->mLock!=mReq ){
158032 pOta->rc = SQLITE_BUSY;
158033 return SQLITE_INTERNAL;
158034 }
158035
158036 pOta->pgsz = iAmt;
158037 if( pOta->nFrame==pOta->nFrameAlloc ){
158038 int nNew = (pOta->nFrameAlloc ? pOta->nFrameAlloc : 64) * 2;
158039 OtaFrame *aNew;
158040 aNew = (OtaFrame*)sqlite3_realloc(pOta->aFrame, nNew * sizeof(OtaFrame));
158041 if( aNew==0 ) return SQLITE_NOMEM;
158042 pOta->aFrame = aNew;
158043 pOta->nFrameAlloc = nNew;
158044 }
158045
158046 iFrame = (u32)((iOff-32) / (i64)(iAmt+24)) + 1;
158047 if( pOta->iMaxFrame<iFrame ) pOta->iMaxFrame = iFrame;
158048 pOta->aFrame[pOta->nFrame].iWalFrame = iFrame;
158049 pOta->aFrame[pOta->nFrame].iDbPage = 0;
158050 pOta->nFrame++;
158051 return SQLITE_OK;
158052 }
158053
158054 /*
158055 ** Called when a page of data is written to offset iOff of the database
158056 ** file while the ota handle is in capture mode. Record the page number
158057 ** of the page being written in the aFrame[] array.
158058 */
158059 static int otaCaptureDbWrite(sqlite3ota *pOta, i64 iOff){
158060 pOta->aFrame[pOta->nFrame-1].iDbPage = (u32)(iOff / pOta->pgsz) + 1;
158061 return SQLITE_OK;
158062 }
158063
158064 /*
158065 ** This is called as part of an incremental checkpoint operation. Copy
158066 ** a single frame of data from the wal file into the database file, as
158067 ** indicated by the OtaFrame object.
158068 */
158069 static void otaCheckpointFrame(sqlite3ota *p, OtaFrame *pFrame){
158070 sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal;
158071 sqlite3_file *pDb = p->pTargetFd->pReal;
158072 i64 iOff;
158073
158074 assert( p->rc==SQLITE_OK );
158075 iOff = (i64)(pFrame->iWalFrame-1) * (p->pgsz + 24) + 32 + 24;
158076 p->rc = pWal->pMethods->xRead(pWal, p->aBuf, p->pgsz, iOff);
158077 if( p->rc ) return;
158078
158079 iOff = (i64)(pFrame->iDbPage-1) * p->pgsz;
158080 p->rc = pDb->pMethods->xWrite(pDb, p->aBuf, p->pgsz, iOff);
158081 }
158082
158083
158084 /*
158085 ** Take an EXCLUSIVE lock on the database file.
158086 */
158087 static void otaLockDatabase(sqlite3ota *p){
158088 sqlite3_file *pReal = p->pTargetFd->pReal;
158089 assert( p->rc==SQLITE_OK );
158090 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
158091 if( p->rc==SQLITE_OK ){
158092 p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
158093 }
158094 }
158095
158096 /*
158097 ** The OTA handle is currently in OTA_STAGE_OAL state, with a SHARED lock
158098 ** on the database file. This proc moves the *-oal file to the *-wal path,
158099 ** then reopens the database file (this time in vanilla, non-oal, WAL mode).
158100 ** If an error occurs, leave an error code and error message in the ota
158101 ** handle.
158102 */
158103 static void otaMoveOalFile(sqlite3ota *p){
158104 const char *zBase = sqlite3_db_filename(p->dbMain, "main");
158105
158106 char *zWal = sqlite3_mprintf("%s-wal", zBase);
158107 char *zOal = sqlite3_mprintf("%s-oal", zBase);
158108
158109 assert( p->eStage==OTA_STAGE_MOVE );
158110 assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
158111 if( zWal==0 || zOal==0 ){
158112 p->rc = SQLITE_NOMEM;
158113 }else{
158114 /* Move the *-oal file to *-wal. At this point connection p->db is
158115 ** holding a SHARED lock on the target database file (because it is
158116 ** in WAL mode). So no other connection may be writing the db.
158117 **
158118 ** In order to ensure that there are no database readers, an EXCLUSIVE
158119 ** lock is obtained here before the *-oal is moved to *-wal.
158120 */
158121 otaLockDatabase(p);
158122 if( p->rc==SQLITE_OK ){
158123 otaFileSuffix3(zBase, zWal);
158124 otaFileSuffix3(zBase, zOal);
158125
158126 /* Re-open the databases. */
158127 otaObjIterFinalize(&p->objiter);
158128 sqlite3_close(p->dbMain);
158129 sqlite3_close(p->dbOta);
158130 p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
158131 if( p->rc==SQLITE_OK ){
158132 p->dbMain = 0;
158133 p->dbOta = 0;
158134 otaOpenDatabase(p);
158135 otaSetupCheckpoint(p, 0);
158136 }
158137 }
158138 }
158139
158140 sqlite3_free(zWal);
158141 sqlite3_free(zOal);
158142 }
158143
158144 /*
158145 ** The SELECT statement iterating through the keys for the current object
158146 ** (p->objiter.pSelect) currently points to a valid row. This function
158147 ** determines the type of operation requested by this row and returns
158148 ** one of the following values to indicate the result:
158149 **
158150 ** * OTA_INSERT
158151 ** * OTA_DELETE
158152 ** * OTA_IDX_DELETE
158153 ** * OTA_UPDATE
158154 **
158155 ** If OTA_UPDATE is returned, then output variable *pzMask is set to
158156 ** point to the text value indicating the columns to update.
158157 **
158158 ** If the ota_control field contains an invalid value, an error code and
158159 ** message are left in the OTA handle and zero returned.
158160 */
158161 static int otaStepType(sqlite3ota *p, const char **pzMask){
158162 int iCol = p->objiter.nCol; /* Index of ota_control column */
158163 int res = 0; /* Return value */
158164
158165 switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){
158166 case SQLITE_INTEGER: {
158167 int iVal = sqlite3_column_int(p->objiter.pSelect, iCol);
158168 if( iVal==0 ){
158169 res = OTA_INSERT;
158170 }else if( iVal==1 ){
158171 res = OTA_DELETE;
158172 }else if( iVal==2 ){
158173 res = OTA_IDX_DELETE;
158174 }else if( iVal==3 ){
158175 res = OTA_IDX_INSERT;
158176 }
158177 break;
158178 }
158179
158180 case SQLITE_TEXT: {
158181 const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol);
158182 if( z==0 ){
158183 p->rc = SQLITE_NOMEM;
158184 }else{
158185 *pzMask = (const char*)z;
158186 }
158187 res = OTA_UPDATE;
158188
158189 break;
158190 }
158191
158192 default:
158193 break;
158194 }
158195
158196 if( res==0 ){
158197 otaBadControlError(p);
158198 }
158199 return res;
158200 }
158201
158202 #ifdef SQLITE_DEBUG
158203 /*
158204 ** Assert that column iCol of statement pStmt is named zName.
158205 */
158206 static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){
158207 const char *zCol = sqlite3_column_name(pStmt, iCol);
158208 assert( 0==sqlite3_stricmp(zName, zCol) );
158209 }
158210 #else
158211 # define assertColumnName(x,y,z)
158212 #endif
158213
158214 /*
158215 ** This function does the work for an sqlite3ota_step() call.
158216 **
158217 ** The object-iterator (p->objiter) currently points to a valid object,
158218 ** and the input cursor (p->objiter.pSelect) currently points to a valid
158219 ** input row. Perform whatever processing is required and return.
158220 **
158221 ** If no error occurs, SQLITE_OK is returned. Otherwise, an error code
158222 ** and message is left in the OTA handle and a copy of the error code
158223 ** returned.
158224 */
158225 static int otaStep(sqlite3ota *p){
158226 OtaObjIter *pIter = &p->objiter;
158227 const char *zMask = 0;
158228 int i;
158229 int eType = otaStepType(p, &zMask);
158230
158231 if( eType ){
158232 assert( eType!=OTA_UPDATE || pIter->zIdx==0 );
158233
158234 if( pIter->zIdx==0 && eType==OTA_IDX_DELETE ){
158235 otaBadControlError(p);
158236 }
158237 else if(
158238 eType==OTA_INSERT
158239 || eType==OTA_DELETE
158240 || eType==OTA_IDX_DELETE
158241 || eType==OTA_IDX_INSERT
158242 ){
158243 sqlite3_value *pVal;
158244 sqlite3_stmt *pWriter;
158245
158246 assert( eType!=OTA_UPDATE );
158247 assert( eType!=OTA_DELETE || pIter->zIdx==0 );
158248
158249 if( eType==OTA_IDX_DELETE || eType==OTA_DELETE ){
158250 pWriter = pIter->pDelete;
158251 }else{
158252 pWriter = pIter->pInsert;
158253 }
158254
158255 for(i=0; i<pIter->nCol; i++){
158256 /* If this is an INSERT into a table b-tree and the table has an
158257 ** explicit INTEGER PRIMARY KEY, check that this is not an attempt
158258 ** to write a NULL into the IPK column. That is not permitted. */
158259 if( eType==OTA_INSERT
158260 && pIter->zIdx==0 && pIter->eType==OTA_PK_IPK && pIter->abTblPk[i]
158261 && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL
158262 ){
158263 p->rc = SQLITE_MISMATCH;
158264 p->zErrmsg = sqlite3_mprintf("datatype mismatch");
158265 goto step_out;
158266 }
158267
158268 if( eType==OTA_DELETE && pIter->abTblPk[i]==0 ){
158269 continue;
158270 }
158271
158272 pVal = sqlite3_column_value(pIter->pSelect, i);
158273 p->rc = sqlite3_bind_value(pWriter, i+1, pVal);
158274 if( p->rc ) goto step_out;
158275 }
158276 if( pIter->zIdx==0
158277 && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
158278 ){
158279 /* For a virtual table, or a table with no primary key, the
158280 ** SELECT statement is:
158281 **
158282 ** SELECT <cols>, ota_control, ota_rowid FROM ....
158283 **
158284 ** Hence column_value(pIter->nCol+1).
158285 */
158286 assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
158287 pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
158288 p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal);
158289 }
158290 if( p->rc==SQLITE_OK ){
158291 sqlite3_step(pWriter);
158292 p->rc = resetAndCollectError(pWriter, &p->zErrmsg);
158293 }
158294 }else{
158295 sqlite3_value *pVal;
158296 sqlite3_stmt *pUpdate = 0;
158297 assert( eType==OTA_UPDATE );
158298 otaGetUpdateStmt(p, pIter, zMask, &pUpdate);
158299 if( pUpdate ){
158300 for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){
158301 char c = zMask[pIter->aiSrcOrder[i]];
158302 pVal = sqlite3_column_value(pIter->pSelect, i);
158303 if( pIter->abTblPk[i] || c=='x' || c=='d' ){
158304 p->rc = sqlite3_bind_value(pUpdate, i+1, pVal);
158305 }
158306 }
158307 if( p->rc==SQLITE_OK
158308 && (pIter->eType==OTA_PK_VTAB || pIter->eType==OTA_PK_NONE)
158309 ){
158310 /* Bind the ota_rowid value to column _rowid_ */
158311 assertColumnName(pIter->pSelect, pIter->nCol+1, "ota_rowid");
158312 pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1);
158313 p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal);
158314 }
158315 if( p->rc==SQLITE_OK ){
158316 sqlite3_step(pUpdate);
158317 p->rc = resetAndCollectError(pUpdate, &p->zErrmsg);
158318 }
158319 }
158320 }
158321 }
158322
158323 step_out:
158324 return p->rc;
158325 }
158326
158327 /*
158328 ** Increment the schema cookie of the main database opened by p->dbMain.
158329 */
158330 static void otaIncrSchemaCookie(sqlite3ota *p){
158331 if( p->rc==SQLITE_OK ){
158332 int iCookie = 1000000;
158333 sqlite3_stmt *pStmt;
158334
158335 p->rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
158336 "PRAGMA schema_version"
158337 );
158338 if( p->rc==SQLITE_OK ){
158339 /* Coverage: it may be that this sqlite3_step() cannot fail. There
158340 ** is already a transaction open, so the prepared statement cannot
158341 ** throw an SQLITE_SCHEMA exception. The only database page the
158342 ** statement reads is page 1, which is guaranteed to be in the cache.
158343 ** And no memory allocations are required. */
158344 if( SQLITE_ROW==sqlite3_step(pStmt) ){
158345 iCookie = sqlite3_column_int(pStmt, 0);
158346 }
158347 otaFinalize(p, pStmt);
158348 }
158349 if( p->rc==SQLITE_OK ){
158350 otaMPrintfExec(p, p->dbMain, "PRAGMA schema_version = %d", iCookie+1);
158351 }
158352 }
158353 }
158354
158355 /*
158356 ** Update the contents of the ota_state table within the ota database. The
158357 ** value stored in the OTA_STATE_STAGE column is eStage. All other values
158358 ** are determined by inspecting the ota handle passed as the first argument.
158359 */
158360 static void otaSaveState(sqlite3ota *p, int eStage){
158361 if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){
158362 sqlite3_stmt *pInsert = 0;
158363 int rc;
158364
158365 assert( p->zErrmsg==0 );
158366 rc = prepareFreeAndCollectError(p->dbOta, &pInsert, &p->zErrmsg,
158367 sqlite3_mprintf(
158368 "INSERT OR REPLACE INTO %s.ota_state(k, v) VALUES "
158369 "(%d, %d), "
158370 "(%d, %Q), "
158371 "(%d, %Q), "
158372 "(%d, %d), "
158373 "(%d, %d), "
158374 "(%d, %lld), "
158375 "(%d, %lld), "
158376 "(%d, %lld) ",
158377 p->zStateDb,
158378 OTA_STATE_STAGE, eStage,
158379 OTA_STATE_TBL, p->objiter.zTbl,
158380 OTA_STATE_IDX, p->objiter.zIdx,
158381 OTA_STATE_ROW, p->nStep,
158382 OTA_STATE_PROGRESS, p->nProgress,
158383 OTA_STATE_CKPT, p->iWalCksum,
158384 OTA_STATE_COOKIE, (i64)p->pTargetFd->iCookie,
158385 OTA_STATE_OALSZ, p->iOalSz
158386 )
158387 );
158388 assert( pInsert==0 || rc==SQLITE_OK );
158389
158390 if( rc==SQLITE_OK ){
158391 sqlite3_step(pInsert);
158392 rc = sqlite3_finalize(pInsert);
158393 }
158394 if( rc!=SQLITE_OK ) p->rc = rc;
158395 }
158396 }
158397
158398
158399 /*
158400 ** Step the OTA object.
158401 */
158402 SQLITE_API int SQLITE_STDCALL sqlite3ota_step(sqlite3ota *p){
158403 if( p ){
158404 switch( p->eStage ){
158405 case OTA_STAGE_OAL: {
158406 OtaObjIter *pIter = &p->objiter;
158407 while( p->rc==SQLITE_OK && pIter->zTbl ){
158408
158409 if( pIter->bCleanup ){
158410 /* Clean up the ota_tmp_xxx table for the previous table. It
158411 ** cannot be dropped as there are currently active SQL statements.
158412 ** But the contents can be deleted. */
158413 if( pIter->abIndexed ){
158414 otaMPrintfExec(p, p->dbOta,
158415 "DELETE FROM %s.'ota_tmp_%q'", p->zStateDb, pIter->zTbl
158416 );
158417 }
158418 }else{
158419 otaObjIterPrepareAll(p, pIter, 0);
158420
158421 /* Advance to the next row to process. */
158422 if( p->rc==SQLITE_OK ){
158423 int rc = sqlite3_step(pIter->pSelect);
158424 if( rc==SQLITE_ROW ){
158425 p->nProgress++;
158426 p->nStep++;
158427 return otaStep(p);
158428 }
158429 p->rc = sqlite3_reset(pIter->pSelect);
158430 p->nStep = 0;
158431 }
158432 }
158433
158434 otaObjIterNext(p, pIter);
158435 }
158436
158437 if( p->rc==SQLITE_OK ){
158438 assert( pIter->zTbl==0 );
158439 otaSaveState(p, OTA_STAGE_MOVE);
158440 otaIncrSchemaCookie(p);
158441 if( p->rc==SQLITE_OK ){
158442 p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
158443 }
158444 if( p->rc==SQLITE_OK ){
158445 p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
158446 }
158447 p->eStage = OTA_STAGE_MOVE;
158448 }
158449 break;
158450 }
158451
158452 case OTA_STAGE_MOVE: {
158453 if( p->rc==SQLITE_OK ){
158454 otaMoveOalFile(p);
158455 p->nProgress++;
158456 }
158457 break;
158458 }
158459
158460 case OTA_STAGE_CKPT: {
158461 if( p->rc==SQLITE_OK ){
158462 if( p->nStep>=p->nFrame ){
158463 sqlite3_file *pDb = p->pTargetFd->pReal;
158464
158465 /* Sync the db file */
158466 p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL);
158467
158468 /* Update nBackfill */
158469 if( p->rc==SQLITE_OK ){
158470 void volatile *ptr;
158471 p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, &ptr);
158472 if( p->rc==SQLITE_OK ){
158473 ((u32 volatile*)ptr)[24] = p->iMaxFrame;
158474 }
158475 }
158476
158477 if( p->rc==SQLITE_OK ){
158478 p->eStage = OTA_STAGE_DONE;
158479 p->rc = SQLITE_DONE;
158480 }
158481 }else{
158482 OtaFrame *pFrame = &p->aFrame[p->nStep];
158483 otaCheckpointFrame(p, pFrame);
158484 p->nStep++;
158485 }
158486 p->nProgress++;
158487 }
158488 break;
158489 }
158490
158491 default:
158492 break;
158493 }
158494 return p->rc;
158495 }else{
158496 return SQLITE_NOMEM;
158497 }
158498 }
158499
158500 /*
158501 ** Free an OtaState object allocated by otaLoadState().
158502 */
158503 static void otaFreeState(OtaState *p){
158504 if( p ){
158505 sqlite3_free(p->zTbl);
158506 sqlite3_free(p->zIdx);
158507 sqlite3_free(p);
158508 }
158509 }
158510
158511 /*
158512 ** Allocate an OtaState object and load the contents of the ota_state
158513 ** table into it. Return a pointer to the new object. It is the
158514 ** responsibility of the caller to eventually free the object using
158515 ** sqlite3_free().
158516 **
158517 ** If an error occurs, leave an error code and message in the ota handle
158518 ** and return NULL.
158519 */
158520 static OtaState *otaLoadState(sqlite3ota *p){
158521 OtaState *pRet = 0;
158522 sqlite3_stmt *pStmt = 0;
158523 int rc;
158524 int rc2;
158525
158526 pRet = (OtaState*)otaMalloc(p, sizeof(OtaState));
158527 if( pRet==0 ) return 0;
158528
158529 rc = prepareFreeAndCollectError(p->dbOta, &pStmt, &p->zErrmsg,
158530 sqlite3_mprintf("SELECT k, v FROM %s.ota_state", p->zStateDb)
158531 );
158532 while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
158533 switch( sqlite3_column_int(pStmt, 0) ){
158534 case OTA_STATE_STAGE:
158535 pRet->eStage = sqlite3_column_int(pStmt, 1);
158536 if( pRet->eStage!=OTA_STAGE_OAL
158537 && pRet->eStage!=OTA_STAGE_MOVE
158538 && pRet->eStage!=OTA_STAGE_CKPT
158539 ){
158540 p->rc = SQLITE_CORRUPT;
158541 }
158542 break;
158543
158544 case OTA_STATE_TBL:
158545 pRet->zTbl = otaStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
158546 break;
158547
158548 case OTA_STATE_IDX:
158549 pRet->zIdx = otaStrndup((char*)sqlite3_column_text(pStmt, 1), &rc);
158550 break;
158551
158552 case OTA_STATE_ROW:
158553 pRet->nRow = sqlite3_column_int(pStmt, 1);
158554 break;
158555
158556 case OTA_STATE_PROGRESS:
158557 pRet->nProgress = sqlite3_column_int64(pStmt, 1);
158558 break;
158559
158560 case OTA_STATE_CKPT:
158561 pRet->iWalCksum = sqlite3_column_int64(pStmt, 1);
158562 break;
158563
158564 case OTA_STATE_COOKIE:
158565 pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1);
158566 break;
158567
158568 case OTA_STATE_OALSZ:
158569 pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1);
158570 break;
158571
158572 default:
158573 rc = SQLITE_CORRUPT;
158574 break;
158575 }
158576 }
158577 rc2 = sqlite3_finalize(pStmt);
158578 if( rc==SQLITE_OK ) rc = rc2;
158579
158580 p->rc = rc;
158581 return pRet;
158582 }
158583
158584 /*
158585 ** Compare strings z1 and z2, returning 0 if they are identical, or non-zero
158586 ** otherwise. Either or both argument may be NULL. Two NULL values are
158587 ** considered equal, and NULL is considered distinct from all other values.
158588 */
158589 static int otaStrCompare(const char *z1, const char *z2){
158590 if( z1==0 && z2==0 ) return 0;
158591 if( z1==0 || z2==0 ) return 1;
158592 return (sqlite3_stricmp(z1, z2)!=0);
158593 }
158594
158595 /*
158596 ** This function is called as part of sqlite3ota_open() when initializing
158597 ** an ota handle in OAL stage. If the ota update has not started (i.e.
158598 ** the ota_state table was empty) it is a no-op. Otherwise, it arranges
158599 ** things so that the next call to sqlite3ota_step() continues on from
158600 ** where the previous ota handle left off.
158601 **
158602 ** If an error occurs, an error code and error message are left in the
158603 ** ota handle passed as the first argument.
158604 */
158605 static void otaSetupOal(sqlite3ota *p, OtaState *pState){
158606 assert( p->rc==SQLITE_OK );
158607 if( pState->zTbl ){
158608 OtaObjIter *pIter = &p->objiter;
158609 int rc = SQLITE_OK;
158610
158611 while( rc==SQLITE_OK && pIter->zTbl && (pIter->bCleanup
158612 || otaStrCompare(pIter->zIdx, pState->zIdx)
158613 || otaStrCompare(pIter->zTbl, pState->zTbl)
158614 )){
158615 rc = otaObjIterNext(p, pIter);
158616 }
158617
158618 if( rc==SQLITE_OK && !pIter->zTbl ){
158619 rc = SQLITE_ERROR;
158620 p->zErrmsg = sqlite3_mprintf("ota_state mismatch error");
158621 }
158622
158623 if( rc==SQLITE_OK ){
158624 p->nStep = pState->nRow;
158625 rc = otaObjIterPrepareAll(p, &p->objiter, p->nStep);
158626 }
158627
158628 p->rc = rc;
158629 }
158630 }
158631
158632 /*
158633 ** If there is a "*-oal" file in the file-system corresponding to the
158634 ** target database in the file-system, delete it. If an error occurs,
158635 ** leave an error code and error message in the ota handle.
158636 */
158637 static void otaDeleteOalFile(sqlite3ota *p){
158638 char *zOal = sqlite3_mprintf("%s-oal", p->zTarget);
158639 assert( p->rc==SQLITE_OK && p->zErrmsg==0 );
158640 unlink(zOal);
158641 sqlite3_free(zOal);
158642 }
158643
158644 /*
158645 ** Allocate a private ota VFS for the ota handle passed as the only
158646 ** argument. This VFS will be used unless the call to sqlite3ota_open()
158647 ** specified a URI with a vfs=? option in place of a target database
158648 ** file name.
158649 */
158650 static void otaCreateVfs(sqlite3ota *p){
158651 int rnd;
158652 char zRnd[64];
158653
158654 assert( p->rc==SQLITE_OK );
158655 sqlite3_randomness(sizeof(int), (void*)&rnd);
158656 sprintf(zRnd, "ota_vfs_%d", rnd);
158657 p->rc = sqlite3ota_create_vfs(zRnd, 0);
158658 if( p->rc==SQLITE_OK ){
158659 sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd);
158660 assert( pVfs );
158661 p->zVfsName = pVfs->zName;
158662 }
158663 }
158664
158665 /*
158666 ** Destroy the private VFS created for the ota handle passed as the only
158667 ** argument by an earlier call to otaCreateVfs().
158668 */
158669 static void otaDeleteVfs(sqlite3ota *p){
158670 if( p->zVfsName ){
158671 sqlite3ota_destroy_vfs(p->zVfsName);
158672 p->zVfsName = 0;
158673 }
158674 }
158675
158676 /*
158677 ** Open and return a new OTA handle.
158678 */
158679 SQLITE_API sqlite3ota *SQLITE_STDCALL sqlite3ota_open(
158680 const char *zTarget,
158681 const char *zOta,
158682 const char *zState
158683 ){
158684 sqlite3ota *p;
158685 int nTarget = strlen(zTarget);
158686 int nOta = strlen(zOta);
158687 int nState = zState ? strlen(zState) : 0;
158688
158689 p = (sqlite3ota*)sqlite3_malloc(sizeof(sqlite3ota)+nTarget+1+nOta+1+nState+1);
158690 if( p ){
158691 OtaState *pState = 0;
158692
158693 /* Create the custom VFS. */
158694 memset(p, 0, sizeof(sqlite3ota));
158695 otaCreateVfs(p);
158696
158697 /* Open the target database */
158698 if( p->rc==SQLITE_OK ){
158699 p->zTarget = (char*)&p[1];
158700 memcpy(p->zTarget, zTarget, nTarget+1);
158701 p->zOta = &p->zTarget[nTarget+1];
158702 memcpy(p->zOta, zOta, nOta+1);
158703 if( zState ){
158704 p->zState = &p->zOta[nOta+1];
158705 memcpy(p->zState, zState, nState+1);
158706 }
158707 otaOpenDatabase(p);
158708 }
158709
158710 /* If it has not already been created, create the ota_state table */
158711 otaMPrintfExec(p, p->dbOta, OTA_CREATE_STATE, p->zStateDb);
158712
158713 if( p->rc==SQLITE_OK ){
158714 pState = otaLoadState(p);
158715 assert( pState || p->rc!=SQLITE_OK );
158716 if( p->rc==SQLITE_OK ){
158717
158718 if( pState->eStage==0 ){
158719 otaDeleteOalFile(p);
158720 p->eStage = OTA_STAGE_OAL;
158721 }else{
158722 p->eStage = pState->eStage;
158723 }
158724 p->nProgress = pState->nProgress;
158725 p->iOalSz = pState->iOalSz;
158726 }
158727 }
158728 assert( p->rc!=SQLITE_OK || p->eStage!=0 );
158729
158730 if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){
158731 if( p->eStage==OTA_STAGE_OAL ){
158732 p->rc = SQLITE_ERROR;
158733 p->zErrmsg = sqlite3_mprintf("cannot update wal mode database");
158734 }else if( p->eStage==OTA_STAGE_MOVE ){
158735 p->eStage = OTA_STAGE_CKPT;
158736 p->nStep = 0;
158737 }
158738 }
158739
158740 if( p->rc==SQLITE_OK
158741 && (p->eStage==OTA_STAGE_OAL || p->eStage==OTA_STAGE_MOVE)
158742 && pState->eStage!=0 && p->pTargetFd->iCookie!=pState->iCookie
158743 ){
158744 /* At this point (pTargetFd->iCookie) contains the value of the
158745 ** change-counter cookie (the thing that gets incremented when a
158746 ** transaction is committed in rollback mode) currently stored on
158747 ** page 1 of the database file. */
158748 p->rc = SQLITE_BUSY;
158749 p->zErrmsg = sqlite3_mprintf("database modified during ota update");
158750 }
158751
158752 if( p->rc==SQLITE_OK ){
158753 if( p->eStage==OTA_STAGE_OAL ){
158754
158755 /* Open transactions both databases. The *-oal file is opened or
158756 ** created at this point. */
158757 p->rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
158758 if( p->rc==SQLITE_OK ){
158759 p->rc = sqlite3_exec(p->dbOta, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg);
158760 }
158761
158762 /* Point the object iterator at the first object */
158763 if( p->rc==SQLITE_OK ){
158764 p->rc = otaObjIterFirst(p, &p->objiter);
158765 }
158766
158767 /* If the OTA database contains no data_xxx tables, declare the OTA
158768 ** update finished. */
158769 if( p->rc==SQLITE_OK && p->objiter.zTbl==0 ){
158770 p->rc = SQLITE_DONE;
158771 }
158772
158773 if( p->rc==SQLITE_OK ){
158774 otaSetupOal(p, pState);
158775 }
158776
158777 }else if( p->eStage==OTA_STAGE_MOVE ){
158778 /* no-op */
158779 }else if( p->eStage==OTA_STAGE_CKPT ){
158780 otaSetupCheckpoint(p, pState);
158781 }else if( p->eStage==OTA_STAGE_DONE ){
158782 p->rc = SQLITE_DONE;
158783 }else{
158784 p->rc = SQLITE_CORRUPT;
158785 }
158786 }
158787
158788 otaFreeState(pState);
158789 }
158790
158791 return p;
158792 }
158793
158794
158795 /*
158796 ** Return the database handle used by pOta.
158797 */
158798 SQLITE_API sqlite3 *SQLITE_STDCALL sqlite3ota_db(sqlite3ota *pOta, int bOta){
158799 sqlite3 *db = 0;
158800 if( pOta ){
158801 db = (bOta ? pOta->dbOta : pOta->dbMain);
158802 }
158803 return db;
158804 }
158805
158806
158807 /*
158808 ** If the error code currently stored in the OTA handle is SQLITE_CONSTRAINT,
158809 ** then edit any error message string so as to remove all occurrences of
158810 ** the pattern "ota_imp_[0-9]*".
158811 */
158812 static void otaEditErrmsg(sqlite3ota *p){
158813 if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){
158814 int i;
158815 int nErrmsg = strlen(p->zErrmsg);
158816 for(i=0; i<(nErrmsg-8); i++){
158817 if( memcmp(&p->zErrmsg[i], "ota_imp_", 8)==0 ){
158818 int nDel = 8;
158819 while( p->zErrmsg[i+nDel]>='0' && p->zErrmsg[i+nDel]<='9' ) nDel++;
158820 memmove(&p->zErrmsg[i], &p->zErrmsg[i+nDel], nErrmsg + 1 - i - nDel);
158821 nErrmsg -= nDel;
158822 }
158823 }
158824 }
158825 }
158826
158827 /*
158828 ** Close the OTA handle.
158829 */
158830 SQLITE_API int SQLITE_STDCALL sqlite3ota_close(sqlite3ota *p, char **pzErrmsg){
158831 int rc;
158832 if( p ){
158833
158834 /* Commit the transaction to the *-oal file. */
158835 if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_OAL ){
158836 p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg);
158837 }
158838
158839 otaSaveState(p, p->eStage);
158840
158841 if( p->rc==SQLITE_OK && p->eStage==OTA_STAGE_OAL ){
158842 p->rc = sqlite3_exec(p->dbOta, "COMMIT", 0, 0, &p->zErrmsg);
158843 }
158844
158845 /* Close any open statement handles. */
158846 otaObjIterFinalize(&p->objiter);
158847
158848 /* Close the open database handle and VFS object. */
158849 sqlite3_close(p->dbMain);
158850 sqlite3_close(p->dbOta);
158851 otaDeleteVfs(p);
158852 sqlite3_free(p->aBuf);
158853 sqlite3_free(p->aFrame);
158854
158855 otaEditErrmsg(p);
158856 rc = p->rc;
158857 *pzErrmsg = p->zErrmsg;
158858 sqlite3_free(p);
158859 }else{
158860 rc = SQLITE_NOMEM;
158861 *pzErrmsg = 0;
158862 }
158863 return rc;
158864 }
158865
158866 /*
158867 ** Return the total number of key-value operations (inserts, deletes or
158868 ** updates) that have been performed on the target database since the
158869 ** current OTA update was started.
158870 */
158871 SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3ota_progress(sqlite3ota *pOta){
158872 return pOta->nProgress;
158873 }
158874
158875 /**************************************************************************
158876 ** Beginning of OTA VFS shim methods. The VFS shim modifies the behaviour
158877 ** of a standard VFS in the following ways:
158878 **
158879 ** 1. Whenever the first page of a main database file is read or
158880 ** written, the value of the change-counter cookie is stored in
158881 ** ota_file.iCookie. Similarly, the value of the "write-version"
158882 ** database header field is stored in ota_file.iWriteVer. This ensures
158883 ** that the values are always trustworthy within an open transaction.
158884 **
158885 ** 2. Whenever an SQLITE_OPEN_WAL file is opened, the (ota_file.pWalFd)
158886 ** member variable of the associated database file descriptor is set
158887 ** to point to the new file. A mutex protected linked list of all main
158888 ** db fds opened using a particular OTA VFS is maintained at
158889 ** ota_vfs.pMain to facilitate this.
158890 **
158891 ** 3. Using a new file-control "SQLITE_FCNTL_OTA", a main db ota_file
158892 ** object can be marked as the target database of an OTA update. This
158893 ** turns on the following extra special behaviour:
158894 **
158895 ** 3a. If xAccess() is called to check if there exists a *-wal file
158896 ** associated with an OTA target database currently in OTA_STAGE_OAL
158897 ** stage (preparing the *-oal file), the following special handling
158898 ** applies:
158899 **
158900 ** * if the *-wal file does exist, return SQLITE_CANTOPEN. An OTA
158901 ** target database may not be in wal mode already.
158902 **
158903 ** * if the *-wal file does not exist, set the output parameter to
158904 ** non-zero (to tell SQLite that it does exist) anyway.
158905 **
158906 ** Then, when xOpen() is called to open the *-wal file associated with
158907 ** the OTA target in OTA_STAGE_OAL stage, instead of opening the *-wal
158908 ** file, the ota vfs opens the corresponding *-oal file instead.
158909 **
158910 ** 3b. The *-shm pages returned by xShmMap() for a target db file in
158911 ** OTA_STAGE_OAL mode are actually stored in heap memory. This is to
158912 ** avoid creating a *-shm file on disk. Additionally, xShmLock() calls
158913 ** are no-ops on target database files in OTA_STAGE_OAL mode. This is
158914 ** because assert() statements in some VFS implementations fail if
158915 ** xShmLock() is called before xShmMap().
158916 **
158917 ** 3c. If an EXCLUSIVE lock is attempted on a target database file in any
158918 ** mode except OTA_STAGE_DONE (all work completed and checkpointed), it
158919 ** fails with an SQLITE_BUSY error. This is to stop OTA connections
158920 ** from automatically checkpointing a *-wal (or *-oal) file from within
158921 ** sqlite3_close().
158922 **
158923 ** 3d. In OTA_STAGE_CAPTURE mode, all xRead() calls on the wal file, and
158924 ** all xWrite() calls on the target database file perform no IO.
158925 ** Instead the frame and page numbers that would be read and written
158926 ** are recorded. Additionally, successful attempts to obtain exclusive
158927 ** xShmLock() WRITER, CHECKPOINTER and READ0 locks on the target
158928 ** database file are recorded. xShmLock() calls to unlock the same
158929 ** locks are no-ops (so that once obtained, these locks are never
158930 ** relinquished). Finally, calls to xSync() on the target database
158931 ** file fail with SQLITE_INTERNAL errors.
158932 */
158933
158934 static void otaUnlockShm(ota_file *p){
158935 if( p->pOta ){
158936 int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock;
158937 int i;
158938 for(i=0; i<SQLITE_SHM_NLOCK;i++){
158939 if( (1<<i) & p->pOta->mLock ){
158940 xShmLock(p->pReal, i, 1, SQLITE_SHM_UNLOCK|SQLITE_SHM_EXCLUSIVE);
158941 }
158942 }
158943 p->pOta->mLock = 0;
158944 }
158945 }
158946
158947 /*
158948 ** Close an ota file.
158949 */
158950 static int otaVfsClose(sqlite3_file *pFile){
158951 ota_file *p = (ota_file*)pFile;
158952 int rc;
158953 int i;
158954
158955 /* Free the contents of the apShm[] array. And the array itself. */
158956 for(i=0; i<p->nShm; i++){
158957 sqlite3_free(p->apShm[i]);
158958 }
158959 sqlite3_free(p->apShm);
158960 p->apShm = 0;
158961 sqlite3_free(p->zDel);
158962
158963 if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
158964 ota_file **pp;
158965 sqlite3_mutex_enter(p->pOtaVfs->mutex);
158966 for(pp=&p->pOtaVfs->pMain; *pp!=p; pp=&((*pp)->pMainNext));
158967 *pp = p->pMainNext;
158968 sqlite3_mutex_leave(p->pOtaVfs->mutex);
158969 otaUnlockShm(p);
158970 p->pReal->pMethods->xShmUnmap(p->pReal, 0);
158971 }
158972
158973 /* Close the underlying file handle */
158974 rc = p->pReal->pMethods->xClose(p->pReal);
158975 return rc;
158976 }
158977
158978
158979 /*
158980 ** Read and return an unsigned 32-bit big-endian integer from the buffer
158981 ** passed as the only argument.
158982 */
158983 static u32 otaGetU32(u8 *aBuf){
158984 return ((u32)aBuf[0] << 24)
158985 + ((u32)aBuf[1] << 16)
158986 + ((u32)aBuf[2] << 8)
158987 + ((u32)aBuf[3]);
158988 }
158989
158990 /*
158991 ** Read data from an otaVfs-file.
158992 */
158993 static int otaVfsRead(
158994 sqlite3_file *pFile,
158995 void *zBuf,
158996 int iAmt,
158997 sqlite_int64 iOfst
158998 ){
158999 ota_file *p = (ota_file*)pFile;
159000 sqlite3ota *pOta = p->pOta;
159001 int rc;
159002
159003 if( pOta && pOta->eStage==OTA_STAGE_CAPTURE ){
159004 assert( p->openFlags & SQLITE_OPEN_WAL );
159005 rc = otaCaptureWalRead(p->pOta, iOfst, iAmt);
159006 }else{
159007 if( pOta && pOta->eStage==OTA_STAGE_OAL
159008 && (p->openFlags & SQLITE_OPEN_WAL)
159009 && iOfst>=pOta->iOalSz
159010 ){
159011 rc = SQLITE_OK;
159012 memset(zBuf, 0, iAmt);
159013 }else{
159014 rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
159015 }
159016 if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
159017 /* These look like magic numbers. But they are stable, as they are part
159018 ** of the definition of the SQLite file format, which may not change. */
159019 u8 *pBuf = (u8*)zBuf;
159020 p->iCookie = otaGetU32(&pBuf[24]);
159021 p->iWriteVer = pBuf[19];
159022 }
159023 }
159024 return rc;
159025 }
159026
159027 /*
159028 ** Write data to an otaVfs-file.
159029 */
159030 static int otaVfsWrite(
159031 sqlite3_file *pFile,
159032 const void *zBuf,
159033 int iAmt,
159034 sqlite_int64 iOfst
159035 ){
159036 ota_file *p = (ota_file*)pFile;
159037 sqlite3ota *pOta = p->pOta;
159038 int rc;
159039
159040 if( pOta && pOta->eStage==OTA_STAGE_CAPTURE ){
159041 assert( p->openFlags & SQLITE_OPEN_MAIN_DB );
159042 rc = otaCaptureDbWrite(p->pOta, iOfst);
159043 }else{
159044 if( pOta && pOta->eStage==OTA_STAGE_OAL
159045 && (p->openFlags & SQLITE_OPEN_WAL)
159046 && iOfst>=pOta->iOalSz
159047 ){
159048 pOta->iOalSz = iAmt + iOfst;
159049 }
159050 rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
159051 if( rc==SQLITE_OK && iOfst==0 && (p->openFlags & SQLITE_OPEN_MAIN_DB) ){
159052 /* These look like magic numbers. But they are stable, as they are part
159053 ** of the definition of the SQLite file format, which may not change. */
159054 u8 *pBuf = (u8*)zBuf;
159055 p->iCookie = otaGetU32(&pBuf[24]);
159056 p->iWriteVer = pBuf[19];
159057 }
159058 }
159059 return rc;
159060 }
159061
159062 /*
159063 ** Truncate an otaVfs-file.
159064 */
159065 static int otaVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
159066 ota_file *p = (ota_file*)pFile;
159067 return p->pReal->pMethods->xTruncate(p->pReal, size);
159068 }
159069
159070 /*
159071 ** Sync an otaVfs-file.
159072 */
159073 static int otaVfsSync(sqlite3_file *pFile, int flags){
159074 ota_file *p = (ota_file *)pFile;
159075 if( p->pOta && p->pOta->eStage==OTA_STAGE_CAPTURE ){
159076 if( p->openFlags & SQLITE_OPEN_MAIN_DB ){
159077 return SQLITE_INTERNAL;
159078 }
159079 return SQLITE_OK;
159080 }
159081 return p->pReal->pMethods->xSync(p->pReal, flags);
159082 }
159083
159084 /*
159085 ** Return the current file-size of an otaVfs-file.
159086 */
159087 static int otaVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
159088 ota_file *p = (ota_file *)pFile;
159089 return p->pReal->pMethods->xFileSize(p->pReal, pSize);
159090 }
159091
159092 /*
159093 ** Lock an otaVfs-file.
159094 */
159095 static int otaVfsLock(sqlite3_file *pFile, int eLock){
159096 ota_file *p = (ota_file*)pFile;
159097 sqlite3ota *pOta = p->pOta;
159098 int rc = SQLITE_OK;
159099
159100 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159101 if( pOta && eLock==SQLITE_LOCK_EXCLUSIVE && pOta->eStage!=OTA_STAGE_DONE ){
159102 /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this
159103 ** prevents it from checkpointing the database from sqlite3_close(). */
159104 rc = SQLITE_BUSY;
159105 }else{
159106 rc = p->pReal->pMethods->xLock(p->pReal, eLock);
159107 }
159108
159109 return rc;
159110 }
159111
159112 /*
159113 ** Unlock an otaVfs-file.
159114 */
159115 static int otaVfsUnlock(sqlite3_file *pFile, int eLock){
159116 ota_file *p = (ota_file *)pFile;
159117 return p->pReal->pMethods->xUnlock(p->pReal, eLock);
159118 }
159119
159120 /*
159121 ** Check if another file-handle holds a RESERVED lock on an otaVfs-file.
159122 */
159123 static int otaVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
159124 ota_file *p = (ota_file *)pFile;
159125 return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
159126 }
159127
159128 /*
159129 ** File control method. For custom operations on an otaVfs-file.
159130 */
159131 static int otaVfsFileControl(sqlite3_file *pFile, int op, void *pArg){
159132 ota_file *p = (ota_file *)pFile;
159133 int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl;
159134 int rc;
159135
159136 assert( p->openFlags &
159137 (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB|SQLITE_OPEN_TRANSIENT_DB)
159138 );
159139 if( op==SQLITE_FCNTL_OTA ){
159140 sqlite3ota *pOta = (sqlite3ota*)pArg;
159141
159142 /* First try to find another OTA vfs lower down in the vfs stack. If
159143 ** one is found, this vfs will operate in pass-through mode. The lower
159144 ** level vfs will do the special OTA handling. */
159145 rc = xControl(p->pReal, op, pArg);
159146
159147 if( rc==SQLITE_NOTFOUND ){
159148 /* Now search for a zipvfs instance lower down in the VFS stack. If
159149 ** one is found, this is an error. */
159150 void *dummy = 0;
159151 rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy);
159152 if( rc==SQLITE_OK ){
159153 rc = SQLITE_ERROR;
159154 pOta->zErrmsg = sqlite3_mprintf("ota/zipvfs setup error");
159155 }else if( rc==SQLITE_NOTFOUND ){
159156 pOta->pTargetFd = p;
159157 p->pOta = pOta;
159158 if( p->pWalFd ) p->pWalFd->pOta = pOta;
159159 rc = SQLITE_OK;
159160 }
159161 }
159162 return rc;
159163 }
159164
159165 rc = xControl(p->pReal, op, pArg);
159166 if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
159167 ota_vfs *pOtaVfs = p->pOtaVfs;
159168 char *zIn = *(char**)pArg;
159169 char *zOut = sqlite3_mprintf("ota(%s)/%z", pOtaVfs->base.zName, zIn);
159170 *(char**)pArg = zOut;
159171 if( zOut==0 ) rc = SQLITE_NOMEM;
159172 }
159173
159174 return rc;
159175 }
159176
159177 /*
159178 ** Return the sector-size in bytes for an otaVfs-file.
159179 */
159180 static int otaVfsSectorSize(sqlite3_file *pFile){
159181 ota_file *p = (ota_file *)pFile;
159182 return p->pReal->pMethods->xSectorSize(p->pReal);
159183 }
159184
159185 /*
159186 ** Return the device characteristic flags supported by an otaVfs-file.
159187 */
159188 static int otaVfsDeviceCharacteristics(sqlite3_file *pFile){
159189 ota_file *p = (ota_file *)pFile;
159190 return p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
159191 }
159192
159193 /*
159194 ** Take or release a shared-memory lock.
159195 */
159196 static int otaVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
159197 ota_file *p = (ota_file*)pFile;
159198 sqlite3ota *pOta = p->pOta;
159199 int rc = SQLITE_OK;
159200
159201 #ifdef SQLITE_AMALGAMATION
159202 assert( WAL_CKPT_LOCK==1 );
159203 #endif
159204
159205 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159206 if( pOta && (pOta->eStage==OTA_STAGE_OAL || pOta->eStage==OTA_STAGE_MOVE) ){
159207 /* Magic number 1 is the WAL_CKPT_LOCK lock. Preventing SQLite from
159208 ** taking this lock also prevents any checkpoints from occurring.
159209 ** todo: really, it's not clear why this might occur, as
159210 ** wal_autocheckpoint ought to be turned off. */
159211 if( ofst==WAL_LOCK_CKPT && n==1 ) rc = SQLITE_BUSY;
159212 }else{
159213 int bCapture = 0;
159214 if( n==1 && (flags & SQLITE_SHM_EXCLUSIVE)
159215 && pOta && pOta->eStage==OTA_STAGE_CAPTURE
159216 && (ofst==WAL_LOCK_WRITE || ofst==WAL_LOCK_CKPT || ofst==WAL_LOCK_READ0)
159217 ){
159218 bCapture = 1;
159219 }
159220
159221 if( bCapture==0 || 0==(flags & SQLITE_SHM_UNLOCK) ){
159222 rc = p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
159223 if( bCapture && rc==SQLITE_OK ){
159224 pOta->mLock |= (1 << ofst);
159225 }
159226 }
159227 }
159228
159229 return rc;
159230 }
159231
159232 /*
159233 ** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file.
159234 */
159235 static int otaVfsShmMap(
159236 sqlite3_file *pFile,
159237 int iRegion,
159238 int szRegion,
159239 int isWrite,
159240 void volatile **pp
159241 ){
159242 ota_file *p = (ota_file*)pFile;
159243 int rc = SQLITE_OK;
159244 int eStage = (p->pOta ? p->pOta->eStage : 0);
159245
159246 /* If not in OTA_STAGE_OAL, allow this call to pass through. Or, if this
159247 ** ota is in the OTA_STAGE_OAL state, use heap memory for *-shm space
159248 ** instead of a file on disk. */
159249 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159250 if( eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_MOVE ){
159251 if( iRegion<=p->nShm ){
159252 int nByte = (iRegion+1) * sizeof(char*);
159253 char **apNew = (char**)sqlite3_realloc(p->apShm, nByte);
159254 if( apNew==0 ){
159255 rc = SQLITE_NOMEM;
159256 }else{
159257 memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
159258 p->apShm = apNew;
159259 p->nShm = iRegion+1;
159260 }
159261 }
159262
159263 if( rc==SQLITE_OK && p->apShm[iRegion]==0 ){
159264 char *pNew = (char*)sqlite3_malloc(szRegion);
159265 if( pNew==0 ){
159266 rc = SQLITE_NOMEM;
159267 }else{
159268 memset(pNew, 0, szRegion);
159269 p->apShm[iRegion] = pNew;
159270 }
159271 }
159272
159273 if( rc==SQLITE_OK ){
159274 *pp = p->apShm[iRegion];
159275 }else{
159276 *pp = 0;
159277 }
159278 }else{
159279 assert( p->apShm==0 );
159280 rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
159281 }
159282
159283 return rc;
159284 }
159285
159286 /*
159287 ** Memory barrier.
159288 */
159289 static void otaVfsShmBarrier(sqlite3_file *pFile){
159290 ota_file *p = (ota_file *)pFile;
159291 p->pReal->pMethods->xShmBarrier(p->pReal);
159292 }
159293
159294 /*
159295 ** The xShmUnmap method.
159296 */
159297 static int otaVfsShmUnmap(sqlite3_file *pFile, int delFlag){
159298 ota_file *p = (ota_file*)pFile;
159299 int rc = SQLITE_OK;
159300 int eStage = (p->pOta ? p->pOta->eStage : 0);
159301
159302 assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
159303 if( eStage==OTA_STAGE_OAL || eStage==OTA_STAGE_MOVE ){
159304 /* no-op */
159305 }else{
159306 /* Release the checkpointer and writer locks */
159307 otaUnlockShm(p);
159308 rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
159309 }
159310 return rc;
159311 }
159312
159313 /*
159314 ** Given that zWal points to a buffer containing a wal file name passed to
159315 ** either the xOpen() or xAccess() VFS method, return a pointer to the
159316 ** file-handle opened by the same database connection on the corresponding
159317 ** database file.
159318 */
159319 static ota_file *otaFindMaindb(ota_vfs *pOtaVfs, const char *zWal){
159320 ota_file *pDb;
159321 sqlite3_mutex_enter(pOtaVfs->mutex);
159322 for(pDb=pOtaVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext);
159323 sqlite3_mutex_leave(pOtaVfs->mutex);
159324 return pDb;
159325 }
159326
159327 /*
159328 ** Open an ota file handle.
159329 */
159330 static int otaVfsOpen(
159331 sqlite3_vfs *pVfs,
159332 const char *zName,
159333 sqlite3_file *pFile,
159334 int flags,
159335 int *pOutFlags
159336 ){
159337 static sqlite3_io_methods otavfs_io_methods = {
159338 2, /* iVersion */
159339 otaVfsClose, /* xClose */
159340 otaVfsRead, /* xRead */
159341 otaVfsWrite, /* xWrite */
159342 otaVfsTruncate, /* xTruncate */
159343 otaVfsSync, /* xSync */
159344 otaVfsFileSize, /* xFileSize */
159345 otaVfsLock, /* xLock */
159346 otaVfsUnlock, /* xUnlock */
159347 otaVfsCheckReservedLock, /* xCheckReservedLock */
159348 otaVfsFileControl, /* xFileControl */
159349 otaVfsSectorSize, /* xSectorSize */
159350 otaVfsDeviceCharacteristics, /* xDeviceCharacteristics */
159351 otaVfsShmMap, /* xShmMap */
159352 otaVfsShmLock, /* xShmLock */
159353 otaVfsShmBarrier, /* xShmBarrier */
159354 otaVfsShmUnmap /* xShmUnmap */
159355 };
159356 ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
159357 sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
159358 ota_file *pFd = (ota_file *)pFile;
159359 int rc = SQLITE_OK;
159360 const char *zOpen = zName;
159361
159362 memset(pFd, 0, sizeof(ota_file));
159363 pFd->pReal = (sqlite3_file*)&pFd[1];
159364 pFd->pOtaVfs = pOtaVfs;
159365 pFd->openFlags = flags;
159366 if( zName ){
159367 if( flags & SQLITE_OPEN_MAIN_DB ){
159368 /* A main database has just been opened. The following block sets
159369 ** (pFd->zWal) to point to a buffer owned by SQLite that contains
159370 ** the name of the *-wal file this db connection will use. SQLite
159371 ** happens to pass a pointer to this buffer when using xAccess()
159372 ** or xOpen() to operate on the *-wal file. */
159373 int n = strlen(zName);
159374 const char *z = &zName[n];
159375 if( flags & SQLITE_OPEN_URI ){
159376 int odd = 0;
159377 while( 1 ){
159378 if( z[0]==0 ){
159379 odd = 1 - odd;
159380 if( odd && z[1]==0 ) break;
159381 }
159382 z++;
159383 }
159384 z += 2;
159385 }else{
159386 while( *z==0 ) z++;
159387 }
159388 z += (n + 8 + 1);
159389 pFd->zWal = z;
159390 }
159391 else if( flags & SQLITE_OPEN_WAL ){
159392 ota_file *pDb = otaFindMaindb(pOtaVfs, zName);
159393 if( pDb ){
159394 if( pDb->pOta && pDb->pOta->eStage==OTA_STAGE_OAL ){
159395 /* This call is to open a *-wal file. Intead, open the *-oal. This
159396 ** code ensures that the string passed to xOpen() is terminated by a
159397 ** pair of '\0' bytes in case the VFS attempts to extract a URI
159398 ** parameter from it. */
159399 int nCopy = strlen(zName);
159400 char *zCopy = sqlite3_malloc(nCopy+2);
159401 if( zCopy ){
159402 memcpy(zCopy, zName, nCopy);
159403 zCopy[nCopy-3] = 'o';
159404 zCopy[nCopy] = '\0';
159405 zCopy[nCopy+1] = '\0';
159406 zOpen = (const char*)(pFd->zDel = zCopy);
159407 }else{
159408 rc = SQLITE_NOMEM;
159409 }
159410 pFd->pOta = pDb->pOta;
159411 }
159412 pDb->pWalFd = pFd;
159413 }
159414 }
159415 }
159416
159417 if( rc==SQLITE_OK ){
159418 rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, flags, pOutFlags);
159419 }
159420 if( pFd->pReal->pMethods ){
159421 /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods
159422 ** pointer and, if the file is a main database file, link it into the
159423 ** mutex protected linked list of all such files. */
159424 pFile->pMethods = &otavfs_io_methods;
159425 if( flags & SQLITE_OPEN_MAIN_DB ){
159426 sqlite3_mutex_enter(pOtaVfs->mutex);
159427 pFd->pMainNext = pOtaVfs->pMain;
159428 pOtaVfs->pMain = pFd;
159429 sqlite3_mutex_leave(pOtaVfs->mutex);
159430 }
159431 }else{
159432 sqlite3_free(pFd->zDel);
159433 }
159434
159435 return rc;
159436 }
159437
159438 /*
159439 ** Delete the file located at zPath.
159440 */
159441 static int otaVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
159442 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159443 return pRealVfs->xDelete(pRealVfs, zPath, dirSync);
159444 }
159445
159446 /*
159447 ** Test for access permissions. Return true if the requested permission
159448 ** is available, or false otherwise.
159449 */
159450 static int otaVfsAccess(
159451 sqlite3_vfs *pVfs,
159452 const char *zPath,
159453 int flags,
159454 int *pResOut
159455 ){
159456 ota_vfs *pOtaVfs = (ota_vfs*)pVfs;
159457 sqlite3_vfs *pRealVfs = pOtaVfs->pRealVfs;
159458 int rc;
159459
159460 rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut);
159461
159462 /* If this call is to check if a *-wal file associated with an OTA target
159463 ** database connection exists, and the OTA update is in OTA_STAGE_OAL,
159464 ** the following special handling is activated:
159465 **
159466 ** a) if the *-wal file does exist, return SQLITE_CANTOPEN. This
159467 ** ensures that the OTA extension never tries to update a database
159468 ** in wal mode, even if the first page of the database file has
159469 ** been damaged.
159470 **
159471 ** b) if the *-wal file does not exist, claim that it does anyway,
159472 ** causing SQLite to call xOpen() to open it. This call will also
159473 ** be intercepted (see the otaVfsOpen() function) and the *-oal
159474 ** file opened instead.
159475 */
159476 if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){
159477 ota_file *pDb = otaFindMaindb(pOtaVfs, zPath);
159478 if( pDb && pDb->pOta && pDb->pOta->eStage==OTA_STAGE_OAL ){
159479 if( *pResOut ){
159480 rc = SQLITE_CANTOPEN;
159481 }else{
159482 *pResOut = 1;
159483 }
159484 }
159485 }
159486
159487 return rc;
159488 }
159489
159490 /*
159491 ** Populate buffer zOut with the full canonical pathname corresponding
159492 ** to the pathname in zPath. zOut is guaranteed to point to a buffer
159493 ** of at least (DEVSYM_MAX_PATHNAME+1) bytes.
159494 */
159495 static int otaVfsFullPathname(
159496 sqlite3_vfs *pVfs,
159497 const char *zPath,
159498 int nOut,
159499 char *zOut
159500 ){
159501 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159502 return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut);
159503 }
159504
159505 #ifndef SQLITE_OMIT_LOAD_EXTENSION
159506 /*
159507 ** Open the dynamic library located at zPath and return a handle.
159508 */
159509 static void *otaVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
159510 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159511 return pRealVfs->xDlOpen(pRealVfs, zPath);
159512 }
159513
159514 /*
159515 ** Populate the buffer zErrMsg (size nByte bytes) with a human readable
159516 ** utf-8 string describing the most recent error encountered associated
159517 ** with dynamic libraries.
159518 */
159519 static void otaVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
159520 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159521 pRealVfs->xDlError(pRealVfs, nByte, zErrMsg);
159522 }
159523
159524 /*
159525 ** Return a pointer to the symbol zSymbol in the dynamic library pHandle.
159526 */
159527 static void (*otaVfsDlSym(
159528 sqlite3_vfs *pVfs,
159529 void *pArg,
159530 const char *zSym
159531 ))(void){
159532 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159533 return pRealVfs->xDlSym(pRealVfs, pArg, zSym);
159534 }
159535
159536 /*
159537 ** Close the dynamic library handle pHandle.
159538 */
159539 static void otaVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){
159540 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159541 return pRealVfs->xDlClose(pRealVfs, pHandle);
159542 }
159543 #endif /* SQLITE_OMIT_LOAD_EXTENSION */
159544
159545 /*
159546 ** Populate the buffer pointed to by zBufOut with nByte bytes of
159547 ** random data.
159548 */
159549 static int otaVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
159550 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159551 return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut);
159552 }
159553
159554 /*
159555 ** Sleep for nMicro microseconds. Return the number of microseconds
159556 ** actually slept.
159557 */
159558 static int otaVfsSleep(sqlite3_vfs *pVfs, int nMicro){
159559 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159560 return pRealVfs->xSleep(pRealVfs, nMicro);
159561 }
159562
159563 /*
159564 ** Return the current time as a Julian Day number in *pTimeOut.
159565 */
159566 static int otaVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
159567 sqlite3_vfs *pRealVfs = ((ota_vfs*)pVfs)->pRealVfs;
159568 return pRealVfs->xCurrentTime(pRealVfs, pTimeOut);
159569 }
159570
159571 /*
159572 ** No-op.
159573 */
159574 static int otaVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){
159575 return 0;
159576 }
159577
159578 /*
159579 ** Deregister and destroy an OTA vfs created by an earlier call to
159580 ** sqlite3ota_create_vfs().
159581 */
159582 SQLITE_API void SQLITE_STDCALL sqlite3ota_destroy_vfs(const char *zName){
159583 sqlite3_vfs *pVfs = sqlite3_vfs_find(zName);
159584 if( pVfs && pVfs->xOpen==otaVfsOpen ){
159585 sqlite3_mutex_free(((ota_vfs*)pVfs)->mutex);
159586 sqlite3_vfs_unregister(pVfs);
159587 sqlite3_free(pVfs);
159588 }
159589 }
159590
159591 /*
159592 ** Create an OTA VFS named zName that accesses the underlying file-system
159593 ** via existing VFS zParent. The new object is registered as a non-default
159594 ** VFS with SQLite before returning.
159595 */
159596 SQLITE_API int SQLITE_STDCALL sqlite3ota_create_vfs(const char *zName, const char *zParent){
159597
159598 /* Template for VFS */
159599 static sqlite3_vfs vfs_template = {
159600 1, /* iVersion */
159601 0, /* szOsFile */
159602 0, /* mxPathname */
159603 0, /* pNext */
159604 0, /* zName */
159605 0, /* pAppData */
159606 otaVfsOpen, /* xOpen */
159607 otaVfsDelete, /* xDelete */
159608 otaVfsAccess, /* xAccess */
159609 otaVfsFullPathname, /* xFullPathname */
159610
159611 #ifndef SQLITE_OMIT_LOAD_EXTENSION
159612 otaVfsDlOpen, /* xDlOpen */
159613 otaVfsDlError, /* xDlError */
159614 otaVfsDlSym, /* xDlSym */
159615 otaVfsDlClose, /* xDlClose */
159616 #else
159617 0, 0, 0, 0,
159618 #endif
159619
159620 otaVfsRandomness, /* xRandomness */
159621 otaVfsSleep, /* xSleep */
159622 otaVfsCurrentTime, /* xCurrentTime */
159623 otaVfsGetLastError, /* xGetLastError */
159624 0, /* xCurrentTimeInt64 (version 2) */
159625 0, 0, 0 /* Unimplemented version 3 methods */
159626 };
159627
159628 ota_vfs *pNew = 0; /* Newly allocated VFS */
159629 int nName;
159630 int rc = SQLITE_OK;
159631
159632 int nByte;
159633 nName = strlen(zName);
159634 nByte = sizeof(ota_vfs) + nName + 1;
159635 pNew = (ota_vfs*)sqlite3_malloc(nByte);
159636 if( pNew==0 ){
159637 rc = SQLITE_NOMEM;
159638 }else{
159639 sqlite3_vfs *pParent; /* Parent VFS */
159640 memset(pNew, 0, nByte);
159641 pParent = sqlite3_vfs_find(zParent);
159642 if( pParent==0 ){
159643 rc = SQLITE_NOTFOUND;
159644 }else{
159645 char *zSpace;
159646 memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs));
159647 pNew->base.mxPathname = pParent->mxPathname;
159648 pNew->base.szOsFile = sizeof(ota_file) + pParent->szOsFile;
159649 pNew->pRealVfs = pParent;
159650 pNew->base.zName = (const char*)(zSpace = (char*)&pNew[1]);
159651 memcpy(zSpace, zName, nName);
159652
159653 /* Allocate the mutex and register the new VFS (not as the default) */
159654 pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
159655 if( pNew->mutex==0 ){
159656 rc = SQLITE_NOMEM;
159657 }else{
159658 rc = sqlite3_vfs_register(&pNew->base, 0);
159659 }
159660 }
159661
159662 if( rc!=SQLITE_OK ){
159663 sqlite3_mutex_free(pNew->mutex);
159664 sqlite3_free(pNew);
159665 }
159666 }
159667
159668 return rc;
159669 }
159670
159671
159672 /**************************************************************************/
159673
159674 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_OTA) */
159675
159676 /************** End of sqlite3ota.c ******************************************/
159677 /************** Begin file dbstat.c ******************************************/
159678 /*
159679 ** 2010 July 12
159680 **
159681 ** The author disclaims copyright to this source code. In place of
@@ -155833,11 +160295,11 @@
160295 }
160296
160297 /*
160298 ** Invoke this routine to register the "dbstat" virtual table module
160299 */
160300 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){
160301 static sqlite3_module dbstat_module = {
160302 0, /* iVersion */
160303 statConnect, /* xCreate */
160304 statConnect, /* xConnect */
160305 statBestIndex, /* xBestIndex */
@@ -155858,8 +160320,10 @@
160320 0, /* xFindMethod */
160321 0, /* xRename */
160322 };
160323 return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
160324 }
160325 #elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
160326 SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
160327 #endif /* SQLITE_ENABLE_DBSTAT_VTAB */
160328
160329 /************** End of dbstat.c **********************************************/
160330
+49 -25
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -109,13 +109,13 @@
109109
**
110110
** See also: [sqlite3_libversion()],
111111
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
112112
** [sqlite_version()] and [sqlite_source_id()].
113113
*/
114
-#define SQLITE_VERSION "3.8.10.1"
115
-#define SQLITE_VERSION_NUMBER 3008010
116
-#define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40"
114
+#define SQLITE_VERSION "3.8.11"
115
+#define SQLITE_VERSION_NUMBER 3008011
116
+#define SQLITE_SOURCE_ID "2015-05-29 17:51:16 db4e9728fae5f7b0fad6aa0a5be317a7c9e7c417"
117117
118118
/*
119119
** CAPI3REF: Run-Time Library Version Numbers
120120
** KEYWORDS: sqlite3_version, sqlite3_sourceid
121121
**
@@ -954,17 +954,25 @@
954954
** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
955955
** opcode causes the xFileControl method to swap the file handle with the one
956956
** pointed to by the pArg argument. This capability is used during testing
957957
** and only needs to be supported when SQLITE_TEST is defined.
958958
**
959
-** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
959
+* <li>[[SQLITE_FCNTL_WAL_BLOCK]]
960960
** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
961961
** be advantageous to block on the next WAL lock if the lock is not immediately
962962
** available. The WAL subsystem issues this signal during rare
963963
** circumstances in order to fix a problem with priority inversion.
964964
** Applications should <em>not</em> use this file-control.
965965
**
966
+** <li>[[SQLITE_FCNTL_ZIPVFS]]
967
+** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
968
+** VFS should return SQLITE_NOTFOUND for this opcode.
969
+**
970
+** <li>[[SQLITE_FCNTL_OTA]]
971
+** The [SQLITE_FCNTL_OTA] opcode is implemented by the special VFS used by
972
+** the OTA extension only. All other VFS should return SQLITE_NOTFOUND for
973
+** this opcode.
966974
** </ul>
967975
*/
968976
#define SQLITE_FCNTL_LOCKSTATE 1
969977
#define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
970978
#define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -986,10 +994,12 @@
986994
#define SQLITE_FCNTL_HAS_MOVED 20
987995
#define SQLITE_FCNTL_SYNC 21
988996
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
989997
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
990998
#define SQLITE_FCNTL_WAL_BLOCK 24
999
+#define SQLITE_FCNTL_ZIPVFS 25
1000
+#define SQLITE_FCNTL_OTA 26
9911001
9921002
/* deprecated names */
9931003
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
9941004
#define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
9951005
#define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3388,11 +3398,13 @@
33883398
**
33893399
** An sqlite3_value object may be either "protected" or "unprotected".
33903400
** Some interfaces require a protected sqlite3_value. Other interfaces
33913401
** will accept either a protected or an unprotected sqlite3_value.
33923402
** Every interface that accepts sqlite3_value arguments specifies
3393
-** whether or not it requires a protected sqlite3_value.
3403
+** whether or not it requires a protected sqlite3_value. The
3404
+** [sqlite3_value_dup()] interface can be used to construct a new
3405
+** protected sqlite3_value from an unprotected sqlite3_value.
33943406
**
33953407
** The terms "protected" and "unprotected" refer to whether or not
33963408
** a mutex is held. An internal mutex is held for a protected
33973409
** sqlite3_value object but no mutex is held for an unprotected
33983410
** sqlite3_value object. If SQLite is compiled to be single-threaded
@@ -3891,12 +3903,10 @@
38913903
/*
38923904
** CAPI3REF: Result Values From A Query
38933905
** KEYWORDS: {column access functions}
38943906
** METHOD: sqlite3_stmt
38953907
**
3896
-** These routines form the "result set" interface.
3897
-**
38983908
** ^These routines return information about a single column of the current
38993909
** result row of a query. ^In every case the first argument is a pointer
39003910
** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
39013911
** that was returned from [sqlite3_prepare_v2()] or one of its variants)
39023912
** and the second argument is the index of the column for which information
@@ -3952,17 +3962,18 @@
39523962
**
39533963
** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
39543964
** even empty strings, are always zero-terminated. ^The return
39553965
** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
39563966
**
3957
-** ^The object returned by [sqlite3_column_value()] is an
3958
-** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
3959
-** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
3967
+** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
3968
+** [unprotected sqlite3_value] object. In a multithreaded environment,
3969
+** an unprotected sqlite3_value object may only be used safely with
3970
+** [sqlite3_bind_value()] and [sqlite3_result_value()].
39603971
** If the [unprotected sqlite3_value] object returned by
39613972
** [sqlite3_column_value()] is used in any other way, including calls
39623973
** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
3963
-** or [sqlite3_value_bytes()], then the behavior is undefined.
3974
+** or [sqlite3_value_bytes()], the behavior is not threadsafe.
39643975
**
39653976
** These routines attempt to convert the value where appropriate. ^For
39663977
** example, if the internal representation is FLOAT and a text result
39673978
** is requested, [sqlite3_snprintf()] is used internally to perform the
39683979
** conversion automatically. ^(The following table details the conversions
@@ -3989,16 +4000,10 @@
39894000
** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
39904001
** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
39914002
** </table>
39924003
** </blockquote>)^
39934004
**
3994
-** The table above makes reference to standard C library functions atoi()
3995
-** and atof(). SQLite does not really use these functions. It has its
3996
-** own equivalent internal routines. The atoi() and atof() names are
3997
-** used in the table for brevity and because they are familiar to most
3998
-** C programmers.
3999
-**
40004005
** Note that when type conversions occur, pointers returned by prior
40014006
** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
40024007
** sqlite3_column_text16() may be invalidated.
40034008
** Type conversions and pointer invalidations might occur
40044009
** in the following cases:
@@ -4019,11 +4024,11 @@
40194024
** not invalidate a prior pointer, though of course the content of the buffer
40204025
** that the prior pointer references will have been modified. Other kinds
40214026
** of conversion are done in place when it is possible, but sometimes they
40224027
** are not possible and in those cases prior pointers are invalidated.
40234028
**
4024
-** The safest and easiest to remember policy is to invoke these routines
4029
+** The safest policy is to invoke these routines
40254030
** in one of the following ways:
40264031
**
40274032
** <ul>
40284033
** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
40294034
** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
@@ -4039,11 +4044,11 @@
40394044
** with calls to sqlite3_column_bytes().
40404045
**
40414046
** ^The pointers returned are valid until a type conversion occurs as
40424047
** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
40434048
** [sqlite3_finalize()] is called. ^The memory space used to hold strings
4044
-** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
4049
+** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
40454050
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
40464051
** [sqlite3_free()].
40474052
**
40484053
** ^(If a memory allocation error occurs during the evaluation of any
40494054
** of these routines, a default value is returned. The default value
@@ -4289,16 +4294,16 @@
42894294
SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
42904295
void*,sqlite3_int64);
42914296
#endif
42924297
42934298
/*
4294
-** CAPI3REF: Obtaining SQL Function Parameter Values
4299
+** CAPI3REF: Obtaining SQL Values
42954300
** METHOD: sqlite3_value
42964301
**
42974302
** The C-language implementation of SQL functions and aggregates uses
42984303
** this set of interface routines to access the parameter values on
4299
-** the function or aggregate.
4304
+** the function or aggregate.
43004305
**
43014306
** The xFunc (for scalar functions) or xStep (for aggregates) parameters
43024307
** to [sqlite3_create_function()] and [sqlite3_create_function16()]
43034308
** define callbacks that implement the SQL functions and aggregates.
43044309
** The 3rd parameter to these callbacks is an array of pointers to
@@ -4347,10 +4352,27 @@
43474352
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
43484353
SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
43494354
SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
43504355
SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
43514356
4357
+/*
4358
+** CAPI3REF: Copy And Free SQL Values
4359
+** METHOD: sqlite3_value
4360
+**
4361
+** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
4362
+** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
4363
+** is a [protected sqlite3_value] object even if the input is not.
4364
+** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
4365
+** memory allocation fails.
4366
+**
4367
+** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
4368
+** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
4369
+** then sqlite3_value_free(V) is a harmless no-op.
4370
+*/
4371
+SQLITE_API SQLITE_EXPERIMENTAL sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
4372
+SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
4373
+
43524374
/*
43534375
** CAPI3REF: Obtain Aggregate Function Context
43544376
** METHOD: sqlite3_context
43554377
**
43564378
** Implementations of aggregate SQL functions use this
@@ -4594,11 +4616,11 @@
45944616
** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
45954617
** then SQLite makes a copy of the result into space obtained from
45964618
** from [sqlite3_malloc()] before it returns.
45974619
**
45984620
** ^The sqlite3_result_value() interface sets the result of
4599
-** the application-defined function to be a copy the
4621
+** the application-defined function to be a copy of the
46004622
** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
46014623
** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
46024624
** so that the [sqlite3_value] specified in the parameter may change or
46034625
** be deallocated after sqlite3_result_value() returns without harm.
46044626
** ^A [protected sqlite3_value] object may always be used where an
@@ -5870,11 +5892,11 @@
58705892
** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
58715893
** always returns zero.
58725894
**
58735895
** ^This function sets the database handle error code and message.
58745896
*/
5875
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
5897
+SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
58765898
58775899
/*
58785900
** CAPI3REF: Close A BLOB Handle
58795901
** DESTRUCTOR: sqlite3_blob
58805902
**
@@ -7680,11 +7702,11 @@
76807702
** as if the loop did not exist - it returns non-zero and leave the variable
76817703
** that pOut points to unchanged.
76827704
**
76837705
** See also: [sqlite3_stmt_scanstatus_reset()]
76847706
*/
7685
-SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
7707
+SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
76867708
sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
76877709
int idx, /* Index of loop to report on */
76887710
int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
76897711
void *pOut /* Result written here */
76907712
);
@@ -7696,11 +7718,11 @@
76967718
** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
76977719
**
76987720
** This API is only available if the library is built with pre-processor
76997721
** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
77007722
*/
7701
-SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
7723
+SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
77027724
77037725
77047726
/*
77057727
** Undo the hack that converts floating point types to integer for
77067728
** builds on processors without floating point support.
@@ -7811,10 +7833,12 @@
78117833
sqlite3_int64 iRowid; /* Rowid for current entry */
78127834
sqlite3_rtree_dbl rParentScore; /* Score of parent node */
78137835
int eParentWithin; /* Visibility of parent node */
78147836
int eWithin; /* OUT: Visiblity */
78157837
sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
7838
+ /* The following fields are only available in 3.8.11 and later */
7839
+ sqlite3_value **apSqlParam; /* Original SQL values of parameters */
78167840
};
78177841
78187842
/*
78197843
** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
78207844
*/
78217845
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -109,13 +109,13 @@
109 **
110 ** See also: [sqlite3_libversion()],
111 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
112 ** [sqlite_version()] and [sqlite_source_id()].
113 */
114 #define SQLITE_VERSION "3.8.10.1"
115 #define SQLITE_VERSION_NUMBER 3008010
116 #define SQLITE_SOURCE_ID "2015-05-09 12:14:55 05b4b1f2a937c06c90db70c09890038f6c98ec40"
117
118 /*
119 ** CAPI3REF: Run-Time Library Version Numbers
120 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
121 **
@@ -954,17 +954,25 @@
954 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
955 ** opcode causes the xFileControl method to swap the file handle with the one
956 ** pointed to by the pArg argument. This capability is used during testing
957 ** and only needs to be supported when SQLITE_TEST is defined.
958 **
959 ** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
960 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
961 ** be advantageous to block on the next WAL lock if the lock is not immediately
962 ** available. The WAL subsystem issues this signal during rare
963 ** circumstances in order to fix a problem with priority inversion.
964 ** Applications should <em>not</em> use this file-control.
965 **
 
 
 
 
 
 
 
 
966 ** </ul>
967 */
968 #define SQLITE_FCNTL_LOCKSTATE 1
969 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
970 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -986,10 +994,12 @@
986 #define SQLITE_FCNTL_HAS_MOVED 20
987 #define SQLITE_FCNTL_SYNC 21
988 #define SQLITE_FCNTL_COMMIT_PHASETWO 22
989 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23
990 #define SQLITE_FCNTL_WAL_BLOCK 24
 
 
991
992 /* deprecated names */
993 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
994 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
995 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3388,11 +3398,13 @@
3388 **
3389 ** An sqlite3_value object may be either "protected" or "unprotected".
3390 ** Some interfaces require a protected sqlite3_value. Other interfaces
3391 ** will accept either a protected or an unprotected sqlite3_value.
3392 ** Every interface that accepts sqlite3_value arguments specifies
3393 ** whether or not it requires a protected sqlite3_value.
 
 
3394 **
3395 ** The terms "protected" and "unprotected" refer to whether or not
3396 ** a mutex is held. An internal mutex is held for a protected
3397 ** sqlite3_value object but no mutex is held for an unprotected
3398 ** sqlite3_value object. If SQLite is compiled to be single-threaded
@@ -3891,12 +3903,10 @@
3891 /*
3892 ** CAPI3REF: Result Values From A Query
3893 ** KEYWORDS: {column access functions}
3894 ** METHOD: sqlite3_stmt
3895 **
3896 ** These routines form the "result set" interface.
3897 **
3898 ** ^These routines return information about a single column of the current
3899 ** result row of a query. ^In every case the first argument is a pointer
3900 ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
3901 ** that was returned from [sqlite3_prepare_v2()] or one of its variants)
3902 ** and the second argument is the index of the column for which information
@@ -3952,17 +3962,18 @@
3952 **
3953 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
3954 ** even empty strings, are always zero-terminated. ^The return
3955 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
3956 **
3957 ** ^The object returned by [sqlite3_column_value()] is an
3958 ** [unprotected sqlite3_value] object. An unprotected sqlite3_value object
3959 ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
 
3960 ** If the [unprotected sqlite3_value] object returned by
3961 ** [sqlite3_column_value()] is used in any other way, including calls
3962 ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
3963 ** or [sqlite3_value_bytes()], then the behavior is undefined.
3964 **
3965 ** These routines attempt to convert the value where appropriate. ^For
3966 ** example, if the internal representation is FLOAT and a text result
3967 ** is requested, [sqlite3_snprintf()] is used internally to perform the
3968 ** conversion automatically. ^(The following table details the conversions
@@ -3989,16 +4000,10 @@
3989 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
3990 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
3991 ** </table>
3992 ** </blockquote>)^
3993 **
3994 ** The table above makes reference to standard C library functions atoi()
3995 ** and atof(). SQLite does not really use these functions. It has its
3996 ** own equivalent internal routines. The atoi() and atof() names are
3997 ** used in the table for brevity and because they are familiar to most
3998 ** C programmers.
3999 **
4000 ** Note that when type conversions occur, pointers returned by prior
4001 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
4002 ** sqlite3_column_text16() may be invalidated.
4003 ** Type conversions and pointer invalidations might occur
4004 ** in the following cases:
@@ -4019,11 +4024,11 @@
4019 ** not invalidate a prior pointer, though of course the content of the buffer
4020 ** that the prior pointer references will have been modified. Other kinds
4021 ** of conversion are done in place when it is possible, but sometimes they
4022 ** are not possible and in those cases prior pointers are invalidated.
4023 **
4024 ** The safest and easiest to remember policy is to invoke these routines
4025 ** in one of the following ways:
4026 **
4027 ** <ul>
4028 ** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
4029 ** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
@@ -4039,11 +4044,11 @@
4039 ** with calls to sqlite3_column_bytes().
4040 **
4041 ** ^The pointers returned are valid until a type conversion occurs as
4042 ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
4043 ** [sqlite3_finalize()] is called. ^The memory space used to hold strings
4044 ** and BLOBs is freed automatically. Do <b>not</b> pass the pointers returned
4045 ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
4046 ** [sqlite3_free()].
4047 **
4048 ** ^(If a memory allocation error occurs during the evaluation of any
4049 ** of these routines, a default value is returned. The default value
@@ -4289,16 +4294,16 @@
4289 SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
4290 void*,sqlite3_int64);
4291 #endif
4292
4293 /*
4294 ** CAPI3REF: Obtaining SQL Function Parameter Values
4295 ** METHOD: sqlite3_value
4296 **
4297 ** The C-language implementation of SQL functions and aggregates uses
4298 ** this set of interface routines to access the parameter values on
4299 ** the function or aggregate.
4300 **
4301 ** The xFunc (for scalar functions) or xStep (for aggregates) parameters
4302 ** to [sqlite3_create_function()] and [sqlite3_create_function16()]
4303 ** define callbacks that implement the SQL functions and aggregates.
4304 ** The 3rd parameter to these callbacks is an array of pointers to
@@ -4347,10 +4352,27 @@
4347 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
4348 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
4349 SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
4350 SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
4351
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4352 /*
4353 ** CAPI3REF: Obtain Aggregate Function Context
4354 ** METHOD: sqlite3_context
4355 **
4356 ** Implementations of aggregate SQL functions use this
@@ -4594,11 +4616,11 @@
4594 ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
4595 ** then SQLite makes a copy of the result into space obtained from
4596 ** from [sqlite3_malloc()] before it returns.
4597 **
4598 ** ^The sqlite3_result_value() interface sets the result of
4599 ** the application-defined function to be a copy the
4600 ** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
4601 ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
4602 ** so that the [sqlite3_value] specified in the parameter may change or
4603 ** be deallocated after sqlite3_result_value() returns without harm.
4604 ** ^A [protected sqlite3_value] object may always be used where an
@@ -5870,11 +5892,11 @@
5870 ** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
5871 ** always returns zero.
5872 **
5873 ** ^This function sets the database handle error code and message.
5874 */
5875 SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
5876
5877 /*
5878 ** CAPI3REF: Close A BLOB Handle
5879 ** DESTRUCTOR: sqlite3_blob
5880 **
@@ -7680,11 +7702,11 @@
7680 ** as if the loop did not exist - it returns non-zero and leave the variable
7681 ** that pOut points to unchanged.
7682 **
7683 ** See also: [sqlite3_stmt_scanstatus_reset()]
7684 */
7685 SQLITE_API SQLITE_EXPERIMENTAL int SQLITE_STDCALL sqlite3_stmt_scanstatus(
7686 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
7687 int idx, /* Index of loop to report on */
7688 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
7689 void *pOut /* Result written here */
7690 );
@@ -7696,11 +7718,11 @@
7696 ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
7697 **
7698 ** This API is only available if the library is built with pre-processor
7699 ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
7700 */
7701 SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
7702
7703
7704 /*
7705 ** Undo the hack that converts floating point types to integer for
7706 ** builds on processors without floating point support.
@@ -7811,10 +7833,12 @@
7811 sqlite3_int64 iRowid; /* Rowid for current entry */
7812 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
7813 int eParentWithin; /* Visibility of parent node */
7814 int eWithin; /* OUT: Visiblity */
7815 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
 
 
7816 };
7817
7818 /*
7819 ** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
7820 */
7821
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -109,13 +109,13 @@
109 **
110 ** See also: [sqlite3_libversion()],
111 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
112 ** [sqlite_version()] and [sqlite_source_id()].
113 */
114 #define SQLITE_VERSION "3.8.11"
115 #define SQLITE_VERSION_NUMBER 3008011
116 #define SQLITE_SOURCE_ID "2015-05-29 17:51:16 db4e9728fae5f7b0fad6aa0a5be317a7c9e7c417"
117
118 /*
119 ** CAPI3REF: Run-Time Library Version Numbers
120 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
121 **
@@ -954,17 +954,25 @@
954 ** The [SQLITE_FCNTL_WIN32_SET_HANDLE] opcode is used for debugging. This
955 ** opcode causes the xFileControl method to swap the file handle with the one
956 ** pointed to by the pArg argument. This capability is used during testing
957 ** and only needs to be supported when SQLITE_TEST is defined.
958 **
959 * <li>[[SQLITE_FCNTL_WAL_BLOCK]]
960 ** The [SQLITE_FCNTL_WAL_BLOCK] is a signal to the VFS layer that it might
961 ** be advantageous to block on the next WAL lock if the lock is not immediately
962 ** available. The WAL subsystem issues this signal during rare
963 ** circumstances in order to fix a problem with priority inversion.
964 ** Applications should <em>not</em> use this file-control.
965 **
966 ** <li>[[SQLITE_FCNTL_ZIPVFS]]
967 ** The [SQLITE_FCNTL_ZIPVFS] opcode is implemented by zipvfs only. All other
968 ** VFS should return SQLITE_NOTFOUND for this opcode.
969 **
970 ** <li>[[SQLITE_FCNTL_OTA]]
971 ** The [SQLITE_FCNTL_OTA] opcode is implemented by the special VFS used by
972 ** the OTA extension only. All other VFS should return SQLITE_NOTFOUND for
973 ** this opcode.
974 ** </ul>
975 */
976 #define SQLITE_FCNTL_LOCKSTATE 1
977 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2
978 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3
@@ -986,10 +994,12 @@
994 #define SQLITE_FCNTL_HAS_MOVED 20
995 #define SQLITE_FCNTL_SYNC 21
996 #define SQLITE_FCNTL_COMMIT_PHASETWO 22
997 #define SQLITE_FCNTL_WIN32_SET_HANDLE 23
998 #define SQLITE_FCNTL_WAL_BLOCK 24
999 #define SQLITE_FCNTL_ZIPVFS 25
1000 #define SQLITE_FCNTL_OTA 26
1001
1002 /* deprecated names */
1003 #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
1004 #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE
1005 #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO
@@ -3388,11 +3398,13 @@
3398 **
3399 ** An sqlite3_value object may be either "protected" or "unprotected".
3400 ** Some interfaces require a protected sqlite3_value. Other interfaces
3401 ** will accept either a protected or an unprotected sqlite3_value.
3402 ** Every interface that accepts sqlite3_value arguments specifies
3403 ** whether or not it requires a protected sqlite3_value. The
3404 ** [sqlite3_value_dup()] interface can be used to construct a new
3405 ** protected sqlite3_value from an unprotected sqlite3_value.
3406 **
3407 ** The terms "protected" and "unprotected" refer to whether or not
3408 ** a mutex is held. An internal mutex is held for a protected
3409 ** sqlite3_value object but no mutex is held for an unprotected
3410 ** sqlite3_value object. If SQLite is compiled to be single-threaded
@@ -3891,12 +3903,10 @@
3903 /*
3904 ** CAPI3REF: Result Values From A Query
3905 ** KEYWORDS: {column access functions}
3906 ** METHOD: sqlite3_stmt
3907 **
 
 
3908 ** ^These routines return information about a single column of the current
3909 ** result row of a query. ^In every case the first argument is a pointer
3910 ** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*]
3911 ** that was returned from [sqlite3_prepare_v2()] or one of its variants)
3912 ** and the second argument is the index of the column for which information
@@ -3952,17 +3962,18 @@
3962 **
3963 ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
3964 ** even empty strings, are always zero-terminated. ^The return
3965 ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
3966 **
3967 ** <b>Warning:</b> ^The object returned by [sqlite3_column_value()] is an
3968 ** [unprotected sqlite3_value] object. In a multithreaded environment,
3969 ** an unprotected sqlite3_value object may only be used safely with
3970 ** [sqlite3_bind_value()] and [sqlite3_result_value()].
3971 ** If the [unprotected sqlite3_value] object returned by
3972 ** [sqlite3_column_value()] is used in any other way, including calls
3973 ** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
3974 ** or [sqlite3_value_bytes()], the behavior is not threadsafe.
3975 **
3976 ** These routines attempt to convert the value where appropriate. ^For
3977 ** example, if the internal representation is FLOAT and a text result
3978 ** is requested, [sqlite3_snprintf()] is used internally to perform the
3979 ** conversion automatically. ^(The following table details the conversions
@@ -3989,16 +4000,10 @@
4000 ** <tr><td> BLOB <td> FLOAT <td> [CAST] to REAL
4001 ** <tr><td> BLOB <td> TEXT <td> Add a zero terminator if needed
4002 ** </table>
4003 ** </blockquote>)^
4004 **
 
 
 
 
 
 
4005 ** Note that when type conversions occur, pointers returned by prior
4006 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
4007 ** sqlite3_column_text16() may be invalidated.
4008 ** Type conversions and pointer invalidations might occur
4009 ** in the following cases:
@@ -4019,11 +4024,11 @@
4024 ** not invalidate a prior pointer, though of course the content of the buffer
4025 ** that the prior pointer references will have been modified. Other kinds
4026 ** of conversion are done in place when it is possible, but sometimes they
4027 ** are not possible and in those cases prior pointers are invalidated.
4028 **
4029 ** The safest policy is to invoke these routines
4030 ** in one of the following ways:
4031 **
4032 ** <ul>
4033 ** <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
4034 ** <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
@@ -4039,11 +4044,11 @@
4044 ** with calls to sqlite3_column_bytes().
4045 **
4046 ** ^The pointers returned are valid until a type conversion occurs as
4047 ** described above, or until [sqlite3_step()] or [sqlite3_reset()] or
4048 ** [sqlite3_finalize()] is called. ^The memory space used to hold strings
4049 ** and BLOBs is freed automatically. Do <em>not</em> pass the pointers returned
4050 ** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
4051 ** [sqlite3_free()].
4052 **
4053 ** ^(If a memory allocation error occurs during the evaluation of any
4054 ** of these routines, a default value is returned. The default value
@@ -4289,16 +4294,16 @@
4294 SQLITE_API SQLITE_DEPRECATED int SQLITE_STDCALL sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),
4295 void*,sqlite3_int64);
4296 #endif
4297
4298 /*
4299 ** CAPI3REF: Obtaining SQL Values
4300 ** METHOD: sqlite3_value
4301 **
4302 ** The C-language implementation of SQL functions and aggregates uses
4303 ** this set of interface routines to access the parameter values on
4304 ** the function or aggregate.
4305 **
4306 ** The xFunc (for scalar functions) or xStep (for aggregates) parameters
4307 ** to [sqlite3_create_function()] and [sqlite3_create_function16()]
4308 ** define callbacks that implement the SQL functions and aggregates.
4309 ** The 3rd parameter to these callbacks is an array of pointers to
@@ -4347,10 +4352,27 @@
4352 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16le(sqlite3_value*);
4353 SQLITE_API const void *SQLITE_STDCALL sqlite3_value_text16be(sqlite3_value*);
4354 SQLITE_API int SQLITE_STDCALL sqlite3_value_type(sqlite3_value*);
4355 SQLITE_API int SQLITE_STDCALL sqlite3_value_numeric_type(sqlite3_value*);
4356
4357 /*
4358 ** CAPI3REF: Copy And Free SQL Values
4359 ** METHOD: sqlite3_value
4360 **
4361 ** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value]
4362 ** object D and returns a pointer to that copy. ^The [sqlite3_value] returned
4363 ** is a [protected sqlite3_value] object even if the input is not.
4364 ** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
4365 ** memory allocation fails.
4366 **
4367 ** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object
4368 ** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer
4369 ** then sqlite3_value_free(V) is a harmless no-op.
4370 */
4371 SQLITE_API SQLITE_EXPERIMENTAL sqlite3_value *SQLITE_STDCALL sqlite3_value_dup(const sqlite3_value*);
4372 SQLITE_API SQLITE_EXPERIMENTAL void SQLITE_STDCALL sqlite3_value_free(sqlite3_value*);
4373
4374 /*
4375 ** CAPI3REF: Obtain Aggregate Function Context
4376 ** METHOD: sqlite3_context
4377 **
4378 ** Implementations of aggregate SQL functions use this
@@ -4594,11 +4616,11 @@
4616 ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT
4617 ** then SQLite makes a copy of the result into space obtained from
4618 ** from [sqlite3_malloc()] before it returns.
4619 **
4620 ** ^The sqlite3_result_value() interface sets the result of
4621 ** the application-defined function to be a copy of the
4622 ** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The
4623 ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
4624 ** so that the [sqlite3_value] specified in the parameter may change or
4625 ** be deallocated after sqlite3_result_value() returns without harm.
4626 ** ^A [protected sqlite3_value] object may always be used where an
@@ -5870,11 +5892,11 @@
5892 ** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle
5893 ** always returns zero.
5894 **
5895 ** ^This function sets the database handle error code and message.
5896 */
5897 SQLITE_API int SQLITE_STDCALL sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64);
5898
5899 /*
5900 ** CAPI3REF: Close A BLOB Handle
5901 ** DESTRUCTOR: sqlite3_blob
5902 **
@@ -7680,11 +7702,11 @@
7702 ** as if the loop did not exist - it returns non-zero and leave the variable
7703 ** that pOut points to unchanged.
7704 **
7705 ** See also: [sqlite3_stmt_scanstatus_reset()]
7706 */
7707 SQLITE_API int SQLITE_STDCALL sqlite3_stmt_scanstatus(
7708 sqlite3_stmt *pStmt, /* Prepared statement for which info desired */
7709 int idx, /* Index of loop to report on */
7710 int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */
7711 void *pOut /* Result written here */
7712 );
@@ -7696,11 +7718,11 @@
7718 ** ^Zero all [sqlite3_stmt_scanstatus()] related event counters.
7719 **
7720 ** This API is only available if the library is built with pre-processor
7721 ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined.
7722 */
7723 SQLITE_API void SQLITE_STDCALL sqlite3_stmt_scanstatus_reset(sqlite3_stmt*);
7724
7725
7726 /*
7727 ** Undo the hack that converts floating point types to integer for
7728 ** builds on processors without floating point support.
@@ -7811,10 +7833,12 @@
7833 sqlite3_int64 iRowid; /* Rowid for current entry */
7834 sqlite3_rtree_dbl rParentScore; /* Score of parent node */
7835 int eParentWithin; /* Visibility of parent node */
7836 int eWithin; /* OUT: Visiblity */
7837 sqlite3_rtree_dbl rScore; /* OUT: Write the score here */
7838 /* The following fields are only available in 3.8.11 and later */
7839 sqlite3_value **apSqlParam; /* Original SQL values of parameters */
7840 };
7841
7842 /*
7843 ** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin.
7844 */
7845
+1 -1
--- src/stash.c
+++ src/stash.c
@@ -58,11 +58,11 @@
5858
Blob sql; /* Query statement text */
5959
Stmt q; /* Query against the vfile table */
6060
Stmt ins; /* Insert statement */
6161
6262
zFile = mprintf("%/", zFName);
63
- file_tree_name(zFile, &fname, 1);
63
+ file_tree_name(zFile, &fname, 0, 1);
6464
zTreename = blob_str(&fname);
6565
blob_zero(&sql);
6666
blob_append_sql(&sql,
6767
"SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
6868
" FROM vfile"
6969
--- src/stash.c
+++ src/stash.c
@@ -58,11 +58,11 @@
58 Blob sql; /* Query statement text */
59 Stmt q; /* Query against the vfile table */
60 Stmt ins; /* Insert statement */
61
62 zFile = mprintf("%/", zFName);
63 file_tree_name(zFile, &fname, 1);
64 zTreename = blob_str(&fname);
65 blob_zero(&sql);
66 blob_append_sql(&sql,
67 "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
68 " FROM vfile"
69
--- src/stash.c
+++ src/stash.c
@@ -58,11 +58,11 @@
58 Blob sql; /* Query statement text */
59 Stmt q; /* Query against the vfile table */
60 Stmt ins; /* Insert statement */
61
62 zFile = mprintf("%/", zFName);
63 file_tree_name(zFile, &fname, 0, 1);
64 zTreename = blob_str(&fname);
65 blob_zero(&sql);
66 blob_append_sql(&sql,
67 "SELECT deleted, isexe, islink, mrid, pathname, coalesce(origname,pathname)"
68 " FROM vfile"
69
+2 -2
--- src/stat.c
+++ src/stat.c
@@ -392,11 +392,11 @@
392392
style_adunit_config(ADUNIT_RIGHT_OK);
393393
style_submenu_element("Stat", "Repository Stats", "stat");
394394
db_multi_exec(
395395
"CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
396396
"CREATE TEMP TABLE trans(name TEXT PRIMARY KEY, tabname TEXT)WITHOUT ROWID;"
397
- "INSERT INTO trans(name,tabname)"
397
+ "INSERT INTO trans(name,tabname)"
398398
" SELECT name, tbl_name FROM %s.sqlite_master;"
399399
"CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
400400
"INSERT INTO piechart(amt,label)"
401401
" SELECT count(*), "
402402
" coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
@@ -421,11 +421,11 @@
421421
if( g.localOpen ){
422422
db_multi_exec(
423423
"DROP TABLE temp.dbx;"
424424
"CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
425425
"DELETE FROM trans;"
426
- "INSERT INTO trans(name,tabname)"
426
+ "INSERT INTO trans(name,tabname)"
427427
" SELECT name, tbl_name FROM %s.sqlite_master;"
428428
"DELETE FROM piechart;"
429429
"INSERT INTO piechart(amt,label)"
430430
" SELECT count(*), "
431431
" coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
432432
--- src/stat.c
+++ src/stat.c
@@ -392,11 +392,11 @@
392 style_adunit_config(ADUNIT_RIGHT_OK);
393 style_submenu_element("Stat", "Repository Stats", "stat");
394 db_multi_exec(
395 "CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
396 "CREATE TEMP TABLE trans(name TEXT PRIMARY KEY, tabname TEXT)WITHOUT ROWID;"
397 "INSERT INTO trans(name,tabname)"
398 " SELECT name, tbl_name FROM %s.sqlite_master;"
399 "CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
400 "INSERT INTO piechart(amt,label)"
401 " SELECT count(*), "
402 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
@@ -421,11 +421,11 @@
421 if( g.localOpen ){
422 db_multi_exec(
423 "DROP TABLE temp.dbx;"
424 "CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
425 "DELETE FROM trans;"
426 "INSERT INTO trans(name,tabname)"
427 " SELECT name, tbl_name FROM %s.sqlite_master;"
428 "DELETE FROM piechart;"
429 "INSERT INTO piechart(amt,label)"
430 " SELECT count(*), "
431 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
432
--- src/stat.c
+++ src/stat.c
@@ -392,11 +392,11 @@
392 style_adunit_config(ADUNIT_RIGHT_OK);
393 style_submenu_element("Stat", "Repository Stats", "stat");
394 db_multi_exec(
395 "CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
396 "CREATE TEMP TABLE trans(name TEXT PRIMARY KEY, tabname TEXT)WITHOUT ROWID;"
397 "INSERT INTO trans(name,tabname)"
398 " SELECT name, tbl_name FROM %s.sqlite_master;"
399 "CREATE TEMP TABLE piechart(amt REAL, label TEXT);"
400 "INSERT INTO piechart(amt,label)"
401 " SELECT count(*), "
402 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
@@ -421,11 +421,11 @@
421 if( g.localOpen ){
422 db_multi_exec(
423 "DROP TABLE temp.dbx;"
424 "CREATE VIRTUAL TABLE temp.dbx USING dbstat(%s);"
425 "DELETE FROM trans;"
426 "INSERT INTO trans(name,tabname)"
427 " SELECT name, tbl_name FROM %s.sqlite_master;"
428 "DELETE FROM piechart;"
429 "INSERT INTO piechart(amt,label)"
430 " SELECT count(*), "
431 " coalesce((SELECT tabname FROM trans WHERE trans.name=dbx.name),name)"
432
+247 -283
--- src/statrep.c
+++ src/statrep.c
@@ -36,24 +36,10 @@
3636
** accepted by /timeline?y=XXXX.
3737
*/
3838
static const char *statsReportTimelineYFlag = NULL;
3939
4040
41
-/*
42
-** Generate a submenu element with a single parameter change.
43
-*/
44
-static void statrep_submenu(
45
- HQuery *pUrl, /* Base URL */
46
- const char *zMenuName, /* Submenu name */
47
- const char *zParam, /* Parameter value to add or change */
48
- const char *zValue, /* Value of the new parameter */
49
- const char *zRemove /* Parameter to omit */
50
-){
51
- style_submenu_element(zMenuName, zMenuName, "%s",
52
- url_render(pUrl, zParam, zValue, zRemove, 0));
53
-}
54
-
5541
/*
5642
** Creates a TEMP VIEW named v_reports which is a wrapper around the
5743
** EVENT table filtered on event.type. It looks for the request
5844
** parameter 'type' (reminder: we "should" use 'y' for consistency
5945
** with /timeline, but /reports uses 'y' for the year) and expects it
@@ -141,63 +127,10 @@
141127
default:
142128
return "all types";
143129
}
144130
}
145131
146
-/*
147
-** A helper for the /reports family of pages which prints out a menu
148
-** of links for the various type=XXX flags. zCurrentViewName must be
149
-** the name/value of the 'view' parameter which is in effect at the
150
-** time this is called. e.g. if called from the 'byuser' view then
151
-** zCurrentViewName must be "byuser". Any URL parameters which need to
152
-** be added to the generated URLs should be passed in zParam. The
153
-** caller is expected to have already encoded any zParam in the %T or
154
-** %t encoding. */
155
-static void stats_report_event_types_menu(const char *zCurrentViewName,
156
- const char *zParam){
157
- char *zTop;
158
- if(zParam && !*zParam){
159
- zParam = NULL;
160
- }
161
- zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName,
162
- zParam ? "&" : "", zParam);
163
- cgi_printf("<div>");
164
- cgi_printf("<span>Types:</span> ");
165
- if('*' == statsReportType){
166
- cgi_printf(" <strong>all</strong>", zTop);
167
- }else{
168
- cgi_printf(" <a href='%s'>all</a>", zTop);
169
- }
170
- if('c' == statsReportType){
171
- cgi_printf(" <strong>check-ins</strong>", zTop);
172
- }else{
173
- cgi_printf(" <a href='%s&type=ci'>check-ins</a>", zTop);
174
- }
175
- if('e' == statsReportType){
176
- cgi_printf(" <strong>technotes</strong>", zTop);
177
- }else{
178
- cgi_printf(" <a href='%s&type=e'>technotes</a>", zTop);
179
- }
180
- if( 't' == statsReportType ){
181
- cgi_printf(" <strong>tickets</strong>", zTop);
182
- }else{
183
- cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop);
184
- }
185
- if( 'g' == statsReportType ){
186
- cgi_printf(" <strong>tags</strong>", zTop);
187
- }else{
188
- cgi_printf(" <a href='%s&type=g'>tags</a>", zTop);
189
- }
190
- if( 'w' == statsReportType ){
191
- cgi_printf(" <strong>wiki</strong>", zTop);
192
- }else{
193
- cgi_printf(" <a href='%s&type=w'>wiki</a>", zTop);
194
- }
195
- fossil_free(zTop);
196
- cgi_printf("</div>");
197
-}
198
-
199132
200133
/*
201134
** Helper for stats_report_by_month_year(), which generates a list of
202135
** week numbers. zTimeframe should be either a timeframe in the form YYYY
203136
** or YYYY-MM.
@@ -227,64 +160,59 @@
227160
}
228161
229162
/*
230163
** Implements the "byyear" and "bymonth" reports for /reports.
231164
** If includeMonth is true then it generates the "bymonth" report,
232
-** else the "byyear" report. If zUserName is not NULL and not empty
233
-** then the report is restricted to events created by the named user
234
-** account.
165
+** else the "byyear" report. If zUserName is not NULL then the report is
166
+** restricted to events created by the named user account.
235167
*/
236168
static void stats_report_by_month_year(char includeMonth,
237169
char includeWeeks,
238170
const char *zUserName){
239171
Stmt query = empty_Stmt;
240172
int nRowNumber = 0; /* current TR number */
241173
int nEventTotal = 0; /* Total event count */
242174
int rowClass = 0; /* counter for alternating
243175
row colors */
244
- Blob sql = empty_blob; /* SQL */
245176
const char *zTimeLabel = includeMonth ? "Year/Month" : "Year";
246177
char zPrevYear[5] = {0}; /* For keeping track of when
247178
we change years while looping */
248179
int nEventsPerYear = 0; /* Total event count for the
249180
current year */
250181
char showYearTotal = 0; /* Flag telling us when to show
251182
the per-year event totals */
252
- Blob header = empty_blob; /* Page header text */
253183
int nMaxEvents = 1; /* for calculating length of graph
254184
bars. */
255185
int iterations = 0; /* number of weeks/months we iterate
256186
over */
187
+ Blob userFilter = empty_blob; /* Optional user=johndoe query string */
257188
stats_report_init_view();
258
- stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
259
- blob_appendf(&header, "Timeline Events (%s) by year%s",
260
- stats_report_label_for_type(),
261
- (includeMonth ? "/month" : ""));
262
- blob_append_sql(&sql,
263
- "SELECT substr(date(mtime),1,%d) AS timeframe, "
264
- "count(*) AS eventCount "
265
- "FROM v_reports ",
266
- includeMonth ? 7 : 4);
267
- if(zUserName&&*zUserName){
268
- blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
269
- blob_appendf(&header," for user %q", zUserName);
270
- }
271
- blob_append(&sql,
272
- " GROUP BY timeframe"
273
- " ORDER BY timeframe DESC",
274
- -1);
275
- db_prepare(&query, "%s", blob_sql_text(&sql));
276
- blob_reset(&sql);
277
- @ <h1>%b(&header)</h1>
189
+ if( zUserName ){
190
+ blob_appendf(&userFilter, "user=%s", zUserName);
191
+ }
192
+ blob_reset(&userFilter);
193
+ db_prepare(&query,
194
+ "SELECT substr(date(mtime),1,%d) AS timeframe,"
195
+ " count(*) AS eventCount"
196
+ " FROM v_reports"
197
+ " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
198
+ " GROUP BY timeframe"
199
+ " ORDER BY timeframe DESC",
200
+ includeMonth ? 7 : 4, zUserName);
201
+ @ <h1>Timeline Events (%s(stats_report_label_for_type()))
202
+ @ by year%s(includeMonth ? "/month" : "")
203
+ if( zUserName ){
204
+ @ for user %h(zUserName)
205
+ }
206
+ @ </h1>
278207
@ <table class='statistics-report-table-events' border='0' cellpadding='2'
279208
@ cellspacing='0' id='statsTable'>
280209
@ <thead>
281210
@ <th>%s(zTimeLabel)</th>
282211
@ <th>Events</th>
283212
@ <th width='90%%'><!-- relative commits graph --></th>
284213
@ </thead><tbody>
285
- blob_reset(&header);
286214
/*
287215
Run the query twice. The first time we calculate the maximum
288216
number of events for a given row. Maybe someone with better SQL
289217
Fu can re-implement this with a single query.
290218
*/
@@ -335,18 +263,18 @@
335263
zTimeframe, nCount,
336264
statsReportTimelineYFlag );
337265
/* Reminder: n=nCount is not actually correct for bymonth unless
338266
that was the only user who caused events.
339267
*/
340
- if( zUserName && *zUserName ){
268
+ if( zUserName ){
341269
cgi_printf("&u=%t", zUserName);
342270
}
343271
cgi_printf("' target='_new'>%s</a>",zTimeframe);
344272
}else {
345273
cgi_printf("<a href='?view=byweek&y=%s&type=%c",
346274
zTimeframe, (char)statsReportType);
347
- if(zUserName && *zUserName){
275
+ if( zUserName ){
348276
cgi_printf("&u=%t", zUserName);
349277
}
350278
cgi_printf("'>%s</a>", zTimeframe);
351279
}
352280
@ </td><td>%d(nCount)</td>
@@ -403,17 +331,16 @@
403331
int rowClass = 0; /* counter for alternating
404332
row colors */
405333
int nMaxEvents = 1; /* max number of events for
406334
all rows. */
407335
stats_report_init_view();
408
- stats_report_event_types_menu("byuser", NULL);
409336
@ <h1>Timeline Events
410337
@ (%s(stats_report_label_for_type())) by User</h1>
411338
db_multi_exec(
412339
"CREATE TEMP TABLE piechart(amt,label);"
413
- "INSERT INTO piechart SELECT count(*), user FROM v_reports"
414
- " GROUP BY user ORDER BY count(*) DESC;"
340
+ "INSERT INTO piechart SELECT count(*), ifnull(euser,user) FROM v_reports"
341
+ " GROUP BY ifnull(euser,user) ORDER BY count(*) DESC;"
415342
);
416343
if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
417344
@ <center><svg width=700 height=400>
418345
piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
419346
@ </svg></centre><hr/>
@@ -424,14 +351,14 @@
424351
@ <th>User</th>
425352
@ <th>Events</th>
426353
@ <th width='90%%'><!-- relative commits graph --></th>
427354
@ </tr></thead><tbody>
428355
db_prepare(&query,
429
- "SELECT user, "
356
+ "SELECT ifnull(euser,user), "
430357
"COUNT(*) AS eventCount "
431358
"FROM v_reports "
432
- "GROUP BY user ORDER BY eventCount DESC");
359
+ "GROUP BY ifnull(euser,user) ORDER BY eventCount DESC");
433360
while( SQLITE_ROW == db_step(&query) ){
434361
const int nCount = db_column_int(&query, 1);
435362
if(nCount>nMaxEvents){
436363
nMaxEvents = nCount;
437364
}
@@ -438,20 +365,21 @@
438365
}
439366
db_reset(&query);
440367
while( SQLITE_ROW == db_step(&query) ){
441368
const char *zUser = db_column_text(&query, 0);
442369
const int nCount = db_column_int(&query, 1);
370
+ char y = (char)statsReportType;
443371
int nSize = nCount
444372
? (int)(100 * nCount / nMaxEvents)
445373
: 0;
446374
if(!nCount) continue /* arguable! Possible? */;
447375
else if(!nSize) nSize = 1;
448376
rowClass = ++nRowNumber % 2;
449377
nEventTotal += nCount;
450
- @<tr class='row%d(rowClass)'>
378
+ @ <tr class='row%d(rowClass)'>
451379
@ <td>
452
- @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
380
+ @ <a href="?view=bymonth&user=%h(zUser)&type=%c(y)">%h(zUser)</a>
453381
@ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td>
454382
@ <td>
455383
@ <div class='statistics-report-graph-line'
456384
@ style='width:%d(nSize)%%;'>&nbsp;</div>
457385
@ </td>
@@ -465,30 +393,37 @@
465393
db_finalize(&query);
466394
output_table_sorting_javascript("statsTable","tkx",2);
467395
}
468396
469397
/*
470
-** Implements the "byfile" view for /reports.
398
+** Implements the "byfile" view for /reports. If zUserName is not NULL then the
399
+** report is restricted to events created by the named user account.
471400
*/
472
-static void stats_report_by_file(){
401
+static void stats_report_by_file(const char *zUserName){
473402
Stmt query;
474403
int mxEvent = 1; /* max number of events across all rows */
475404
int nRowNumber = 0;
476405
477406
db_multi_exec(
478407
"CREATE TEMP TABLE statrep(filename, cnt);"
479408
"INSERT INTO statrep(filename, cnt)"
480409
" SELECT filename.name, count(distinct mlink.mid)"
481
- " FROM filename, mlink"
410
+ " FROM filename, mlink, event"
482411
" WHERE filename.fnid=mlink.fnid"
483
- " GROUP BY 1;"
412
+ " AND mlink.mid=event.objid"
413
+ " AND ifnull(coalesce(euser,user,'')=%Q,1)"
414
+ " GROUP BY 1", zUserName
484415
);
485416
db_prepare(&query,
486417
"SELECT filename, cnt FROM statrep ORDER BY cnt DESC, filename /*sort*/"
487418
);
488419
mxEvent = db_int(1, "SELECT max(cnt) FROM statrep");
489
- @ <h1>Check-ins Per File</h1>
420
+ @ <h1>Check-ins Per File
421
+ if( zUserName ){
422
+ @ for user %h(zUserName)
423
+ }
424
+ @ </h1>
490425
@ <table class='statistics-report-table-events' border='0'
491426
@ cellpadding='2' cellspacing='0' id='statsTable'>
492427
@ <thead><tr>
493428
@ <th>File</th>
494429
@ <th>Check-ins</th>
@@ -514,41 +449,56 @@
514449
db_finalize(&query);
515450
output_table_sorting_javascript("statsTable","tNx",2);
516451
}
517452
518453
/*
519
-** Implements the "byweekday" view for /reports.
454
+** Implements the "byweekday" view for /reports. If zUserName is not NULL then
455
+** the report is restricted to events created by the named user account.
520456
*/
521
-static void stats_report_day_of_week(){
457
+static void stats_report_day_of_week(const char *zUserName){
522458
Stmt query = empty_Stmt;
523459
int nRowNumber = 0; /* current TR number */
524460
int nEventTotal = 0; /* Total event count */
525461
int rowClass = 0; /* counter for alternating
526462
row colors */
527463
int nMaxEvents = 1; /* max number of events for
528464
all rows. */
465
+ Blob userFilter = empty_blob; /* Optional user=johndoe query string */
529466
static const char *const daysOfWeek[] = {
530467
"Monday", "Tuesday", "Wednesday", "Thursday",
531468
"Friday", "Saturday", "Sunday"
532469
};
533470
534471
stats_report_init_view();
535
- stats_report_event_types_menu("byweekday", NULL);
472
+ if( zUserName ){
473
+ blob_appendf(&userFilter, "user=%s", zUserName);
474
+ }
536475
db_prepare(&query,
537
- "SELECT cast(mtime %% 7 AS INTEGER) dow, "
538
- "COUNT(*) AS eventCount "
539
- "FROM v_reports "
540
- "GROUP BY dow ORDER BY dow");
541
- @ <h1>Timeline Events
542
- @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
476
+ "SELECT cast(mtime %% 7 AS INTEGER) dow,"
477
+ " COUNT(*) AS eventCount"
478
+ " FROM v_reports"
479
+ " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
480
+ " GROUP BY dow ORDER BY dow", zUserName);
481
+ @ <h1>Timeline Events (%h(stats_report_label_for_type())) by Day of the Week
482
+ if( zUserName ){
483
+ @ for user %h(zUserName)
484
+ }
485
+ @ </h1>
543486
db_multi_exec(
544487
"CREATE TEMP TABLE piechart(amt,label);"
545
- "INSERT INTO piechart SELECT count(*), cast(mtime %% 7 AS INT) FROM v_reports"
546
- " GROUP BY 2 ORDER BY 2;"
547
- "UPDATE piechart SET label = CASE label WHEN 0 THEN 'Monday' WHEN 1 THEN 'Tuesday'"
548
- " WHEN 2 THEN 'Wednesday' WHEN 3 THEN 'Thursday' WHEN 4 THEN 'Friday'"
549
- " WHEN 5 THEN 'Saturday' ELSE 'Sunday' END;"
488
+ "INSERT INTO piechart"
489
+ " SELECT count(*), cast(mtime %% 7 AS INT) FROM v_reports"
490
+ " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
491
+ " GROUP BY 2 ORDER BY 2;"
492
+ "UPDATE piechart SET label = CASE label"
493
+ " WHEN 0 THEN 'Monday'"
494
+ " WHEN 1 THEN 'Tuesday'"
495
+ " WHEN 2 THEN 'Wednesday'"
496
+ " WHEN 3 THEN 'Thursday'"
497
+ " WHEN 4 THEN 'Friday'"
498
+ " WHEN 5 THEN 'Saturday'"
499
+ " ELSE 'Sunday' END;", zUserName
550500
);
551501
if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
552502
@ <center><svg width=700 height=400>
553503
piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
554504
@ </svg></centre><hr/>
@@ -595,139 +545,110 @@
595545
596546
597547
/*
598548
** Helper for stats_report_by_month_year(), which generates a list of
599549
** week numbers. zTimeframe should be either a timeframe in the form YYYY
600
-** or YYYY-MM.
550
+** or YYYY-MM. If zUserName is not NULL then the report is restricted to events
551
+** created by the named user account.
601552
*/
602553
static void stats_report_year_weeks(const char *zUserName){
603
- const char *zYear = P("y");
604
- int nYear = zYear ? strlen(zYear) : 0;
605
- int i = 0;
606
- Stmt qYears = empty_Stmt;
607
- char *zDefaultYear = NULL;
608
- Blob sql = empty_blob;
554
+ const char *zYear = P("y"); /* Year for which report shown */
555
+ Stmt q;
609556
int nMaxEvents = 1; /* max number of events for
610557
all rows. */
611558
int iterations = 0; /* # of active time periods. */
612
- stats_report_init_view();
613
- if(4==nYear){
614
- Blob urlParams = empty_blob;
615
- blob_appendf(&urlParams, "y=%T", zYear);
616
- stats_report_event_types_menu("byweek", blob_str(&urlParams));
617
- blob_reset(&urlParams);
618
- }else{
619
- stats_report_event_types_menu("byweek", NULL);
620
- }
621
- blob_append(&sql,
622
- "SELECT DISTINCT substr(date(mtime),1,4) AS y "
623
- "FROM v_reports WHERE 1 ", -1);
624
- if(zUserName&&*zUserName){
625
- blob_append_sql(&sql,"AND user=%Q ", zUserName);
626
- }
627
- blob_append(&sql,"GROUP BY y ORDER BY y", -1);
628
- db_prepare(&qYears, "%s", blob_sql_text(&sql));
629
- blob_reset(&sql);
630
- cgi_printf("Select year: ");
631
- while( SQLITE_ROW == db_step(&qYears) ){
632
- const char *zT = db_column_text(&qYears, 0);
633
- if( i++ ){
634
- cgi_printf(" ");
635
- }
636
- cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT,
637
- (char)statsReportType);
638
- if(zUserName && *zUserName){
639
- cgi_printf("&user=%t",zUserName);
640
- }
641
- cgi_printf("'>%s</a>",zT);
642
- }
643
- db_finalize(&qYears);
644
- cgi_printf("<br/>");
645
- if(!zYear || !*zYear){
646
- zDefaultYear = db_text("????", "SELECT strftime('%%Y')");
647
- zYear = zDefaultYear;
648
- nYear = 4;
649
- }
650
- if(4 == nYear){
651
- Stmt stWeek = empty_Stmt;
652
- int rowCount = 0;
653
- int total = 0;
654
- Blob header = empty_blob;
655
- blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
656
- "of %h", stats_report_label_for_type(),
657
- zYear);
658
- blob_append_sql(&sql,
659
- "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
660
- "count(*) AS n "
661
- "FROM v_reports "
662
- "WHERE %Q=substr(date(mtime),1,4) "
663
- "AND mtime < current_timestamp ",
664
- zYear);
665
- if(zUserName&&*zUserName){
666
- blob_append_sql(&sql, " AND user=%Q ", zUserName);
667
- blob_appendf(&header," for user %h", zUserName);
668
- }
669
- blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
670
- cgi_printf("<h1>%h</h1>", blob_str(&header));
671
- blob_reset(&header);
672
- cgi_printf("<table class='statistics-report-table-events' "
673
- "border='0' cellpadding='2' width='100%%' "
674
- "cellspacing='0' id='statsTable'>");
675
- cgi_printf("<thead><tr>"
676
- "<th>Week</th>"
677
- "<th>Events</th>"
678
- "<th width='90%%'><!-- relative commits graph --></th>"
679
- "</tr></thead>"
680
- "<tbody>");
681
- db_prepare(&stWeek, "%s", blob_sql_text(&sql));
682
- blob_reset(&sql);
683
- while( SQLITE_ROW == db_step(&stWeek) ){
684
- const int nCount = db_column_int(&stWeek, 1);
685
- if(nCount>nMaxEvents){
686
- nMaxEvents = nCount;
687
- }
688
- ++iterations;
689
- }
690
- db_reset(&stWeek);
691
- while( SQLITE_ROW == db_step(&stWeek) ){
692
- const char *zWeek = db_column_text(&stWeek,0);
693
- const int nCount = db_column_int(&stWeek,1);
694
- int nSize = nCount
695
- ? (int)(100 * nCount / nMaxEvents)
696
- : 0;
697
- if(!nSize) nSize = 1;
698
- total += nCount;
699
- cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
700
- cgi_printf("<td><a href='%R/timeline?yw=%t-%s&n=%d&y=%s",
701
- zYear, zWeek, nCount,
702
- statsReportTimelineYFlag);
703
- if(zUserName && *zUserName){
704
- cgi_printf("&u=%t",zUserName);
705
- }
706
- cgi_printf("'>%s</a></td>",zWeek);
707
-
708
- cgi_printf("<td>%d</td>",nCount);
709
- cgi_printf("<td>");
710
- if(nCount){
711
- cgi_printf("<div class='statistics-report-graph-line'"
712
- "style='width:%d%%;'>&nbsp;</div>",
713
- nSize);
714
- }
715
- cgi_printf("</td></tr>");
716
- }
717
- db_finalize(&stWeek);
718
- free(zDefaultYear);
719
- cgi_printf("</tbody></table>");
720
- if(total){
721
- int nAvg = iterations ? (total/iterations) : 0;
722
- cgi_printf("<br><div>Total events: %d<br>"
723
- "Average per active week: %d</div>",
724
- total, nAvg);
725
- }
726
- output_table_sorting_javascript("statsTable","tnx",-1);
727
- }
728
-}
559
+ int rowCount = 0;
560
+ int total = 0;
561
+
562
+ stats_report_init_view();
563
+ style_submenu_sql("y", "Year:",
564
+ "WITH RECURSIVE a(b) AS ("
565
+ " SELECT substr(date('now'),1,4) UNION ALL"
566
+ " SELECT b-1 FROM a"
567
+ " WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)"
568
+ ") SELECT b, b FROM a ORDER BY b DESC");
569
+ if( zYear==0 || strlen(zYear)!=4 ){
570
+ zYear = db_text("1970","SELECT substr(date('now'),1,4);");
571
+ }
572
+ cgi_printf("<br/>");
573
+ db_prepare(&q,
574
+ "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
575
+ " count(*) AS n "
576
+ " FROM v_reports "
577
+ " WHERE %Q=substr(date(mtime),1,4) "
578
+ " AND mtime < current_timestamp "
579
+ " AND ifnull(coalesce(euser,user,'')=%Q,1)"
580
+ " GROUP BY wk ORDER BY wk DESC", zYear, zUserName);
581
+ @ <h1>Timeline events (%h(stats_report_label_for_type()))
582
+ @ for the calendar weeks of %h(zYear)
583
+ if( zUserName ){
584
+ @ for user %h(zUserName)
585
+ }
586
+ @ </h1>
587
+ cgi_printf("<table class='statistics-report-table-events' "
588
+ "border='0' cellpadding='2' width='100%%' "
589
+ "cellspacing='0' id='statsTable'>");
590
+ cgi_printf("<thead><tr>"
591
+ "<th>Week</th>"
592
+ "<th>Events</th>"
593
+ "<th width='90%%'><!-- relative commits graph --></th>"
594
+ "</tr></thead>"
595
+ "<tbody>");
596
+ while( SQLITE_ROW == db_step(&q) ){
597
+ const int nCount = db_column_int(&q, 1);
598
+ if(nCount>nMaxEvents){
599
+ nMaxEvents = nCount;
600
+ }
601
+ ++iterations;
602
+ }
603
+ db_reset(&q);
604
+ while( SQLITE_ROW == db_step(&q) ){
605
+ const char *zWeek = db_column_text(&q,0);
606
+ const int nCount = db_column_int(&q,1);
607
+ int nSize = nCount
608
+ ? (int)(100 * nCount / nMaxEvents)
609
+ : 0;
610
+ if(!nSize) nSize = 1;
611
+ total += nCount;
612
+ cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
613
+ cgi_printf("<td><a href='%R/timeline?yw=%t-%s&n=%d&y=%s",
614
+ zYear, zWeek, nCount,
615
+ statsReportTimelineYFlag);
616
+ if( zUserName ){
617
+ cgi_printf("&u=%t",zUserName);
618
+ }
619
+ cgi_printf("'>%s</a></td>",zWeek);
620
+
621
+ cgi_printf("<td>%d</td>",nCount);
622
+ cgi_printf("<td>");
623
+ if(nCount){
624
+ cgi_printf("<div class='statistics-report-graph-line'"
625
+ "style='width:%d%%;'>&nbsp;</div>",
626
+ nSize);
627
+ }
628
+ cgi_printf("</td></tr>");
629
+ }
630
+ db_finalize(&q);
631
+ cgi_printf("</tbody></table>");
632
+ if(total){
633
+ int nAvg = iterations ? (total/iterations) : 0;
634
+ cgi_printf("<br><div>Total events: %d<br>"
635
+ "Average per active week: %d</div>",
636
+ total, nAvg);
637
+ }
638
+ output_table_sorting_javascript("statsTable","tnx",-1);
639
+}
640
+
641
+/* Report types
642
+*/
643
+#define RPT_BYFILE 1
644
+#define RPT_BYMONTH 2
645
+#define RPT_BYUSER 3
646
+#define RPT_BYWEEK 4
647
+#define RPT_BYWEEKDAY 5
648
+#define RPT_BYYEAR 6
649
+#define RPT_NONE 0 /* None of the above */
729650
730651
/*
731652
** WEBPAGE: reports
732653
**
733654
** Shows activity reports for the repository.
@@ -747,51 +668,94 @@
747668
** y=YYYY The year to report (default is the server's
748669
** current year).
749670
*/
750671
void stats_report_page(){
751672
HQuery url; /* URL for various branch links */
752
- const char *zView = P("view"); /* Which view/report to show. */
753
- const char *zUserName = P("user");
673
+ const char *zView = P("view"); /* Which view/report to show. */
674
+ int eType = RPT_NONE; /* Numeric code for view/report to show */
675
+ int i; /* Loop counter */
676
+ const char *zUserName; /* Name of user */
677
+ const char *azView[16]; /* Drop-down menu of view types */
678
+ static const struct {
679
+ const char *zName; /* Name of view= screen type */
680
+ const char *zVal; /* Value of view= query parameter */
681
+ int eType; /* Corresponding RPT_* define */
682
+ } aViewType[] = {
683
+ { "File Changes","byfile", RPT_BYFILE },
684
+ { "By Month", "bymonth", RPT_BYMONTH },
685
+ { "By User", "byuser", RPT_BYUSER },
686
+ { "By Week", "byweek", RPT_BYWEEK },
687
+ { "By Weekday", "byweekday", RPT_BYWEEKDAY },
688
+ { "By Year", "byyear", RPT_BYYEAR },
689
+ };
690
+ static const char *const azType[] = {
691
+ "a", "All Changes",
692
+ "ci", "Check-ins",
693
+ "g", "Tags",
694
+ "e", "Tech Notes",
695
+ "t", "Tickets",
696
+ "w", "Wiki"
697
+ };
754698
755699
login_check_credentials();
756700
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
757
- if(!zUserName) zUserName = P("u");
758
- url_initialize(&url, "reports");
759
- if(zUserName && *zUserName){
760
- url_add_parameter(&url,"user", zUserName);
761
- statrep_submenu(&url, "(Remove User Flag)", "view", zView, "user");
762
- }
763
- statrep_submenu(&url, "By Year", "view", "byyear", 0);
764
- statrep_submenu(&url, "By Month", "view", "bymonth", 0);
765
- statrep_submenu(&url, "By Week", "view", "byweek", 0);
766
- statrep_submenu(&url, "By Weekday", "view", "byweekday", 0);
767
- statrep_submenu(&url, "By User", "view", "byuser", "user");
768
- statrep_submenu(&url, "By File", "view", "byfile", "file");
701
+ zUserName = P("user");
702
+ if( zUserName==0 ) zUserName = P("u");
703
+ if( zUserName && zUserName[0]==0 ) zUserName = 0;
704
+ if( zView==0 ){
705
+ zView = "byuser";
706
+ cgi_replace_query_parameter("view","byuser");
707
+ }
708
+ for(i=0; i<ArraySize(aViewType); i++){
709
+ if( fossil_strcmp(zView, aViewType[i].zVal)==0 ){
710
+ eType = aViewType[i].eType;
711
+ break;
712
+ }
713
+ }
714
+ url_initialize(&url, "reports");
715
+ cgi_query_parameters_to_url(&url);
716
+ if( eType!=RPT_NONE ){
717
+ int nView = 0; /* Slots used in azView[] */
718
+ for(i=0; i<ArraySize(aViewType); i++){
719
+ azView[nView++] = aViewType[i].zVal;
720
+ azView[nView++] = aViewType[i].zName;
721
+ }
722
+ if( eType!=RPT_BYFILE ){
723
+ style_submenu_multichoice("type", ArraySize(azType)/2, azType, 0);
724
+ }
725
+ style_submenu_multichoice("view", nView/2, azView, 0);
726
+ if( eType!=RPT_BYUSER ){
727
+ style_submenu_sql("u","User:",
728
+ "SELECT '', 'All Users' UNION ALL "
729
+ "SELECT x, x FROM ("
730
+ " SELECT DISTINCT trim(coalesce(euser,user)) AS x FROM event %s"
731
+ " ORDER BY 1 COLLATE nocase) WHERE x!=''",
732
+ eType==RPT_BYFILE ? "WHERE type='ci'" : ""
733
+ );
734
+ }
735
+ }
769736
style_submenu_element("Stats", "Stats", "%R/stat");
770737
url_reset(&url);
771738
style_header("Activity Reports");
772
- if(0==fossil_strcmp(zView,"byyear")){
773
- stats_report_by_month_year(0, 0, zUserName);
774
- }else if(0==fossil_strcmp(zView,"bymonth")){
775
- stats_report_by_month_year(1, 0, zUserName);
776
- }else if(0==fossil_strcmp(zView,"byweek")){
777
- stats_report_year_weeks(zUserName);
778
- }else if(0==fossil_strcmp(zView,"byuser")){
779
- stats_report_by_user();
780
- }else if(0==fossil_strcmp(zView,"byweekday")){
781
- stats_report_day_of_week();
782
- }else if(0==fossil_strcmp(zView,"byfile")){
783
- stats_report_by_file();
784
- }else{
785
- @ <h1>Activity Reports:</h1>
786
- @ <ul>
787
- @ <li>%z(href("?view=byyear"))Events by year</a></li>
788
- @ <li>%z(href("?view=bymonth"))Events by month</a></li>
789
- @ <li>%z(href("?view=byweek"))Events by calendar week</a></li>
790
- @ <li>%z(href("?view=byweekday"))Events by day of the week</a></li>
791
- @ <li>%z(href("?view=byuser"))Events by user</a></li>
792
- @ <li>%z(href("?view=byfile"))Events by file</a></li>
793
- @ </ul>
794
- }
795
-
739
+ switch( eType ){
740
+ case RPT_BYYEAR:
741
+ stats_report_by_month_year(0, 0, zUserName);
742
+ break;
743
+ case RPT_BYMONTH:
744
+ stats_report_by_month_year(1, 0, zUserName);
745
+ break;
746
+ case RPT_BYWEEK:
747
+ stats_report_year_weeks(zUserName);
748
+ break;
749
+ default:
750
+ case RPT_BYUSER:
751
+ stats_report_by_user();
752
+ break;
753
+ case RPT_BYWEEKDAY:
754
+ stats_report_day_of_week(zUserName);
755
+ break;
756
+ case RPT_BYFILE:
757
+ stats_report_by_file(zUserName);
758
+ break;
759
+ }
796760
style_footer();
797761
}
798762
--- src/statrep.c
+++ src/statrep.c
@@ -36,24 +36,10 @@
36 ** accepted by /timeline?y=XXXX.
37 */
38 static const char *statsReportTimelineYFlag = NULL;
39
40
41 /*
42 ** Generate a submenu element with a single parameter change.
43 */
44 static void statrep_submenu(
45 HQuery *pUrl, /* Base URL */
46 const char *zMenuName, /* Submenu name */
47 const char *zParam, /* Parameter value to add or change */
48 const char *zValue, /* Value of the new parameter */
49 const char *zRemove /* Parameter to omit */
50 ){
51 style_submenu_element(zMenuName, zMenuName, "%s",
52 url_render(pUrl, zParam, zValue, zRemove, 0));
53 }
54
55 /*
56 ** Creates a TEMP VIEW named v_reports which is a wrapper around the
57 ** EVENT table filtered on event.type. It looks for the request
58 ** parameter 'type' (reminder: we "should" use 'y' for consistency
59 ** with /timeline, but /reports uses 'y' for the year) and expects it
@@ -141,63 +127,10 @@
141 default:
142 return "all types";
143 }
144 }
145
146 /*
147 ** A helper for the /reports family of pages which prints out a menu
148 ** of links for the various type=XXX flags. zCurrentViewName must be
149 ** the name/value of the 'view' parameter which is in effect at the
150 ** time this is called. e.g. if called from the 'byuser' view then
151 ** zCurrentViewName must be "byuser". Any URL parameters which need to
152 ** be added to the generated URLs should be passed in zParam. The
153 ** caller is expected to have already encoded any zParam in the %T or
154 ** %t encoding. */
155 static void stats_report_event_types_menu(const char *zCurrentViewName,
156 const char *zParam){
157 char *zTop;
158 if(zParam && !*zParam){
159 zParam = NULL;
160 }
161 zTop = mprintf("%s/reports?view=%s%s%s", g.zTop, zCurrentViewName,
162 zParam ? "&" : "", zParam);
163 cgi_printf("<div>");
164 cgi_printf("<span>Types:</span> ");
165 if('*' == statsReportType){
166 cgi_printf(" <strong>all</strong>", zTop);
167 }else{
168 cgi_printf(" <a href='%s'>all</a>", zTop);
169 }
170 if('c' == statsReportType){
171 cgi_printf(" <strong>check-ins</strong>", zTop);
172 }else{
173 cgi_printf(" <a href='%s&type=ci'>check-ins</a>", zTop);
174 }
175 if('e' == statsReportType){
176 cgi_printf(" <strong>technotes</strong>", zTop);
177 }else{
178 cgi_printf(" <a href='%s&type=e'>technotes</a>", zTop);
179 }
180 if( 't' == statsReportType ){
181 cgi_printf(" <strong>tickets</strong>", zTop);
182 }else{
183 cgi_printf(" <a href='%s&type=t'>tickets</a>", zTop);
184 }
185 if( 'g' == statsReportType ){
186 cgi_printf(" <strong>tags</strong>", zTop);
187 }else{
188 cgi_printf(" <a href='%s&type=g'>tags</a>", zTop);
189 }
190 if( 'w' == statsReportType ){
191 cgi_printf(" <strong>wiki</strong>", zTop);
192 }else{
193 cgi_printf(" <a href='%s&type=w'>wiki</a>", zTop);
194 }
195 fossil_free(zTop);
196 cgi_printf("</div>");
197 }
198
199
200 /*
201 ** Helper for stats_report_by_month_year(), which generates a list of
202 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
203 ** or YYYY-MM.
@@ -227,64 +160,59 @@
227 }
228
229 /*
230 ** Implements the "byyear" and "bymonth" reports for /reports.
231 ** If includeMonth is true then it generates the "bymonth" report,
232 ** else the "byyear" report. If zUserName is not NULL and not empty
233 ** then the report is restricted to events created by the named user
234 ** account.
235 */
236 static void stats_report_by_month_year(char includeMonth,
237 char includeWeeks,
238 const char *zUserName){
239 Stmt query = empty_Stmt;
240 int nRowNumber = 0; /* current TR number */
241 int nEventTotal = 0; /* Total event count */
242 int rowClass = 0; /* counter for alternating
243 row colors */
244 Blob sql = empty_blob; /* SQL */
245 const char *zTimeLabel = includeMonth ? "Year/Month" : "Year";
246 char zPrevYear[5] = {0}; /* For keeping track of when
247 we change years while looping */
248 int nEventsPerYear = 0; /* Total event count for the
249 current year */
250 char showYearTotal = 0; /* Flag telling us when to show
251 the per-year event totals */
252 Blob header = empty_blob; /* Page header text */
253 int nMaxEvents = 1; /* for calculating length of graph
254 bars. */
255 int iterations = 0; /* number of weeks/months we iterate
256 over */
 
257 stats_report_init_view();
258 stats_report_event_types_menu( includeMonth ? "bymonth" : "byyear", NULL );
259 blob_appendf(&header, "Timeline Events (%s) by year%s",
260 stats_report_label_for_type(),
261 (includeMonth ? "/month" : ""));
262 blob_append_sql(&sql,
263 "SELECT substr(date(mtime),1,%d) AS timeframe, "
264 "count(*) AS eventCount "
265 "FROM v_reports ",
266 includeMonth ? 7 : 4);
267 if(zUserName&&*zUserName){
268 blob_append_sql(&sql, " WHERE user=%Q ", zUserName);
269 blob_appendf(&header," for user %q", zUserName);
270 }
271 blob_append(&sql,
272 " GROUP BY timeframe"
273 " ORDER BY timeframe DESC",
274 -1);
275 db_prepare(&query, "%s", blob_sql_text(&sql));
276 blob_reset(&sql);
277 @ <h1>%b(&header)</h1>
278 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
279 @ cellspacing='0' id='statsTable'>
280 @ <thead>
281 @ <th>%s(zTimeLabel)</th>
282 @ <th>Events</th>
283 @ <th width='90%%'><!-- relative commits graph --></th>
284 @ </thead><tbody>
285 blob_reset(&header);
286 /*
287 Run the query twice. The first time we calculate the maximum
288 number of events for a given row. Maybe someone with better SQL
289 Fu can re-implement this with a single query.
290 */
@@ -335,18 +263,18 @@
335 zTimeframe, nCount,
336 statsReportTimelineYFlag );
337 /* Reminder: n=nCount is not actually correct for bymonth unless
338 that was the only user who caused events.
339 */
340 if( zUserName && *zUserName ){
341 cgi_printf("&u=%t", zUserName);
342 }
343 cgi_printf("' target='_new'>%s</a>",zTimeframe);
344 }else {
345 cgi_printf("<a href='?view=byweek&y=%s&type=%c",
346 zTimeframe, (char)statsReportType);
347 if(zUserName && *zUserName){
348 cgi_printf("&u=%t", zUserName);
349 }
350 cgi_printf("'>%s</a>", zTimeframe);
351 }
352 @ </td><td>%d(nCount)</td>
@@ -403,17 +331,16 @@
403 int rowClass = 0; /* counter for alternating
404 row colors */
405 int nMaxEvents = 1; /* max number of events for
406 all rows. */
407 stats_report_init_view();
408 stats_report_event_types_menu("byuser", NULL);
409 @ <h1>Timeline Events
410 @ (%s(stats_report_label_for_type())) by User</h1>
411 db_multi_exec(
412 "CREATE TEMP TABLE piechart(amt,label);"
413 "INSERT INTO piechart SELECT count(*), user FROM v_reports"
414 " GROUP BY user ORDER BY count(*) DESC;"
415 );
416 if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
417 @ <center><svg width=700 height=400>
418 piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
419 @ </svg></centre><hr/>
@@ -424,14 +351,14 @@
424 @ <th>User</th>
425 @ <th>Events</th>
426 @ <th width='90%%'><!-- relative commits graph --></th>
427 @ </tr></thead><tbody>
428 db_prepare(&query,
429 "SELECT user, "
430 "COUNT(*) AS eventCount "
431 "FROM v_reports "
432 "GROUP BY user ORDER BY eventCount DESC");
433 while( SQLITE_ROW == db_step(&query) ){
434 const int nCount = db_column_int(&query, 1);
435 if(nCount>nMaxEvents){
436 nMaxEvents = nCount;
437 }
@@ -438,20 +365,21 @@
438 }
439 db_reset(&query);
440 while( SQLITE_ROW == db_step(&query) ){
441 const char *zUser = db_column_text(&query, 0);
442 const int nCount = db_column_int(&query, 1);
 
443 int nSize = nCount
444 ? (int)(100 * nCount / nMaxEvents)
445 : 0;
446 if(!nCount) continue /* arguable! Possible? */;
447 else if(!nSize) nSize = 1;
448 rowClass = ++nRowNumber % 2;
449 nEventTotal += nCount;
450 @<tr class='row%d(rowClass)'>
451 @ <td>
452 @ <a href="?view=bymonth&user=%h(zUser)&type=%c((char)statsReportType)">%h(zUser)</a>
453 @ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td>
454 @ <td>
455 @ <div class='statistics-report-graph-line'
456 @ style='width:%d(nSize)%%;'>&nbsp;</div>
457 @ </td>
@@ -465,30 +393,37 @@
465 db_finalize(&query);
466 output_table_sorting_javascript("statsTable","tkx",2);
467 }
468
469 /*
470 ** Implements the "byfile" view for /reports.
 
471 */
472 static void stats_report_by_file(){
473 Stmt query;
474 int mxEvent = 1; /* max number of events across all rows */
475 int nRowNumber = 0;
476
477 db_multi_exec(
478 "CREATE TEMP TABLE statrep(filename, cnt);"
479 "INSERT INTO statrep(filename, cnt)"
480 " SELECT filename.name, count(distinct mlink.mid)"
481 " FROM filename, mlink"
482 " WHERE filename.fnid=mlink.fnid"
483 " GROUP BY 1;"
 
 
484 );
485 db_prepare(&query,
486 "SELECT filename, cnt FROM statrep ORDER BY cnt DESC, filename /*sort*/"
487 );
488 mxEvent = db_int(1, "SELECT max(cnt) FROM statrep");
489 @ <h1>Check-ins Per File</h1>
 
 
 
 
490 @ <table class='statistics-report-table-events' border='0'
491 @ cellpadding='2' cellspacing='0' id='statsTable'>
492 @ <thead><tr>
493 @ <th>File</th>
494 @ <th>Check-ins</th>
@@ -514,41 +449,56 @@
514 db_finalize(&query);
515 output_table_sorting_javascript("statsTable","tNx",2);
516 }
517
518 /*
519 ** Implements the "byweekday" view for /reports.
 
520 */
521 static void stats_report_day_of_week(){
522 Stmt query = empty_Stmt;
523 int nRowNumber = 0; /* current TR number */
524 int nEventTotal = 0; /* Total event count */
525 int rowClass = 0; /* counter for alternating
526 row colors */
527 int nMaxEvents = 1; /* max number of events for
528 all rows. */
 
529 static const char *const daysOfWeek[] = {
530 "Monday", "Tuesday", "Wednesday", "Thursday",
531 "Friday", "Saturday", "Sunday"
532 };
533
534 stats_report_init_view();
535 stats_report_event_types_menu("byweekday", NULL);
 
 
536 db_prepare(&query,
537 "SELECT cast(mtime %% 7 AS INTEGER) dow, "
538 "COUNT(*) AS eventCount "
539 "FROM v_reports "
540 "GROUP BY dow ORDER BY dow");
541 @ <h1>Timeline Events
542 @ (%s(stats_report_label_for_type())) by Day of the Week</h1>
 
 
 
 
543 db_multi_exec(
544 "CREATE TEMP TABLE piechart(amt,label);"
545 "INSERT INTO piechart SELECT count(*), cast(mtime %% 7 AS INT) FROM v_reports"
546 " GROUP BY 2 ORDER BY 2;"
547 "UPDATE piechart SET label = CASE label WHEN 0 THEN 'Monday' WHEN 1 THEN 'Tuesday'"
548 " WHEN 2 THEN 'Wednesday' WHEN 3 THEN 'Thursday' WHEN 4 THEN 'Friday'"
549 " WHEN 5 THEN 'Saturday' ELSE 'Sunday' END;"
 
 
 
 
 
 
 
550 );
551 if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
552 @ <center><svg width=700 height=400>
553 piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
554 @ </svg></centre><hr/>
@@ -595,139 +545,110 @@
595
596
597 /*
598 ** Helper for stats_report_by_month_year(), which generates a list of
599 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
600 ** or YYYY-MM.
 
601 */
602 static void stats_report_year_weeks(const char *zUserName){
603 const char *zYear = P("y");
604 int nYear = zYear ? strlen(zYear) : 0;
605 int i = 0;
606 Stmt qYears = empty_Stmt;
607 char *zDefaultYear = NULL;
608 Blob sql = empty_blob;
609 int nMaxEvents = 1; /* max number of events for
610 all rows. */
611 int iterations = 0; /* # of active time periods. */
612 stats_report_init_view();
613 if(4==nYear){
614 Blob urlParams = empty_blob;
615 blob_appendf(&urlParams, "y=%T", zYear);
616 stats_report_event_types_menu("byweek", blob_str(&urlParams));
617 blob_reset(&urlParams);
618 }else{
619 stats_report_event_types_menu("byweek", NULL);
620 }
621 blob_append(&sql,
622 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
623 "FROM v_reports WHERE 1 ", -1);
624 if(zUserName&&*zUserName){
625 blob_append_sql(&sql,"AND user=%Q ", zUserName);
626 }
627 blob_append(&sql,"GROUP BY y ORDER BY y", -1);
628 db_prepare(&qYears, "%s", blob_sql_text(&sql));
629 blob_reset(&sql);
630 cgi_printf("Select year: ");
631 while( SQLITE_ROW == db_step(&qYears) ){
632 const char *zT = db_column_text(&qYears, 0);
633 if( i++ ){
634 cgi_printf(" ");
635 }
636 cgi_printf("<a href='?view=byweek&y=%s&type=%c", zT,
637 (char)statsReportType);
638 if(zUserName && *zUserName){
639 cgi_printf("&user=%t",zUserName);
640 }
641 cgi_printf("'>%s</a>",zT);
642 }
643 db_finalize(&qYears);
644 cgi_printf("<br/>");
645 if(!zYear || !*zYear){
646 zDefaultYear = db_text("????", "SELECT strftime('%%Y')");
647 zYear = zDefaultYear;
648 nYear = 4;
649 }
650 if(4 == nYear){
651 Stmt stWeek = empty_Stmt;
652 int rowCount = 0;
653 int total = 0;
654 Blob header = empty_blob;
655 blob_appendf(&header, "Timeline events (%s) for the calendar weeks "
656 "of %h", stats_report_label_for_type(),
657 zYear);
658 blob_append_sql(&sql,
659 "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
660 "count(*) AS n "
661 "FROM v_reports "
662 "WHERE %Q=substr(date(mtime),1,4) "
663 "AND mtime < current_timestamp ",
664 zYear);
665 if(zUserName&&*zUserName){
666 blob_append_sql(&sql, " AND user=%Q ", zUserName);
667 blob_appendf(&header," for user %h", zUserName);
668 }
669 blob_append_sql(&sql, "GROUP BY wk ORDER BY wk DESC");
670 cgi_printf("<h1>%h</h1>", blob_str(&header));
671 blob_reset(&header);
672 cgi_printf("<table class='statistics-report-table-events' "
673 "border='0' cellpadding='2' width='100%%' "
674 "cellspacing='0' id='statsTable'>");
675 cgi_printf("<thead><tr>"
676 "<th>Week</th>"
677 "<th>Events</th>"
678 "<th width='90%%'><!-- relative commits graph --></th>"
679 "</tr></thead>"
680 "<tbody>");
681 db_prepare(&stWeek, "%s", blob_sql_text(&sql));
682 blob_reset(&sql);
683 while( SQLITE_ROW == db_step(&stWeek) ){
684 const int nCount = db_column_int(&stWeek, 1);
685 if(nCount>nMaxEvents){
686 nMaxEvents = nCount;
687 }
688 ++iterations;
689 }
690 db_reset(&stWeek);
691 while( SQLITE_ROW == db_step(&stWeek) ){
692 const char *zWeek = db_column_text(&stWeek,0);
693 const int nCount = db_column_int(&stWeek,1);
694 int nSize = nCount
695 ? (int)(100 * nCount / nMaxEvents)
696 : 0;
697 if(!nSize) nSize = 1;
698 total += nCount;
699 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
700 cgi_printf("<td><a href='%R/timeline?yw=%t-%s&n=%d&y=%s",
701 zYear, zWeek, nCount,
702 statsReportTimelineYFlag);
703 if(zUserName && *zUserName){
704 cgi_printf("&u=%t",zUserName);
705 }
706 cgi_printf("'>%s</a></td>",zWeek);
707
708 cgi_printf("<td>%d</td>",nCount);
709 cgi_printf("<td>");
710 if(nCount){
711 cgi_printf("<div class='statistics-report-graph-line'"
712 "style='width:%d%%;'>&nbsp;</div>",
713 nSize);
714 }
715 cgi_printf("</td></tr>");
716 }
717 db_finalize(&stWeek);
718 free(zDefaultYear);
719 cgi_printf("</tbody></table>");
720 if(total){
721 int nAvg = iterations ? (total/iterations) : 0;
722 cgi_printf("<br><div>Total events: %d<br>"
723 "Average per active week: %d</div>",
724 total, nAvg);
725 }
726 output_table_sorting_javascript("statsTable","tnx",-1);
727 }
728 }
729
730 /*
731 ** WEBPAGE: reports
732 **
733 ** Shows activity reports for the repository.
@@ -747,51 +668,94 @@
747 ** y=YYYY The year to report (default is the server's
748 ** current year).
749 */
750 void stats_report_page(){
751 HQuery url; /* URL for various branch links */
752 const char *zView = P("view"); /* Which view/report to show. */
753 const char *zUserName = P("user");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
754
755 login_check_credentials();
756 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
757 if(!zUserName) zUserName = P("u");
758 url_initialize(&url, "reports");
759 if(zUserName && *zUserName){
760 url_add_parameter(&url,"user", zUserName);
761 statrep_submenu(&url, "(Remove User Flag)", "view", zView, "user");
762 }
763 statrep_submenu(&url, "By Year", "view", "byyear", 0);
764 statrep_submenu(&url, "By Month", "view", "bymonth", 0);
765 statrep_submenu(&url, "By Week", "view", "byweek", 0);
766 statrep_submenu(&url, "By Weekday", "view", "byweekday", 0);
767 statrep_submenu(&url, "By User", "view", "byuser", "user");
768 statrep_submenu(&url, "By File", "view", "byfile", "file");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
769 style_submenu_element("Stats", "Stats", "%R/stat");
770 url_reset(&url);
771 style_header("Activity Reports");
772 if(0==fossil_strcmp(zView,"byyear")){
773 stats_report_by_month_year(0, 0, zUserName);
774 }else if(0==fossil_strcmp(zView,"bymonth")){
775 stats_report_by_month_year(1, 0, zUserName);
776 }else if(0==fossil_strcmp(zView,"byweek")){
777 stats_report_year_weeks(zUserName);
778 }else if(0==fossil_strcmp(zView,"byuser")){
779 stats_report_by_user();
780 }else if(0==fossil_strcmp(zView,"byweekday")){
781 stats_report_day_of_week();
782 }else if(0==fossil_strcmp(zView,"byfile")){
783 stats_report_by_file();
784 }else{
785 @ <h1>Activity Reports:</h1>
786 @ <ul>
787 @ <li>%z(href("?view=byyear"))Events by year</a></li>
788 @ <li>%z(href("?view=bymonth"))Events by month</a></li>
789 @ <li>%z(href("?view=byweek"))Events by calendar week</a></li>
790 @ <li>%z(href("?view=byweekday"))Events by day of the week</a></li>
791 @ <li>%z(href("?view=byuser"))Events by user</a></li>
792 @ <li>%z(href("?view=byfile"))Events by file</a></li>
793 @ </ul>
794 }
795
796 style_footer();
797 }
798
--- src/statrep.c
+++ src/statrep.c
@@ -36,24 +36,10 @@
36 ** accepted by /timeline?y=XXXX.
37 */
38 static const char *statsReportTimelineYFlag = NULL;
39
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41 /*
42 ** Creates a TEMP VIEW named v_reports which is a wrapper around the
43 ** EVENT table filtered on event.type. It looks for the request
44 ** parameter 'type' (reminder: we "should" use 'y' for consistency
45 ** with /timeline, but /reports uses 'y' for the year) and expects it
@@ -141,63 +127,10 @@
127 default:
128 return "all types";
129 }
130 }
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
133 /*
134 ** Helper for stats_report_by_month_year(), which generates a list of
135 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
136 ** or YYYY-MM.
@@ -227,64 +160,59 @@
160 }
161
162 /*
163 ** Implements the "byyear" and "bymonth" reports for /reports.
164 ** If includeMonth is true then it generates the "bymonth" report,
165 ** else the "byyear" report. If zUserName is not NULL then the report is
166 ** restricted to events created by the named user account.
 
167 */
168 static void stats_report_by_month_year(char includeMonth,
169 char includeWeeks,
170 const char *zUserName){
171 Stmt query = empty_Stmt;
172 int nRowNumber = 0; /* current TR number */
173 int nEventTotal = 0; /* Total event count */
174 int rowClass = 0; /* counter for alternating
175 row colors */
 
176 const char *zTimeLabel = includeMonth ? "Year/Month" : "Year";
177 char zPrevYear[5] = {0}; /* For keeping track of when
178 we change years while looping */
179 int nEventsPerYear = 0; /* Total event count for the
180 current year */
181 char showYearTotal = 0; /* Flag telling us when to show
182 the per-year event totals */
 
183 int nMaxEvents = 1; /* for calculating length of graph
184 bars. */
185 int iterations = 0; /* number of weeks/months we iterate
186 over */
187 Blob userFilter = empty_blob; /* Optional user=johndoe query string */
188 stats_report_init_view();
189 if( zUserName ){
190 blob_appendf(&userFilter, "user=%s", zUserName);
191 }
192 blob_reset(&userFilter);
193 db_prepare(&query,
194 "SELECT substr(date(mtime),1,%d) AS timeframe,"
195 " count(*) AS eventCount"
196 " FROM v_reports"
197 " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
198 " GROUP BY timeframe"
199 " ORDER BY timeframe DESC",
200 includeMonth ? 7 : 4, zUserName);
201 @ <h1>Timeline Events (%s(stats_report_label_for_type()))
202 @ by year%s(includeMonth ? "/month" : "")
203 if( zUserName ){
204 @ for user %h(zUserName)
205 }
206 @ </h1>
 
 
207 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
208 @ cellspacing='0' id='statsTable'>
209 @ <thead>
210 @ <th>%s(zTimeLabel)</th>
211 @ <th>Events</th>
212 @ <th width='90%%'><!-- relative commits graph --></th>
213 @ </thead><tbody>
 
214 /*
215 Run the query twice. The first time we calculate the maximum
216 number of events for a given row. Maybe someone with better SQL
217 Fu can re-implement this with a single query.
218 */
@@ -335,18 +263,18 @@
263 zTimeframe, nCount,
264 statsReportTimelineYFlag );
265 /* Reminder: n=nCount is not actually correct for bymonth unless
266 that was the only user who caused events.
267 */
268 if( zUserName ){
269 cgi_printf("&u=%t", zUserName);
270 }
271 cgi_printf("' target='_new'>%s</a>",zTimeframe);
272 }else {
273 cgi_printf("<a href='?view=byweek&y=%s&type=%c",
274 zTimeframe, (char)statsReportType);
275 if( zUserName ){
276 cgi_printf("&u=%t", zUserName);
277 }
278 cgi_printf("'>%s</a>", zTimeframe);
279 }
280 @ </td><td>%d(nCount)</td>
@@ -403,17 +331,16 @@
331 int rowClass = 0; /* counter for alternating
332 row colors */
333 int nMaxEvents = 1; /* max number of events for
334 all rows. */
335 stats_report_init_view();
 
336 @ <h1>Timeline Events
337 @ (%s(stats_report_label_for_type())) by User</h1>
338 db_multi_exec(
339 "CREATE TEMP TABLE piechart(amt,label);"
340 "INSERT INTO piechart SELECT count(*), ifnull(euser,user) FROM v_reports"
341 " GROUP BY ifnull(euser,user) ORDER BY count(*) DESC;"
342 );
343 if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
344 @ <center><svg width=700 height=400>
345 piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
346 @ </svg></centre><hr/>
@@ -424,14 +351,14 @@
351 @ <th>User</th>
352 @ <th>Events</th>
353 @ <th width='90%%'><!-- relative commits graph --></th>
354 @ </tr></thead><tbody>
355 db_prepare(&query,
356 "SELECT ifnull(euser,user), "
357 "COUNT(*) AS eventCount "
358 "FROM v_reports "
359 "GROUP BY ifnull(euser,user) ORDER BY eventCount DESC");
360 while( SQLITE_ROW == db_step(&query) ){
361 const int nCount = db_column_int(&query, 1);
362 if(nCount>nMaxEvents){
363 nMaxEvents = nCount;
364 }
@@ -438,20 +365,21 @@
365 }
366 db_reset(&query);
367 while( SQLITE_ROW == db_step(&query) ){
368 const char *zUser = db_column_text(&query, 0);
369 const int nCount = db_column_int(&query, 1);
370 char y = (char)statsReportType;
371 int nSize = nCount
372 ? (int)(100 * nCount / nMaxEvents)
373 : 0;
374 if(!nCount) continue /* arguable! Possible? */;
375 else if(!nSize) nSize = 1;
376 rowClass = ++nRowNumber % 2;
377 nEventTotal += nCount;
378 @ <tr class='row%d(rowClass)'>
379 @ <td>
380 @ <a href="?view=bymonth&user=%h(zUser)&type=%c(y)">%h(zUser)</a>
381 @ </td><td data-sortkey='%08x(-nCount)'>%d(nCount)</td>
382 @ <td>
383 @ <div class='statistics-report-graph-line'
384 @ style='width:%d(nSize)%%;'>&nbsp;</div>
385 @ </td>
@@ -465,30 +393,37 @@
393 db_finalize(&query);
394 output_table_sorting_javascript("statsTable","tkx",2);
395 }
396
397 /*
398 ** Implements the "byfile" view for /reports. If zUserName is not NULL then the
399 ** report is restricted to events created by the named user account.
400 */
401 static void stats_report_by_file(const char *zUserName){
402 Stmt query;
403 int mxEvent = 1; /* max number of events across all rows */
404 int nRowNumber = 0;
405
406 db_multi_exec(
407 "CREATE TEMP TABLE statrep(filename, cnt);"
408 "INSERT INTO statrep(filename, cnt)"
409 " SELECT filename.name, count(distinct mlink.mid)"
410 " FROM filename, mlink, event"
411 " WHERE filename.fnid=mlink.fnid"
412 " AND mlink.mid=event.objid"
413 " AND ifnull(coalesce(euser,user,'')=%Q,1)"
414 " GROUP BY 1", zUserName
415 );
416 db_prepare(&query,
417 "SELECT filename, cnt FROM statrep ORDER BY cnt DESC, filename /*sort*/"
418 );
419 mxEvent = db_int(1, "SELECT max(cnt) FROM statrep");
420 @ <h1>Check-ins Per File
421 if( zUserName ){
422 @ for user %h(zUserName)
423 }
424 @ </h1>
425 @ <table class='statistics-report-table-events' border='0'
426 @ cellpadding='2' cellspacing='0' id='statsTable'>
427 @ <thead><tr>
428 @ <th>File</th>
429 @ <th>Check-ins</th>
@@ -514,41 +449,56 @@
449 db_finalize(&query);
450 output_table_sorting_javascript("statsTable","tNx",2);
451 }
452
453 /*
454 ** Implements the "byweekday" view for /reports. If zUserName is not NULL then
455 ** the report is restricted to events created by the named user account.
456 */
457 static void stats_report_day_of_week(const char *zUserName){
458 Stmt query = empty_Stmt;
459 int nRowNumber = 0; /* current TR number */
460 int nEventTotal = 0; /* Total event count */
461 int rowClass = 0; /* counter for alternating
462 row colors */
463 int nMaxEvents = 1; /* max number of events for
464 all rows. */
465 Blob userFilter = empty_blob; /* Optional user=johndoe query string */
466 static const char *const daysOfWeek[] = {
467 "Monday", "Tuesday", "Wednesday", "Thursday",
468 "Friday", "Saturday", "Sunday"
469 };
470
471 stats_report_init_view();
472 if( zUserName ){
473 blob_appendf(&userFilter, "user=%s", zUserName);
474 }
475 db_prepare(&query,
476 "SELECT cast(mtime %% 7 AS INTEGER) dow,"
477 " COUNT(*) AS eventCount"
478 " FROM v_reports"
479 " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
480 " GROUP BY dow ORDER BY dow", zUserName);
481 @ <h1>Timeline Events (%h(stats_report_label_for_type())) by Day of the Week
482 if( zUserName ){
483 @ for user %h(zUserName)
484 }
485 @ </h1>
486 db_multi_exec(
487 "CREATE TEMP TABLE piechart(amt,label);"
488 "INSERT INTO piechart"
489 " SELECT count(*), cast(mtime %% 7 AS INT) FROM v_reports"
490 " WHERE ifnull(coalesce(euser,user,'')=%Q,1)"
491 " GROUP BY 2 ORDER BY 2;"
492 "UPDATE piechart SET label = CASE label"
493 " WHEN 0 THEN 'Monday'"
494 " WHEN 1 THEN 'Tuesday'"
495 " WHEN 2 THEN 'Wednesday'"
496 " WHEN 3 THEN 'Thursday'"
497 " WHEN 4 THEN 'Friday'"
498 " WHEN 5 THEN 'Saturday'"
499 " ELSE 'Sunday' END;", zUserName
500 );
501 if( db_int(0, "SELECT count(*) FROM piechart")>=2 ){
502 @ <center><svg width=700 height=400>
503 piechart_render(700, 400, PIE_OTHER|PIE_PERCENT);
504 @ </svg></centre><hr/>
@@ -595,139 +545,110 @@
545
546
547 /*
548 ** Helper for stats_report_by_month_year(), which generates a list of
549 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
550 ** or YYYY-MM. If zUserName is not NULL then the report is restricted to events
551 ** created by the named user account.
552 */
553 static void stats_report_year_weeks(const char *zUserName){
554 const char *zYear = P("y"); /* Year for which report shown */
555 Stmt q;
 
 
 
 
556 int nMaxEvents = 1; /* max number of events for
557 all rows. */
558 int iterations = 0; /* # of active time periods. */
559 int rowCount = 0;
560 int total = 0;
561
562 stats_report_init_view();
563 style_submenu_sql("y", "Year:",
564 "WITH RECURSIVE a(b) AS ("
565 " SELECT substr(date('now'),1,4) UNION ALL"
566 " SELECT b-1 FROM a"
567 " WHERE b>0+(SELECT substr(date(min(mtime)),1,4) FROM event)"
568 ") SELECT b, b FROM a ORDER BY b DESC");
569 if( zYear==0 || strlen(zYear)!=4 ){
570 zYear = db_text("1970","SELECT substr(date('now'),1,4);");
571 }
572 cgi_printf("<br/>");
573 db_prepare(&q,
574 "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
575 " count(*) AS n "
576 " FROM v_reports "
577 " WHERE %Q=substr(date(mtime),1,4) "
578 " AND mtime < current_timestamp "
579 " AND ifnull(coalesce(euser,user,'')=%Q,1)"
580 " GROUP BY wk ORDER BY wk DESC", zYear, zUserName);
581 @ <h1>Timeline events (%h(stats_report_label_for_type()))
582 @ for the calendar weeks of %h(zYear)
583 if( zUserName ){
584 @ for user %h(zUserName)
585 }
586 @ </h1>
587 cgi_printf("<table class='statistics-report-table-events' "
588 "border='0' cellpadding='2' width='100%%' "
589 "cellspacing='0' id='statsTable'>");
590 cgi_printf("<thead><tr>"
591 "<th>Week</th>"
592 "<th>Events</th>"
593 "<th width='90%%'><!-- relative commits graph --></th>"
594 "</tr></thead>"
595 "<tbody>");
596 while( SQLITE_ROW == db_step(&q) ){
597 const int nCount = db_column_int(&q, 1);
598 if(nCount>nMaxEvents){
599 nMaxEvents = nCount;
600 }
601 ++iterations;
602 }
603 db_reset(&q);
604 while( SQLITE_ROW == db_step(&q) ){
605 const char *zWeek = db_column_text(&q,0);
606 const int nCount = db_column_int(&q,1);
607 int nSize = nCount
608 ? (int)(100 * nCount / nMaxEvents)
609 : 0;
610 if(!nSize) nSize = 1;
611 total += nCount;
612 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
613 cgi_printf("<td><a href='%R/timeline?yw=%t-%s&n=%d&y=%s",
614 zYear, zWeek, nCount,
615 statsReportTimelineYFlag);
616 if( zUserName ){
617 cgi_printf("&u=%t",zUserName);
618 }
619 cgi_printf("'>%s</a></td>",zWeek);
620
621 cgi_printf("<td>%d</td>",nCount);
622 cgi_printf("<td>");
623 if(nCount){
624 cgi_printf("<div class='statistics-report-graph-line'"
625 "style='width:%d%%;'>&nbsp;</div>",
626 nSize);
627 }
628 cgi_printf("</td></tr>");
629 }
630 db_finalize(&q);
631 cgi_printf("</tbody></table>");
632 if(total){
633 int nAvg = iterations ? (total/iterations) : 0;
634 cgi_printf("<br><div>Total events: %d<br>"
635 "Average per active week: %d</div>",
636 total, nAvg);
637 }
638 output_table_sorting_javascript("statsTable","tnx",-1);
639 }
640
641 /* Report types
642 */
643 #define RPT_BYFILE 1
644 #define RPT_BYMONTH 2
645 #define RPT_BYUSER 3
646 #define RPT_BYWEEK 4
647 #define RPT_BYWEEKDAY 5
648 #define RPT_BYYEAR 6
649 #define RPT_NONE 0 /* None of the above */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
651 /*
652 ** WEBPAGE: reports
653 **
654 ** Shows activity reports for the repository.
@@ -747,51 +668,94 @@
668 ** y=YYYY The year to report (default is the server's
669 ** current year).
670 */
671 void stats_report_page(){
672 HQuery url; /* URL for various branch links */
673 const char *zView = P("view"); /* Which view/report to show. */
674 int eType = RPT_NONE; /* Numeric code for view/report to show */
675 int i; /* Loop counter */
676 const char *zUserName; /* Name of user */
677 const char *azView[16]; /* Drop-down menu of view types */
678 static const struct {
679 const char *zName; /* Name of view= screen type */
680 const char *zVal; /* Value of view= query parameter */
681 int eType; /* Corresponding RPT_* define */
682 } aViewType[] = {
683 { "File Changes","byfile", RPT_BYFILE },
684 { "By Month", "bymonth", RPT_BYMONTH },
685 { "By User", "byuser", RPT_BYUSER },
686 { "By Week", "byweek", RPT_BYWEEK },
687 { "By Weekday", "byweekday", RPT_BYWEEKDAY },
688 { "By Year", "byyear", RPT_BYYEAR },
689 };
690 static const char *const azType[] = {
691 "a", "All Changes",
692 "ci", "Check-ins",
693 "g", "Tags",
694 "e", "Tech Notes",
695 "t", "Tickets",
696 "w", "Wiki"
697 };
698
699 login_check_credentials();
700 if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
701 zUserName = P("user");
702 if( zUserName==0 ) zUserName = P("u");
703 if( zUserName && zUserName[0]==0 ) zUserName = 0;
704 if( zView==0 ){
705 zView = "byuser";
706 cgi_replace_query_parameter("view","byuser");
707 }
708 for(i=0; i<ArraySize(aViewType); i++){
709 if( fossil_strcmp(zView, aViewType[i].zVal)==0 ){
710 eType = aViewType[i].eType;
711 break;
712 }
713 }
714 url_initialize(&url, "reports");
715 cgi_query_parameters_to_url(&url);
716 if( eType!=RPT_NONE ){
717 int nView = 0; /* Slots used in azView[] */
718 for(i=0; i<ArraySize(aViewType); i++){
719 azView[nView++] = aViewType[i].zVal;
720 azView[nView++] = aViewType[i].zName;
721 }
722 if( eType!=RPT_BYFILE ){
723 style_submenu_multichoice("type", ArraySize(azType)/2, azType, 0);
724 }
725 style_submenu_multichoice("view", nView/2, azView, 0);
726 if( eType!=RPT_BYUSER ){
727 style_submenu_sql("u","User:",
728 "SELECT '', 'All Users' UNION ALL "
729 "SELECT x, x FROM ("
730 " SELECT DISTINCT trim(coalesce(euser,user)) AS x FROM event %s"
731 " ORDER BY 1 COLLATE nocase) WHERE x!=''",
732 eType==RPT_BYFILE ? "WHERE type='ci'" : ""
733 );
734 }
735 }
736 style_submenu_element("Stats", "Stats", "%R/stat");
737 url_reset(&url);
738 style_header("Activity Reports");
739 switch( eType ){
740 case RPT_BYYEAR:
741 stats_report_by_month_year(0, 0, zUserName);
742 break;
743 case RPT_BYMONTH:
744 stats_report_by_month_year(1, 0, zUserName);
745 break;
746 case RPT_BYWEEK:
747 stats_report_year_weeks(zUserName);
748 break;
749 default:
750 case RPT_BYUSER:
751 stats_report_by_user();
752 break;
753 case RPT_BYWEEKDAY:
754 stats_report_day_of_week(zUserName);
755 break;
756 case RPT_BYFILE:
757 stats_report_by_file(zUserName);
758 break;
759 }
 
 
 
760 style_footer();
761 }
762
+39 -2
--- src/style.c
+++ src/style.c
@@ -48,11 +48,11 @@
4848
const char *zName; /* Form query parameter */
4949
const char *zLabel; /* Label. Might be NULL for FF_MULTI */
5050
unsigned char eType; /* FF_ENTRY, FF_MULTI, FF_BINARY */
5151
unsigned char isDisabled; /* True if this control is grayed out */
5252
short int iSize; /* Width for FF_ENTRY. Count for FF_MULTI */
53
- const char **azChoice; /* value/display pairs for FF_MULTI */
53
+ const char *const *azChoice;/* value/display pairs for FF_MULTI */
5454
const char *zFalse; /* FF_BINARY label when false */
5555
} aSubmenuCtrl[20];
5656
static int nSubmenuCtrl = 0;
5757
#define FF_ENTRY 1
5858
#define FF_MULTI 2
@@ -274,20 +274,54 @@
274274
nSubmenuCtrl++;
275275
}
276276
void style_submenu_multichoice(
277277
const char *zName, /* Query parameter name */
278278
int nChoice, /* Number of options */
279
- const char **azChoice, /* value/display pairs. 2*nChoice entries */
279
+ const char *const *azChoice,/* value/display pairs. 2*nChoice entries */
280280
int isDisabled /* True if this control is disabled */
281281
){
282282
assert( nSubmenuCtrl < ArraySize(aSubmenuCtrl) );
283283
aSubmenuCtrl[nSubmenuCtrl].zName = zName;
284284
aSubmenuCtrl[nSubmenuCtrl].iSize = nChoice;
285285
aSubmenuCtrl[nSubmenuCtrl].azChoice = azChoice;
286286
aSubmenuCtrl[nSubmenuCtrl].isDisabled = isDisabled;
287287
aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
288288
nSubmenuCtrl++;
289
+}
290
+void style_submenu_sql(
291
+ const char *zName, /* Query parameter name */
292
+ const char *zLabel, /* Label on the control */
293
+ const char *zFormat, /* Format string for SQL command for choices */
294
+ ... /* Arguments to the format string */
295
+){
296
+ Stmt q;
297
+ int n = 0;
298
+ int nAlloc = 0;
299
+ char **az = 0;
300
+ va_list ap;
301
+
302
+ va_start(ap, zFormat);
303
+ db_vprepare(&q, 0, zFormat, ap);
304
+ va_end(ap);
305
+ while( SQLITE_ROW==db_step(&q) ){
306
+ if( n+2>=nAlloc ){
307
+ nAlloc += nAlloc + 20;
308
+ az = fossil_realloc(az, sizeof(char*)*nAlloc);
309
+ }
310
+ az[n++] = fossil_strdup(db_column_text(&q,0));
311
+ az[n++] = fossil_strdup(db_column_text(&q,1));
312
+ }
313
+ db_finalize(&q);
314
+ if( n>0 ){
315
+ aSubmenuCtrl[nSubmenuCtrl].zName = zName;
316
+ aSubmenuCtrl[nSubmenuCtrl].zLabel = zLabel;
317
+ aSubmenuCtrl[nSubmenuCtrl].iSize = n/2;
318
+ aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char *const *)az;
319
+ aSubmenuCtrl[nSubmenuCtrl].isDisabled = 0;
320
+ aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
321
+ nSubmenuCtrl++;
322
+ }
289323
}
290324
291325
292326
/*
293327
** Compare two submenu items for sorting purposes
@@ -514,10 +548,13 @@
514548
break;
515549
}
516550
case FF_MULTI: {
517551
int j;
518552
const char *zVal = P(zQPN);
553
+ if( aSubmenuCtrl[i].zLabel ){
554
+ cgi_printf("&nbsp;%h", aSubmenuCtrl[i].zLabel);
555
+ }
519556
cgi_printf(
520557
"<select class='submenuctrl' size='1' name='%s'%s "
521558
"onchange='gebi(\"f01\").submit();'>\n",
522559
zQPN, zDisabled
523560
);
524561
--- src/style.c
+++ src/style.c
@@ -48,11 +48,11 @@
48 const char *zName; /* Form query parameter */
49 const char *zLabel; /* Label. Might be NULL for FF_MULTI */
50 unsigned char eType; /* FF_ENTRY, FF_MULTI, FF_BINARY */
51 unsigned char isDisabled; /* True if this control is grayed out */
52 short int iSize; /* Width for FF_ENTRY. Count for FF_MULTI */
53 const char **azChoice; /* value/display pairs for FF_MULTI */
54 const char *zFalse; /* FF_BINARY label when false */
55 } aSubmenuCtrl[20];
56 static int nSubmenuCtrl = 0;
57 #define FF_ENTRY 1
58 #define FF_MULTI 2
@@ -274,20 +274,54 @@
274 nSubmenuCtrl++;
275 }
276 void style_submenu_multichoice(
277 const char *zName, /* Query parameter name */
278 int nChoice, /* Number of options */
279 const char **azChoice, /* value/display pairs. 2*nChoice entries */
280 int isDisabled /* True if this control is disabled */
281 ){
282 assert( nSubmenuCtrl < ArraySize(aSubmenuCtrl) );
283 aSubmenuCtrl[nSubmenuCtrl].zName = zName;
284 aSubmenuCtrl[nSubmenuCtrl].iSize = nChoice;
285 aSubmenuCtrl[nSubmenuCtrl].azChoice = azChoice;
286 aSubmenuCtrl[nSubmenuCtrl].isDisabled = isDisabled;
287 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
288 nSubmenuCtrl++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289 }
290
291
292 /*
293 ** Compare two submenu items for sorting purposes
@@ -514,10 +548,13 @@
514 break;
515 }
516 case FF_MULTI: {
517 int j;
518 const char *zVal = P(zQPN);
 
 
 
519 cgi_printf(
520 "<select class='submenuctrl' size='1' name='%s'%s "
521 "onchange='gebi(\"f01\").submit();'>\n",
522 zQPN, zDisabled
523 );
524
--- src/style.c
+++ src/style.c
@@ -48,11 +48,11 @@
48 const char *zName; /* Form query parameter */
49 const char *zLabel; /* Label. Might be NULL for FF_MULTI */
50 unsigned char eType; /* FF_ENTRY, FF_MULTI, FF_BINARY */
51 unsigned char isDisabled; /* True if this control is grayed out */
52 short int iSize; /* Width for FF_ENTRY. Count for FF_MULTI */
53 const char *const *azChoice;/* value/display pairs for FF_MULTI */
54 const char *zFalse; /* FF_BINARY label when false */
55 } aSubmenuCtrl[20];
56 static int nSubmenuCtrl = 0;
57 #define FF_ENTRY 1
58 #define FF_MULTI 2
@@ -274,20 +274,54 @@
274 nSubmenuCtrl++;
275 }
276 void style_submenu_multichoice(
277 const char *zName, /* Query parameter name */
278 int nChoice, /* Number of options */
279 const char *const *azChoice,/* value/display pairs. 2*nChoice entries */
280 int isDisabled /* True if this control is disabled */
281 ){
282 assert( nSubmenuCtrl < ArraySize(aSubmenuCtrl) );
283 aSubmenuCtrl[nSubmenuCtrl].zName = zName;
284 aSubmenuCtrl[nSubmenuCtrl].iSize = nChoice;
285 aSubmenuCtrl[nSubmenuCtrl].azChoice = azChoice;
286 aSubmenuCtrl[nSubmenuCtrl].isDisabled = isDisabled;
287 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
288 nSubmenuCtrl++;
289 }
290 void style_submenu_sql(
291 const char *zName, /* Query parameter name */
292 const char *zLabel, /* Label on the control */
293 const char *zFormat, /* Format string for SQL command for choices */
294 ... /* Arguments to the format string */
295 ){
296 Stmt q;
297 int n = 0;
298 int nAlloc = 0;
299 char **az = 0;
300 va_list ap;
301
302 va_start(ap, zFormat);
303 db_vprepare(&q, 0, zFormat, ap);
304 va_end(ap);
305 while( SQLITE_ROW==db_step(&q) ){
306 if( n+2>=nAlloc ){
307 nAlloc += nAlloc + 20;
308 az = fossil_realloc(az, sizeof(char*)*nAlloc);
309 }
310 az[n++] = fossil_strdup(db_column_text(&q,0));
311 az[n++] = fossil_strdup(db_column_text(&q,1));
312 }
313 db_finalize(&q);
314 if( n>0 ){
315 aSubmenuCtrl[nSubmenuCtrl].zName = zName;
316 aSubmenuCtrl[nSubmenuCtrl].zLabel = zLabel;
317 aSubmenuCtrl[nSubmenuCtrl].iSize = n/2;
318 aSubmenuCtrl[nSubmenuCtrl].azChoice = (const char *const *)az;
319 aSubmenuCtrl[nSubmenuCtrl].isDisabled = 0;
320 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
321 nSubmenuCtrl++;
322 }
323 }
324
325
326 /*
327 ** Compare two submenu items for sorting purposes
@@ -514,10 +548,13 @@
548 break;
549 }
550 case FF_MULTI: {
551 int j;
552 const char *zVal = P(zQPN);
553 if( aSubmenuCtrl[i].zLabel ){
554 cgi_printf("&nbsp;%h", aSubmenuCtrl[i].zLabel);
555 }
556 cgi_printf(
557 "<select class='submenuctrl' size='1' name='%s'%s "
558 "onchange='gebi(\"f01\").submit();'>\n",
559 zQPN, zDisabled
560 );
561
+1 -1
--- src/th.h
+++ src/th.h
@@ -172,11 +172,11 @@
172172
/*
173173
** Interfaces to the full Tcl core library from "th_tcl.c".
174174
*/
175175
int th_register_tcl(Th_Interp *, void *);
176176
int unloadTcl(Th_Interp *, void *);
177
-int evaluateTclWithEvents(Th_Interp *, void *, const char *, int, int, int);
177
+int evaluateTclWithEvents(Th_Interp *,void *,const char *,int,int,int,int);
178178
#endif
179179
180180
/*
181181
** General purpose hash table from th_lang.c.
182182
*/
183183
--- src/th.h
+++ src/th.h
@@ -172,11 +172,11 @@
172 /*
173 ** Interfaces to the full Tcl core library from "th_tcl.c".
174 */
175 int th_register_tcl(Th_Interp *, void *);
176 int unloadTcl(Th_Interp *, void *);
177 int evaluateTclWithEvents(Th_Interp *, void *, const char *, int, int, int);
178 #endif
179
180 /*
181 ** General purpose hash table from th_lang.c.
182 */
183
--- src/th.h
+++ src/th.h
@@ -172,11 +172,11 @@
172 /*
173 ** Interfaces to the full Tcl core library from "th_tcl.c".
174 */
175 int th_register_tcl(Th_Interp *, void *);
176 int unloadTcl(Th_Interp *, void *);
177 int evaluateTclWithEvents(Th_Interp *,void *,const char *,int,int,int,int);
178 #endif
179
180 /*
181 ** General purpose hash table from th_lang.c.
182 */
183
--- src/th_lang.c
+++ src/th_lang.c
@@ -255,10 +255,47 @@
255255
return rc;
256256
}
257257
258258
/*
259259
** TH Syntax:
260
+**
261
+** lsearch list string
262
+*/
263
+static int lsearch_command(
264
+ Th_Interp *interp,
265
+ void *ctx,
266
+ int argc,
267
+ const char **argv,
268
+ int *argl
269
+){
270
+ int rc;
271
+ char **azElem;
272
+ int *anElem;
273
+ int nCount;
274
+ int i;
275
+
276
+ if( argc!=3 ){
277
+ return Th_WrongNumArgs(interp, "lsearch list string");
278
+ }
279
+
280
+ rc = Th_SplitList(interp, argv[1], argl[1], &azElem, &anElem, &nCount);
281
+ if( rc==TH_OK ){
282
+ Th_SetResultInt(interp, -1);
283
+ for(i=0; i<nCount; i++){
284
+ if( anElem[i]==argl[2] && 0==memcmp(azElem[i], argv[2], argl[2]) ){
285
+ Th_SetResultInt(interp, i);
286
+ break;
287
+ }
288
+ }
289
+ Th_Free(interp, azElem);
290
+ }
291
+
292
+ return rc;
293
+}
294
+
295
+/*
296
+** TH Syntax:
260297
**
261298
** set varname ?value?
262299
*/
263300
static int set_command(
264301
Th_Interp *interp,
@@ -883,10 +920,11 @@
883920
rc = Th_ListAppendCommands(interp, &zElem, &nElem);
884921
if( rc!=TH_OK ){
885922
return rc;
886923
}
887924
Th_SetResult(interp, zElem, nElem);
925
+ if( zElem ) Th_Free(interp, zElem);
888926
return TH_OK;
889927
}
890928
891929
/*
892930
** TH Syntax:
@@ -906,10 +944,11 @@
906944
rc = Th_ListAppendVariables(interp, &zElem, &nElem);
907945
if( rc!=TH_OK ){
908946
return rc;
909947
}
910948
Th_SetResult(interp, zElem, nElem);
949
+ if( zElem ) Th_Free(interp, zElem);
911950
return TH_OK;
912951
}
913952
914953
/*
915954
** TH Syntax:
@@ -1130,10 +1169,11 @@
11301169
{"if", if_command, 0},
11311170
{"info", info_command, 0},
11321171
{"lindex", lindex_command, 0},
11331172
{"list", list_command, 0},
11341173
{"llength", llength_command, 0},
1174
+ {"lsearch", lsearch_command, 0},
11351175
{"proc", proc_command, 0},
11361176
{"rename", rename_command, 0},
11371177
{"set", set_command, 0},
11381178
{"string", string_command, 0},
11391179
{"unset", unset_command, 0},
11401180
--- src/th_lang.c
+++ src/th_lang.c
@@ -255,10 +255,47 @@
255 return rc;
256 }
257
258 /*
259 ** TH Syntax:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260 **
261 ** set varname ?value?
262 */
263 static int set_command(
264 Th_Interp *interp,
@@ -883,10 +920,11 @@
883 rc = Th_ListAppendCommands(interp, &zElem, &nElem);
884 if( rc!=TH_OK ){
885 return rc;
886 }
887 Th_SetResult(interp, zElem, nElem);
 
888 return TH_OK;
889 }
890
891 /*
892 ** TH Syntax:
@@ -906,10 +944,11 @@
906 rc = Th_ListAppendVariables(interp, &zElem, &nElem);
907 if( rc!=TH_OK ){
908 return rc;
909 }
910 Th_SetResult(interp, zElem, nElem);
 
911 return TH_OK;
912 }
913
914 /*
915 ** TH Syntax:
@@ -1130,10 +1169,11 @@
1130 {"if", if_command, 0},
1131 {"info", info_command, 0},
1132 {"lindex", lindex_command, 0},
1133 {"list", list_command, 0},
1134 {"llength", llength_command, 0},
 
1135 {"proc", proc_command, 0},
1136 {"rename", rename_command, 0},
1137 {"set", set_command, 0},
1138 {"string", string_command, 0},
1139 {"unset", unset_command, 0},
1140
--- src/th_lang.c
+++ src/th_lang.c
@@ -255,10 +255,47 @@
255 return rc;
256 }
257
258 /*
259 ** TH Syntax:
260 **
261 ** lsearch list string
262 */
263 static int lsearch_command(
264 Th_Interp *interp,
265 void *ctx,
266 int argc,
267 const char **argv,
268 int *argl
269 ){
270 int rc;
271 char **azElem;
272 int *anElem;
273 int nCount;
274 int i;
275
276 if( argc!=3 ){
277 return Th_WrongNumArgs(interp, "lsearch list string");
278 }
279
280 rc = Th_SplitList(interp, argv[1], argl[1], &azElem, &anElem, &nCount);
281 if( rc==TH_OK ){
282 Th_SetResultInt(interp, -1);
283 for(i=0; i<nCount; i++){
284 if( anElem[i]==argl[2] && 0==memcmp(azElem[i], argv[2], argl[2]) ){
285 Th_SetResultInt(interp, i);
286 break;
287 }
288 }
289 Th_Free(interp, azElem);
290 }
291
292 return rc;
293 }
294
295 /*
296 ** TH Syntax:
297 **
298 ** set varname ?value?
299 */
300 static int set_command(
301 Th_Interp *interp,
@@ -883,10 +920,11 @@
920 rc = Th_ListAppendCommands(interp, &zElem, &nElem);
921 if( rc!=TH_OK ){
922 return rc;
923 }
924 Th_SetResult(interp, zElem, nElem);
925 if( zElem ) Th_Free(interp, zElem);
926 return TH_OK;
927 }
928
929 /*
930 ** TH Syntax:
@@ -906,10 +944,11 @@
944 rc = Th_ListAppendVariables(interp, &zElem, &nElem);
945 if( rc!=TH_OK ){
946 return rc;
947 }
948 Th_SetResult(interp, zElem, nElem);
949 if( zElem ) Th_Free(interp, zElem);
950 return TH_OK;
951 }
952
953 /*
954 ** TH Syntax:
@@ -1130,10 +1169,11 @@
1169 {"if", if_command, 0},
1170 {"info", info_command, 0},
1171 {"lindex", lindex_command, 0},
1172 {"list", list_command, 0},
1173 {"llength", llength_command, 0},
1174 {"lsearch", lsearch_command, 0},
1175 {"proc", proc_command, 0},
1176 {"rename", rename_command, 0},
1177 {"set", set_command, 0},
1178 {"string", string_command, 0},
1179 {"unset", unset_command, 0},
1180
--- src/th_main.c
+++ src/th_main.c
@@ -1324,10 +1324,55 @@
13241324
Th_Trace("[setting %s%#h] => %d<br />\n", strict ? "strict " : "",
13251325
argl[nArg], argv[nArg], rc);
13261326
}
13271327
return rc;
13281328
}
1329
+
1330
+/*
1331
+** TH1 command: glob_match ?-one? ?--? patternList string
1332
+**
1333
+** Checks the string against the specified glob pattern -OR- list of glob
1334
+** patterns and returns non-zero if there is a match.
1335
+*/
1336
+#define GLOB_MATCH_WRONGNUMARGS "glob_match ?-one? ?--? patternList string"
1337
+static int globMatchCmd(
1338
+ Th_Interp *interp,
1339
+ void *p,
1340
+ int argc,
1341
+ const char **argv,
1342
+ int *argl
1343
+){
1344
+ int rc;
1345
+ int one = 0;
1346
+ int nArg = 1;
1347
+ Glob *pGlob = 0;
1348
+ if( argc<3 || argc>5 ){
1349
+ return Th_WrongNumArgs(interp, GLOB_MATCH_WRONGNUMARGS);
1350
+ }
1351
+ if( fossil_strcmp(argv[nArg], "-one")==0 ){
1352
+ one = 1; nArg++;
1353
+ }
1354
+ if( fossil_strcmp(argv[nArg], "--")==0 ) nArg++;
1355
+ if( nArg+2!=argc ){
1356
+ return Th_WrongNumArgs(interp, GLOB_MATCH_WRONGNUMARGS);
1357
+ }
1358
+ if( one ){
1359
+ Th_SetResultInt(interp, sqlite3_strglob(argv[nArg], argv[nArg+1])==0);
1360
+ rc = TH_OK;
1361
+ }else{
1362
+ pGlob = glob_create(argv[nArg]);
1363
+ if( pGlob ){
1364
+ Th_SetResultInt(interp, glob_match(pGlob, argv[nArg+1]));
1365
+ rc = TH_OK;
1366
+ }else{
1367
+ Th_SetResult(interp, "unable to create glob from pattern list", -1);
1368
+ rc = TH_ERROR;
1369
+ }
1370
+ glob_free(pGlob);
1371
+ }
1372
+ return rc;
1373
+}
13291374
13301375
/*
13311376
** TH1 command: regexp ?-nocase? ?--? exp string
13321377
**
13331378
** Checks the string against the specified regular expression and returns
@@ -1553,10 +1598,11 @@
15531598
{"combobox", comboboxCmd, 0},
15541599
{"date", dateCmd, 0},
15551600
{"decorate", wikiCmd, (void*)&aFlags[2]},
15561601
{"enable_output", enableOutputCmd, 0},
15571602
{"getParameter", getParameterCmd, 0},
1603
+ {"glob_match", globMatchCmd, 0},
15581604
{"globalState", globalStateCmd, 0},
15591605
{"httpize", httpizeCmd, 0},
15601606
{"hascap", hascapCmd, (void*)&zeroInt},
15611607
{"hasfeature", hasfeatureCmd, 0},
15621608
{"html", putsCmd, (void*)&aFlags[0]},
15631609
--- src/th_main.c
+++ src/th_main.c
@@ -1324,10 +1324,55 @@
1324 Th_Trace("[setting %s%#h] => %d<br />\n", strict ? "strict " : "",
1325 argl[nArg], argv[nArg], rc);
1326 }
1327 return rc;
1328 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1329
1330 /*
1331 ** TH1 command: regexp ?-nocase? ?--? exp string
1332 **
1333 ** Checks the string against the specified regular expression and returns
@@ -1553,10 +1598,11 @@
1553 {"combobox", comboboxCmd, 0},
1554 {"date", dateCmd, 0},
1555 {"decorate", wikiCmd, (void*)&aFlags[2]},
1556 {"enable_output", enableOutputCmd, 0},
1557 {"getParameter", getParameterCmd, 0},
 
1558 {"globalState", globalStateCmd, 0},
1559 {"httpize", httpizeCmd, 0},
1560 {"hascap", hascapCmd, (void*)&zeroInt},
1561 {"hasfeature", hasfeatureCmd, 0},
1562 {"html", putsCmd, (void*)&aFlags[0]},
1563
--- src/th_main.c
+++ src/th_main.c
@@ -1324,10 +1324,55 @@
1324 Th_Trace("[setting %s%#h] => %d<br />\n", strict ? "strict " : "",
1325 argl[nArg], argv[nArg], rc);
1326 }
1327 return rc;
1328 }
1329
1330 /*
1331 ** TH1 command: glob_match ?-one? ?--? patternList string
1332 **
1333 ** Checks the string against the specified glob pattern -OR- list of glob
1334 ** patterns and returns non-zero if there is a match.
1335 */
1336 #define GLOB_MATCH_WRONGNUMARGS "glob_match ?-one? ?--? patternList string"
1337 static int globMatchCmd(
1338 Th_Interp *interp,
1339 void *p,
1340 int argc,
1341 const char **argv,
1342 int *argl
1343 ){
1344 int rc;
1345 int one = 0;
1346 int nArg = 1;
1347 Glob *pGlob = 0;
1348 if( argc<3 || argc>5 ){
1349 return Th_WrongNumArgs(interp, GLOB_MATCH_WRONGNUMARGS);
1350 }
1351 if( fossil_strcmp(argv[nArg], "-one")==0 ){
1352 one = 1; nArg++;
1353 }
1354 if( fossil_strcmp(argv[nArg], "--")==0 ) nArg++;
1355 if( nArg+2!=argc ){
1356 return Th_WrongNumArgs(interp, GLOB_MATCH_WRONGNUMARGS);
1357 }
1358 if( one ){
1359 Th_SetResultInt(interp, sqlite3_strglob(argv[nArg], argv[nArg+1])==0);
1360 rc = TH_OK;
1361 }else{
1362 pGlob = glob_create(argv[nArg]);
1363 if( pGlob ){
1364 Th_SetResultInt(interp, glob_match(pGlob, argv[nArg+1]));
1365 rc = TH_OK;
1366 }else{
1367 Th_SetResult(interp, "unable to create glob from pattern list", -1);
1368 rc = TH_ERROR;
1369 }
1370 glob_free(pGlob);
1371 }
1372 return rc;
1373 }
1374
1375 /*
1376 ** TH1 command: regexp ?-nocase? ?--? exp string
1377 **
1378 ** Checks the string against the specified regular expression and returns
@@ -1553,10 +1598,11 @@
1598 {"combobox", comboboxCmd, 0},
1599 {"date", dateCmd, 0},
1600 {"decorate", wikiCmd, (void*)&aFlags[2]},
1601 {"enable_output", enableOutputCmd, 0},
1602 {"getParameter", getParameterCmd, 0},
1603 {"glob_match", globMatchCmd, 0},
1604 {"globalState", globalStateCmd, 0},
1605 {"httpize", httpizeCmd, 0},
1606 {"hascap", hascapCmd, (void*)&zeroInt},
1607 {"hasfeature", hasfeatureCmd, 0},
1608 {"html", putsCmd, (void*)&aFlags[0]},
1609
+152 -48
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -44,12 +44,14 @@
4444
}
4545
4646
#define FREE_ARGV_TO_OBJV() \
4747
for(obji=1; obji<argc; obji++){ \
4848
Tcl_DecrRefCount(objv[obji-1]); \
49
+ objv[obji-1] = 0; \
4950
} \
50
- ckfree((char *)objv);
51
+ ckfree((char *)objv); \
52
+ objv = 0;
5153
5254
/*
5355
** Fetch the Tcl interpreter from the specified void pointer, cast to a Tcl
5456
** context.
5557
*/
@@ -61,18 +63,35 @@
6163
** indicates whether or not we can/should use direct objProc calls.
6264
*/
6365
#define GET_CTX_TCL_USEOBJPROC(ctx) \
6466
((struct TclContext *)(ctx))->useObjProc
6567
68
+/*
69
+** This is the name of an environment variable that may refer to a Tcl library
70
+** directory or file name. If this environment variable is set [to anything],
71
+** its value will be used when searching for a Tcl library to load.
72
+*/
73
+#ifndef TCL_PATH_ENV_VAR_NAME
74
+# define TCL_PATH_ENV_VAR_NAME "FOSSIL_TCL_PATH"
75
+#endif
76
+
6677
/*
6778
** Define the Tcl shared library name, some exported function names, and some
6879
** cross-platform macros for use with the Tcl stubs mechanism, when enabled.
6980
*/
7081
#if defined(USE_TCL_STUBS)
7182
# if defined(_WIN32)
72
-# define WIN32_LEAN_AND_MEAN
83
+# if !defined(WIN32_LEAN_AND_MEAN)
84
+# define WIN32_LEAN_AND_MEAN
85
+# endif
86
+# if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0502)
87
+# define _WIN32_WINNT 0x0502 /* SetDllDirectory, Windows XP SP2 */
88
+# endif
7389
# include <windows.h>
90
+# ifndef TCL_DIRECTORY_SEP
91
+# define TCL_DIRECTORY_SEP '\\'
92
+# endif
7493
# ifndef TCL_LIBRARY_NAME
7594
# define TCL_LIBRARY_NAME "tcl86.dll\0"
7695
# endif
7796
# ifndef TCL_MINOR_OFFSET
7897
# define TCL_MINOR_OFFSET (4)
@@ -86,10 +105,13 @@
86105
# ifndef dlclose
87106
# define dlclose(a) FreeLibrary((HANDLE)(a))
88107
# endif
89108
# else
90109
# include <dlfcn.h>
110
+# ifndef TCL_DIRECTORY_SEP
111
+# define TCL_DIRECTORY_SEP '/'
112
+# endif
91113
# if defined(__CYGWIN__)
92114
# ifndef TCL_LIBRARY_NAME
93115
# define TCL_LIBRARY_NAME "libtcl8.6.dll\0"
94116
# endif
95117
# ifndef TCL_MINOR_OFFSET
@@ -123,22 +145,35 @@
123145
# ifndef TCL_FINALIZE_NAME
124146
# define TCL_FINALIZE_NAME "_Tcl_Finalize\0"
125147
# endif
126148
#endif /* defined(USE_TCL_STUBS) */
127149
150
+/*
151
+** If this constant is defined to non-zero, the Win32 SetDllDirectory function
152
+** will be used during the Tcl library loading process if the path environment
153
+** variable for Tcl was set.
154
+*/
155
+#ifndef TCL_USE_SET_DLL_DIRECTORY
156
+# if defined(_WIN32) && defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)
157
+# define TCL_USE_SET_DLL_DIRECTORY (1)
158
+# else
159
+# define TCL_USE_SET_DLL_DIRECTORY (0)
160
+# endif
161
+#endif /* TCL_USE_SET_DLL_DIRECTORY */
162
+
128163
/*
129164
** The function types for Tcl_FindExecutable and Tcl_CreateInterp are needed
130165
** when the Tcl library is being loaded dynamically by a stubs-enabled
131166
** application (i.e. the inverse of using a stubs-enabled package). These are
132167
** the only Tcl API functions that MUST be called prior to being able to call
133168
** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete
134169
** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp
135170
** and Tcl_Finalize function types are also required.
136171
*/
137
-typedef void (tcl_FindExecutableProc) (const char * argv0);
172
+typedef void (tcl_FindExecutableProc) (const char *);
138173
typedef Tcl_Interp *(tcl_CreateInterpProc) (void);
139
-typedef void (tcl_DeleteInterpProc) (Tcl_Interp *interp);
174
+typedef void (tcl_DeleteInterpProc) (Tcl_Interp *);
140175
typedef void (tcl_FinalizeProc) (void);
141176
142177
/*
143178
** The function types for the "hook" functions to be called before and after a
144179
** TH1 command makes a call to evaluate a Tcl script. If the "pre" function
@@ -242,10 +277,25 @@
242277
if( major==8 && minor==6 && type==TCL_BETA_RELEASE && patchLevel<3 ){
243278
return 0; /* NOTE: Disabled on Tcl 8.6b1/b2, SF bug #3399564. */
244279
}
245280
return 1; /* NOTE: For all other cases, assume good. */
246281
}
282
+
283
+/*
284
+** Is the loaded version of Tcl one where TIP #285 (asynchronous script
285
+** cancellation) is available? This should return non-zero only for Tcl
286
+** 8.6 and higher.
287
+*/
288
+static int canUseTip285(){
289
+ int major = -1, minor = -1, patchLevel = -1, type = -1;
290
+
291
+ Tcl_GetVersion(&major, &minor, &patchLevel, &type);
292
+ if( major<0 || minor<0 || patchLevel<0 || type<0 ){
293
+ return 0; /* NOTE: Invalid version info, assume bad. */
294
+ }
295
+ return (major>8 || (major==8 && minor>=6));
296
+}
247297
248298
/*
249299
** Creates and initializes a Tcl interpreter for use with the specified TH1
250300
** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
251301
** by the caller. This must be declared here because quite a few functions in
@@ -337,17 +387,18 @@
337387
** copied from and should be kept in sync with the one in "main.c".
338388
*/
339389
struct TclContext {
340390
int argc; /* Number of original arguments. */
341391
char **argv; /* Full copy of the original arguments. */
342
- void *library; /* The Tcl library module handle. */
392
+ void *hLibrary; /* The Tcl library module handle. */
343393
tcl_FindExecutableProc *xFindExecutable; /* Tcl_FindExecutable() pointer. */
344394
tcl_CreateInterpProc *xCreateInterp; /* Tcl_CreateInterp() pointer. */
345395
tcl_DeleteInterpProc *xDeleteInterp; /* Tcl_DeleteInterp() pointer. */
346396
tcl_FinalizeProc *xFinalize; /* Tcl_Finalize() pointer. */
347397
Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
348398
int useObjProc; /* Non-zero if an objProc can be called directly. */
399
+ int useTip285; /* Non-zero if TIP #285 is available. */
349400
char *setup; /* The optional Tcl setup script. */
350401
tcl_NotifyProc *xPreEval; /* Optional, called before Tcl_Eval*(). */
351402
void *pPreContext; /* Optional, provided to xPreEval(). */
352403
tcl_NotifyProc *xPostEval; /* Optional, called after Tcl_Eval*(). */
353404
void *pPostContext; /* Optional, provided to xPostEval(). */
@@ -423,18 +474,18 @@
423474
Tcl_Preserve((ClientData)tclInterp);
424475
if( argc==2 ){
425476
objPtr = Tcl_NewStringObj(argv[1], argl[1]);
426477
Tcl_IncrRefCount(objPtr);
427478
rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
428
- Tcl_DecrRefCount(objPtr);
479
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
429480
}else{
430481
USE_ARGV_TO_OBJV();
431482
COPY_ARGV_TO_OBJV();
432483
objPtr = Tcl_ConcatObj(objc, objv);
433484
Tcl_IncrRefCount(objPtr);
434485
rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
435
- Tcl_DecrRefCount(objPtr);
486
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
436487
FREE_ARGV_TO_OBJV();
437488
}
438489
zResult = getTclResult(tclInterp, &nResult);
439490
Th_SetResult(interp, zResult, nResult);
440491
Tcl_Release((ClientData)tclInterp);
@@ -482,27 +533,29 @@
482533
Tcl_Preserve((ClientData)tclInterp);
483534
if( argc==2 ){
484535
objPtr = Tcl_NewStringObj(argv[1], argl[1]);
485536
Tcl_IncrRefCount(objPtr);
486537
rc = Tcl_ExprObj(tclInterp, objPtr, &resultObjPtr);
487
- Tcl_DecrRefCount(objPtr);
538
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
488539
}else{
489540
USE_ARGV_TO_OBJV();
490541
COPY_ARGV_TO_OBJV();
491542
objPtr = Tcl_ConcatObj(objc, objv);
492543
Tcl_IncrRefCount(objPtr);
493544
rc = Tcl_ExprObj(tclInterp, objPtr, &resultObjPtr);
494
- Tcl_DecrRefCount(objPtr);
545
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
495546
FREE_ARGV_TO_OBJV();
496547
}
497548
if( rc==TCL_OK ){
498549
zResult = Tcl_GetStringFromObj(resultObjPtr, &nResult);
499550
}else{
500551
zResult = getTclResult(tclInterp, &nResult);
501552
}
502553
Th_SetResult(interp, zResult, nResult);
503
- if( rc==TCL_OK ) Tcl_DecrRefCount(resultObjPtr);
554
+ if( rc==TCL_OK ){
555
+ Tcl_DecrRefCount(resultObjPtr); resultObjPtr = 0;
556
+ }
504557
Tcl_Release((ClientData)tclInterp);
505558
rc = notifyPreOrPostEval(1, interp, ctx, argc, argv, argl,
506559
getTh1ReturnCode(rc));
507560
return rc;
508561
}
@@ -550,21 +603,21 @@
550603
Tcl_Obj *objPtr = Tcl_NewStringObj(argv[1], argl[1]);
551604
Tcl_IncrRefCount(objPtr);
552605
command = Tcl_GetCommandFromObj(tclInterp, objPtr);
553606
if( !command || Tcl_GetCommandInfoFromToken(command, &cmdInfo)==0 ){
554607
Th_ErrorMessage(interp, "Tcl command not found:", argv[1], argl[1]);
555
- Tcl_DecrRefCount(objPtr);
608
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
556609
Tcl_Release((ClientData)tclInterp);
557610
return TH_ERROR;
558611
}
559612
if( !cmdInfo.objProc ){
560613
Th_ErrorMessage(interp, "cannot invoke Tcl command:", argv[1], argl[1]);
561
- Tcl_DecrRefCount(objPtr);
614
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
562615
Tcl_Release((ClientData)tclInterp);
563616
return TH_ERROR;
564617
}
565
- Tcl_DecrRefCount(objPtr);
618
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
566619
COPY_ARGV_TO_OBJV();
567620
Tcl_ResetResult(tclInterp);
568621
rc = cmdInfo.objProc(cmdInfo.objClientData, tclInterp, objc, objv);
569622
FREE_ARGV_TO_OBJV();
570623
}else
@@ -686,95 +739,131 @@
686739
** shared library and fetch the function pointers necessary to create an
687740
** interpreter and initialize the stubs mechanism; otherwise, simply setup
688741
** the function pointers provided by the caller with the statically linked
689742
** functions.
690743
*/
744
+char *fossil_getenv(const char *zName); /* file.h */
745
+int file_isdir(const char *zPath); /* file.h */
746
+char *file_dirname(const char *zPath); /* file.h */
747
+void fossil_free(void *p); /* util.h */
748
+
691749
static int loadTcl(
692750
Th_Interp *interp,
693
- void **pLibrary,
751
+ void **phLibrary,
694752
tcl_FindExecutableProc **pxFindExecutable,
695753
tcl_CreateInterpProc **pxCreateInterp,
696754
tcl_DeleteInterpProc **pxDeleteInterp,
697755
tcl_FinalizeProc **pxFinalize
698756
){
699757
#if defined(USE_TCL_STUBS)
700
- char fileName[] = TCL_LIBRARY_NAME;
758
+ const char *zEnvPath = fossil_getenv(TCL_PATH_ENV_VAR_NAME);
759
+ char aFileName[] = TCL_LIBRARY_NAME;
701760
#endif /* defined(USE_TCL_STUBS) */
702761
703
- if( !pLibrary || !pxFindExecutable || !pxCreateInterp ||
762
+ if( !phLibrary || !pxFindExecutable || !pxCreateInterp ||
704763
!pxDeleteInterp || !pxFinalize ){
705764
Th_ErrorMessage(interp,
706765
"invalid Tcl loader argument(s)", (const char *)"", 0);
707766
return TH_ERROR;
708767
}
709768
#if defined(USE_TCL_STUBS)
710769
do {
711
- void *library = dlopen(fileName, RTLD_NOW | RTLD_GLOBAL);
712
- if( library ){
770
+ char *zFileName;
771
+ void *hLibrary;
772
+ if( !zEnvPath ){
773
+ zFileName = aFileName; /* NOTE: Assume present in PATH. */
774
+ }else if( file_isdir(zEnvPath)==1 ){
775
+#if TCL_USE_SET_DLL_DIRECTORY
776
+ SetDllDirectory(zEnvPath); /* NOTE: Maybe needed for "zlib1.dll". */
777
+#endif /* TCL_USE_SET_DLL_DIRECTORY */
778
+ /* NOTE: The environment variable contains a directory name. */
779
+ zFileName = sqlite3_mprintf("%s%c%s%c", zEnvPath, TCL_DIRECTORY_SEP,
780
+ aFileName, '\0');
781
+ }else{
782
+#if TCL_USE_SET_DLL_DIRECTORY
783
+ char *zDirName = file_dirname(zEnvPath);
784
+ if( zDirName ){
785
+ SetDllDirectory(zDirName); /* NOTE: Maybe needed for "zlib1.dll". */
786
+ }
787
+#endif /* TCL_USE_SET_DLL_DIRECTORY */
788
+ /* NOTE: The environment variable might contain a file name. */
789
+ zFileName = sqlite3_mprintf("%s%c", zEnvPath, '\0');
790
+#if TCL_USE_SET_DLL_DIRECTORY
791
+ if( zDirName ){
792
+ fossil_free(zDirName); zDirName = 0;
793
+ }
794
+#endif /* TCL_USE_SET_DLL_DIRECTORY */
795
+ }
796
+ hLibrary = dlopen(zFileName, RTLD_NOW | RTLD_GLOBAL);
797
+ /* NOTE: If the file name was allocated, free it now. */
798
+ if( zFileName!=aFileName ){
799
+ sqlite3_free(zFileName); zFileName = 0;
800
+ }
801
+ if( hLibrary ){
713802
tcl_FindExecutableProc *xFindExecutable;
714803
tcl_CreateInterpProc *xCreateInterp;
715804
tcl_DeleteInterpProc *xDeleteInterp;
716805
tcl_FinalizeProc *xFinalize;
717806
const char *procName = TCL_FINDEXECUTABLE_NAME;
718
- xFindExecutable = (tcl_FindExecutableProc *)dlsym(library, procName + 1);
807
+ xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName+1);
719808
if( !xFindExecutable ){
720
- xFindExecutable = (tcl_FindExecutableProc *)dlsym(library, procName);
809
+ xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName);
721810
}
722811
if( !xFindExecutable ){
723812
Th_ErrorMessage(interp,
724813
"could not locate Tcl_FindExecutable", (const char *)"", 0);
725
- dlclose(library);
814
+ dlclose(hLibrary); hLibrary = 0;
726815
return TH_ERROR;
727816
}
728817
procName = TCL_CREATEINTERP_NAME;
729
- xCreateInterp = (tcl_CreateInterpProc *)dlsym(library, procName + 1);
818
+ xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName+1);
730819
if( !xCreateInterp ){
731
- xCreateInterp = (tcl_CreateInterpProc *)dlsym(library, procName);
820
+ xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName);
732821
}
733822
if( !xCreateInterp ){
734823
Th_ErrorMessage(interp,
735824
"could not locate Tcl_CreateInterp", (const char *)"", 0);
736
- dlclose(library);
825
+ dlclose(hLibrary); hLibrary = 0;
737826
return TH_ERROR;
738827
}
739828
procName = TCL_DELETEINTERP_NAME;
740
- xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(library, procName + 1);
829
+ xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(hLibrary, procName+1);
741830
if( !xDeleteInterp ){
742
- xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(library, procName);
831
+ xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(hLibrary, procName);
743832
}
744833
if( !xDeleteInterp ){
745834
Th_ErrorMessage(interp,
746835
"could not locate Tcl_DeleteInterp", (const char *)"", 0);
747
- dlclose(library);
836
+ dlclose(hLibrary); hLibrary = 0;
748837
return TH_ERROR;
749838
}
750839
procName = TCL_FINALIZE_NAME;
751
- xFinalize = (tcl_FinalizeProc *)dlsym(library, procName + 1);
840
+ xFinalize = (tcl_FinalizeProc *)dlsym(hLibrary, procName+1);
752841
if( !xFinalize ){
753
- xFinalize = (tcl_FinalizeProc *)dlsym(library, procName);
842
+ xFinalize = (tcl_FinalizeProc *)dlsym(hLibrary, procName);
754843
}
755844
if( !xFinalize ){
756845
Th_ErrorMessage(interp,
757846
"could not locate Tcl_Finalize", (const char *)"", 0);
758
- dlclose(library);
847
+ dlclose(hLibrary); hLibrary = 0;
759848
return TH_ERROR;
760849
}
761
- *pLibrary = library;
850
+ *phLibrary = hLibrary;
762851
*pxFindExecutable = xFindExecutable;
763852
*pxCreateInterp = xCreateInterp;
764853
*pxDeleteInterp = xDeleteInterp;
765854
*pxFinalize = xFinalize;
766855
return TH_OK;
767856
}
768
- } while( --fileName[TCL_MINOR_OFFSET]>'3' ); /* Tcl 8.4+ */
769
- fileName[TCL_MINOR_OFFSET] = 'x';
857
+ } while( --aFileName[TCL_MINOR_OFFSET]>'3' ); /* Tcl 8.4+ */
858
+ aFileName[TCL_MINOR_OFFSET] = 'x';
770859
Th_ErrorMessage(interp,
771860
"could not load any supported Tcl 8.6, 8.5, or 8.4 shared library \"",
772
- fileName, -1);
861
+ aFileName, -1);
773862
return TH_ERROR;
774863
#else
775
- *pLibrary = 0;
864
+ *phLibrary = 0;
776865
*pxFindExecutable = Tcl_FindExecutable;
777866
*pxCreateInterp = Tcl_CreateInterp;
778867
*pxDeleteInterp = Tcl_DeleteInterp;
779868
*pxFinalize = Tcl_Finalize;
780869
return TH_OK;
@@ -800,19 +889,19 @@
800889
}
801890
objPtr = Tcl_NewStringObj(argv[0], -1);
802891
Tcl_IncrRefCount(objPtr);
803892
resultObjPtr = Tcl_SetVar2Ex(pInterp, "argv0", NULL, objPtr,
804893
TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
805
- Tcl_DecrRefCount(objPtr);
894
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
806895
if( !resultObjPtr ){
807896
return TCL_ERROR;
808897
}
809898
objPtr = Tcl_NewIntObj(argc - 1);
810899
Tcl_IncrRefCount(objPtr);
811900
resultObjPtr = Tcl_SetVar2Ex(pInterp, "argc", NULL, objPtr,
812901
TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
813
- Tcl_DecrRefCount(objPtr);
902
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
814903
if( !resultObjPtr ){
815904
return TCL_ERROR;
816905
}
817906
listPtr = Tcl_NewListObj(0, NULL);
818907
Tcl_IncrRefCount(listPtr);
@@ -819,11 +908,11 @@
819908
if( argc>1 ){
820909
while( --argc ){
821910
objPtr = Tcl_NewStringObj(*++argv, -1);
822911
Tcl_IncrRefCount(objPtr);
823912
rc = Tcl_ListObjAppendElement(pInterp, listPtr, objPtr);
824
- Tcl_DecrRefCount(objPtr);
913
+ Tcl_DecrRefCount(objPtr); objPtr = 0;
825914
if( rc!=TCL_OK ){
826915
break;
827916
}
828917
}
829918
}
@@ -832,11 +921,11 @@
832921
TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
833922
if( !resultObjPtr ){
834923
rc = TCL_ERROR;
835924
}
836925
}
837
- Tcl_DecrRefCount(listPtr);
926
+ Tcl_DecrRefCount(listPtr); listPtr = 0;
838927
return rc;
839928
}
840929
841930
/*
842931
** Evaluate a Tcl script, creating the Tcl interpreter if necessary. If the
@@ -850,22 +939,25 @@
850939
int evaluateTclWithEvents(
851940
Th_Interp *interp,
852941
void *pContext,
853942
const char *zScript,
854943
int nScript,
944
+ int bCancel,
855945
int bWait,
856946
int bVerbose
857947
){
858948
struct TclContext *tclContext = (struct TclContext *)pContext;
859949
Tcl_Interp *tclInterp;
860950
int rc;
861951
int flags = TCL_ALL_EVENTS;
952
+ int useTip285;
862953
863954
if( createTclInterp(interp, pContext)!=TH_OK ){
864955
return TH_ERROR;
865956
}
866957
tclInterp = tclContext->interp;
958
+ useTip285 = bCancel ? tclContext->useTip285 : 0;
867959
rc = Tcl_EvalEx(tclInterp, zScript, nScript, TCL_EVAL_GLOBAL);
868960
if( rc!=TCL_OK ){
869961
if( bVerbose ){
870962
const char *zResult = getTclResult(tclInterp, 0);
871963
fossil_print("%s: ", getTclReturnCodeName(rc, 0));
@@ -872,13 +964,20 @@
872964
fossil_print("%s\n", zResult);
873965
}
874966
return rc;
875967
}
876968
if( !bWait ) flags |= TCL_DONT_WAIT;
969
+ Tcl_Preserve((ClientData)tclInterp);
877970
while( Tcl_DoOneEvent(flags) ){
878
- /* do nothing */
971
+ if( Tcl_InterpDeleted(tclInterp) ){
972
+ break;
973
+ }
974
+ if( useTip285 && Tcl_Canceled(tclInterp, 0)!=TCL_OK ){
975
+ break;
976
+ }
879977
}
978
+ Tcl_Release((ClientData)tclInterp);
880979
return rc;
881980
}
882981
883982
/*
884983
** Creates and initializes a Tcl interpreter for use with the specified TH1
@@ -902,11 +1001,11 @@
9021001
return TH_ERROR;
9031002
}
9041003
if( tclContext->interp ){
9051004
return TH_OK;
9061005
}
907
- if( loadTcl(interp, &tclContext->library, &tclContext->xFindExecutable,
1006
+ if( loadTcl(interp, &tclContext->hLibrary, &tclContext->xFindExecutable,
9081007
&tclContext->xCreateInterp, &tclContext->xDeleteInterp,
9091008
&tclContext->xFinalize)!=TH_OK ){
9101009
return TH_ERROR;
9111010
}
9121011
argc = tclContext->argc;
@@ -959,14 +1058,19 @@
9591058
Tcl_DeleteInterp(tclInterp);
9601059
tclContext->interp = tclInterp = 0;
9611060
return TH_ERROR;
9621061
}
9631062
/*
964
- ** Determine if an objProc can be called directly for a Tcl command invoked
965
- ** via the tclInvoke TH1 command.
1063
+ ** Determine (and cache) if an objProc can be called directly for a Tcl
1064
+ ** command invoked via the tclInvoke TH1 command.
9661065
*/
9671066
tclContext->useObjProc = canUseObjProc();
1067
+ /*
1068
+ ** Determine (and cache) whether or not we can use TIP #285 (asynchronous
1069
+ ** script cancellation).
1070
+ */
1071
+ tclContext->useTip285 = canUseTip285();
9681072
/* Add the TH1 integration commands to Tcl. */
9691073
Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp);
9701074
Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL);
9711075
Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL);
9721076
/* If necessary, evaluate the custom Tcl setup script. */
@@ -990,11 +1094,11 @@
9901094
){
9911095
struct TclContext *tclContext = (struct TclContext *)pContext;
9921096
Tcl_Interp *tclInterp;
9931097
tcl_FinalizeProc *xFinalize;
9941098
#if defined(USE_TCL_STUBS)
995
- void *library;
1099
+ void *hLibrary;
9961100
#endif /* defined(USE_TCL_STUBS) */
9971101
9981102
if( !tclContext ){
9991103
Th_ErrorMessage(interp,
10001104
"invalid Tcl context", (const char *)"", 0);
@@ -1028,14 +1132,14 @@
10281132
** http://comments.gmane.org/gmane.comp.gnu.mingw.user/41724
10291133
**
10301134
** The workaround is to manually unload the loaded Tcl library prior to
10311135
** exiting the process.
10321136
*/
1033
- library = tclContext->library;
1034
- if( library ){
1035
- dlclose(library);
1036
- tclContext->library = library = 0;
1137
+ hLibrary = tclContext->hLibrary;
1138
+ if( hLibrary ){
1139
+ dlclose(hLibrary);
1140
+ tclContext->hLibrary = hLibrary = 0;
10371141
}
10381142
#endif /* defined(USE_TCL_STUBS) */
10391143
return TH_OK;
10401144
}
10411145
10421146
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -44,12 +44,14 @@
44 }
45
46 #define FREE_ARGV_TO_OBJV() \
47 for(obji=1; obji<argc; obji++){ \
48 Tcl_DecrRefCount(objv[obji-1]); \
 
49 } \
50 ckfree((char *)objv);
 
51
52 /*
53 ** Fetch the Tcl interpreter from the specified void pointer, cast to a Tcl
54 ** context.
55 */
@@ -61,18 +63,35 @@
61 ** indicates whether or not we can/should use direct objProc calls.
62 */
63 #define GET_CTX_TCL_USEOBJPROC(ctx) \
64 ((struct TclContext *)(ctx))->useObjProc
65
 
 
 
 
 
 
 
 
 
66 /*
67 ** Define the Tcl shared library name, some exported function names, and some
68 ** cross-platform macros for use with the Tcl stubs mechanism, when enabled.
69 */
70 #if defined(USE_TCL_STUBS)
71 # if defined(_WIN32)
72 # define WIN32_LEAN_AND_MEAN
 
 
 
 
 
73 # include <windows.h>
 
 
 
74 # ifndef TCL_LIBRARY_NAME
75 # define TCL_LIBRARY_NAME "tcl86.dll\0"
76 # endif
77 # ifndef TCL_MINOR_OFFSET
78 # define TCL_MINOR_OFFSET (4)
@@ -86,10 +105,13 @@
86 # ifndef dlclose
87 # define dlclose(a) FreeLibrary((HANDLE)(a))
88 # endif
89 # else
90 # include <dlfcn.h>
 
 
 
91 # if defined(__CYGWIN__)
92 # ifndef TCL_LIBRARY_NAME
93 # define TCL_LIBRARY_NAME "libtcl8.6.dll\0"
94 # endif
95 # ifndef TCL_MINOR_OFFSET
@@ -123,22 +145,35 @@
123 # ifndef TCL_FINALIZE_NAME
124 # define TCL_FINALIZE_NAME "_Tcl_Finalize\0"
125 # endif
126 #endif /* defined(USE_TCL_STUBS) */
127
 
 
 
 
 
 
 
 
 
 
 
 
 
128 /*
129 ** The function types for Tcl_FindExecutable and Tcl_CreateInterp are needed
130 ** when the Tcl library is being loaded dynamically by a stubs-enabled
131 ** application (i.e. the inverse of using a stubs-enabled package). These are
132 ** the only Tcl API functions that MUST be called prior to being able to call
133 ** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete
134 ** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp
135 ** and Tcl_Finalize function types are also required.
136 */
137 typedef void (tcl_FindExecutableProc) (const char * argv0);
138 typedef Tcl_Interp *(tcl_CreateInterpProc) (void);
139 typedef void (tcl_DeleteInterpProc) (Tcl_Interp *interp);
140 typedef void (tcl_FinalizeProc) (void);
141
142 /*
143 ** The function types for the "hook" functions to be called before and after a
144 ** TH1 command makes a call to evaluate a Tcl script. If the "pre" function
@@ -242,10 +277,25 @@
242 if( major==8 && minor==6 && type==TCL_BETA_RELEASE && patchLevel<3 ){
243 return 0; /* NOTE: Disabled on Tcl 8.6b1/b2, SF bug #3399564. */
244 }
245 return 1; /* NOTE: For all other cases, assume good. */
246 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
248 /*
249 ** Creates and initializes a Tcl interpreter for use with the specified TH1
250 ** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
251 ** by the caller. This must be declared here because quite a few functions in
@@ -337,17 +387,18 @@
337 ** copied from and should be kept in sync with the one in "main.c".
338 */
339 struct TclContext {
340 int argc; /* Number of original arguments. */
341 char **argv; /* Full copy of the original arguments. */
342 void *library; /* The Tcl library module handle. */
343 tcl_FindExecutableProc *xFindExecutable; /* Tcl_FindExecutable() pointer. */
344 tcl_CreateInterpProc *xCreateInterp; /* Tcl_CreateInterp() pointer. */
345 tcl_DeleteInterpProc *xDeleteInterp; /* Tcl_DeleteInterp() pointer. */
346 tcl_FinalizeProc *xFinalize; /* Tcl_Finalize() pointer. */
347 Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
348 int useObjProc; /* Non-zero if an objProc can be called directly. */
 
349 char *setup; /* The optional Tcl setup script. */
350 tcl_NotifyProc *xPreEval; /* Optional, called before Tcl_Eval*(). */
351 void *pPreContext; /* Optional, provided to xPreEval(). */
352 tcl_NotifyProc *xPostEval; /* Optional, called after Tcl_Eval*(). */
353 void *pPostContext; /* Optional, provided to xPostEval(). */
@@ -423,18 +474,18 @@
423 Tcl_Preserve((ClientData)tclInterp);
424 if( argc==2 ){
425 objPtr = Tcl_NewStringObj(argv[1], argl[1]);
426 Tcl_IncrRefCount(objPtr);
427 rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
428 Tcl_DecrRefCount(objPtr);
429 }else{
430 USE_ARGV_TO_OBJV();
431 COPY_ARGV_TO_OBJV();
432 objPtr = Tcl_ConcatObj(objc, objv);
433 Tcl_IncrRefCount(objPtr);
434 rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
435 Tcl_DecrRefCount(objPtr);
436 FREE_ARGV_TO_OBJV();
437 }
438 zResult = getTclResult(tclInterp, &nResult);
439 Th_SetResult(interp, zResult, nResult);
440 Tcl_Release((ClientData)tclInterp);
@@ -482,27 +533,29 @@
482 Tcl_Preserve((ClientData)tclInterp);
483 if( argc==2 ){
484 objPtr = Tcl_NewStringObj(argv[1], argl[1]);
485 Tcl_IncrRefCount(objPtr);
486 rc = Tcl_ExprObj(tclInterp, objPtr, &resultObjPtr);
487 Tcl_DecrRefCount(objPtr);
488 }else{
489 USE_ARGV_TO_OBJV();
490 COPY_ARGV_TO_OBJV();
491 objPtr = Tcl_ConcatObj(objc, objv);
492 Tcl_IncrRefCount(objPtr);
493 rc = Tcl_ExprObj(tclInterp, objPtr, &resultObjPtr);
494 Tcl_DecrRefCount(objPtr);
495 FREE_ARGV_TO_OBJV();
496 }
497 if( rc==TCL_OK ){
498 zResult = Tcl_GetStringFromObj(resultObjPtr, &nResult);
499 }else{
500 zResult = getTclResult(tclInterp, &nResult);
501 }
502 Th_SetResult(interp, zResult, nResult);
503 if( rc==TCL_OK ) Tcl_DecrRefCount(resultObjPtr);
 
 
504 Tcl_Release((ClientData)tclInterp);
505 rc = notifyPreOrPostEval(1, interp, ctx, argc, argv, argl,
506 getTh1ReturnCode(rc));
507 return rc;
508 }
@@ -550,21 +603,21 @@
550 Tcl_Obj *objPtr = Tcl_NewStringObj(argv[1], argl[1]);
551 Tcl_IncrRefCount(objPtr);
552 command = Tcl_GetCommandFromObj(tclInterp, objPtr);
553 if( !command || Tcl_GetCommandInfoFromToken(command, &cmdInfo)==0 ){
554 Th_ErrorMessage(interp, "Tcl command not found:", argv[1], argl[1]);
555 Tcl_DecrRefCount(objPtr);
556 Tcl_Release((ClientData)tclInterp);
557 return TH_ERROR;
558 }
559 if( !cmdInfo.objProc ){
560 Th_ErrorMessage(interp, "cannot invoke Tcl command:", argv[1], argl[1]);
561 Tcl_DecrRefCount(objPtr);
562 Tcl_Release((ClientData)tclInterp);
563 return TH_ERROR;
564 }
565 Tcl_DecrRefCount(objPtr);
566 COPY_ARGV_TO_OBJV();
567 Tcl_ResetResult(tclInterp);
568 rc = cmdInfo.objProc(cmdInfo.objClientData, tclInterp, objc, objv);
569 FREE_ARGV_TO_OBJV();
570 }else
@@ -686,95 +739,131 @@
686 ** shared library and fetch the function pointers necessary to create an
687 ** interpreter and initialize the stubs mechanism; otherwise, simply setup
688 ** the function pointers provided by the caller with the statically linked
689 ** functions.
690 */
 
 
 
 
 
691 static int loadTcl(
692 Th_Interp *interp,
693 void **pLibrary,
694 tcl_FindExecutableProc **pxFindExecutable,
695 tcl_CreateInterpProc **pxCreateInterp,
696 tcl_DeleteInterpProc **pxDeleteInterp,
697 tcl_FinalizeProc **pxFinalize
698 ){
699 #if defined(USE_TCL_STUBS)
700 char fileName[] = TCL_LIBRARY_NAME;
 
701 #endif /* defined(USE_TCL_STUBS) */
702
703 if( !pLibrary || !pxFindExecutable || !pxCreateInterp ||
704 !pxDeleteInterp || !pxFinalize ){
705 Th_ErrorMessage(interp,
706 "invalid Tcl loader argument(s)", (const char *)"", 0);
707 return TH_ERROR;
708 }
709 #if defined(USE_TCL_STUBS)
710 do {
711 void *library = dlopen(fileName, RTLD_NOW | RTLD_GLOBAL);
712 if( library ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
713 tcl_FindExecutableProc *xFindExecutable;
714 tcl_CreateInterpProc *xCreateInterp;
715 tcl_DeleteInterpProc *xDeleteInterp;
716 tcl_FinalizeProc *xFinalize;
717 const char *procName = TCL_FINDEXECUTABLE_NAME;
718 xFindExecutable = (tcl_FindExecutableProc *)dlsym(library, procName + 1);
719 if( !xFindExecutable ){
720 xFindExecutable = (tcl_FindExecutableProc *)dlsym(library, procName);
721 }
722 if( !xFindExecutable ){
723 Th_ErrorMessage(interp,
724 "could not locate Tcl_FindExecutable", (const char *)"", 0);
725 dlclose(library);
726 return TH_ERROR;
727 }
728 procName = TCL_CREATEINTERP_NAME;
729 xCreateInterp = (tcl_CreateInterpProc *)dlsym(library, procName + 1);
730 if( !xCreateInterp ){
731 xCreateInterp = (tcl_CreateInterpProc *)dlsym(library, procName);
732 }
733 if( !xCreateInterp ){
734 Th_ErrorMessage(interp,
735 "could not locate Tcl_CreateInterp", (const char *)"", 0);
736 dlclose(library);
737 return TH_ERROR;
738 }
739 procName = TCL_DELETEINTERP_NAME;
740 xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(library, procName + 1);
741 if( !xDeleteInterp ){
742 xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(library, procName);
743 }
744 if( !xDeleteInterp ){
745 Th_ErrorMessage(interp,
746 "could not locate Tcl_DeleteInterp", (const char *)"", 0);
747 dlclose(library);
748 return TH_ERROR;
749 }
750 procName = TCL_FINALIZE_NAME;
751 xFinalize = (tcl_FinalizeProc *)dlsym(library, procName + 1);
752 if( !xFinalize ){
753 xFinalize = (tcl_FinalizeProc *)dlsym(library, procName);
754 }
755 if( !xFinalize ){
756 Th_ErrorMessage(interp,
757 "could not locate Tcl_Finalize", (const char *)"", 0);
758 dlclose(library);
759 return TH_ERROR;
760 }
761 *pLibrary = library;
762 *pxFindExecutable = xFindExecutable;
763 *pxCreateInterp = xCreateInterp;
764 *pxDeleteInterp = xDeleteInterp;
765 *pxFinalize = xFinalize;
766 return TH_OK;
767 }
768 } while( --fileName[TCL_MINOR_OFFSET]>'3' ); /* Tcl 8.4+ */
769 fileName[TCL_MINOR_OFFSET] = 'x';
770 Th_ErrorMessage(interp,
771 "could not load any supported Tcl 8.6, 8.5, or 8.4 shared library \"",
772 fileName, -1);
773 return TH_ERROR;
774 #else
775 *pLibrary = 0;
776 *pxFindExecutable = Tcl_FindExecutable;
777 *pxCreateInterp = Tcl_CreateInterp;
778 *pxDeleteInterp = Tcl_DeleteInterp;
779 *pxFinalize = Tcl_Finalize;
780 return TH_OK;
@@ -800,19 +889,19 @@
800 }
801 objPtr = Tcl_NewStringObj(argv[0], -1);
802 Tcl_IncrRefCount(objPtr);
803 resultObjPtr = Tcl_SetVar2Ex(pInterp, "argv0", NULL, objPtr,
804 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
805 Tcl_DecrRefCount(objPtr);
806 if( !resultObjPtr ){
807 return TCL_ERROR;
808 }
809 objPtr = Tcl_NewIntObj(argc - 1);
810 Tcl_IncrRefCount(objPtr);
811 resultObjPtr = Tcl_SetVar2Ex(pInterp, "argc", NULL, objPtr,
812 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
813 Tcl_DecrRefCount(objPtr);
814 if( !resultObjPtr ){
815 return TCL_ERROR;
816 }
817 listPtr = Tcl_NewListObj(0, NULL);
818 Tcl_IncrRefCount(listPtr);
@@ -819,11 +908,11 @@
819 if( argc>1 ){
820 while( --argc ){
821 objPtr = Tcl_NewStringObj(*++argv, -1);
822 Tcl_IncrRefCount(objPtr);
823 rc = Tcl_ListObjAppendElement(pInterp, listPtr, objPtr);
824 Tcl_DecrRefCount(objPtr);
825 if( rc!=TCL_OK ){
826 break;
827 }
828 }
829 }
@@ -832,11 +921,11 @@
832 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
833 if( !resultObjPtr ){
834 rc = TCL_ERROR;
835 }
836 }
837 Tcl_DecrRefCount(listPtr);
838 return rc;
839 }
840
841 /*
842 ** Evaluate a Tcl script, creating the Tcl interpreter if necessary. If the
@@ -850,22 +939,25 @@
850 int evaluateTclWithEvents(
851 Th_Interp *interp,
852 void *pContext,
853 const char *zScript,
854 int nScript,
 
855 int bWait,
856 int bVerbose
857 ){
858 struct TclContext *tclContext = (struct TclContext *)pContext;
859 Tcl_Interp *tclInterp;
860 int rc;
861 int flags = TCL_ALL_EVENTS;
 
862
863 if( createTclInterp(interp, pContext)!=TH_OK ){
864 return TH_ERROR;
865 }
866 tclInterp = tclContext->interp;
 
867 rc = Tcl_EvalEx(tclInterp, zScript, nScript, TCL_EVAL_GLOBAL);
868 if( rc!=TCL_OK ){
869 if( bVerbose ){
870 const char *zResult = getTclResult(tclInterp, 0);
871 fossil_print("%s: ", getTclReturnCodeName(rc, 0));
@@ -872,13 +964,20 @@
872 fossil_print("%s\n", zResult);
873 }
874 return rc;
875 }
876 if( !bWait ) flags |= TCL_DONT_WAIT;
 
877 while( Tcl_DoOneEvent(flags) ){
878 /* do nothing */
 
 
 
 
 
879 }
 
880 return rc;
881 }
882
883 /*
884 ** Creates and initializes a Tcl interpreter for use with the specified TH1
@@ -902,11 +1001,11 @@
902 return TH_ERROR;
903 }
904 if( tclContext->interp ){
905 return TH_OK;
906 }
907 if( loadTcl(interp, &tclContext->library, &tclContext->xFindExecutable,
908 &tclContext->xCreateInterp, &tclContext->xDeleteInterp,
909 &tclContext->xFinalize)!=TH_OK ){
910 return TH_ERROR;
911 }
912 argc = tclContext->argc;
@@ -959,14 +1058,19 @@
959 Tcl_DeleteInterp(tclInterp);
960 tclContext->interp = tclInterp = 0;
961 return TH_ERROR;
962 }
963 /*
964 ** Determine if an objProc can be called directly for a Tcl command invoked
965 ** via the tclInvoke TH1 command.
966 */
967 tclContext->useObjProc = canUseObjProc();
 
 
 
 
 
968 /* Add the TH1 integration commands to Tcl. */
969 Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp);
970 Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL);
971 Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL);
972 /* If necessary, evaluate the custom Tcl setup script. */
@@ -990,11 +1094,11 @@
990 ){
991 struct TclContext *tclContext = (struct TclContext *)pContext;
992 Tcl_Interp *tclInterp;
993 tcl_FinalizeProc *xFinalize;
994 #if defined(USE_TCL_STUBS)
995 void *library;
996 #endif /* defined(USE_TCL_STUBS) */
997
998 if( !tclContext ){
999 Th_ErrorMessage(interp,
1000 "invalid Tcl context", (const char *)"", 0);
@@ -1028,14 +1132,14 @@
1028 ** http://comments.gmane.org/gmane.comp.gnu.mingw.user/41724
1029 **
1030 ** The workaround is to manually unload the loaded Tcl library prior to
1031 ** exiting the process.
1032 */
1033 library = tclContext->library;
1034 if( library ){
1035 dlclose(library);
1036 tclContext->library = library = 0;
1037 }
1038 #endif /* defined(USE_TCL_STUBS) */
1039 return TH_OK;
1040 }
1041
1042
--- src/th_tcl.c
+++ src/th_tcl.c
@@ -44,12 +44,14 @@
44 }
45
46 #define FREE_ARGV_TO_OBJV() \
47 for(obji=1; obji<argc; obji++){ \
48 Tcl_DecrRefCount(objv[obji-1]); \
49 objv[obji-1] = 0; \
50 } \
51 ckfree((char *)objv); \
52 objv = 0;
53
54 /*
55 ** Fetch the Tcl interpreter from the specified void pointer, cast to a Tcl
56 ** context.
57 */
@@ -61,18 +63,35 @@
63 ** indicates whether or not we can/should use direct objProc calls.
64 */
65 #define GET_CTX_TCL_USEOBJPROC(ctx) \
66 ((struct TclContext *)(ctx))->useObjProc
67
68 /*
69 ** This is the name of an environment variable that may refer to a Tcl library
70 ** directory or file name. If this environment variable is set [to anything],
71 ** its value will be used when searching for a Tcl library to load.
72 */
73 #ifndef TCL_PATH_ENV_VAR_NAME
74 # define TCL_PATH_ENV_VAR_NAME "FOSSIL_TCL_PATH"
75 #endif
76
77 /*
78 ** Define the Tcl shared library name, some exported function names, and some
79 ** cross-platform macros for use with the Tcl stubs mechanism, when enabled.
80 */
81 #if defined(USE_TCL_STUBS)
82 # if defined(_WIN32)
83 # if !defined(WIN32_LEAN_AND_MEAN)
84 # define WIN32_LEAN_AND_MEAN
85 # endif
86 # if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0502)
87 # define _WIN32_WINNT 0x0502 /* SetDllDirectory, Windows XP SP2 */
88 # endif
89 # include <windows.h>
90 # ifndef TCL_DIRECTORY_SEP
91 # define TCL_DIRECTORY_SEP '\\'
92 # endif
93 # ifndef TCL_LIBRARY_NAME
94 # define TCL_LIBRARY_NAME "tcl86.dll\0"
95 # endif
96 # ifndef TCL_MINOR_OFFSET
97 # define TCL_MINOR_OFFSET (4)
@@ -86,10 +105,13 @@
105 # ifndef dlclose
106 # define dlclose(a) FreeLibrary((HANDLE)(a))
107 # endif
108 # else
109 # include <dlfcn.h>
110 # ifndef TCL_DIRECTORY_SEP
111 # define TCL_DIRECTORY_SEP '/'
112 # endif
113 # if defined(__CYGWIN__)
114 # ifndef TCL_LIBRARY_NAME
115 # define TCL_LIBRARY_NAME "libtcl8.6.dll\0"
116 # endif
117 # ifndef TCL_MINOR_OFFSET
@@ -123,22 +145,35 @@
145 # ifndef TCL_FINALIZE_NAME
146 # define TCL_FINALIZE_NAME "_Tcl_Finalize\0"
147 # endif
148 #endif /* defined(USE_TCL_STUBS) */
149
150 /*
151 ** If this constant is defined to non-zero, the Win32 SetDllDirectory function
152 ** will be used during the Tcl library loading process if the path environment
153 ** variable for Tcl was set.
154 */
155 #ifndef TCL_USE_SET_DLL_DIRECTORY
156 # if defined(_WIN32) && defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0502)
157 # define TCL_USE_SET_DLL_DIRECTORY (1)
158 # else
159 # define TCL_USE_SET_DLL_DIRECTORY (0)
160 # endif
161 #endif /* TCL_USE_SET_DLL_DIRECTORY */
162
163 /*
164 ** The function types for Tcl_FindExecutable and Tcl_CreateInterp are needed
165 ** when the Tcl library is being loaded dynamically by a stubs-enabled
166 ** application (i.e. the inverse of using a stubs-enabled package). These are
167 ** the only Tcl API functions that MUST be called prior to being able to call
168 ** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete
169 ** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp
170 ** and Tcl_Finalize function types are also required.
171 */
172 typedef void (tcl_FindExecutableProc) (const char *);
173 typedef Tcl_Interp *(tcl_CreateInterpProc) (void);
174 typedef void (tcl_DeleteInterpProc) (Tcl_Interp *);
175 typedef void (tcl_FinalizeProc) (void);
176
177 /*
178 ** The function types for the "hook" functions to be called before and after a
179 ** TH1 command makes a call to evaluate a Tcl script. If the "pre" function
@@ -242,10 +277,25 @@
277 if( major==8 && minor==6 && type==TCL_BETA_RELEASE && patchLevel<3 ){
278 return 0; /* NOTE: Disabled on Tcl 8.6b1/b2, SF bug #3399564. */
279 }
280 return 1; /* NOTE: For all other cases, assume good. */
281 }
282
283 /*
284 ** Is the loaded version of Tcl one where TIP #285 (asynchronous script
285 ** cancellation) is available? This should return non-zero only for Tcl
286 ** 8.6 and higher.
287 */
288 static int canUseTip285(){
289 int major = -1, minor = -1, patchLevel = -1, type = -1;
290
291 Tcl_GetVersion(&major, &minor, &patchLevel, &type);
292 if( major<0 || minor<0 || patchLevel<0 || type<0 ){
293 return 0; /* NOTE: Invalid version info, assume bad. */
294 }
295 return (major>8 || (major==8 && minor>=6));
296 }
297
298 /*
299 ** Creates and initializes a Tcl interpreter for use with the specified TH1
300 ** interpreter. Stores the created Tcl interpreter in the Tcl context supplied
301 ** by the caller. This must be declared here because quite a few functions in
@@ -337,17 +387,18 @@
387 ** copied from and should be kept in sync with the one in "main.c".
388 */
389 struct TclContext {
390 int argc; /* Number of original arguments. */
391 char **argv; /* Full copy of the original arguments. */
392 void *hLibrary; /* The Tcl library module handle. */
393 tcl_FindExecutableProc *xFindExecutable; /* Tcl_FindExecutable() pointer. */
394 tcl_CreateInterpProc *xCreateInterp; /* Tcl_CreateInterp() pointer. */
395 tcl_DeleteInterpProc *xDeleteInterp; /* Tcl_DeleteInterp() pointer. */
396 tcl_FinalizeProc *xFinalize; /* Tcl_Finalize() pointer. */
397 Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
398 int useObjProc; /* Non-zero if an objProc can be called directly. */
399 int useTip285; /* Non-zero if TIP #285 is available. */
400 char *setup; /* The optional Tcl setup script. */
401 tcl_NotifyProc *xPreEval; /* Optional, called before Tcl_Eval*(). */
402 void *pPreContext; /* Optional, provided to xPreEval(). */
403 tcl_NotifyProc *xPostEval; /* Optional, called after Tcl_Eval*(). */
404 void *pPostContext; /* Optional, provided to xPostEval(). */
@@ -423,18 +474,18 @@
474 Tcl_Preserve((ClientData)tclInterp);
475 if( argc==2 ){
476 objPtr = Tcl_NewStringObj(argv[1], argl[1]);
477 Tcl_IncrRefCount(objPtr);
478 rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
479 Tcl_DecrRefCount(objPtr); objPtr = 0;
480 }else{
481 USE_ARGV_TO_OBJV();
482 COPY_ARGV_TO_OBJV();
483 objPtr = Tcl_ConcatObj(objc, objv);
484 Tcl_IncrRefCount(objPtr);
485 rc = Tcl_EvalObjEx(tclInterp, objPtr, 0);
486 Tcl_DecrRefCount(objPtr); objPtr = 0;
487 FREE_ARGV_TO_OBJV();
488 }
489 zResult = getTclResult(tclInterp, &nResult);
490 Th_SetResult(interp, zResult, nResult);
491 Tcl_Release((ClientData)tclInterp);
@@ -482,27 +533,29 @@
533 Tcl_Preserve((ClientData)tclInterp);
534 if( argc==2 ){
535 objPtr = Tcl_NewStringObj(argv[1], argl[1]);
536 Tcl_IncrRefCount(objPtr);
537 rc = Tcl_ExprObj(tclInterp, objPtr, &resultObjPtr);
538 Tcl_DecrRefCount(objPtr); objPtr = 0;
539 }else{
540 USE_ARGV_TO_OBJV();
541 COPY_ARGV_TO_OBJV();
542 objPtr = Tcl_ConcatObj(objc, objv);
543 Tcl_IncrRefCount(objPtr);
544 rc = Tcl_ExprObj(tclInterp, objPtr, &resultObjPtr);
545 Tcl_DecrRefCount(objPtr); objPtr = 0;
546 FREE_ARGV_TO_OBJV();
547 }
548 if( rc==TCL_OK ){
549 zResult = Tcl_GetStringFromObj(resultObjPtr, &nResult);
550 }else{
551 zResult = getTclResult(tclInterp, &nResult);
552 }
553 Th_SetResult(interp, zResult, nResult);
554 if( rc==TCL_OK ){
555 Tcl_DecrRefCount(resultObjPtr); resultObjPtr = 0;
556 }
557 Tcl_Release((ClientData)tclInterp);
558 rc = notifyPreOrPostEval(1, interp, ctx, argc, argv, argl,
559 getTh1ReturnCode(rc));
560 return rc;
561 }
@@ -550,21 +603,21 @@
603 Tcl_Obj *objPtr = Tcl_NewStringObj(argv[1], argl[1]);
604 Tcl_IncrRefCount(objPtr);
605 command = Tcl_GetCommandFromObj(tclInterp, objPtr);
606 if( !command || Tcl_GetCommandInfoFromToken(command, &cmdInfo)==0 ){
607 Th_ErrorMessage(interp, "Tcl command not found:", argv[1], argl[1]);
608 Tcl_DecrRefCount(objPtr); objPtr = 0;
609 Tcl_Release((ClientData)tclInterp);
610 return TH_ERROR;
611 }
612 if( !cmdInfo.objProc ){
613 Th_ErrorMessage(interp, "cannot invoke Tcl command:", argv[1], argl[1]);
614 Tcl_DecrRefCount(objPtr); objPtr = 0;
615 Tcl_Release((ClientData)tclInterp);
616 return TH_ERROR;
617 }
618 Tcl_DecrRefCount(objPtr); objPtr = 0;
619 COPY_ARGV_TO_OBJV();
620 Tcl_ResetResult(tclInterp);
621 rc = cmdInfo.objProc(cmdInfo.objClientData, tclInterp, objc, objv);
622 FREE_ARGV_TO_OBJV();
623 }else
@@ -686,95 +739,131 @@
739 ** shared library and fetch the function pointers necessary to create an
740 ** interpreter and initialize the stubs mechanism; otherwise, simply setup
741 ** the function pointers provided by the caller with the statically linked
742 ** functions.
743 */
744 char *fossil_getenv(const char *zName); /* file.h */
745 int file_isdir(const char *zPath); /* file.h */
746 char *file_dirname(const char *zPath); /* file.h */
747 void fossil_free(void *p); /* util.h */
748
749 static int loadTcl(
750 Th_Interp *interp,
751 void **phLibrary,
752 tcl_FindExecutableProc **pxFindExecutable,
753 tcl_CreateInterpProc **pxCreateInterp,
754 tcl_DeleteInterpProc **pxDeleteInterp,
755 tcl_FinalizeProc **pxFinalize
756 ){
757 #if defined(USE_TCL_STUBS)
758 const char *zEnvPath = fossil_getenv(TCL_PATH_ENV_VAR_NAME);
759 char aFileName[] = TCL_LIBRARY_NAME;
760 #endif /* defined(USE_TCL_STUBS) */
761
762 if( !phLibrary || !pxFindExecutable || !pxCreateInterp ||
763 !pxDeleteInterp || !pxFinalize ){
764 Th_ErrorMessage(interp,
765 "invalid Tcl loader argument(s)", (const char *)"", 0);
766 return TH_ERROR;
767 }
768 #if defined(USE_TCL_STUBS)
769 do {
770 char *zFileName;
771 void *hLibrary;
772 if( !zEnvPath ){
773 zFileName = aFileName; /* NOTE: Assume present in PATH. */
774 }else if( file_isdir(zEnvPath)==1 ){
775 #if TCL_USE_SET_DLL_DIRECTORY
776 SetDllDirectory(zEnvPath); /* NOTE: Maybe needed for "zlib1.dll". */
777 #endif /* TCL_USE_SET_DLL_DIRECTORY */
778 /* NOTE: The environment variable contains a directory name. */
779 zFileName = sqlite3_mprintf("%s%c%s%c", zEnvPath, TCL_DIRECTORY_SEP,
780 aFileName, '\0');
781 }else{
782 #if TCL_USE_SET_DLL_DIRECTORY
783 char *zDirName = file_dirname(zEnvPath);
784 if( zDirName ){
785 SetDllDirectory(zDirName); /* NOTE: Maybe needed for "zlib1.dll". */
786 }
787 #endif /* TCL_USE_SET_DLL_DIRECTORY */
788 /* NOTE: The environment variable might contain a file name. */
789 zFileName = sqlite3_mprintf("%s%c", zEnvPath, '\0');
790 #if TCL_USE_SET_DLL_DIRECTORY
791 if( zDirName ){
792 fossil_free(zDirName); zDirName = 0;
793 }
794 #endif /* TCL_USE_SET_DLL_DIRECTORY */
795 }
796 hLibrary = dlopen(zFileName, RTLD_NOW | RTLD_GLOBAL);
797 /* NOTE: If the file name was allocated, free it now. */
798 if( zFileName!=aFileName ){
799 sqlite3_free(zFileName); zFileName = 0;
800 }
801 if( hLibrary ){
802 tcl_FindExecutableProc *xFindExecutable;
803 tcl_CreateInterpProc *xCreateInterp;
804 tcl_DeleteInterpProc *xDeleteInterp;
805 tcl_FinalizeProc *xFinalize;
806 const char *procName = TCL_FINDEXECUTABLE_NAME;
807 xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName+1);
808 if( !xFindExecutable ){
809 xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName);
810 }
811 if( !xFindExecutable ){
812 Th_ErrorMessage(interp,
813 "could not locate Tcl_FindExecutable", (const char *)"", 0);
814 dlclose(hLibrary); hLibrary = 0;
815 return TH_ERROR;
816 }
817 procName = TCL_CREATEINTERP_NAME;
818 xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName+1);
819 if( !xCreateInterp ){
820 xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName);
821 }
822 if( !xCreateInterp ){
823 Th_ErrorMessage(interp,
824 "could not locate Tcl_CreateInterp", (const char *)"", 0);
825 dlclose(hLibrary); hLibrary = 0;
826 return TH_ERROR;
827 }
828 procName = TCL_DELETEINTERP_NAME;
829 xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(hLibrary, procName+1);
830 if( !xDeleteInterp ){
831 xDeleteInterp = (tcl_DeleteInterpProc *)dlsym(hLibrary, procName);
832 }
833 if( !xDeleteInterp ){
834 Th_ErrorMessage(interp,
835 "could not locate Tcl_DeleteInterp", (const char *)"", 0);
836 dlclose(hLibrary); hLibrary = 0;
837 return TH_ERROR;
838 }
839 procName = TCL_FINALIZE_NAME;
840 xFinalize = (tcl_FinalizeProc *)dlsym(hLibrary, procName+1);
841 if( !xFinalize ){
842 xFinalize = (tcl_FinalizeProc *)dlsym(hLibrary, procName);
843 }
844 if( !xFinalize ){
845 Th_ErrorMessage(interp,
846 "could not locate Tcl_Finalize", (const char *)"", 0);
847 dlclose(hLibrary); hLibrary = 0;
848 return TH_ERROR;
849 }
850 *phLibrary = hLibrary;
851 *pxFindExecutable = xFindExecutable;
852 *pxCreateInterp = xCreateInterp;
853 *pxDeleteInterp = xDeleteInterp;
854 *pxFinalize = xFinalize;
855 return TH_OK;
856 }
857 } while( --aFileName[TCL_MINOR_OFFSET]>'3' ); /* Tcl 8.4+ */
858 aFileName[TCL_MINOR_OFFSET] = 'x';
859 Th_ErrorMessage(interp,
860 "could not load any supported Tcl 8.6, 8.5, or 8.4 shared library \"",
861 aFileName, -1);
862 return TH_ERROR;
863 #else
864 *phLibrary = 0;
865 *pxFindExecutable = Tcl_FindExecutable;
866 *pxCreateInterp = Tcl_CreateInterp;
867 *pxDeleteInterp = Tcl_DeleteInterp;
868 *pxFinalize = Tcl_Finalize;
869 return TH_OK;
@@ -800,19 +889,19 @@
889 }
890 objPtr = Tcl_NewStringObj(argv[0], -1);
891 Tcl_IncrRefCount(objPtr);
892 resultObjPtr = Tcl_SetVar2Ex(pInterp, "argv0", NULL, objPtr,
893 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
894 Tcl_DecrRefCount(objPtr); objPtr = 0;
895 if( !resultObjPtr ){
896 return TCL_ERROR;
897 }
898 objPtr = Tcl_NewIntObj(argc - 1);
899 Tcl_IncrRefCount(objPtr);
900 resultObjPtr = Tcl_SetVar2Ex(pInterp, "argc", NULL, objPtr,
901 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
902 Tcl_DecrRefCount(objPtr); objPtr = 0;
903 if( !resultObjPtr ){
904 return TCL_ERROR;
905 }
906 listPtr = Tcl_NewListObj(0, NULL);
907 Tcl_IncrRefCount(listPtr);
@@ -819,11 +908,11 @@
908 if( argc>1 ){
909 while( --argc ){
910 objPtr = Tcl_NewStringObj(*++argv, -1);
911 Tcl_IncrRefCount(objPtr);
912 rc = Tcl_ListObjAppendElement(pInterp, listPtr, objPtr);
913 Tcl_DecrRefCount(objPtr); objPtr = 0;
914 if( rc!=TCL_OK ){
915 break;
916 }
917 }
918 }
@@ -832,11 +921,11 @@
921 TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG);
922 if( !resultObjPtr ){
923 rc = TCL_ERROR;
924 }
925 }
926 Tcl_DecrRefCount(listPtr); listPtr = 0;
927 return rc;
928 }
929
930 /*
931 ** Evaluate a Tcl script, creating the Tcl interpreter if necessary. If the
@@ -850,22 +939,25 @@
939 int evaluateTclWithEvents(
940 Th_Interp *interp,
941 void *pContext,
942 const char *zScript,
943 int nScript,
944 int bCancel,
945 int bWait,
946 int bVerbose
947 ){
948 struct TclContext *tclContext = (struct TclContext *)pContext;
949 Tcl_Interp *tclInterp;
950 int rc;
951 int flags = TCL_ALL_EVENTS;
952 int useTip285;
953
954 if( createTclInterp(interp, pContext)!=TH_OK ){
955 return TH_ERROR;
956 }
957 tclInterp = tclContext->interp;
958 useTip285 = bCancel ? tclContext->useTip285 : 0;
959 rc = Tcl_EvalEx(tclInterp, zScript, nScript, TCL_EVAL_GLOBAL);
960 if( rc!=TCL_OK ){
961 if( bVerbose ){
962 const char *zResult = getTclResult(tclInterp, 0);
963 fossil_print("%s: ", getTclReturnCodeName(rc, 0));
@@ -872,13 +964,20 @@
964 fossil_print("%s\n", zResult);
965 }
966 return rc;
967 }
968 if( !bWait ) flags |= TCL_DONT_WAIT;
969 Tcl_Preserve((ClientData)tclInterp);
970 while( Tcl_DoOneEvent(flags) ){
971 if( Tcl_InterpDeleted(tclInterp) ){
972 break;
973 }
974 if( useTip285 && Tcl_Canceled(tclInterp, 0)!=TCL_OK ){
975 break;
976 }
977 }
978 Tcl_Release((ClientData)tclInterp);
979 return rc;
980 }
981
982 /*
983 ** Creates and initializes a Tcl interpreter for use with the specified TH1
@@ -902,11 +1001,11 @@
1001 return TH_ERROR;
1002 }
1003 if( tclContext->interp ){
1004 return TH_OK;
1005 }
1006 if( loadTcl(interp, &tclContext->hLibrary, &tclContext->xFindExecutable,
1007 &tclContext->xCreateInterp, &tclContext->xDeleteInterp,
1008 &tclContext->xFinalize)!=TH_OK ){
1009 return TH_ERROR;
1010 }
1011 argc = tclContext->argc;
@@ -959,14 +1058,19 @@
1058 Tcl_DeleteInterp(tclInterp);
1059 tclContext->interp = tclInterp = 0;
1060 return TH_ERROR;
1061 }
1062 /*
1063 ** Determine (and cache) if an objProc can be called directly for a Tcl
1064 ** command invoked via the tclInvoke TH1 command.
1065 */
1066 tclContext->useObjProc = canUseObjProc();
1067 /*
1068 ** Determine (and cache) whether or not we can use TIP #285 (asynchronous
1069 ** script cancellation).
1070 */
1071 tclContext->useTip285 = canUseTip285();
1072 /* Add the TH1 integration commands to Tcl. */
1073 Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp);
1074 Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL);
1075 Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL);
1076 /* If necessary, evaluate the custom Tcl setup script. */
@@ -990,11 +1094,11 @@
1094 ){
1095 struct TclContext *tclContext = (struct TclContext *)pContext;
1096 Tcl_Interp *tclInterp;
1097 tcl_FinalizeProc *xFinalize;
1098 #if defined(USE_TCL_STUBS)
1099 void *hLibrary;
1100 #endif /* defined(USE_TCL_STUBS) */
1101
1102 if( !tclContext ){
1103 Th_ErrorMessage(interp,
1104 "invalid Tcl context", (const char *)"", 0);
@@ -1028,14 +1132,14 @@
1132 ** http://comments.gmane.org/gmane.comp.gnu.mingw.user/41724
1133 **
1134 ** The workaround is to manually unload the loaded Tcl library prior to
1135 ** exiting the process.
1136 */
1137 hLibrary = tclContext->hLibrary;
1138 if( hLibrary ){
1139 dlclose(hLibrary);
1140 tclContext->hLibrary = hLibrary = 0;
1141 }
1142 #endif /* defined(USE_TCL_STUBS) */
1143 return TH_OK;
1144 }
1145
1146
+6 -6
--- src/timeline.c
+++ src/timeline.c
@@ -786,11 +786,11 @@
786786
}else{
787787
@ mergeOffset = railPitch-minRailPitch-mLine.w;
788788
@ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
789789
@ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
790790
}
791
- @
791
+ @
792792
@ var canvasWidth = (nrail-1)*railPitch + node.w;
793793
@ canvasDiv.style.width = canvasWidth + "px";
794794
@ canvasDiv.style.position = "relative";
795795
@ }
796796
@ function drawBox(cls,color,x0,y0,x1,y1){
@@ -1277,24 +1277,24 @@
12771277
return;
12781278
}
12791279
url_initialize(&url, "timeline");
12801280
cgi_query_parameters_to_url(&url);
12811281
if( zTagName && g.perm.Read ){
1282
- tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
1282
+ tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zTagName);
12831283
zThisTag = zTagName;
12841284
}else if( zBrName && g.perm.Read ){
1285
- tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1285
+ tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
12861286
zThisTag = zBrName;
12871287
}else{
12881288
tagid = 0;
12891289
}
12901290
if( zMark && zMark[0]==0 ){
12911291
if( zAfter ) zMark = zAfter;
12921292
if( zBefore ) zMark = zBefore;
12931293
if( zCirca ) zMark = zCirca;
12941294
}
1295
- if( tagid>0
1295
+ if( tagid
12961296
&& db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
12971297
){
12981298
nEntry = -1;
12991299
zCirca = 0;
13001300
}
@@ -1492,11 +1492,11 @@
14921492
}
14931493
else if( zYearWeek ){
14941494
blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
14951495
zYearWeek);
14961496
}
1497
- if( tagid>0 ){
1497
+ if( tagid ){
14981498
blob_append_sql(&sql,
14991499
" AND (EXISTS(SELECT 1 FROM tagxref"
15001500
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid);
15011501
15021502
if( zBrName ){
@@ -2084,11 +2084,11 @@
20842084
if( zType==0 ){
20852085
/* When zFilePattern is specified and type is not specified, only show
20862086
* file check-ins */
20872087
zType="ci";
20882088
}
2089
- file_tree_name(zFilePattern, &treeName, 1);
2089
+ file_tree_name(zFilePattern, &treeName, 0, 1);
20902090
if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
20912091
/* When zTreeName refers to g.zLocalRoot, it's like not specifying
20922092
* zFilePattern. */
20932093
zFilePattern = 0;
20942094
}
20952095
--- src/timeline.c
+++ src/timeline.c
@@ -786,11 +786,11 @@
786 }else{
787 @ mergeOffset = railPitch-minRailPitch-mLine.w;
788 @ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
789 @ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
790 }
791 @
792 @ var canvasWidth = (nrail-1)*railPitch + node.w;
793 @ canvasDiv.style.width = canvasWidth + "px";
794 @ canvasDiv.style.position = "relative";
795 @ }
796 @ function drawBox(cls,color,x0,y0,x1,y1){
@@ -1277,24 +1277,24 @@
1277 return;
1278 }
1279 url_initialize(&url, "timeline");
1280 cgi_query_parameters_to_url(&url);
1281 if( zTagName && g.perm.Read ){
1282 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
1283 zThisTag = zTagName;
1284 }else if( zBrName && g.perm.Read ){
1285 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1286 zThisTag = zBrName;
1287 }else{
1288 tagid = 0;
1289 }
1290 if( zMark && zMark[0]==0 ){
1291 if( zAfter ) zMark = zAfter;
1292 if( zBefore ) zMark = zBefore;
1293 if( zCirca ) zMark = zCirca;
1294 }
1295 if( tagid>0
1296 && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
1297 ){
1298 nEntry = -1;
1299 zCirca = 0;
1300 }
@@ -1492,11 +1492,11 @@
1492 }
1493 else if( zYearWeek ){
1494 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1495 zYearWeek);
1496 }
1497 if( tagid>0 ){
1498 blob_append_sql(&sql,
1499 " AND (EXISTS(SELECT 1 FROM tagxref"
1500 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid);
1501
1502 if( zBrName ){
@@ -2084,11 +2084,11 @@
2084 if( zType==0 ){
2085 /* When zFilePattern is specified and type is not specified, only show
2086 * file check-ins */
2087 zType="ci";
2088 }
2089 file_tree_name(zFilePattern, &treeName, 1);
2090 if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
2091 /* When zTreeName refers to g.zLocalRoot, it's like not specifying
2092 * zFilePattern. */
2093 zFilePattern = 0;
2094 }
2095
--- src/timeline.c
+++ src/timeline.c
@@ -786,11 +786,11 @@
786 }else{
787 @ mergeOffset = railPitch-minRailPitch-mLine.w;
788 @ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
789 @ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
790 }
791 @
792 @ var canvasWidth = (nrail-1)*railPitch + node.w;
793 @ canvasDiv.style.width = canvasWidth + "px";
794 @ canvasDiv.style.position = "relative";
795 @ }
796 @ function drawBox(cls,color,x0,y0,x1,y1){
@@ -1277,24 +1277,24 @@
1277 return;
1278 }
1279 url_initialize(&url, "timeline");
1280 cgi_query_parameters_to_url(&url);
1281 if( zTagName && g.perm.Read ){
1282 tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zTagName);
1283 zThisTag = zTagName;
1284 }else if( zBrName && g.perm.Read ){
1285 tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1286 zThisTag = zBrName;
1287 }else{
1288 tagid = 0;
1289 }
1290 if( zMark && zMark[0]==0 ){
1291 if( zAfter ) zMark = zAfter;
1292 if( zBefore ) zMark = zBefore;
1293 if( zCirca ) zMark = zCirca;
1294 }
1295 if( tagid
1296 && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
1297 ){
1298 nEntry = -1;
1299 zCirca = 0;
1300 }
@@ -1492,11 +1492,11 @@
1492 }
1493 else if( zYearWeek ){
1494 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1495 zYearWeek);
1496 }
1497 if( tagid ){
1498 blob_append_sql(&sql,
1499 " AND (EXISTS(SELECT 1 FROM tagxref"
1500 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid);
1501
1502 if( zBrName ){
@@ -2084,11 +2084,11 @@
2084 if( zType==0 ){
2085 /* When zFilePattern is specified and type is not specified, only show
2086 * file check-ins */
2087 zType="ci";
2088 }
2089 file_tree_name(zFilePattern, &treeName, 0, 1);
2090 if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
2091 /* When zTreeName refers to g.zLocalRoot, it's like not specifying
2092 * zFilePattern. */
2093 zFilePattern = 0;
2094 }
2095
+6 -6
--- src/timeline.c
+++ src/timeline.c
@@ -786,11 +786,11 @@
786786
}else{
787787
@ mergeOffset = railPitch-minRailPitch-mLine.w;
788788
@ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
789789
@ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
790790
}
791
- @
791
+ @
792792
@ var canvasWidth = (nrail-1)*railPitch + node.w;
793793
@ canvasDiv.style.width = canvasWidth + "px";
794794
@ canvasDiv.style.position = "relative";
795795
@ }
796796
@ function drawBox(cls,color,x0,y0,x1,y1){
@@ -1277,24 +1277,24 @@
12771277
return;
12781278
}
12791279
url_initialize(&url, "timeline");
12801280
cgi_query_parameters_to_url(&url);
12811281
if( zTagName && g.perm.Read ){
1282
- tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
1282
+ tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zTagName);
12831283
zThisTag = zTagName;
12841284
}else if( zBrName && g.perm.Read ){
1285
- tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1285
+ tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
12861286
zThisTag = zBrName;
12871287
}else{
12881288
tagid = 0;
12891289
}
12901290
if( zMark && zMark[0]==0 ){
12911291
if( zAfter ) zMark = zAfter;
12921292
if( zBefore ) zMark = zBefore;
12931293
if( zCirca ) zMark = zCirca;
12941294
}
1295
- if( tagid>0
1295
+ if( tagid
12961296
&& db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
12971297
){
12981298
nEntry = -1;
12991299
zCirca = 0;
13001300
}
@@ -1492,11 +1492,11 @@
14921492
}
14931493
else if( zYearWeek ){
14941494
blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
14951495
zYearWeek);
14961496
}
1497
- if( tagid>0 ){
1497
+ if( tagid ){
14981498
blob_append_sql(&sql,
14991499
" AND (EXISTS(SELECT 1 FROM tagxref"
15001500
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid);
15011501
15021502
if( zBrName ){
@@ -2084,11 +2084,11 @@
20842084
if( zType==0 ){
20852085
/* When zFilePattern is specified and type is not specified, only show
20862086
* file check-ins */
20872087
zType="ci";
20882088
}
2089
- file_tree_name(zFilePattern, &treeName, 1);
2089
+ file_tree_name(zFilePattern, &treeName, 0, 1);
20902090
if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
20912091
/* When zTreeName refers to g.zLocalRoot, it's like not specifying
20922092
* zFilePattern. */
20932093
zFilePattern = 0;
20942094
}
20952095
--- src/timeline.c
+++ src/timeline.c
@@ -786,11 +786,11 @@
786 }else{
787 @ mergeOffset = railPitch-minRailPitch-mLine.w;
788 @ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
789 @ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
790 }
791 @
792 @ var canvasWidth = (nrail-1)*railPitch + node.w;
793 @ canvasDiv.style.width = canvasWidth + "px";
794 @ canvasDiv.style.position = "relative";
795 @ }
796 @ function drawBox(cls,color,x0,y0,x1,y1){
@@ -1277,24 +1277,24 @@
1277 return;
1278 }
1279 url_initialize(&url, "timeline");
1280 cgi_query_parameters_to_url(&url);
1281 if( zTagName && g.perm.Read ){
1282 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTagName);
1283 zThisTag = zTagName;
1284 }else if( zBrName && g.perm.Read ){
1285 tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1286 zThisTag = zBrName;
1287 }else{
1288 tagid = 0;
1289 }
1290 if( zMark && zMark[0]==0 ){
1291 if( zAfter ) zMark = zAfter;
1292 if( zBefore ) zMark = zBefore;
1293 if( zCirca ) zMark = zCirca;
1294 }
1295 if( tagid>0
1296 && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
1297 ){
1298 nEntry = -1;
1299 zCirca = 0;
1300 }
@@ -1492,11 +1492,11 @@
1492 }
1493 else if( zYearWeek ){
1494 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1495 zYearWeek);
1496 }
1497 if( tagid>0 ){
1498 blob_append_sql(&sql,
1499 " AND (EXISTS(SELECT 1 FROM tagxref"
1500 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid);
1501
1502 if( zBrName ){
@@ -2084,11 +2084,11 @@
2084 if( zType==0 ){
2085 /* When zFilePattern is specified and type is not specified, only show
2086 * file check-ins */
2087 zType="ci";
2088 }
2089 file_tree_name(zFilePattern, &treeName, 1);
2090 if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
2091 /* When zTreeName refers to g.zLocalRoot, it's like not specifying
2092 * zFilePattern. */
2093 zFilePattern = 0;
2094 }
2095
--- src/timeline.c
+++ src/timeline.c
@@ -786,11 +786,11 @@
786 }else{
787 @ mergeOffset = railPitch-minRailPitch-mLine.w;
788 @ mergeOffset = Math.min(mergeOffset, elems.mergeoffset.w);
789 @ mergeOffset = mergeOffset>0 ? mergeOffset + line.w/2 : 0;
790 }
791 @
792 @ var canvasWidth = (nrail-1)*railPitch + node.w;
793 @ canvasDiv.style.width = canvasWidth + "px";
794 @ canvasDiv.style.position = "relative";
795 @ }
796 @ function drawBox(cls,color,x0,y0,x1,y1){
@@ -1277,24 +1277,24 @@
1277 return;
1278 }
1279 url_initialize(&url, "timeline");
1280 cgi_query_parameters_to_url(&url);
1281 if( zTagName && g.perm.Read ){
1282 tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zTagName);
1283 zThisTag = zTagName;
1284 }else if( zBrName && g.perm.Read ){
1285 tagid = db_int(-1,"SELECT tagid FROM tag WHERE tagname='sym-%q'",zBrName);
1286 zThisTag = zBrName;
1287 }else{
1288 tagid = 0;
1289 }
1290 if( zMark && zMark[0]==0 ){
1291 if( zAfter ) zMark = zAfter;
1292 if( zBefore ) zMark = zBefore;
1293 if( zCirca ) zMark = zCirca;
1294 }
1295 if( tagid
1296 && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
1297 ){
1298 nEntry = -1;
1299 zCirca = 0;
1300 }
@@ -1492,11 +1492,11 @@
1492 }
1493 else if( zYearWeek ){
1494 blob_append_sql(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1495 zYearWeek);
1496 }
1497 if( tagid ){
1498 blob_append_sql(&sql,
1499 " AND (EXISTS(SELECT 1 FROM tagxref"
1500 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n", tagid);
1501
1502 if( zBrName ){
@@ -2084,11 +2084,11 @@
2084 if( zType==0 ){
2085 /* When zFilePattern is specified and type is not specified, only show
2086 * file check-ins */
2087 zType="ci";
2088 }
2089 file_tree_name(zFilePattern, &treeName, 0, 1);
2090 if( fossil_strcmp(blob_str(&treeName), ".")==0 ){
2091 /* When zTreeName refers to g.zLocalRoot, it's like not specifying
2092 * zFilePattern. */
2093 zFilePattern = 0;
2094 }
2095
+5 -5
--- src/translate.c
+++ src/translate.c
@@ -40,15 +40,15 @@
4040
** rather than text that is to be output via cgi_printf(). Render it
4141
** as such.
4242
**
4343
** Enhancement #2:
4444
**
45
-** Comments of the form: "/* @-comment: CC" cause CC to become a
46
-** comment character for the @-substitution. Typical values for CC are
47
-** "--" (for SQL text) or "#" (for Tcl script) or "//" (for C++ code).
48
-** Lines of subsequent @-blocks that begin with CC are omitted from the
49
-** output.
45
+** Comments of the form: "|* @-comment: CC" (where "|" is really "/")
46
+** cause CC to become a comment character for the @-substitution.
47
+** Typical values for CC are "--" (for SQL text) or "#" (for Tcl script)
48
+** or "//" (for C++ code). Lines of subsequent @-blocks that begin with
49
+** CC are omitted from the output.
5050
**
5151
*/
5252
#include <stdio.h>
5353
#include <ctype.h>
5454
#include <stdlib.h>
5555
--- src/translate.c
+++ src/translate.c
@@ -40,15 +40,15 @@
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for Tcl script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55
--- src/translate.c
+++ src/translate.c
@@ -40,15 +40,15 @@
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "|* @-comment: CC" (where "|" is really "/")
46 ** cause CC to become a comment character for the @-substitution.
47 ** Typical values for CC are "--" (for SQL text) or "#" (for Tcl script)
48 ** or "//" (for C++ code). Lines of subsequent @-blocks that begin with
49 ** CC are omitted from the output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55
+1 -1
--- src/undo.c
+++ src/undo.c
@@ -437,11 +437,11 @@
437437
fossil_fatal("nothing to %s", zCmd);
438438
}
439439
for(i=2; i<g.argc; i++){
440440
const char *zFile = g.argv[i];
441441
Blob path;
442
- file_tree_name(zFile, &path, 1);
442
+ file_tree_name(zFile, &path, 0, 1);
443443
undo_one(blob_str(&path), isRedo);
444444
blob_reset(&path);
445445
}
446446
}
447447
vid2 = db_lget_int("checkout", 0);
448448
--- src/undo.c
+++ src/undo.c
@@ -437,11 +437,11 @@
437 fossil_fatal("nothing to %s", zCmd);
438 }
439 for(i=2; i<g.argc; i++){
440 const char *zFile = g.argv[i];
441 Blob path;
442 file_tree_name(zFile, &path, 1);
443 undo_one(blob_str(&path), isRedo);
444 blob_reset(&path);
445 }
446 }
447 vid2 = db_lget_int("checkout", 0);
448
--- src/undo.c
+++ src/undo.c
@@ -437,11 +437,11 @@
437 fossil_fatal("nothing to %s", zCmd);
438 }
439 for(i=2; i<g.argc; i++){
440 const char *zFile = g.argv[i];
441 Blob path;
442 file_tree_name(zFile, &path, 0, 1);
443 undo_one(blob_str(&path), isRedo);
444 blob_reset(&path);
445 }
446 }
447 vid2 = db_lget_int("checkout", 0);
448
+86 -81
--- src/unicode.c
+++ src/unicode.c
@@ -49,11 +49,11 @@
4949
0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15,
5050
0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07,
5151
0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B,
5252
0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09,
5353
0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801,
54
- 0x00239020, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804,
54
+ 0x00238C21, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804,
5555
0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02,
5656
0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802,
5757
0x00280403, 0x0028F001, 0x0028F805, 0x00291C02, 0x00292C03,
5858
0x00294401, 0x0029C002, 0x0029D401, 0x002A0403, 0x002AF001,
5959
0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802, 0x002BC002,
@@ -72,66 +72,67 @@
7272
0x00417803, 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C,
7373
0x00423C01, 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A,
7474
0x00500001, 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03,
7575
0x005C4803, 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023,
7676
0x005F6004, 0x005F7401, 0x0060000F, 0x0062A401, 0x0064800C,
77
- 0x0064C00C, 0x00650001, 0x00651002, 0x0066C011, 0x00672002,
78
- 0x00677822, 0x00685C05, 0x00687802, 0x0069540A, 0x0069801D,
79
- 0x0069FC01, 0x006A8007, 0x006AA006, 0x006AC00F, 0x006C0005,
80
- 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, 0x006F980E,
81
- 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, 0x00730008,
82
- 0x00734019, 0x0073B401, 0x0073C803, 0x0073E002, 0x00770036,
83
- 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
84
- 0x007FB403, 0x007FF402, 0x00800065, 0x0081980A, 0x0081E805,
85
- 0x00822805, 0x0082801E, 0x00834021, 0x00840002, 0x00840C04,
86
- 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
87
- 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
88
- 0x00852804, 0x00853C01, 0x0086426B, 0x00900027, 0x0091000B,
89
- 0x0092704E, 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6022,
90
- 0x00AEF40C, 0x00AF2808, 0x00B39406, 0x00B3BC03, 0x00B3E404,
77
+ 0x0064C00C, 0x00650001, 0x00651002, 0x00677822, 0x00685C05,
78
+ 0x00687802, 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007,
79
+ 0x006AA006, 0x006AC00F, 0x006C0005, 0x006CD011, 0x006D6823,
80
+ 0x006E0003, 0x006E840D, 0x006F980E, 0x006FF004, 0x00709014,
81
+ 0x0070EC05, 0x0071F802, 0x00730008, 0x00734019, 0x0073B401,
82
+ 0x0073C803, 0x0073E002, 0x00770036, 0x0077F004, 0x007EF401,
83
+ 0x007EFC03, 0x007F3403, 0x007F7403, 0x007FB403, 0x007FF402,
84
+ 0x00800065, 0x0081980A, 0x0081E805, 0x00822805, 0x0082801F,
85
+ 0x00834021, 0x00840002, 0x00840C04, 0x00842002, 0x00845001,
86
+ 0x00845803, 0x00847806, 0x00849401, 0x00849C01, 0x0084A401,
87
+ 0x0084B801, 0x0084E802, 0x00850005, 0x00852804, 0x00853C01,
88
+ 0x00862802, 0x0086426B, 0x00900027, 0x0091000B, 0x0092704E,
89
+ 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6022, 0x00AEF40C,
90
+ 0x00AF2808, 0x00AFB004, 0x00B39406, 0x00B3BC03, 0x00B3E404,
9191
0x00B3F802, 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C013,
9292
0x00BA001A, 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005,
9393
0x00C02019, 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404,
9494
0x00C28001, 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024,
9595
0x00C8001F, 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827,
9696
0x00CB003F, 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802,
97
- 0x02983403, 0x0299BC10, 0x029A7C01, 0x029BC008, 0x029C0017,
97
+ 0x02983403, 0x0299BC10, 0x029A7802, 0x029BC008, 0x029C0017,
9898
0x029C8002, 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01,
9999
0x02A08C09, 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D011,
100
- 0x02A33802, 0x02A38012, 0x02A3E003, 0x02A4980A, 0x02A51C0D,
101
- 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802, 0x02A79401,
102
- 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004, 0x02A9DC03,
103
- 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02, 0x02AAF802,
104
- 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402, 0x02AD6C01,
105
- 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, 0x037FFC01,
106
- 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, 0x03F7F002,
107
- 0x03F8001A, 0x03F8800E, 0x03F8C023, 0x03F95013, 0x03F9A004,
100
+ 0x02A33802, 0x02A38012, 0x02A3E003, 0x02A3F001, 0x02A4980A,
101
+ 0x02A51C0D, 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802,
102
+ 0x02A79401, 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004,
103
+ 0x02A9DC03, 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02,
104
+ 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402,
105
+ 0x02AD6C01, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
106
+ 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
107
+ 0x03F7F002, 0x03F8001A, 0x03F88033, 0x03F95013, 0x03F9A004,
108108
0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, 0x03FD6C0B,
109109
0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, 0x0404DC09,
110110
0x0405E411, 0x04063001, 0x0406400C, 0x04068001, 0x0407402E,
111111
0x040B8001, 0x040DD805, 0x040E7C01, 0x040F4001, 0x0415BC01,
112112
0x04215C01, 0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403,
113113
0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
114114
0x0429FC01, 0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407,
115115
0x042E6404, 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012,
116116
0x04440003, 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003,
117
- 0x0446CC0E, 0x04471404, 0x04473401, 0x0448B012, 0x044B7C0C,
118
- 0x044C0403, 0x044CF001, 0x044CF807, 0x044D1C02, 0x044D2C03,
119
- 0x044D5C01, 0x044D8802, 0x044D9807, 0x044DC005, 0x0452C014,
120
- 0x04531801, 0x0456BC07, 0x0456E012, 0x0458C014, 0x045AAC0D,
117
+ 0x0446CC0E, 0x04471409, 0x04476C01, 0x04477403, 0x0448B012,
118
+ 0x044AA401, 0x044B7C0C, 0x044C0004, 0x044CF001, 0x044CF807,
119
+ 0x044D1C02, 0x044D2C03, 0x044D5C01, 0x044D8802, 0x044D9807,
120
+ 0x044DC005, 0x0452C014, 0x04531801, 0x0456BC07, 0x0456E020,
121
+ 0x04577002, 0x0458C014, 0x045AAC0D, 0x045C740F, 0x045CF004,
121122
0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010, 0x05AD1002,
122123
0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6, 0x07440027,
123
- 0x0744A4B5, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01,
124
+ 0x0744A4C0, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01,
124125
0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01,
125
- 0x075E2401, 0x075EA401, 0x075F0C01, 0x07A34007, 0x07BBC002,
126
- 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F, 0x07C3040F,
127
- 0x07C34425, 0x07C4401F, 0x07C4C03C, 0x07C5C02B, 0x07C7981D,
128
- 0x07C8402B, 0x07C90009, 0x07C94002, 0x07CC002D, 0x07CCC04E,
129
- 0x07CE004F, 0x07CF5024, 0x07D000FF, 0x07D4004B, 0x07D5402A,
130
- 0x07D5EC29, 0x07D6949E, 0x07D9148B, 0x07DB800D, 0x07DBC004,
131
- 0x07DC0074, 0x07DE0055, 0x07E0000C, 0x07E04038, 0x07E1400A,
132
- 0x07E18028, 0x07E2401E, 0x38000401, 0x38008060, 0x380400F0,
126
+ 0x075E2401, 0x075EA401, 0x075F0C01, 0x0760028C, 0x076A6C05,
127
+ 0x076A840F, 0x07A34007, 0x07BBC002, 0x07C0002C, 0x07C0C064,
128
+ 0x07C2800F, 0x07C2C40F, 0x07C3040F, 0x07C34425, 0x07C4401F,
129
+ 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
130
+ 0x07C94002, 0x07CC027A, 0x07D5EC29, 0x07D6952C, 0x07DB800D,
131
+ 0x07DBC004, 0x07DC0074, 0x07DE0055, 0x07E0000C, 0x07E04038,
132
+ 0x07E1400A, 0x07E18028, 0x07E2401E, 0x07E44009, 0x07E60005,
133
+ 0x07E70001, 0x38000401, 0x38008060, 0x380400F0,
133134
};
134135
static const unsigned int aAscii[4] = {
135136
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
136137
};
137138
@@ -259,12 +260,12 @@
259260
unsigned char flags;
260261
unsigned char nRange;
261262
} aEntry[] = {
262263
{65, 14, 26}, {181, 64, 1}, {192, 14, 23},
263264
{216, 14, 7}, {256, 1, 48}, {306, 1, 6},
264
- {313, 1, 16}, {330, 1, 46}, {376, 126, 1},
265
- {377, 1, 6}, {383, 114, 1}, {385, 50, 1},
265
+ {313, 1, 16}, {330, 1, 46}, {376, 132, 1},
266
+ {377, 1, 6}, {383, 120, 1}, {385, 50, 1},
266267
{386, 1, 4}, {390, 44, 1}, {391, 0, 1},
267268
{393, 42, 2}, {395, 0, 1}, {398, 32, 1},
268269
{399, 38, 1}, {400, 40, 1}, {401, 0, 1},
269270
{403, 42, 1}, {404, 46, 1}, {406, 52, 1},
270271
{407, 48, 1}, {408, 0, 1}, {412, 52, 1},
@@ -273,64 +274,65 @@
273274
{428, 0, 1}, {430, 60, 1}, {431, 0, 1},
274275
{433, 58, 2}, {435, 1, 4}, {439, 62, 1},
275276
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
276277
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
277278
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
278
- {497, 2, 1}, {498, 1, 4}, {502, 132, 1},
279
- {503, 144, 1}, {504, 1, 40}, {544, 120, 1},
280
- {546, 1, 18}, {570, 70, 1}, {571, 0, 1},
281
- {573, 118, 1}, {574, 68, 1}, {577, 0, 1},
282
- {579, 116, 1}, {580, 28, 1}, {581, 30, 1},
279
+ {497, 2, 1}, {498, 1, 4}, {502, 138, 1},
280
+ {503, 150, 1}, {504, 1, 40}, {544, 126, 1},
281
+ {546, 1, 18}, {570, 72, 1}, {571, 0, 1},
282
+ {573, 124, 1}, {574, 70, 1}, {577, 0, 1},
283
+ {579, 122, 1}, {580, 28, 1}, {581, 30, 1},
283284
{582, 1, 10}, {837, 36, 1}, {880, 1, 4},
284285
{886, 0, 1}, {895, 36, 1}, {902, 18, 1},
285286
{904, 16, 3}, {908, 26, 1}, {910, 24, 2},
286287
{913, 14, 17}, {931, 14, 9}, {962, 0, 1},
287
- {975, 4, 1}, {976, 150, 1}, {977, 152, 1},
288
- {981, 156, 1}, {982, 154, 1}, {984, 1, 24},
289
- {1008, 146, 1}, {1009, 148, 1}, {1012, 140, 1},
290
- {1013, 138, 1}, {1015, 0, 1}, {1017, 162, 1},
291
- {1018, 0, 1}, {1021, 120, 3}, {1024, 34, 16},
288
+ {975, 4, 1}, {976, 156, 1}, {977, 158, 1},
289
+ {981, 162, 1}, {982, 160, 1}, {984, 1, 24},
290
+ {1008, 152, 1}, {1009, 154, 1}, {1012, 146, 1},
291
+ {1013, 144, 1}, {1015, 0, 1}, {1017, 168, 1},
292
+ {1018, 0, 1}, {1021, 126, 3}, {1024, 34, 16},
292293
{1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54},
293294
{1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96},
294
- {1329, 22, 38}, {4256, 66, 38}, {4295, 66, 1},
295
- {4301, 66, 1}, {7680, 1, 150}, {7835, 142, 1},
296
- {7838, 106, 1}, {7840, 1, 96}, {7944, 160, 8},
297
- {7960, 160, 6}, {7976, 160, 8}, {7992, 160, 8},
298
- {8008, 160, 6}, {8025, 161, 8}, {8040, 160, 8},
299
- {8072, 160, 8}, {8088, 160, 8}, {8104, 160, 8},
300
- {8120, 160, 2}, {8122, 136, 2}, {8124, 158, 1},
301
- {8126, 110, 1}, {8136, 134, 4}, {8140, 158, 1},
302
- {8152, 160, 2}, {8154, 130, 2}, {8168, 160, 2},
303
- {8170, 128, 2}, {8172, 162, 1}, {8184, 122, 2},
304
- {8186, 124, 2}, {8188, 158, 1}, {8486, 108, 1},
305
- {8490, 102, 1}, {8491, 104, 1}, {8498, 12, 1},
306
- {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26},
307
- {11264, 22, 47}, {11360, 0, 1}, {11362, 98, 1},
308
- {11363, 112, 1}, {11364, 100, 1}, {11367, 1, 6},
309
- {11373, 94, 1}, {11374, 96, 1}, {11375, 90, 1},
310
- {11376, 92, 1}, {11378, 0, 1}, {11381, 0, 1},
311
- {11390, 88, 2}, {11392, 1, 100}, {11499, 1, 4},
312
- {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 28},
313
- {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4},
314
- {42877, 86, 1}, {42878, 1, 10}, {42891, 0, 1},
315
- {42893, 82, 1}, {42896, 1, 4}, {42902, 1, 20},
316
- {42922, 76, 1}, {42923, 72, 1}, {42924, 74, 1},
317
- {42925, 78, 1}, {42928, 84, 1}, {42929, 80, 1},
318
- {65313, 14, 26},
295
+ {1329, 22, 38}, {4256, 68, 38}, {4295, 68, 1},
296
+ {4301, 68, 1}, {5112, 166, 6}, {7680, 1, 150},
297
+ {7835, 148, 1}, {7838, 112, 1}, {7840, 1, 96},
298
+ {7944, 166, 8}, {7960, 166, 6}, {7976, 166, 8},
299
+ {7992, 166, 8}, {8008, 166, 6}, {8025, 167, 8},
300
+ {8040, 166, 8}, {8072, 166, 8}, {8088, 166, 8},
301
+ {8104, 166, 8}, {8120, 166, 2}, {8122, 142, 2},
302
+ {8124, 164, 1}, {8126, 116, 1}, {8136, 140, 4},
303
+ {8140, 164, 1}, {8152, 166, 2}, {8154, 136, 2},
304
+ {8168, 166, 2}, {8170, 134, 2}, {8172, 168, 1},
305
+ {8184, 128, 2}, {8186, 130, 2}, {8188, 164, 1},
306
+ {8486, 114, 1}, {8490, 108, 1}, {8491, 110, 1},
307
+ {8498, 12, 1}, {8544, 8, 16}, {8579, 0, 1},
308
+ {9398, 10, 26}, {11264, 22, 47}, {11360, 0, 1},
309
+ {11362, 104, 1}, {11363, 118, 1}, {11364, 106, 1},
310
+ {11367, 1, 6}, {11373, 100, 1}, {11374, 102, 1},
311
+ {11375, 96, 1}, {11376, 98, 1}, {11378, 0, 1},
312
+ {11381, 0, 1}, {11390, 94, 2}, {11392, 1, 100},
313
+ {11499, 1, 4}, {11506, 0, 1}, {42560, 1, 46},
314
+ {42624, 1, 28}, {42786, 1, 14}, {42802, 1, 62},
315
+ {42873, 1, 4}, {42877, 92, 1}, {42878, 1, 10},
316
+ {42891, 0, 1}, {42893, 84, 1}, {42896, 1, 4},
317
+ {42902, 1, 20}, {42922, 78, 1}, {42923, 74, 1},
318
+ {42924, 76, 1}, {42925, 80, 1}, {42928, 88, 1},
319
+ {42929, 82, 1}, {42930, 86, 1}, {42931, 66, 1},
320
+ {42932, 1, 4}, {43888, 90, 80}, {65313, 14, 26},
319321
};
320322
static const unsigned short aiOff[] = {
321323
1, 2, 8, 15, 16, 26, 28, 32,
322324
37, 38, 40, 48, 63, 64, 69, 71,
323325
79, 80, 116, 202, 203, 205, 206, 207,
324326
209, 210, 211, 213, 214, 217, 218, 219,
325
- 775, 7264, 10792, 10795, 23217, 23221, 23228, 23231,
326
- 23254, 23256, 23278, 30204, 54721, 54753, 54754, 54756,
327
- 54787, 54793, 54809, 57153, 57274, 57921, 58019, 58363,
328
- 61722, 65268, 65341, 65373, 65406, 65408, 65410, 65415,
329
- 65424, 65436, 65439, 65450, 65462, 65472, 65476, 65478,
330
- 65480, 65482, 65488, 65506, 65511, 65514, 65521, 65527,
331
- 65528, 65529,
327
+ 775, 928, 7264, 10792, 10795, 23217, 23221, 23228,
328
+ 23231, 23254, 23256, 23275, 23278, 26672, 30204, 54721,
329
+ 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
330
+ 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406,
331
+ 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
332
+ 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
333
+ 65514, 65521, 65527, 65528, 65529,
332334
};
333335
334336
int ret = c;
335337
336338
assert( c>=0 );
@@ -366,12 +368,15 @@
366368
if( bRemoveDiacritic ) ret = unicode_remove_diacritic(ret);
367369
}
368370
369371
else if( c>=66560 && c<66600 ){
370372
ret = c + 40;
373
+ }
374
+ else if( c>=68736 && c<68787 ){
375
+ ret = c + 64;
371376
}
372377
else if( c>=71840 && c<71872 ){
373378
ret = c + 32;
374379
}
375380
376381
return ret;
377382
}
378383
--- src/unicode.c
+++ src/unicode.c
@@ -49,11 +49,11 @@
49 0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15,
50 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07,
51 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B,
52 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09,
53 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801,
54 0x00239020, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804,
55 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02,
56 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802,
57 0x00280403, 0x0028F001, 0x0028F805, 0x00291C02, 0x00292C03,
58 0x00294401, 0x0029C002, 0x0029D401, 0x002A0403, 0x002AF001,
59 0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802, 0x002BC002,
@@ -72,66 +72,67 @@
72 0x00417803, 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C,
73 0x00423C01, 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A,
74 0x00500001, 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03,
75 0x005C4803, 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023,
76 0x005F6004, 0x005F7401, 0x0060000F, 0x0062A401, 0x0064800C,
77 0x0064C00C, 0x00650001, 0x00651002, 0x0066C011, 0x00672002,
78 0x00677822, 0x00685C05, 0x00687802, 0x0069540A, 0x0069801D,
79 0x0069FC01, 0x006A8007, 0x006AA006, 0x006AC00F, 0x006C0005,
80 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D, 0x006F980E,
81 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802, 0x00730008,
82 0x00734019, 0x0073B401, 0x0073C803, 0x0073E002, 0x00770036,
83 0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
84 0x007FB403, 0x007FF402, 0x00800065, 0x0081980A, 0x0081E805,
85 0x00822805, 0x0082801E, 0x00834021, 0x00840002, 0x00840C04,
86 0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
87 0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
88 0x00852804, 0x00853C01, 0x0086426B, 0x00900027, 0x0091000B,
89 0x0092704E, 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6022,
90 0x00AEF40C, 0x00AF2808, 0x00B39406, 0x00B3BC03, 0x00B3E404,
91 0x00B3F802, 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C013,
92 0x00BA001A, 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005,
93 0x00C02019, 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404,
94 0x00C28001, 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024,
95 0x00C8001F, 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827,
96 0x00CB003F, 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802,
97 0x02983403, 0x0299BC10, 0x029A7C01, 0x029BC008, 0x029C0017,
98 0x029C8002, 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01,
99 0x02A08C09, 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D011,
100 0x02A33802, 0x02A38012, 0x02A3E003, 0x02A4980A, 0x02A51C0D,
101 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802, 0x02A79401,
102 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004, 0x02A9DC03,
103 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02, 0x02AAF802,
104 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402, 0x02AD6C01,
105 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02, 0x037FFC01,
106 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802, 0x03F7F002,
107 0x03F8001A, 0x03F8800E, 0x03F8C023, 0x03F95013, 0x03F9A004,
108 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, 0x03FD6C0B,
109 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, 0x0404DC09,
110 0x0405E411, 0x04063001, 0x0406400C, 0x04068001, 0x0407402E,
111 0x040B8001, 0x040DD805, 0x040E7C01, 0x040F4001, 0x0415BC01,
112 0x04215C01, 0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403,
113 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
114 0x0429FC01, 0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407,
115 0x042E6404, 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012,
116 0x04440003, 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003,
117 0x0446CC0E, 0x04471404, 0x04473401, 0x0448B012, 0x044B7C0C,
118 0x044C0403, 0x044CF001, 0x044CF807, 0x044D1C02, 0x044D2C03,
119 0x044D5C01, 0x044D8802, 0x044D9807, 0x044DC005, 0x0452C014,
120 0x04531801, 0x0456BC07, 0x0456E012, 0x0458C014, 0x045AAC0D,
 
121 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010, 0x05AD1002,
122 0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6, 0x07440027,
123 0x0744A4B5, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01,
124 0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01,
125 0x075E2401, 0x075EA401, 0x075F0C01, 0x07A34007, 0x07BBC002,
126 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F, 0x07C3040F,
127 0x07C34425, 0x07C4401F, 0x07C4C03C, 0x07C5C02B, 0x07C7981D,
128 0x07C8402B, 0x07C90009, 0x07C94002, 0x07CC002D, 0x07CCC04E,
129 0x07CE004F, 0x07CF5024, 0x07D000FF, 0x07D4004B, 0x07D5402A,
130 0x07D5EC29, 0x07D6949E, 0x07D9148B, 0x07DB800D, 0x07DBC004,
131 0x07DC0074, 0x07DE0055, 0x07E0000C, 0x07E04038, 0x07E1400A,
132 0x07E18028, 0x07E2401E, 0x38000401, 0x38008060, 0x380400F0,
133 };
134 static const unsigned int aAscii[4] = {
135 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
136 };
137
@@ -259,12 +260,12 @@
259 unsigned char flags;
260 unsigned char nRange;
261 } aEntry[] = {
262 {65, 14, 26}, {181, 64, 1}, {192, 14, 23},
263 {216, 14, 7}, {256, 1, 48}, {306, 1, 6},
264 {313, 1, 16}, {330, 1, 46}, {376, 126, 1},
265 {377, 1, 6}, {383, 114, 1}, {385, 50, 1},
266 {386, 1, 4}, {390, 44, 1}, {391, 0, 1},
267 {393, 42, 2}, {395, 0, 1}, {398, 32, 1},
268 {399, 38, 1}, {400, 40, 1}, {401, 0, 1},
269 {403, 42, 1}, {404, 46, 1}, {406, 52, 1},
270 {407, 48, 1}, {408, 0, 1}, {412, 52, 1},
@@ -273,64 +274,65 @@
273 {428, 0, 1}, {430, 60, 1}, {431, 0, 1},
274 {433, 58, 2}, {435, 1, 4}, {439, 62, 1},
275 {440, 0, 1}, {444, 0, 1}, {452, 2, 1},
276 {453, 0, 1}, {455, 2, 1}, {456, 0, 1},
277 {458, 2, 1}, {459, 1, 18}, {478, 1, 18},
278 {497, 2, 1}, {498, 1, 4}, {502, 132, 1},
279 {503, 144, 1}, {504, 1, 40}, {544, 120, 1},
280 {546, 1, 18}, {570, 70, 1}, {571, 0, 1},
281 {573, 118, 1}, {574, 68, 1}, {577, 0, 1},
282 {579, 116, 1}, {580, 28, 1}, {581, 30, 1},
283 {582, 1, 10}, {837, 36, 1}, {880, 1, 4},
284 {886, 0, 1}, {895, 36, 1}, {902, 18, 1},
285 {904, 16, 3}, {908, 26, 1}, {910, 24, 2},
286 {913, 14, 17}, {931, 14, 9}, {962, 0, 1},
287 {975, 4, 1}, {976, 150, 1}, {977, 152, 1},
288 {981, 156, 1}, {982, 154, 1}, {984, 1, 24},
289 {1008, 146, 1}, {1009, 148, 1}, {1012, 140, 1},
290 {1013, 138, 1}, {1015, 0, 1}, {1017, 162, 1},
291 {1018, 0, 1}, {1021, 120, 3}, {1024, 34, 16},
292 {1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54},
293 {1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96},
294 {1329, 22, 38}, {4256, 66, 38}, {4295, 66, 1},
295 {4301, 66, 1}, {7680, 1, 150}, {7835, 142, 1},
296 {7838, 106, 1}, {7840, 1, 96}, {7944, 160, 8},
297 {7960, 160, 6}, {7976, 160, 8}, {7992, 160, 8},
298 {8008, 160, 6}, {8025, 161, 8}, {8040, 160, 8},
299 {8072, 160, 8}, {8088, 160, 8}, {8104, 160, 8},
300 {8120, 160, 2}, {8122, 136, 2}, {8124, 158, 1},
301 {8126, 110, 1}, {8136, 134, 4}, {8140, 158, 1},
302 {8152, 160, 2}, {8154, 130, 2}, {8168, 160, 2},
303 {8170, 128, 2}, {8172, 162, 1}, {8184, 122, 2},
304 {8186, 124, 2}, {8188, 158, 1}, {8486, 108, 1},
305 {8490, 102, 1}, {8491, 104, 1}, {8498, 12, 1},
306 {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26},
307 {11264, 22, 47}, {11360, 0, 1}, {11362, 98, 1},
308 {11363, 112, 1}, {11364, 100, 1}, {11367, 1, 6},
309 {11373, 94, 1}, {11374, 96, 1}, {11375, 90, 1},
310 {11376, 92, 1}, {11378, 0, 1}, {11381, 0, 1},
311 {11390, 88, 2}, {11392, 1, 100}, {11499, 1, 4},
312 {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 28},
313 {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4},
314 {42877, 86, 1}, {42878, 1, 10}, {42891, 0, 1},
315 {42893, 82, 1}, {42896, 1, 4}, {42902, 1, 20},
316 {42922, 76, 1}, {42923, 72, 1}, {42924, 74, 1},
317 {42925, 78, 1}, {42928, 84, 1}, {42929, 80, 1},
318 {65313, 14, 26},
 
319 };
320 static const unsigned short aiOff[] = {
321 1, 2, 8, 15, 16, 26, 28, 32,
322 37, 38, 40, 48, 63, 64, 69, 71,
323 79, 80, 116, 202, 203, 205, 206, 207,
324 209, 210, 211, 213, 214, 217, 218, 219,
325 775, 7264, 10792, 10795, 23217, 23221, 23228, 23231,
326 23254, 23256, 23278, 30204, 54721, 54753, 54754, 54756,
327 54787, 54793, 54809, 57153, 57274, 57921, 58019, 58363,
328 61722, 65268, 65341, 65373, 65406, 65408, 65410, 65415,
329 65424, 65436, 65439, 65450, 65462, 65472, 65476, 65478,
330 65480, 65482, 65488, 65506, 65511, 65514, 65521, 65527,
331 65528, 65529,
332 };
333
334 int ret = c;
335
336 assert( c>=0 );
@@ -366,12 +368,15 @@
366 if( bRemoveDiacritic ) ret = unicode_remove_diacritic(ret);
367 }
368
369 else if( c>=66560 && c<66600 ){
370 ret = c + 40;
 
 
 
371 }
372 else if( c>=71840 && c<71872 ){
373 ret = c + 32;
374 }
375
376 return ret;
377 }
378
--- src/unicode.c
+++ src/unicode.c
@@ -49,11 +49,11 @@
49 0x00164437, 0x0017CC02, 0x0018001D, 0x00187802, 0x00192C15,
50 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07,
51 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B,
52 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804, 0x00206C09,
53 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801,
54 0x00238C21, 0x0024E803, 0x0024F812, 0x00254407, 0x00258804,
55 0x0025C001, 0x00260403, 0x0026F001, 0x0026F807, 0x00271C02,
56 0x00272C03, 0x00275C01, 0x00278802, 0x0027C802, 0x0027E802,
57 0x00280403, 0x0028F001, 0x0028F805, 0x00291C02, 0x00292C03,
58 0x00294401, 0x0029C002, 0x0029D401, 0x002A0403, 0x002AF001,
59 0x002AF808, 0x002B1C03, 0x002B2C03, 0x002B8802, 0x002BC002,
@@ -72,66 +72,67 @@
72 0x00417803, 0x00418803, 0x00419C07, 0x0041C404, 0x0042080C,
73 0x00423C01, 0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A,
74 0x00500001, 0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03,
75 0x005C4803, 0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023,
76 0x005F6004, 0x005F7401, 0x0060000F, 0x0062A401, 0x0064800C,
77 0x0064C00C, 0x00650001, 0x00651002, 0x00677822, 0x00685C05,
78 0x00687802, 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007,
79 0x006AA006, 0x006AC00F, 0x006C0005, 0x006CD011, 0x006D6823,
80 0x006E0003, 0x006E840D, 0x006F980E, 0x006FF004, 0x00709014,
81 0x0070EC05, 0x0071F802, 0x00730008, 0x00734019, 0x0073B401,
82 0x0073C803, 0x0073E002, 0x00770036, 0x0077F004, 0x007EF401,
83 0x007EFC03, 0x007F3403, 0x007F7403, 0x007FB403, 0x007FF402,
84 0x00800065, 0x0081980A, 0x0081E805, 0x00822805, 0x0082801F,
85 0x00834021, 0x00840002, 0x00840C04, 0x00842002, 0x00845001,
86 0x00845803, 0x00847806, 0x00849401, 0x00849C01, 0x0084A401,
87 0x0084B801, 0x0084E802, 0x00850005, 0x00852804, 0x00853C01,
88 0x00862802, 0x0086426B, 0x00900027, 0x0091000B, 0x0092704E,
89 0x00940276, 0x009E53E0, 0x00ADD820, 0x00AE6022, 0x00AEF40C,
90 0x00AF2808, 0x00AFB004, 0x00B39406, 0x00B3BC03, 0x00B3E404,
91 0x00B3F802, 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C013,
92 0x00BA001A, 0x00BA6C59, 0x00BC00D6, 0x00BFC00C, 0x00C00005,
93 0x00C02019, 0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404,
94 0x00C28001, 0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70024,
95 0x00C8001F, 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827,
96 0x00CB003F, 0x00CC0100, 0x01370040, 0x02924037, 0x0293F802,
97 0x02983403, 0x0299BC10, 0x029A7802, 0x029BC008, 0x029C0017,
98 0x029C8002, 0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01,
99 0x02A08C09, 0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D011,
100 0x02A33802, 0x02A38012, 0x02A3E003, 0x02A3F001, 0x02A4980A,
101 0x02A51C0D, 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802,
102 0x02A79401, 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004,
103 0x02A9DC03, 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02,
104 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402,
105 0x02AD6C01, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
106 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
107 0x03F7F002, 0x03F8001A, 0x03F88033, 0x03F95013, 0x03F9A004,
108 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06, 0x03FD6C0B,
109 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003, 0x0404DC09,
110 0x0405E411, 0x04063001, 0x0406400C, 0x04068001, 0x0407402E,
111 0x040B8001, 0x040DD805, 0x040E7C01, 0x040F4001, 0x0415BC01,
112 0x04215C01, 0x0421DC02, 0x04247C01, 0x0424FC01, 0x04280403,
113 0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
114 0x0429FC01, 0x042B2001, 0x042B9402, 0x042BC007, 0x042CE407,
115 0x042E6404, 0x04400003, 0x0440E016, 0x0441FC04, 0x0442C012,
116 0x04440003, 0x04449C0E, 0x04450004, 0x0445CC03, 0x04460003,
117 0x0446CC0E, 0x04471409, 0x04476C01, 0x04477403, 0x0448B012,
118 0x044AA401, 0x044B7C0C, 0x044C0004, 0x044CF001, 0x044CF807,
119 0x044D1C02, 0x044D2C03, 0x044D5C01, 0x044D8802, 0x044D9807,
120 0x044DC005, 0x0452C014, 0x04531801, 0x0456BC07, 0x0456E020,
121 0x04577002, 0x0458C014, 0x045AAC0D, 0x045C740F, 0x045CF004,
122 0x0491C005, 0x05A9B802, 0x05ABC006, 0x05ACC010, 0x05AD1002,
123 0x05BD442E, 0x05BE3C04, 0x06F27008, 0x074000F6, 0x07440027,
124 0x0744A4C0, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01,
125 0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01,
126 0x075E2401, 0x075EA401, 0x075F0C01, 0x0760028C, 0x076A6C05,
127 0x076A840F, 0x07A34007, 0x07BBC002, 0x07C0002C, 0x07C0C064,
128 0x07C2800F, 0x07C2C40F, 0x07C3040F, 0x07C34425, 0x07C4401F,
129 0x07C4C03C, 0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009,
130 0x07C94002, 0x07CC027A, 0x07D5EC29, 0x07D6952C, 0x07DB800D,
131 0x07DBC004, 0x07DC0074, 0x07DE0055, 0x07E0000C, 0x07E04038,
132 0x07E1400A, 0x07E18028, 0x07E2401E, 0x07E44009, 0x07E60005,
133 0x07E70001, 0x38000401, 0x38008060, 0x380400F0,
134 };
135 static const unsigned int aAscii[4] = {
136 0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
137 };
138
@@ -259,12 +260,12 @@
260 unsigned char flags;
261 unsigned char nRange;
262 } aEntry[] = {
263 {65, 14, 26}, {181, 64, 1}, {192, 14, 23},
264 {216, 14, 7}, {256, 1, 48}, {306, 1, 6},
265 {313, 1, 16}, {330, 1, 46}, {376, 132, 1},
266 {377, 1, 6}, {383, 120, 1}, {385, 50, 1},
267 {386, 1, 4}, {390, 44, 1}, {391, 0, 1},
268 {393, 42, 2}, {395, 0, 1}, {398, 32, 1},
269 {399, 38, 1}, {400, 40, 1}, {401, 0, 1},
270 {403, 42, 1}, {404, 46, 1}, {406, 52, 1},
271 {407, 48, 1}, {408, 0, 1}, {412, 52, 1},
@@ -273,64 +274,65 @@
274 {428, 0, 1}, {430, 60, 1}, {431, 0, 1},
275 {433, 58, 2}, {435, 1, 4}, {439, 62, 1},
276 {440, 0, 1}, {444, 0, 1}, {452, 2, 1},
277 {453, 0, 1}, {455, 2, 1}, {456, 0, 1},
278 {458, 2, 1}, {459, 1, 18}, {478, 1, 18},
279 {497, 2, 1}, {498, 1, 4}, {502, 138, 1},
280 {503, 150, 1}, {504, 1, 40}, {544, 126, 1},
281 {546, 1, 18}, {570, 72, 1}, {571, 0, 1},
282 {573, 124, 1}, {574, 70, 1}, {577, 0, 1},
283 {579, 122, 1}, {580, 28, 1}, {581, 30, 1},
284 {582, 1, 10}, {837, 36, 1}, {880, 1, 4},
285 {886, 0, 1}, {895, 36, 1}, {902, 18, 1},
286 {904, 16, 3}, {908, 26, 1}, {910, 24, 2},
287 {913, 14, 17}, {931, 14, 9}, {962, 0, 1},
288 {975, 4, 1}, {976, 156, 1}, {977, 158, 1},
289 {981, 162, 1}, {982, 160, 1}, {984, 1, 24},
290 {1008, 152, 1}, {1009, 154, 1}, {1012, 146, 1},
291 {1013, 144, 1}, {1015, 0, 1}, {1017, 168, 1},
292 {1018, 0, 1}, {1021, 126, 3}, {1024, 34, 16},
293 {1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54},
294 {1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96},
295 {1329, 22, 38}, {4256, 68, 38}, {4295, 68, 1},
296 {4301, 68, 1}, {5112, 166, 6}, {7680, 1, 150},
297 {7835, 148, 1}, {7838, 112, 1}, {7840, 1, 96},
298 {7944, 166, 8}, {7960, 166, 6}, {7976, 166, 8},
299 {7992, 166, 8}, {8008, 166, 6}, {8025, 167, 8},
300 {8040, 166, 8}, {8072, 166, 8}, {8088, 166, 8},
301 {8104, 166, 8}, {8120, 166, 2}, {8122, 142, 2},
302 {8124, 164, 1}, {8126, 116, 1}, {8136, 140, 4},
303 {8140, 164, 1}, {8152, 166, 2}, {8154, 136, 2},
304 {8168, 166, 2}, {8170, 134, 2}, {8172, 168, 1},
305 {8184, 128, 2}, {8186, 130, 2}, {8188, 164, 1},
306 {8486, 114, 1}, {8490, 108, 1}, {8491, 110, 1},
307 {8498, 12, 1}, {8544, 8, 16}, {8579, 0, 1},
308 {9398, 10, 26}, {11264, 22, 47}, {11360, 0, 1},
309 {11362, 104, 1}, {11363, 118, 1}, {11364, 106, 1},
310 {11367, 1, 6}, {11373, 100, 1}, {11374, 102, 1},
311 {11375, 96, 1}, {11376, 98, 1}, {11378, 0, 1},
312 {11381, 0, 1}, {11390, 94, 2}, {11392, 1, 100},
313 {11499, 1, 4}, {11506, 0, 1}, {42560, 1, 46},
314 {42624, 1, 28}, {42786, 1, 14}, {42802, 1, 62},
315 {42873, 1, 4}, {42877, 92, 1}, {42878, 1, 10},
316 {42891, 0, 1}, {42893, 84, 1}, {42896, 1, 4},
317 {42902, 1, 20}, {42922, 78, 1}, {42923, 74, 1},
318 {42924, 76, 1}, {42925, 80, 1}, {42928, 88, 1},
319 {42929, 82, 1}, {42930, 86, 1}, {42931, 66, 1},
320 {42932, 1, 4}, {43888, 90, 80}, {65313, 14, 26},
321 };
322 static const unsigned short aiOff[] = {
323 1, 2, 8, 15, 16, 26, 28, 32,
324 37, 38, 40, 48, 63, 64, 69, 71,
325 79, 80, 116, 202, 203, 205, 206, 207,
326 209, 210, 211, 213, 214, 217, 218, 219,
327 775, 928, 7264, 10792, 10795, 23217, 23221, 23228,
328 23231, 23254, 23256, 23275, 23278, 26672, 30204, 54721,
329 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
330 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406,
331 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462,
332 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511,
333 65514, 65521, 65527, 65528, 65529,
334 };
335
336 int ret = c;
337
338 assert( c>=0 );
@@ -366,12 +368,15 @@
368 if( bRemoveDiacritic ) ret = unicode_remove_diacritic(ret);
369 }
370
371 else if( c>=66560 && c<66600 ){
372 ret = c + 40;
373 }
374 else if( c>=68736 && c<68787 ){
375 ret = c + 64;
376 }
377 else if( c>=71840 && c<71872 ){
378 ret = c + 32;
379 }
380
381 return ret;
382 }
383
+18 -26
--- src/update.c
+++ src/update.c
@@ -352,11 +352,11 @@
352352
353353
blob_zero(&sql);
354354
blob_append(&sql, "DELETE FROM fv WHERE ", -1);
355355
zSep = "";
356356
for(i=3; i<g.argc; i++){
357
- file_tree_name(g.argv[i], &treename, 1);
357
+ file_tree_name(g.argv[i], &treename, 0, 1);
358358
if( file_wd_isdir(g.argv[i])==1 ){
359359
if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
360360
blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
361361
zSep /*safe-for-%s*/, blob_str(&treename));
362362
}else{
@@ -586,43 +586,32 @@
586586
db_end_transaction(0);
587587
}
588588
}
589589
590590
/*
591
-** Make sure empty directories are created
591
+** Create empty directories specified by the empty-dirs setting.
592592
*/
593593
void ensure_empty_dirs_created(void){
594
- /* Make empty directories? */
595594
char *zEmptyDirs = db_get("empty-dirs", 0);
596595
if( zEmptyDirs!=0 ){
597
- char *bc;
596
+ int i;
598597
Blob dirName;
599598
Blob dirsList;
600599
601
- blob_zero(&dirsList);
602
- blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
603
- /* Replace commas by spaces */
604
- bc = blob_str(&dirsList);
605
- while( (*bc)!='\0' ){
606
- if( (*bc)==',' ) { *bc = ' '; }
607
- ++bc;
608
- }
609
- /* Make directories */
610
- blob_zero(&dirName);
600
+ zEmptyDirs = fossil_strdup(zEmptyDirs);
601
+ for(i=0; zEmptyDirs[i]; i++){
602
+ if( zEmptyDirs[i]==',' ) zEmptyDirs[i] = ' ';
603
+ }
604
+ blob_init(&dirsList, zEmptyDirs, -1);
611605
while( blob_token(&dirsList, &dirName) ){
612
- const char *zDir = blob_str(&dirName);
613
- /* Make full pathname of the directory */
614
- Blob path;
615
- const char *zPath;
616
-
617
- blob_zero(&path);
618
- blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
619
- zPath = blob_str(&path);
620
- /* Handle various cases of existence of the directory */
606
+ char *zDir = blob_str(&dirName);
607
+ char *zPath = mprintf("%s/%s", g.zLocalRoot, zDir);
621608
switch( file_wd_isdir(zPath) ){
622609
case 0: { /* doesn't exist */
623
- if( file_mkdir(zPath, 0)!=0 ) {
610
+ fossil_free(zPath);
611
+ zPath = mprintf("%s/%s/x", g.zLocalRoot, zDir);
612
+ if( file_mkfolder(zPath, 0, 1)!=0 ) {
624613
fossil_warning("couldn't create directory %s as "
625614
"required by empty-dirs setting", zDir);
626615
}
627616
break;
628617
}
@@ -633,12 +622,15 @@
633622
case 2: { /* exists, but isn't a directory */
634623
fossil_warning("file %s found, but a directory is required "
635624
"by empty-dirs setting", zDir);
636625
}
637626
}
638
- blob_reset(&path);
627
+ fossil_free(zPath);
628
+ blob_reset(&dirName);
639629
}
630
+ blob_reset(&dirsList);
631
+ fossil_free(zEmptyDirs);
640632
}
641633
}
642634
643635
644636
/*
@@ -746,11 +738,11 @@
746738
747739
if( g.argc>2 ){
748740
for(i=2; i<g.argc; i++){
749741
Blob fname;
750742
zFile = mprintf("%/", g.argv[i]);
751
- file_tree_name(zFile, &fname, 1);
743
+ file_tree_name(zFile, &fname, 0, 1);
752744
db_multi_exec(
753745
"REPLACE INTO torevert VALUES(%B);"
754746
"INSERT OR IGNORE INTO torevert"
755747
" SELECT pathname"
756748
" FROM vfile"
757749
--- src/update.c
+++ src/update.c
@@ -352,11 +352,11 @@
352
353 blob_zero(&sql);
354 blob_append(&sql, "DELETE FROM fv WHERE ", -1);
355 zSep = "";
356 for(i=3; i<g.argc; i++){
357 file_tree_name(g.argv[i], &treename, 1);
358 if( file_wd_isdir(g.argv[i])==1 ){
359 if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
360 blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
361 zSep /*safe-for-%s*/, blob_str(&treename));
362 }else{
@@ -586,43 +586,32 @@
586 db_end_transaction(0);
587 }
588 }
589
590 /*
591 ** Make sure empty directories are created
592 */
593 void ensure_empty_dirs_created(void){
594 /* Make empty directories? */
595 char *zEmptyDirs = db_get("empty-dirs", 0);
596 if( zEmptyDirs!=0 ){
597 char *bc;
598 Blob dirName;
599 Blob dirsList;
600
601 blob_zero(&dirsList);
602 blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs));
603 /* Replace commas by spaces */
604 bc = blob_str(&dirsList);
605 while( (*bc)!='\0' ){
606 if( (*bc)==',' ) { *bc = ' '; }
607 ++bc;
608 }
609 /* Make directories */
610 blob_zero(&dirName);
611 while( blob_token(&dirsList, &dirName) ){
612 const char *zDir = blob_str(&dirName);
613 /* Make full pathname of the directory */
614 Blob path;
615 const char *zPath;
616
617 blob_zero(&path);
618 blob_appendf(&path, "%s/%s", g.zLocalRoot, zDir);
619 zPath = blob_str(&path);
620 /* Handle various cases of existence of the directory */
621 switch( file_wd_isdir(zPath) ){
622 case 0: { /* doesn't exist */
623 if( file_mkdir(zPath, 0)!=0 ) {
 
 
624 fossil_warning("couldn't create directory %s as "
625 "required by empty-dirs setting", zDir);
626 }
627 break;
628 }
@@ -633,12 +622,15 @@
633 case 2: { /* exists, but isn't a directory */
634 fossil_warning("file %s found, but a directory is required "
635 "by empty-dirs setting", zDir);
636 }
637 }
638 blob_reset(&path);
 
639 }
 
 
640 }
641 }
642
643
644 /*
@@ -746,11 +738,11 @@
746
747 if( g.argc>2 ){
748 for(i=2; i<g.argc; i++){
749 Blob fname;
750 zFile = mprintf("%/", g.argv[i]);
751 file_tree_name(zFile, &fname, 1);
752 db_multi_exec(
753 "REPLACE INTO torevert VALUES(%B);"
754 "INSERT OR IGNORE INTO torevert"
755 " SELECT pathname"
756 " FROM vfile"
757
--- src/update.c
+++ src/update.c
@@ -352,11 +352,11 @@
352
353 blob_zero(&sql);
354 blob_append(&sql, "DELETE FROM fv WHERE ", -1);
355 zSep = "";
356 for(i=3; i<g.argc; i++){
357 file_tree_name(g.argv[i], &treename, 0, 1);
358 if( file_wd_isdir(g.argv[i])==1 ){
359 if( blob_size(&treename) != 1 || blob_str(&treename)[0] != '.' ){
360 blob_append_sql(&sql, "%sfn NOT GLOB '%q/*' ",
361 zSep /*safe-for-%s*/, blob_str(&treename));
362 }else{
@@ -586,43 +586,32 @@
586 db_end_transaction(0);
587 }
588 }
589
590 /*
591 ** Create empty directories specified by the empty-dirs setting.
592 */
593 void ensure_empty_dirs_created(void){
 
594 char *zEmptyDirs = db_get("empty-dirs", 0);
595 if( zEmptyDirs!=0 ){
596 int i;
597 Blob dirName;
598 Blob dirsList;
599
600 zEmptyDirs = fossil_strdup(zEmptyDirs);
601 for(i=0; zEmptyDirs[i]; i++){
602 if( zEmptyDirs[i]==',' ) zEmptyDirs[i] = ' ';
603 }
604 blob_init(&dirsList, zEmptyDirs, -1);
 
 
 
 
 
605 while( blob_token(&dirsList, &dirName) ){
606 char *zDir = blob_str(&dirName);
607 char *zPath = mprintf("%s/%s", g.zLocalRoot, zDir);
 
 
 
 
 
 
 
608 switch( file_wd_isdir(zPath) ){
609 case 0: { /* doesn't exist */
610 fossil_free(zPath);
611 zPath = mprintf("%s/%s/x", g.zLocalRoot, zDir);
612 if( file_mkfolder(zPath, 0, 1)!=0 ) {
613 fossil_warning("couldn't create directory %s as "
614 "required by empty-dirs setting", zDir);
615 }
616 break;
617 }
@@ -633,12 +622,15 @@
622 case 2: { /* exists, but isn't a directory */
623 fossil_warning("file %s found, but a directory is required "
624 "by empty-dirs setting", zDir);
625 }
626 }
627 fossil_free(zPath);
628 blob_reset(&dirName);
629 }
630 blob_reset(&dirsList);
631 fossil_free(zEmptyDirs);
632 }
633 }
634
635
636 /*
@@ -746,11 +738,11 @@
738
739 if( g.argc>2 ){
740 for(i=2; i<g.argc; i++){
741 Blob fname;
742 zFile = mprintf("%/", g.argv[i]);
743 file_tree_name(zFile, &fname, 0, 1);
744 db_multi_exec(
745 "REPLACE INTO torevert VALUES(%B);"
746 "INSERT OR IGNORE INTO torevert"
747 " SELECT pathname"
748 " FROM vfile"
749
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1151,11 +1151,13 @@
11511151
return zTarget+5;
11521152
}
11531153
if( strcmp(zTarget, "Sandbox")==0 ) return zTarget;
11541154
if( wiki_name_is_wellformed((const unsigned char *)zTarget)
11551155
&& ((p->state & WIKI_NOBADLINKS)==0 ||
1156
- db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'", zTarget))
1156
+ db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'"
1157
+ " AND (SELECT value FROM tagxref WHERE tagid=tag.tagid"
1158
+ " ORDER BY mtime DESC LIMIT 1) > 0", zTarget))
11571159
){
11581160
return zTarget;
11591161
}
11601162
return 0;
11611163
}
11621164
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1151,11 +1151,13 @@
1151 return zTarget+5;
1152 }
1153 if( strcmp(zTarget, "Sandbox")==0 ) return zTarget;
1154 if( wiki_name_is_wellformed((const unsigned char *)zTarget)
1155 && ((p->state & WIKI_NOBADLINKS)==0 ||
1156 db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'", zTarget))
 
 
1157 ){
1158 return zTarget;
1159 }
1160 return 0;
1161 }
1162
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1151,11 +1151,13 @@
1151 return zTarget+5;
1152 }
1153 if( strcmp(zTarget, "Sandbox")==0 ) return zTarget;
1154 if( wiki_name_is_wellformed((const unsigned char *)zTarget)
1155 && ((p->state & WIKI_NOBADLINKS)==0 ||
1156 db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'"
1157 " AND (SELECT value FROM tagxref WHERE tagid=tag.tagid"
1158 " ORDER BY mtime DESC LIMIT 1) > 0", zTarget))
1159 ){
1160 return zTarget;
1161 }
1162 return 0;
1163 }
1164
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1151,11 +1151,13 @@
11511151
return zTarget+5;
11521152
}
11531153
if( strcmp(zTarget, "Sandbox")==0 ) return zTarget;
11541154
if( wiki_name_is_wellformed((const unsigned char *)zTarget)
11551155
&& ((p->state & WIKI_NOBADLINKS)==0 ||
1156
- db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'", zTarget))
1156
+ db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'"
1157
+ " AND (SELECT value FROM tagxref WHERE tagid=tag.tagid"
1158
+ " ORDER BY mtime DESC LIMIT 1) > 0", zTarget))
11571159
){
11581160
return zTarget;
11591161
}
11601162
return 0;
11611163
}
11621164
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1151,11 +1151,13 @@
1151 return zTarget+5;
1152 }
1153 if( strcmp(zTarget, "Sandbox")==0 ) return zTarget;
1154 if( wiki_name_is_wellformed((const unsigned char *)zTarget)
1155 && ((p->state & WIKI_NOBADLINKS)==0 ||
1156 db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'", zTarget))
 
 
1157 ){
1158 return zTarget;
1159 }
1160 return 0;
1161 }
1162
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1151,11 +1151,13 @@
1151 return zTarget+5;
1152 }
1153 if( strcmp(zTarget, "Sandbox")==0 ) return zTarget;
1154 if( wiki_name_is_wellformed((const unsigned char *)zTarget)
1155 && ((p->state & WIKI_NOBADLINKS)==0 ||
1156 db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'wiki-%q'"
1157 " AND (SELECT value FROM tagxref WHERE tagid=tag.tagid"
1158 " ORDER BY mtime DESC LIMIT 1) > 0", zTarget))
1159 ){
1160 return zTarget;
1161 }
1162 return 0;
1163 }
1164
--- test/file1.test
+++ test/file1.test
@@ -33,10 +33,28 @@
3333
fossil test-relative-name --chdir $subdir $path
3434
test relative-name-$testname.$i {$::RESULT==$result}
3535
incr i
3636
}
3737
}
38
+
39
+proc relative-tree-name {testname args} {
40
+ set i 1
41
+ foreach {subdir path result} $args {
42
+ fossil test-tree-name --chdir $subdir $path
43
+ test relative-tree-name-$testname.$i {$::RESULT==$result}
44
+ incr i
45
+ }
46
+}
47
+
48
+proc absolute-tree-name {testname args} {
49
+ set i 1
50
+ foreach {subdir path result} $args {
51
+ fossil test-tree-name --chdir $subdir --absolute $path
52
+ test absolute-tree-name-$testname.$i {$::RESULT==$result}
53
+ incr i
54
+ }
55
+}
3856
3957
simplify-name 100 . . .// . .. .. ..///// ..
4058
simplify-name 101 {} {} / / ///////// / ././././ .
4159
simplify-name 102 x x /x /x ///x //x
4260
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
@@ -55,8 +73,21 @@
5573
file mkdir test1/test2
5674
5775
relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test
5876
relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test
5977
relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2
78
+relative-name 103 . [pwd] .
79
+
80
+relative-tree-name 100 . . file1 test1 [pwd] file1 test1 [pwd]/ file1 test1 [pwd]/test file1/test
81
+relative-tree-name 101 test1/test2 [pwd] file1 test1/test2 [pwd]/ file1 test1/test2 [pwd]/test file1/test
82
+relative-tree-name 102 test1 [pwd]/test file1/test . [pwd]/file1 file1/file1 . [pwd]/file1/file2 file1/file1/file2
83
+relative-tree-name 103 . [pwd] file1
84
+
85
+set dirname [file normalize [file dirname [pwd]]]
86
+
87
+absolute-tree-name 100 . . $dirname test1 [pwd] [pwd] test1 [pwd]/ $dirname/file1 test1 [pwd]/test $dirname/file1/test
88
+absolute-tree-name 101 test1/test2 [pwd] $dirname/file1 test1/test2 [pwd]/ $dirname/file1 test1/test2 [pwd]/test $dirname/file1/test
89
+absolute-tree-name 102 test1 [pwd]/test $dirname/file1/test . [pwd]/file1 $dirname/file1/file1 . [pwd]/file1/file2 $dirname/file1/file1/file2
90
+absolute-tree-name 103 . [pwd] $dirname/file1
6091
6192
catch {file delete test1/test2}
6293
catch {file delete test1}
6394
--- test/file1.test
+++ test/file1.test
@@ -33,10 +33,28 @@
33 fossil test-relative-name --chdir $subdir $path
34 test relative-name-$testname.$i {$::RESULT==$result}
35 incr i
36 }
37 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
39 simplify-name 100 . . .// . .. .. ..///// ..
40 simplify-name 101 {} {} / / ///////// / ././././ .
41 simplify-name 102 x x /x /x ///x //x
42 simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
@@ -55,8 +73,21 @@
55 file mkdir test1/test2
56
57 relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test
58 relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test
59 relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2
 
 
 
 
 
 
 
 
 
 
 
 
 
60
61 catch {file delete test1/test2}
62 catch {file delete test1}
63
--- test/file1.test
+++ test/file1.test
@@ -33,10 +33,28 @@
33 fossil test-relative-name --chdir $subdir $path
34 test relative-name-$testname.$i {$::RESULT==$result}
35 incr i
36 }
37 }
38
39 proc relative-tree-name {testname args} {
40 set i 1
41 foreach {subdir path result} $args {
42 fossil test-tree-name --chdir $subdir $path
43 test relative-tree-name-$testname.$i {$::RESULT==$result}
44 incr i
45 }
46 }
47
48 proc absolute-tree-name {testname args} {
49 set i 1
50 foreach {subdir path result} $args {
51 fossil test-tree-name --chdir $subdir --absolute $path
52 test absolute-tree-name-$testname.$i {$::RESULT==$result}
53 incr i
54 }
55 }
56
57 simplify-name 100 . . .// . .. .. ..///// ..
58 simplify-name 101 {} {} / / ///////// / ././././ .
59 simplify-name 102 x x /x /x ///x //x
60 simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
@@ -55,8 +73,21 @@
73 file mkdir test1/test2
74
75 relative-name 100 . . . test1 [pwd] .. test1 [pwd]/ .. test1 [pwd]/test ../test
76 relative-name 101 test1/test2 [pwd] ../.. test1/test2 [pwd]/ ../.. test1/test2 [pwd]/test ../../test
77 relative-name 102 test1 [pwd]/test ../test . [pwd]/file1 ./file1 . [pwd]/file1/file2 ./file1/file2
78 relative-name 103 . [pwd] .
79
80 relative-tree-name 100 . . file1 test1 [pwd] file1 test1 [pwd]/ file1 test1 [pwd]/test file1/test
81 relative-tree-name 101 test1/test2 [pwd] file1 test1/test2 [pwd]/ file1 test1/test2 [pwd]/test file1/test
82 relative-tree-name 102 test1 [pwd]/test file1/test . [pwd]/file1 file1/file1 . [pwd]/file1/file2 file1/file1/file2
83 relative-tree-name 103 . [pwd] file1
84
85 set dirname [file normalize [file dirname [pwd]]]
86
87 absolute-tree-name 100 . . $dirname test1 [pwd] [pwd] test1 [pwd]/ $dirname/file1 test1 [pwd]/test $dirname/file1/test
88 absolute-tree-name 101 test1/test2 [pwd] $dirname/file1 test1/test2 [pwd]/ $dirname/file1 test1/test2 [pwd]/test $dirname/file1/test
89 absolute-tree-name 102 test1 [pwd]/test $dirname/file1/test . [pwd]/file1 $dirname/file1/file1 . [pwd]/file1/file2 $dirname/file1/file1/file2
90 absolute-tree-name 103 . [pwd] $dirname/file1
91
92 catch {file delete test1/test2}
93 catch {file delete test1}
94
--- test/merge6.test
+++ test/merge6.test
@@ -23,26 +23,26 @@
2323
####################################################################
2424
2525
repo_init
2626
fossil ls
2727
28
-test merge_multi-0 {[string map [list \r\n \n] [string trim $RESULT]] eq {}}
28
+test merge_multi-0 {[normalize_result] eq {}}
2929
3030
write_file f1 "f1 line"
3131
fossil add f1
3232
fossil commit -m "base file"
3333
fossil ls
3434
35
-test merge_multi-1 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1}}
35
+test merge_multi-1 {[normalize_result] eq {f1}}
3636
3737
fossil update trunk
3838
write_file f2 "f2 line"
3939
fossil add f2
4040
fossil commit -m "branch for file f2" -b branch_for_f2
4141
fossil ls
4242
43
-test merge_multi-2 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
43
+test merge_multi-2 {[normalize_result] eq {f1
4444
f2}}
4545
4646
fossil update trunk
4747
write_file f3 "f3 line"
4848
write_file f4 "f4 line"
@@ -49,19 +49,19 @@
4949
fossil add f3
5050
fossil add f4
5151
fossil commit -m "branch for files f3 and f4" -b branch_for_f3_f4
5252
fossil ls
5353
54
-test merge_multi-3 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
54
+test merge_multi-3 {[normalize_result] eq {f1
5555
f3
5656
f4}}
5757
5858
fossil update trunk
5959
fossil merge branch_for_f2
6060
fossil merge branch_for_f3_f4
6161
fossil commit -m "new trunk files f2, f3, and f4 via merge"
6262
fossil ls
6363
64
-test merge_multi-4 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
64
+test merge_multi-4 {[normalize_result] eq {f1
6565
f2
6666
f3
6767
f4}}
6868
--- test/merge6.test
+++ test/merge6.test
@@ -23,26 +23,26 @@
23 ####################################################################
24
25 repo_init
26 fossil ls
27
28 test merge_multi-0 {[string map [list \r\n \n] [string trim $RESULT]] eq {}}
29
30 write_file f1 "f1 line"
31 fossil add f1
32 fossil commit -m "base file"
33 fossil ls
34
35 test merge_multi-1 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1}}
36
37 fossil update trunk
38 write_file f2 "f2 line"
39 fossil add f2
40 fossil commit -m "branch for file f2" -b branch_for_f2
41 fossil ls
42
43 test merge_multi-2 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
44 f2}}
45
46 fossil update trunk
47 write_file f3 "f3 line"
48 write_file f4 "f4 line"
@@ -49,19 +49,19 @@
49 fossil add f3
50 fossil add f4
51 fossil commit -m "branch for files f3 and f4" -b branch_for_f3_f4
52 fossil ls
53
54 test merge_multi-3 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
55 f3
56 f4}}
57
58 fossil update trunk
59 fossil merge branch_for_f2
60 fossil merge branch_for_f3_f4
61 fossil commit -m "new trunk files f2, f3, and f4 via merge"
62 fossil ls
63
64 test merge_multi-4 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
65 f2
66 f3
67 f4}}
68
--- test/merge6.test
+++ test/merge6.test
@@ -23,26 +23,26 @@
23 ####################################################################
24
25 repo_init
26 fossil ls
27
28 test merge_multi-0 {[normalize_result] eq {}}
29
30 write_file f1 "f1 line"
31 fossil add f1
32 fossil commit -m "base file"
33 fossil ls
34
35 test merge_multi-1 {[normalize_result] eq {f1}}
36
37 fossil update trunk
38 write_file f2 "f2 line"
39 fossil add f2
40 fossil commit -m "branch for file f2" -b branch_for_f2
41 fossil ls
42
43 test merge_multi-2 {[normalize_result] eq {f1
44 f2}}
45
46 fossil update trunk
47 write_file f3 "f3 line"
48 write_file f4 "f4 line"
@@ -49,19 +49,19 @@
49 fossil add f3
50 fossil add f4
51 fossil commit -m "branch for files f3 and f4" -b branch_for_f3_f4
52 fossil ls
53
54 test merge_multi-3 {[normalize_result] eq {f1
55 f3
56 f4}}
57
58 fossil update trunk
59 fossil merge branch_for_f2
60 fossil merge branch_for_f3_f4
61 fossil commit -m "new trunk files f2, f3, and f4 via merge"
62 fossil ls
63
64 test merge_multi-4 {[normalize_result] eq {f1
65 f2
66 f3
67 f4}}
68
--- test/merge_renames.test
+++ test/merge_renames.test
@@ -197,11 +197,11 @@
197197
fossil merge trunk
198198
fossil commit -m "trunk merged, should have 3 files"
199199
200200
fossil ls
201201
202
-test merge_renames-5 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
202
+test merge_renames-5 {[normalize_result] eq {f1
203203
f2
204204
f3}}
205205
206206
######################################
207207
#
208208
209209
ADDED test/mv-rm.test
--- test/merge_renames.test
+++ test/merge_renames.test
@@ -197,11 +197,11 @@
197 fossil merge trunk
198 fossil commit -m "trunk merged, should have 3 files"
199
200 fossil ls
201
202 test merge_renames-5 {[string map [list \r\n \n] [string trim $RESULT]] eq {f1
203 f2
204 f3}}
205
206 ######################################
207 #
208
209 DDED test/mv-rm.test
--- test/merge_renames.test
+++ test/merge_renames.test
@@ -197,11 +197,11 @@
197 fossil merge trunk
198 fossil commit -m "trunk merged, should have 3 files"
199
200 fossil ls
201
202 test merge_renames-5 {[normalize_result] eq {f1
203 f2
204 f3}}
205
206 ######################################
207 #
208
209 DDED test/mv-rm.test
--- a/test/mv-rm.test
+++ b/test/mv-rm.test
@@ -0,0 +1,82 @@
1
+#
2
+
3
+test_cleanup
4
+REVERT f1\nDELETE subdir1/f1REVERT f2\nDELETE subdir2/f2#
5
+
6
+test_cleanup
7
+REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
8
+
9
+test_cleanREVERT f8\nDELETE subdir8/DELETE subdir1/f1\nREVERT fDELETE subdir2/f2\nDELETE subdir3/f3\nREVERT f3DELETE subdir4/f4\nDELETE 5/f5\nREVERT f5DELETE subdir6/f6\nREVERT f6#
10
+
11
+test_cleanup
12
+REVERT f1\nDELETE subdir1/f1REVERT f2\nDELETE subdir2/f2#
13
+
14
+test_cleanup
15
+REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
16
+
17
+test_cleanREVERT f8\nDELETE subdir8/nDELETE scatch {eputs res=$h {exec $::fossilexe info} res
18
+if {![regexp {use --repository} $res]} {
19
+ puts stderr "Cannot run this test within an open checkout"
20
+ return
21
+}p
22
+repo_initrepo_init: subdir1/f1\nREVERTED: f:ED:res]} {
23
+ puts stderr "Cannot run this test within an open checkout"
24
+ return
25
+}p
26
+repo_initrepo_init:ED: f3: subdir4/f4\nREVERTED: f4: subdir5/f5\nREVERTED: f5: subdir6/f6\nREVERTED: f6: subdir7/f7\nREVERTED: f7: subdir8/f8ED: f8ED: subdirB/f9\nREVERTED:ED:ED:ED: subdirB/f9\nREVERTED:ED:ED: f413REVERT f4\nDE#
27
+
28
+test_cleanup
29
+REVERT f1\nDELETE subdir1/f1REVERT f2\nDELETE subdir2/f2#
30
+
31
+test_cleanup
32
+REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
33
+
34
+test_cleanREVERT f8\nDELETE subdir8/DELETE subdir1/f1\nREVERT fDELETE subdir2/f2\nDELETE subdir3/f3\nREVERT f3DELETE subdir4/f4\nDELETE 5/f5\nREVERT write_file f12 "f12 f5DELERT f6#
35
+
36
+test_cleanup
37
+REVERT ED: subdirB/ f12ubdirB/f9\nREVERTED:ED:ubdirB/f9\nREVERTED:ED:6REVERT f4\nDE#8] f6\nDELETE subdir6/#
38
+
39
+test_cleanREVERT f8\nDELETE subdir8/DELETE subdir1/f1\nREVERT fDELETE subdir2/f2\nDELETE subdir3/f3\nREV#
40
+
41
+tes f8R@UG,14A0B7;#
42
+
43
+test_cleanT f1\nDELETE subdir1/f1R Move File to Newp@23l,v:
44
+
45
+fossil mv --hard f12 d2/f13
46
+test mv-file-newup
47
+REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
48
+
49
+test_cleanREVER#
50
+
51
+test_cleanup12"
52
+}
53
+
54
+test mv-file-new-directory-2 {[file size d2/f13] == 3}
55
+test mv-file-new-directory-3file-new-directoryd2/f13\nREVERTED: f12${undoMsg}"
56
+}
57
+
58
+test mv-file-new-directory-5 {[file size f12] == 3}
59
+test mv-file-new-directory-6 {[read_file f12] eq "f12"#
60
+# Test 18: Move Directory to New#
61
+
62
+fossil mv --hard subdirC subdirD
63
+test mv-file-new-directory-7up
64
+REVERT f4\nDELETE subdi#
65
+
66
+test_cleanup
67
+REVEETE 5/"
68
+}
69
+
70
+test mv-file-new-directory-8 {[file size subdirD/f10] == 3}
71
+test mv-file-new-directory-9 {[read_file subdirD/f10] eq "f10"}
72
+test mv-file-new-directory-10 {[file size subdirD/f11] == 3}
73
+test mv-file-new-directory-11 {[reafile-new-directory-12up
74
+REVERT #
75
+
76
+test_cleanup
77
+REVERTtest mv-file-new-directory-13 {[file size subdirC/f10] == 3}
78
+test mv-file-new-directory-14 {[read_file subdirC/f10] eq "f10"}
79
+test mv-file-new-directory-15 {[file size subdirC/f11] == 3}
80
+test mv-file-new-directory-16 {[read_file subdirC/f11] eq "f11"}
81
+
82
+cd $rootDir
--- a/test/mv-rm.test
+++ b/test/mv-rm.test
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/test/mv-rm.test
+++ b/test/mv-rm.test
@@ -0,0 +1,82 @@
1 #
2
3 test_cleanup
4 REVERT f1\nDELETE subdir1/f1REVERT f2\nDELETE subdir2/f2#
5
6 test_cleanup
7 REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
8
9 test_cleanREVERT f8\nDELETE subdir8/DELETE subdir1/f1\nREVERT fDELETE subdir2/f2\nDELETE subdir3/f3\nREVERT f3DELETE subdir4/f4\nDELETE 5/f5\nREVERT f5DELETE subdir6/f6\nREVERT f6#
10
11 test_cleanup
12 REVERT f1\nDELETE subdir1/f1REVERT f2\nDELETE subdir2/f2#
13
14 test_cleanup
15 REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
16
17 test_cleanREVERT f8\nDELETE subdir8/nDELETE scatch {eputs res=$h {exec $::fossilexe info} res
18 if {![regexp {use --repository} $res]} {
19 puts stderr "Cannot run this test within an open checkout"
20 return
21 }p
22 repo_initrepo_init: subdir1/f1\nREVERTED: f:ED:res]} {
23 puts stderr "Cannot run this test within an open checkout"
24 return
25 }p
26 repo_initrepo_init:ED: f3: subdir4/f4\nREVERTED: f4: subdir5/f5\nREVERTED: f5: subdir6/f6\nREVERTED: f6: subdir7/f7\nREVERTED: f7: subdir8/f8ED: f8ED: subdirB/f9\nREVERTED:ED:ED:ED: subdirB/f9\nREVERTED:ED:ED: f413REVERT f4\nDE#
27
28 test_cleanup
29 REVERT f1\nDELETE subdir1/f1REVERT f2\nDELETE subdir2/f2#
30
31 test_cleanup
32 REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
33
34 test_cleanREVERT f8\nDELETE subdir8/DELETE subdir1/f1\nREVERT fDELETE subdir2/f2\nDELETE subdir3/f3\nREVERT f3DELETE subdir4/f4\nDELETE 5/f5\nREVERT write_file f12 "f12 f5DELERT f6#
35
36 test_cleanup
37 REVERT ED: subdirB/ f12ubdirB/f9\nREVERTED:ED:ubdirB/f9\nREVERTED:ED:6REVERT f4\nDE#8] f6\nDELETE subdir6/#
38
39 test_cleanREVERT f8\nDELETE subdir8/DELETE subdir1/f1\nREVERT fDELETE subdir2/f2\nDELETE subdir3/f3\nREV#
40
41 tes f8R@UG,14A0B7;#
42
43 test_cleanT f1\nDELETE subdir1/f1R Move File to Newp@23l,v:
44
45 fossil mv --hard f12 d2/f13
46 test mv-file-newup
47 REVERT f4\nDELETE subdir4/REVERT f5\nREVERT f6\nDELETE subdir6/#
48
49 test_cleanREVER#
50
51 test_cleanup12"
52 }
53
54 test mv-file-new-directory-2 {[file size d2/f13] == 3}
55 test mv-file-new-directory-3file-new-directoryd2/f13\nREVERTED: f12${undoMsg}"
56 }
57
58 test mv-file-new-directory-5 {[file size f12] == 3}
59 test mv-file-new-directory-6 {[read_file f12] eq "f12"#
60 # Test 18: Move Directory to New#
61
62 fossil mv --hard subdirC subdirD
63 test mv-file-new-directory-7up
64 REVERT f4\nDELETE subdi#
65
66 test_cleanup
67 REVEETE 5/"
68 }
69
70 test mv-file-new-directory-8 {[file size subdirD/f10] == 3}
71 test mv-file-new-directory-9 {[read_file subdirD/f10] eq "f10"}
72 test mv-file-new-directory-10 {[file size subdirD/f11] == 3}
73 test mv-file-new-directory-11 {[reafile-new-directory-12up
74 REVERT #
75
76 test_cleanup
77 REVERTtest mv-file-new-directory-13 {[file size subdirC/f10] == 3}
78 test mv-file-new-directory-14 {[read_file subdirC/f10] eq "f10"}
79 test mv-file-new-directory-15 {[file size subdirC/f11] == 3}
80 test mv-file-new-directory-16 {[read_file subdirC/f11] eq "f11"}
81
82 cd $rootDir
--- test/th1-tcl.test
+++ test/th1-tcl.test
@@ -54,20 +54,18 @@
5454
\d+
5555
two words
5656
4
5757
\d+
5858
one_word
59
-three words now
60
-$} [string map [list \r\n \n] $RESULT]]}
59
+three words now$} [normalize_result]]}
6160
6261
###############################################################################
6362
6463
fossil test-th-render --open-config \
6564
[file nativename [file join $dir th1-tcl2.txt]]
6665
67
-test th1-tcl-2 {[regexp -- {^\d+
68
-$} [string map [list \r\n \n] $RESULT]]}
66
+test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
6967
7068
###############################################################################
7169
7270
fossil test-th-render --open-config \
7371
[file nativename [file join $dir th1-tcl3.txt]]
7472
--- test/th1-tcl.test
+++ test/th1-tcl.test
@@ -54,20 +54,18 @@
54 \d+
55 two words
56 4
57 \d+
58 one_word
59 three words now
60 $} [string map [list \r\n \n] $RESULT]]}
61
62 ###############################################################################
63
64 fossil test-th-render --open-config \
65 [file nativename [file join $dir th1-tcl2.txt]]
66
67 test th1-tcl-2 {[regexp -- {^\d+
68 $} [string map [list \r\n \n] $RESULT]]}
69
70 ###############################################################################
71
72 fossil test-th-render --open-config \
73 [file nativename [file join $dir th1-tcl3.txt]]
74
--- test/th1-tcl.test
+++ test/th1-tcl.test
@@ -54,20 +54,18 @@
54 \d+
55 two words
56 4
57 \d+
58 one_word
59 three words now$} [normalize_result]]}
 
60
61 ###############################################################################
62
63 fossil test-th-render --open-config \
64 [file nativename [file join $dir th1-tcl2.txt]]
65
66 test th1-tcl-2 {[regexp -- {^\d+$} [normalize_result]]}
 
67
68 ###############################################################################
69
70 fossil test-th-render --open-config \
71 [file nativename [file join $dir th1-tcl3.txt]]
72
+131 -7
--- test/th1.test
+++ test/th1.test
@@ -591,17 +591,17 @@
591591
592592
###############################################################################
593593
594594
fossil test-th-eval --th-trace "trace {}"
595595
if {$th1Hooks} {
596
- test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
596
+ test th1-trace-2 {[normalize_result] eq \
597597
{------------------ BEGIN TRACE LOG ------------------
598598
th1-init 0x0 => 0x0<br />
599599
600600
------------------- END TRACE LOG -------------------}}
601601
} else {
602
- test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
602
+ test th1-trace-2 {[normalize_result] eq \
603603
{------------------ BEGIN TRACE LOG ------------------
604604
th1-init 0x0 => 0x0<br />
605605
th1-setup {} => TH_OK<br />
606606
607607
------------------- END TRACE LOG -------------------}}
@@ -614,17 +614,17 @@
614614
615615
###############################################################################
616616
617617
fossil test-th-eval --th-trace "trace {this is a trace message.}"
618618
if {$th1Hooks} {
619
- test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
619
+ test th1-trace-4 {[normalize_result] eq \
620620
{------------------ BEGIN TRACE LOG ------------------
621621
th1-init 0x0 => 0x0<br />
622622
this is a trace message.
623623
------------------- END TRACE LOG -------------------}}
624624
} else {
625
- test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
625
+ test th1-trace-4 {[normalize_result] eq \
626626
{------------------ BEGIN TRACE LOG ------------------
627627
th1-init 0x0 => 0x0<br />
628628
th1-setup {} => TH_OK<br />
629629
this is a trace message.
630630
------------------- END TRACE LOG -------------------}}
@@ -857,15 +857,15 @@
857857
# NOTE: This test may fail if the command names do not always come
858858
# out in a deterministic order from TH1.
859859
#
860860
fossil test-th-eval "info commands"
861861
test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
862
-enable_output uplevel http expr utime styleFooter catch if tclReady\
863
-searchable reinitialize combobox lindex query html anoncap randhex\
862
+enable_output uplevel http expr glob_match utime styleFooter catch if\
863
+tclReady searchable reinitialize combobox lindex query html anoncap randhex\
864864
llength for set break regexp styleHeader puts return checkout decorate\
865865
artifact trace wiki proc hascap globalState continue getParameter\
866
-hasfeature setting breakpoint upvar render repository string unset\
866
+hasfeature setting lsearch breakpoint upvar render repository string unset\
867867
setParameter list error info rename anycap httpize}}
868868
869869
###############################################################################
870870
871871
fossil test-th-eval "info vars"
@@ -888,5 +888,129 @@
888888
889889
###############################################################################
890890
891891
fossil test-th-eval "set y 1; proc foo {} {set x 1; uplevel 1 {info vars}}; foo"
892892
test th1-info-vars-5 {$RESULT eq "y"}
893
+
894
+###############################################################################
895
+
896
+fossil test-th-eval "lsearch"
897
+test th1-lsearch-1 {$RESULT eq \
898
+ {TH_ERROR: wrong # args: should be "lsearch list string"}}
899
+
900
+###############################################################################
901
+
902
+fossil test-th-eval "lsearch a"
903
+test th1-lsearch-2 {$RESULT eq \
904
+ {TH_ERROR: wrong # args: should be "lsearch list string"}}
905
+
906
+###############################################################################
907
+
908
+fossil test-th-eval "lsearch a a a"
909
+test th1-lsearch-3 {$RESULT eq \
910
+ {TH_ERROR: wrong # args: should be "lsearch list string"}}
911
+
912
+###############################################################################
913
+
914
+fossil test-th-eval "lsearch {a b c} a"
915
+test th1-lsearch-4 {$RESULT eq "0"}
916
+
917
+###############################################################################
918
+
919
+fossil test-th-eval "lsearch {a b c} b"
920
+test th1-lsearch-5 {$RESULT eq "1"}
921
+
922
+###############################################################################
923
+
924
+fossil test-th-eval "lsearch {a b c} c"
925
+test th1-lsearch-6 {$RESULT eq "2"}
926
+
927
+###############################################################################
928
+
929
+fossil test-th-eval "lsearch {a b c} d"
930
+test th1-lsearch-7 {$RESULT eq "-1"}
931
+
932
+###############################################################################
933
+
934
+fossil test-th-eval "lsearch {a b c} aa"
935
+test th1-lsearch-8 {$RESULT eq "-1"}
936
+
937
+###############################################################################
938
+
939
+fossil test-th-eval "lsearch {aa b c} a"
940
+test th1-lsearch-9 {$RESULT eq "-1"}
941
+
942
+###############################################################################
943
+
944
+fossil test-th-eval "lsearch \"\{aa b c\" a"
945
+test th1-lsearch-10 {$RESULT eq "TH_ERROR: Expected list, got: \"\{aa b c\""}
946
+
947
+###############################################################################
948
+
949
+fossil test-th-eval "glob_match"
950
+test th1-glob-match-1 {$RESULT eq \
951
+{TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
952
+
953
+###############################################################################
954
+
955
+fossil test-th-eval "glob_match -one"
956
+test th1-glob-match-2 {$RESULT eq \
957
+{TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
958
+
959
+###############################################################################
960
+
961
+fossil test-th-eval "glob_match --"
962
+test th1-glob-match-3 {$RESULT eq \
963
+{TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
964
+
965
+###############################################################################
966
+
967
+fossil test-th-eval "glob_match -one --"
968
+test th1-glob-match-4 {$RESULT eq \
969
+{TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
970
+
971
+###############################################################################
972
+
973
+fossil test-th-eval "glob_match -one -- 1"
974
+test th1-glob-match-5 {$RESULT eq \
975
+{TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
976
+
977
+###############################################################################
978
+
979
+fossil test-th-eval "glob_match -one -- 1 2 3"
980
+test th1-glob-match-6 {$RESULT eq \
981
+{TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
982
+
983
+###############################################################################
984
+
985
+fossil test-th-eval {list [glob_match a A] [glob_match A a]}
986
+test th1-glob-match-7 {$RESULT eq "0 0"}
987
+
988
+###############################################################################
989
+
990
+fossil test-th-eval {list [glob_match a,b a] [glob_match a,b b]}
991
+test th1-glob-match-8 {$RESULT eq "1 2"}
992
+
993
+###############################################################################
994
+
995
+fossil test-th-eval {list [glob_match -one a,b a] [glob_match -one a,b b]}
996
+test th1-glob-match-9 {$RESULT eq "0 0"}
997
+
998
+###############################################################################
999
+
1000
+fossil test-th-eval {list [glob_match -one a,b a,b] [glob_match -one a b,a]}
1001
+test th1-glob-match-10 {$RESULT eq "1 0"}
1002
+
1003
+###############################################################################
1004
+
1005
+fossil test-th-eval {list [glob_match a*c abc] [glob_match abc a*c]}
1006
+test th1-glob-match-11 {$RESULT eq "1 0"}
1007
+
1008
+###############################################################################
1009
+
1010
+fossil test-th-eval {list [glob_match a?c abc] [glob_match abc a?c]}
1011
+test th1-glob-match-12 {$RESULT eq "1 0"}
1012
+
1013
+###############################################################################
1014
+
1015
+fossil test-th-eval {list [glob_match {a[bd]c} abc] [glob_match abc {a[bd]c}]}
1016
+test th1-glob-match-13 {$RESULT eq "1 0"}
8931017
--- test/th1.test
+++ test/th1.test
@@ -591,17 +591,17 @@
591
592 ###############################################################################
593
594 fossil test-th-eval --th-trace "trace {}"
595 if {$th1Hooks} {
596 test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
597 {------------------ BEGIN TRACE LOG ------------------
598 th1-init 0x0 => 0x0<br />
599
600 ------------------- END TRACE LOG -------------------}}
601 } else {
602 test th1-trace-2 {[string map [list \r\n \n] [string trim $RESULT]] eq \
603 {------------------ BEGIN TRACE LOG ------------------
604 th1-init 0x0 => 0x0<br />
605 th1-setup {} => TH_OK<br />
606
607 ------------------- END TRACE LOG -------------------}}
@@ -614,17 +614,17 @@
614
615 ###############################################################################
616
617 fossil test-th-eval --th-trace "trace {this is a trace message.}"
618 if {$th1Hooks} {
619 test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
620 {------------------ BEGIN TRACE LOG ------------------
621 th1-init 0x0 => 0x0<br />
622 this is a trace message.
623 ------------------- END TRACE LOG -------------------}}
624 } else {
625 test th1-trace-4 {[string map [list \r\n \n] [string trim $RESULT]] eq \
626 {------------------ BEGIN TRACE LOG ------------------
627 th1-init 0x0 => 0x0<br />
628 th1-setup {} => TH_OK<br />
629 this is a trace message.
630 ------------------- END TRACE LOG -------------------}}
@@ -857,15 +857,15 @@
857 # NOTE: This test may fail if the command names do not always come
858 # out in a deterministic order from TH1.
859 #
860 fossil test-th-eval "info commands"
861 test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
862 enable_output uplevel http expr utime styleFooter catch if tclReady\
863 searchable reinitialize combobox lindex query html anoncap randhex\
864 llength for set break regexp styleHeader puts return checkout decorate\
865 artifact trace wiki proc hascap globalState continue getParameter\
866 hasfeature setting breakpoint upvar render repository string unset\
867 setParameter list error info rename anycap httpize}}
868
869 ###############################################################################
870
871 fossil test-th-eval "info vars"
@@ -888,5 +888,129 @@
888
889 ###############################################################################
890
891 fossil test-th-eval "set y 1; proc foo {} {set x 1; uplevel 1 {info vars}}; foo"
892 test th1-info-vars-5 {$RESULT eq "y"}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
893
--- test/th1.test
+++ test/th1.test
@@ -591,17 +591,17 @@
591
592 ###############################################################################
593
594 fossil test-th-eval --th-trace "trace {}"
595 if {$th1Hooks} {
596 test th1-trace-2 {[normalize_result] eq \
597 {------------------ BEGIN TRACE LOG ------------------
598 th1-init 0x0 => 0x0<br />
599
600 ------------------- END TRACE LOG -------------------}}
601 } else {
602 test th1-trace-2 {[normalize_result] eq \
603 {------------------ BEGIN TRACE LOG ------------------
604 th1-init 0x0 => 0x0<br />
605 th1-setup {} => TH_OK<br />
606
607 ------------------- END TRACE LOG -------------------}}
@@ -614,17 +614,17 @@
614
615 ###############################################################################
616
617 fossil test-th-eval --th-trace "trace {this is a trace message.}"
618 if {$th1Hooks} {
619 test th1-trace-4 {[normalize_result] eq \
620 {------------------ BEGIN TRACE LOG ------------------
621 th1-init 0x0 => 0x0<br />
622 this is a trace message.
623 ------------------- END TRACE LOG -------------------}}
624 } else {
625 test th1-trace-4 {[normalize_result] eq \
626 {------------------ BEGIN TRACE LOG ------------------
627 th1-init 0x0 => 0x0<br />
628 th1-setup {} => TH_OK<br />
629 this is a trace message.
630 ------------------- END TRACE LOG -------------------}}
@@ -857,15 +857,15 @@
857 # NOTE: This test may fail if the command names do not always come
858 # out in a deterministic order from TH1.
859 #
860 fossil test-th-eval "info commands"
861 test th1-info-commands-1 {$RESULT eq {linecount htmlize date stime\
862 enable_output uplevel http expr glob_match utime styleFooter catch if\
863 tclReady searchable reinitialize combobox lindex query html anoncap randhex\
864 llength for set break regexp styleHeader puts return checkout decorate\
865 artifact trace wiki proc hascap globalState continue getParameter\
866 hasfeature setting lsearch breakpoint upvar render repository string unset\
867 setParameter list error info rename anycap httpize}}
868
869 ###############################################################################
870
871 fossil test-th-eval "info vars"
@@ -888,5 +888,129 @@
888
889 ###############################################################################
890
891 fossil test-th-eval "set y 1; proc foo {} {set x 1; uplevel 1 {info vars}}; foo"
892 test th1-info-vars-5 {$RESULT eq "y"}
893
894 ###############################################################################
895
896 fossil test-th-eval "lsearch"
897 test th1-lsearch-1 {$RESULT eq \
898 {TH_ERROR: wrong # args: should be "lsearch list string"}}
899
900 ###############################################################################
901
902 fossil test-th-eval "lsearch a"
903 test th1-lsearch-2 {$RESULT eq \
904 {TH_ERROR: wrong # args: should be "lsearch list string"}}
905
906 ###############################################################################
907
908 fossil test-th-eval "lsearch a a a"
909 test th1-lsearch-3 {$RESULT eq \
910 {TH_ERROR: wrong # args: should be "lsearch list string"}}
911
912 ###############################################################################
913
914 fossil test-th-eval "lsearch {a b c} a"
915 test th1-lsearch-4 {$RESULT eq "0"}
916
917 ###############################################################################
918
919 fossil test-th-eval "lsearch {a b c} b"
920 test th1-lsearch-5 {$RESULT eq "1"}
921
922 ###############################################################################
923
924 fossil test-th-eval "lsearch {a b c} c"
925 test th1-lsearch-6 {$RESULT eq "2"}
926
927 ###############################################################################
928
929 fossil test-th-eval "lsearch {a b c} d"
930 test th1-lsearch-7 {$RESULT eq "-1"}
931
932 ###############################################################################
933
934 fossil test-th-eval "lsearch {a b c} aa"
935 test th1-lsearch-8 {$RESULT eq "-1"}
936
937 ###############################################################################
938
939 fossil test-th-eval "lsearch {aa b c} a"
940 test th1-lsearch-9 {$RESULT eq "-1"}
941
942 ###############################################################################
943
944 fossil test-th-eval "lsearch \"\{aa b c\" a"
945 test th1-lsearch-10 {$RESULT eq "TH_ERROR: Expected list, got: \"\{aa b c\""}
946
947 ###############################################################################
948
949 fossil test-th-eval "glob_match"
950 test th1-glob-match-1 {$RESULT eq \
951 {TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
952
953 ###############################################################################
954
955 fossil test-th-eval "glob_match -one"
956 test th1-glob-match-2 {$RESULT eq \
957 {TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
958
959 ###############################################################################
960
961 fossil test-th-eval "glob_match --"
962 test th1-glob-match-3 {$RESULT eq \
963 {TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
964
965 ###############################################################################
966
967 fossil test-th-eval "glob_match -one --"
968 test th1-glob-match-4 {$RESULT eq \
969 {TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
970
971 ###############################################################################
972
973 fossil test-th-eval "glob_match -one -- 1"
974 test th1-glob-match-5 {$RESULT eq \
975 {TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
976
977 ###############################################################################
978
979 fossil test-th-eval "glob_match -one -- 1 2 3"
980 test th1-glob-match-6 {$RESULT eq \
981 {TH_ERROR: wrong # args: should be "glob_match ?-one? ?--? patternList string"}}
982
983 ###############################################################################
984
985 fossil test-th-eval {list [glob_match a A] [glob_match A a]}
986 test th1-glob-match-7 {$RESULT eq "0 0"}
987
988 ###############################################################################
989
990 fossil test-th-eval {list [glob_match a,b a] [glob_match a,b b]}
991 test th1-glob-match-8 {$RESULT eq "1 2"}
992
993 ###############################################################################
994
995 fossil test-th-eval {list [glob_match -one a,b a] [glob_match -one a,b b]}
996 test th1-glob-match-9 {$RESULT eq "0 0"}
997
998 ###############################################################################
999
1000 fossil test-th-eval {list [glob_match -one a,b a,b] [glob_match -one a b,a]}
1001 test th1-glob-match-10 {$RESULT eq "1 0"}
1002
1003 ###############################################################################
1004
1005 fossil test-th-eval {list [glob_match a*c abc] [glob_match abc a*c]}
1006 test th1-glob-match-11 {$RESULT eq "1 0"}
1007
1008 ###############################################################################
1009
1010 fossil test-th-eval {list [glob_match a?c abc] [glob_match abc a?c]}
1011 test th1-glob-match-12 {$RESULT eq "1 0"}
1012
1013 ###############################################################################
1014
1015 fossil test-th-eval {list [glob_match {a[bd]c} abc] [glob_match abc {a[bd]c}]}
1016 test th1-glob-match-13 {$RESULT eq "1 0"}
1017
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -150,11 +150,11 @@
150150
#### The directories where the OpenSSL include and library files are located.
151151
# The recommended usage here is to use the Sysinternals junction tool
152152
# to create a hard link between an "openssl-1.x" sub-directory of the
153153
# Fossil source code directory and the target OpenSSL source directory.
154154
#
155
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2a
155
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2c
156156
OPENSSLINCDIR = $(OPENSSLDIR)/include
157157
OPENSSLLIBDIR = $(OPENSSLDIR)
158158
159159
#### Either the directory where the Tcl library is installed or the Tcl
160160
# source code directory resides (depending on the value of the macro
161161
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -150,11 +150,11 @@
150 #### The directories where the OpenSSL include and library files are located.
151 # The recommended usage here is to use the Sysinternals junction tool
152 # to create a hard link between an "openssl-1.x" sub-directory of the
153 # Fossil source code directory and the target OpenSSL source directory.
154 #
155 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2a
156 OPENSSLINCDIR = $(OPENSSLDIR)/include
157 OPENSSLLIBDIR = $(OPENSSLDIR)
158
159 #### Either the directory where the Tcl library is installed or the Tcl
160 # source code directory resides (depending on the value of the macro
161
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -150,11 +150,11 @@
150 #### The directories where the OpenSSL include and library files are located.
151 # The recommended usage here is to use the Sysinternals junction tool
152 # to create a hard link between an "openssl-1.x" sub-directory of the
153 # Fossil source code directory and the target OpenSSL source directory.
154 #
155 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2c
156 OPENSSLINCDIR = $(OPENSSLDIR)/include
157 OPENSSLLIBDIR = $(OPENSSLDIR)
158
159 #### Either the directory where the Tcl library is installed or the Tcl
160 # source code directory resides (depending on the value of the macro
161
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -150,11 +150,11 @@
150150
#### The directories where the OpenSSL include and library files are located.
151151
# The recommended usage here is to use the Sysinternals junction tool
152152
# to create a hard link between an "openssl-1.x" sub-directory of the
153153
# Fossil source code directory and the target OpenSSL source directory.
154154
#
155
-OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2a
155
+OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2c
156156
OPENSSLINCDIR = $(OPENSSLDIR)/include
157157
OPENSSLLIBDIR = $(OPENSSLDIR)
158158
159159
#### Either the directory where the Tcl library is installed or the Tcl
160160
# source code directory resides (depending on the value of the macro
161161
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -150,11 +150,11 @@
150 #### The directories where the OpenSSL include and library files are located.
151 # The recommended usage here is to use the Sysinternals junction tool
152 # to create a hard link between an "openssl-1.x" sub-directory of the
153 # Fossil source code directory and the target OpenSSL source directory.
154 #
155 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2a
156 OPENSSLINCDIR = $(OPENSSLDIR)/include
157 OPENSSLLIBDIR = $(OPENSSLDIR)
158
159 #### Either the directory where the Tcl library is installed or the Tcl
160 # source code directory resides (depending on the value of the macro
161
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -150,11 +150,11 @@
150 #### The directories where the OpenSSL include and library files are located.
151 # The recommended usage here is to use the Sysinternals junction tool
152 # to create a hard link between an "openssl-1.x" sub-directory of the
153 # Fossil source code directory and the target OpenSSL source directory.
154 #
155 OPENSSLDIR = $(SRCDIR)/../compat/openssl-1.0.2c
156 OPENSSLINCDIR = $(OPENSSLDIR)/include
157 OPENSSLLIBDIR = $(OPENSSLDIR)
158
159 #### Either the directory where the Tcl library is installed or the Tcl
160 # source code directory resides (depending on the value of the macro
161
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -58,11 +58,11 @@
5858
5959
# Uncomment to enable Tcl support
6060
# FOSSIL_ENABLE_TCL = 1
6161
6262
!ifdef FOSSIL_ENABLE_SSL
63
-SSLDIR = $(B)\compat\openssl-1.0.2a
63
+SSLDIR = $(B)\compat\openssl-1.0.2c
6464
SSLINCDIR = $(SSLDIR)\inc32
6565
SSLLIBDIR = $(SSLDIR)\out32
6666
SSLLFLAGS = /nologo /opt:ref /debug
6767
SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
6868
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
6969
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -58,11 +58,11 @@
58
59 # Uncomment to enable Tcl support
60 # FOSSIL_ENABLE_TCL = 1
61
62 !ifdef FOSSIL_ENABLE_SSL
63 SSLDIR = $(B)\compat\openssl-1.0.2a
64 SSLINCDIR = $(SSLDIR)\inc32
65 SSLLIBDIR = $(SSLDIR)\out32
66 SSLLFLAGS = /nologo /opt:ref /debug
67 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
68 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
69
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -58,11 +58,11 @@
58
59 # Uncomment to enable Tcl support
60 # FOSSIL_ENABLE_TCL = 1
61
62 !ifdef FOSSIL_ENABLE_SSL
63 SSLDIR = $(B)\compat\openssl-1.0.2c
64 SSLINCDIR = $(SSLDIR)\inc32
65 SSLLIBDIR = $(SSLDIR)\out32
66 SSLLFLAGS = /nologo /opt:ref /debug
67 SSLLIB = ssleay32.lib libeay32.lib user32.lib gdi32.lib
68 !if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
69
+1 -1
--- www/build.wiki
+++ www/build.wiki
@@ -135,11 +135,11 @@
135135
the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
136136
first <a href="https://www.openssl.org/source/">download the official
137137
source code for OpenSSL</a> and extract it to an appropriately named
138138
"<b>openssl-X.Y.ZA</b>" subdirectory within the local
139139
[/tree?ci=trunk&name=compat | compat] directory (e.g.
140
-"<b>compat/openssl-1.0.2a</b>"), then make sure that some recent
140
+"<b>compat/openssl-1.0.2c</b>"), then make sure that some recent
141141
<a href="http://www.perl.org/">Perl</a> binaries are installed locally,
142142
and finally run one of the following commands:
143143
<blockquote><pre>
144144
nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
145145
</pre></blockquote>
146146
--- www/build.wiki
+++ www/build.wiki
@@ -135,11 +135,11 @@
135 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
136 first <a href="https://www.openssl.org/source/">download the official
137 source code for OpenSSL</a> and extract it to an appropriately named
138 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
139 [/tree?ci=trunk&name=compat | compat] directory (e.g.
140 "<b>compat/openssl-1.0.2a</b>"), then make sure that some recent
141 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
142 and finally run one of the following commands:
143 <blockquote><pre>
144 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
145 </pre></blockquote>
146
--- www/build.wiki
+++ www/build.wiki
@@ -135,11 +135,11 @@
135 the optional <a href="https://www.openssl.org/">OpenSSL</a> support,
136 first <a href="https://www.openssl.org/source/">download the official
137 source code for OpenSSL</a> and extract it to an appropriately named
138 "<b>openssl-X.Y.ZA</b>" subdirectory within the local
139 [/tree?ci=trunk&name=compat | compat] directory (e.g.
140 "<b>compat/openssl-1.0.2c</b>"), then make sure that some recent
141 <a href="http://www.perl.org/">Perl</a> binaries are installed locally,
142 and finally run one of the following commands:
143 <blockquote><pre>
144 nmake /f Makefile.msc FOSSIL_ENABLE_SSL=1 FOSSIL_BUILD_SSL=1 PERLDIR=C:\full\path\to\Perl\bin
145 </pre></blockquote>
146
+19 -17
--- www/hints.wiki
+++ www/hints.wiki
@@ -1,49 +1,51 @@
11
<title>Fossil Tips And Usage Hints</title>
22
33
1. Click on nodes of any timeline graph to see diffs between the two
44
selected versions.
55
6
- 2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
6
+ 2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
77
to get a pop-up
88
window containing a complete side-by-side diff. (NB: The pop-up
9
- window is run as a separate Tcl/Tk process, so you will need to
9
+ window is run as a separate Tcl/Tk process, so you will need to
1010
have Tcl/Tk installed on your machine for this to work. Visit
1111
[http://www.activestate.com/activetcl] to for a quick download of
1212
Tcl/Tk if you do not already have it on your system.)
1313
14
- 3. The "[/help/clean | fossil clean -f]" or
15
- "[/help/clean | fossil clean --verily]" command is a great
16
- alternative to "make clean".
17
-
18
- 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
19
- edits in any of your Fossil projects. Use
14
+ 3. The "[/help/clean | fossil clean -x]" command is a great
15
+ alternative to "make clean". You can use "[/help/clean | fossil clean -f]"
16
+ as a slightly safer alternative if the "ignore-glob" setting is
17
+ not set. WARNING: make sure you did a "fossil add" for all source-files
18
+ you plan to commit, otherwise those files will be deleted without warning.
19
+
20
+ 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
21
+ edits in any of your Fossil projects. Use
2022
"[/help?cmd=all | fossil all pull]" on your laptop
2123
prior to going off network (for example, on a long plane ride)
2224
to make sure you have all the latest content locally. Then run
2325
"[/help/all|fossil all push]" when you get back online to upload
2426
your changes.
25
-
27
+
2628
5. To see an entire timeline, type "all" into the "Max:" entry box.
27
-
29
+
2830
6. You can manually add a "c=CHECKIN" query parameter to the timeline
2931
URL to get a snapshot of what was going on about the time of some
3032
check-in. The "CHECKIN" can be
3133
[./checkin_names.wiki | any valid check-in or version name], including
32
- tags, branch names, and dates. For example, to see what was going
34
+ tags, branch names, and dates. For example, to see what was going
3335
on in the Fossil repository on 2008-01-01, visit
3436
[http://www.fossil-scm.org/fossil/timeline?c=2008-01-01].
35
-
37
+
3638
7. Further to the previous two hints, there are lots of query parameters
3739
that you can add to timeline pages. The available query parameters
3840
are tersely documented [/help?cmd=/timeline | here].
39
-
41
+
4042
8. You can run "[/help?cmd=test-diff | fossil test-diff --tk $file1 $file2]"
41
- to get a pop-up window with side-by-side diffs of two files, even if
42
- neither of the two files is part of any Fossil repository. Note that
43
+ to get a pop-up window with side-by-side diffs of two files, even if
44
+ neither of the two files is part of any Fossil repository. Note that
4345
this command is "test-diff", not "diff".
44
-
46
+
4547
9. On web pages showing the content of a file (for example
4648
[http://www.fossil-scm.org/fossil/artifact/c7dd1de9f]) you can manually
4749
add a query parameter of the form "ln=FROM,TO" to the URL that
4850
will cause the range of lines indicated to be highlighted. This
4951
is useful in pointing out a few lines of code using a hyperlink
@@ -50,10 +52,10 @@
5052
in an email or text message. Example:
5153
[http://www.fossil-scm.org/fossil/artifact/c7dd1de9f?ln=28,30].
5254
Adding the "ln" query parameter without any argument simply turns
5355
on line numbers. This feature only works right with files with
5456
a mimetype of text/plain, of course.
55
-
57
+
5658
10. When editing documentation to be checked in as managed files, you can
5759
preview what the documentation will look like by using the special
5860
"ckout" branch name in the "doc" URL while running "fossil ui".
5961
See the [./embeddeddoc.wiki | embedded documentation] for details.
6062
--- www/hints.wiki
+++ www/hints.wiki
@@ -1,49 +1,51 @@
1 <title>Fossil Tips And Usage Hints</title>
2
3 1. Click on nodes of any timeline graph to see diffs between the two
4 selected versions.
5
6 2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
7 to get a pop-up
8 window containing a complete side-by-side diff. (NB: The pop-up
9 window is run as a separate Tcl/Tk process, so you will need to
10 have Tcl/Tk installed on your machine for this to work. Visit
11 [http://www.activestate.com/activetcl] to for a quick download of
12 Tcl/Tk if you do not already have it on your system.)
13
14 3. The "[/help/clean | fossil clean -f]" or
15 "[/help/clean | fossil clean --verily]" command is a great
16 alternative to "make clean".
17
18 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
19 edits in any of your Fossil projects. Use
 
 
20 "[/help?cmd=all | fossil all pull]" on your laptop
21 prior to going off network (for example, on a long plane ride)
22 to make sure you have all the latest content locally. Then run
23 "[/help/all|fossil all push]" when you get back online to upload
24 your changes.
25
26 5. To see an entire timeline, type "all" into the "Max:" entry box.
27
28 6. You can manually add a "c=CHECKIN" query parameter to the timeline
29 URL to get a snapshot of what was going on about the time of some
30 check-in. The "CHECKIN" can be
31 [./checkin_names.wiki | any valid check-in or version name], including
32 tags, branch names, and dates. For example, to see what was going
33 on in the Fossil repository on 2008-01-01, visit
34 [http://www.fossil-scm.org/fossil/timeline?c=2008-01-01].
35
36 7. Further to the previous two hints, there are lots of query parameters
37 that you can add to timeline pages. The available query parameters
38 are tersely documented [/help?cmd=/timeline | here].
39
40 8. You can run "[/help?cmd=test-diff | fossil test-diff --tk $file1 $file2]"
41 to get a pop-up window with side-by-side diffs of two files, even if
42 neither of the two files is part of any Fossil repository. Note that
43 this command is "test-diff", not "diff".
44
45 9. On web pages showing the content of a file (for example
46 [http://www.fossil-scm.org/fossil/artifact/c7dd1de9f]) you can manually
47 add a query parameter of the form "ln=FROM,TO" to the URL that
48 will cause the range of lines indicated to be highlighted. This
49 is useful in pointing out a few lines of code using a hyperlink
@@ -50,10 +52,10 @@
50 in an email or text message. Example:
51 [http://www.fossil-scm.org/fossil/artifact/c7dd1de9f?ln=28,30].
52 Adding the "ln" query parameter without any argument simply turns
53 on line numbers. This feature only works right with files with
54 a mimetype of text/plain, of course.
55
56 10. When editing documentation to be checked in as managed files, you can
57 preview what the documentation will look like by using the special
58 "ckout" branch name in the "doc" URL while running "fossil ui".
59 See the [./embeddeddoc.wiki | embedded documentation] for details.
60
--- www/hints.wiki
+++ www/hints.wiki
@@ -1,49 +1,51 @@
1 <title>Fossil Tips And Usage Hints</title>
2
3 1. Click on nodes of any timeline graph to see diffs between the two
4 selected versions.
5
6 2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
7 to get a pop-up
8 window containing a complete side-by-side diff. (NB: The pop-up
9 window is run as a separate Tcl/Tk process, so you will need to
10 have Tcl/Tk installed on your machine for this to work. Visit
11 [http://www.activestate.com/activetcl] to for a quick download of
12 Tcl/Tk if you do not already have it on your system.)
13
14 3. The "[/help/clean | fossil clean -x]" command is a great
15 alternative to "make clean". You can use "[/help/clean | fossil clean -f]"
16 as a slightly safer alternative if the "ignore-glob" setting is
17 not set. WARNING: make sure you did a "fossil add" for all source-files
18 you plan to commit, otherwise those files will be deleted without warning.
19
20 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
21 edits in any of your Fossil projects. Use
22 "[/help?cmd=all | fossil all pull]" on your laptop
23 prior to going off network (for example, on a long plane ride)
24 to make sure you have all the latest content locally. Then run
25 "[/help/all|fossil all push]" when you get back online to upload
26 your changes.
27
28 5. To see an entire timeline, type "all" into the "Max:" entry box.
29
30 6. You can manually add a "c=CHECKIN" query parameter to the timeline
31 URL to get a snapshot of what was going on about the time of some
32 check-in. The "CHECKIN" can be
33 [./checkin_names.wiki | any valid check-in or version name], including
34 tags, branch names, and dates. For example, to see what was going
35 on in the Fossil repository on 2008-01-01, visit
36 [http://www.fossil-scm.org/fossil/timeline?c=2008-01-01].
37
38 7. Further to the previous two hints, there are lots of query parameters
39 that you can add to timeline pages. The available query parameters
40 are tersely documented [/help?cmd=/timeline | here].
41
42 8. You can run "[/help?cmd=test-diff | fossil test-diff --tk $file1 $file2]"
43 to get a pop-up window with side-by-side diffs of two files, even if
44 neither of the two files is part of any Fossil repository. Note that
45 this command is "test-diff", not "diff".
46
47 9. On web pages showing the content of a file (for example
48 [http://www.fossil-scm.org/fossil/artifact/c7dd1de9f]) you can manually
49 add a query parameter of the form "ln=FROM,TO" to the URL that
50 will cause the range of lines indicated to be highlighted. This
51 is useful in pointing out a few lines of code using a hyperlink
@@ -50,10 +52,10 @@
52 in an email or text message. Example:
53 [http://www.fossil-scm.org/fossil/artifact/c7dd1de9f?ln=28,30].
54 Adding the "ln" query parameter without any argument simply turns
55 on line numbers. This feature only works right with files with
56 a mimetype of text/plain, of course.
57
58 10. When editing documentation to be checked in as managed files, you can
59 preview what the documentation will look like by using the special
60 "ckout" branch name in the "doc" URL while running "fossil ui".
61 See the [./embeddeddoc.wiki | embedded documentation] for details.
62
+22 -21
--- www/index.wiki
+++ www/index.wiki
@@ -30,28 +30,28 @@
3030
In addition to doing [./concepts.wiki | distributed version control]
3131
like Git and Mercurial,
3232
Fossil also supports [./bugtheory.wiki | bug tracking],
3333
[./wikitheory.wiki | wiki], and [./event.wiki | technotes].
3434
35
- 2. <b>Built-in Web Interface</b> -
35
+ 2. <b>Built-in Web Interface</b> -
3636
Fossil has a built-in and intuitive [./webui.wiki | web interface]
37
- with a rich assortment of information pages
37
+ with a rich assortment of information pages
3838
([./webpage-ex.md|examples]) designed to promote situational awareness.
3939
4040
This entire website&#185;
4141
is just a running instance of Fossil. The pages you see here
4242
are all [./wikitheory.wiki | wiki] or
4343
[./embeddeddoc.wiki | embedded documentation].
4444
When you clone Fossil from one of its
45
- [./selfhost.wiki | self-hosting repositories],
45
+ [./selfhost.wiki | self-hosting repositories],
4646
you get more than just source code - you get this entire website.
47
- <span style='font-size:75%;'>(&#185;except the
47
+ <span style='font-size:75%;'>(&#185;except the
4848
[http://www.fossil-scm.org/download.html | download] page)</span>
4949
5050
3. <b>Self-Contained</b> -
5151
Fossil is a single self-contained stand-alone executable.
52
- To install, simply download a
52
+ To install, simply download a
5353
<a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
5454
for Linux, Mac, OpenBSD, or Windows and put it on your $PATH.
5555
[./build.wiki | Easy-to-compile source code] is also available.
5656
5757
4. <b>Simple Networking</b> -
@@ -68,11 +68,11 @@
6868
[./server.wiki | server configurations].
6969
7070
6. <b>Autosync</b> -
7171
Fossil supports [./concepts.wiki#workflow | "autosync" mode]
7272
which helps to keep projects moving
73
- forward by reducing the amount of needless
73
+ forward by reducing the amount of needless
7474
[./branching.wiki | forking and merging] often
7575
associated with distributed projects.
7676
7777
7. <b>Robust &amp; Reliable</b> -
7878
Fossil stores content using an [./fileformat.wiki | enduring file format]
@@ -85,47 +85,48 @@
8585
8686
<hr>
8787
<h3>Links For Fossil Users:</h3>
8888
8989
* "Fuel" is cross-platform GUI front-end for Fossil
90
- written in Qt. [http://fuelscm.org/].
90
+ written in Qt. [http://fuelscm.org/].
9191
Fuel is an independent project run by a different group of
9292
developers.
93
- * [./reviews.wiki | Testimonials] from satisfied fossil users and
93
+ * [./reviews.wiki | Testimonials] from satisfied Fossil users and
9494
[./quotes.wiki | Quotes] about Fossil and other DVCSes.
9595
* [./faq.wiki | FAQ]
96
- * The [./concepts.wiki | concepts] behind fossil
97
- * [./quickstart.wiki | Quick Start] guide to using fossil
98
- * [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
96
+ * The [./concepts.wiki | concepts] behind Fossil.
97
+ * [./quickstart.wiki | Quick Start] guide to using Fossil.
98
+ * [./qandc.wiki | Questions &amp; Criticisms] directed at Fossil.
9999
* [./build.wiki | Compiling and Installing]
100100
* Fossil supports [./embeddeddoc.wiki | embedded documentation]
101101
that is versioned along with project source code.
102
- * Fossil uses an [./fileformat.wiki | enduring file format] that is
102
+ * Fossil uses an [./fileformat.wiki | enduring file format] that is
103103
designed to be readable, searchable, and extensible by people
104104
not yet born.
105105
* A tutorial on [./branching.wiki | branching], what it means and how
106
- to do it using fossil.
106
+ to do it using Fossil.
107107
* The [./selfcheck.wiki | automatic self-check] mechanism
108108
helps insure project integrity.
109109
* Fossil contains a [./wikitheory.wiki | built-in wiki].
110110
* An [./event.wiki | Event] is a special kind of wiki page associated
111111
with a point in time rather than a name.
112
- * [./settings.wiki | Settings] control the behaviour of fossil.
112
+ * [./settings.wiki | Settings] control the behaviour of Fossil.
113113
* [./ssl.wiki | Use SSL] to encrypt communication with the server.
114114
* There is a
115115
[http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | mailing list]
116
- (with publicly readable
117
- [http://www.mail-archive.com/[email protected] | archives]
118
- available for discussing fossil issues.
116
+ (with publicly readable
117
+ [http://www.mail-archive.com/[email protected] | archives])
118
+ available for discussing Fossil issues.
119119
* [./stats.wiki | Performance statistics] taken from real-world projects
120
- hosted on fossil.
121
- * How to [./shunning.wiki | delete content] from a fossil repository.
120
+ hosted on Fossil.
121
+ * How to [./shunning.wiki | delete content] from a Fossil repository.
122122
* How Fossil does [./password.wiki | password management].
123123
* On-line [/help | help].
124124
* Documentation on the
125
- [http://www.sqliteconcepts.org/THManual.pdf | TH1 Script Language] used
126
- to configure the ticketing subsystem.
125
+ [http://www.sqliteconcepts.org/THManual.pdf | TH1 scripting language] used
126
+ to configure the ticketing subsystem and the [./th1.md | extra commands]
127
+ provided by Fossil itself.
127128
* A free hosting server for Fossil repositories is available at
128129
[http://chiselapp.com/].
129130
* How to [./server.wiki | set up a server] for your repository.
130131
* Customizing the [./custom_ticket.wiki | ticket system].
131132
* Methods to [./checkin_names.wiki | identify a specific check-in].
132133
--- www/index.wiki
+++ www/index.wiki
@@ -30,28 +30,28 @@
30 In addition to doing [./concepts.wiki | distributed version control]
31 like Git and Mercurial,
32 Fossil also supports [./bugtheory.wiki | bug tracking],
33 [./wikitheory.wiki | wiki], and [./event.wiki | technotes].
34
35 2. <b>Built-in Web Interface</b> -
36 Fossil has a built-in and intuitive [./webui.wiki | web interface]
37 with a rich assortment of information pages
38 ([./webpage-ex.md|examples]) designed to promote situational awareness.
39
40 This entire website&#185;
41 is just a running instance of Fossil. The pages you see here
42 are all [./wikitheory.wiki | wiki] or
43 [./embeddeddoc.wiki | embedded documentation].
44 When you clone Fossil from one of its
45 [./selfhost.wiki | self-hosting repositories],
46 you get more than just source code - you get this entire website.
47 <span style='font-size:75%;'>(&#185;except the
48 [http://www.fossil-scm.org/download.html | download] page)</span>
49
50 3. <b>Self-Contained</b> -
51 Fossil is a single self-contained stand-alone executable.
52 To install, simply download a
53 <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
54 for Linux, Mac, OpenBSD, or Windows and put it on your $PATH.
55 [./build.wiki | Easy-to-compile source code] is also available.
56
57 4. <b>Simple Networking</b> -
@@ -68,11 +68,11 @@
68 [./server.wiki | server configurations].
69
70 6. <b>Autosync</b> -
71 Fossil supports [./concepts.wiki#workflow | "autosync" mode]
72 which helps to keep projects moving
73 forward by reducing the amount of needless
74 [./branching.wiki | forking and merging] often
75 associated with distributed projects.
76
77 7. <b>Robust &amp; Reliable</b> -
78 Fossil stores content using an [./fileformat.wiki | enduring file format]
@@ -85,47 +85,48 @@
85
86 <hr>
87 <h3>Links For Fossil Users:</h3>
88
89 * "Fuel" is cross-platform GUI front-end for Fossil
90 written in Qt. [http://fuelscm.org/].
91 Fuel is an independent project run by a different group of
92 developers.
93 * [./reviews.wiki | Testimonials] from satisfied fossil users and
94 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
95 * [./faq.wiki | FAQ]
96 * The [./concepts.wiki | concepts] behind fossil
97 * [./quickstart.wiki | Quick Start] guide to using fossil
98 * [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
99 * [./build.wiki | Compiling and Installing]
100 * Fossil supports [./embeddeddoc.wiki | embedded documentation]
101 that is versioned along with project source code.
102 * Fossil uses an [./fileformat.wiki | enduring file format] that is
103 designed to be readable, searchable, and extensible by people
104 not yet born.
105 * A tutorial on [./branching.wiki | branching], what it means and how
106 to do it using fossil.
107 * The [./selfcheck.wiki | automatic self-check] mechanism
108 helps insure project integrity.
109 * Fossil contains a [./wikitheory.wiki | built-in wiki].
110 * An [./event.wiki | Event] is a special kind of wiki page associated
111 with a point in time rather than a name.
112 * [./settings.wiki | Settings] control the behaviour of fossil.
113 * [./ssl.wiki | Use SSL] to encrypt communication with the server.
114 * There is a
115 [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | mailing list]
116 (with publicly readable
117 [http://www.mail-archive.com/[email protected] | archives]
118 available for discussing fossil issues.
119 * [./stats.wiki | Performance statistics] taken from real-world projects
120 hosted on fossil.
121 * How to [./shunning.wiki | delete content] from a fossil repository.
122 * How Fossil does [./password.wiki | password management].
123 * On-line [/help | help].
124 * Documentation on the
125 [http://www.sqliteconcepts.org/THManual.pdf | TH1 Script Language] used
126 to configure the ticketing subsystem.
 
127 * A free hosting server for Fossil repositories is available at
128 [http://chiselapp.com/].
129 * How to [./server.wiki | set up a server] for your repository.
130 * Customizing the [./custom_ticket.wiki | ticket system].
131 * Methods to [./checkin_names.wiki | identify a specific check-in].
132
--- www/index.wiki
+++ www/index.wiki
@@ -30,28 +30,28 @@
30 In addition to doing [./concepts.wiki | distributed version control]
31 like Git and Mercurial,
32 Fossil also supports [./bugtheory.wiki | bug tracking],
33 [./wikitheory.wiki | wiki], and [./event.wiki | technotes].
34
35 2. <b>Built-in Web Interface</b> -
36 Fossil has a built-in and intuitive [./webui.wiki | web interface]
37 with a rich assortment of information pages
38 ([./webpage-ex.md|examples]) designed to promote situational awareness.
39
40 This entire website&#185;
41 is just a running instance of Fossil. The pages you see here
42 are all [./wikitheory.wiki | wiki] or
43 [./embeddeddoc.wiki | embedded documentation].
44 When you clone Fossil from one of its
45 [./selfhost.wiki | self-hosting repositories],
46 you get more than just source code - you get this entire website.
47 <span style='font-size:75%;'>(&#185;except the
48 [http://www.fossil-scm.org/download.html | download] page)</span>
49
50 3. <b>Self-Contained</b> -
51 Fossil is a single self-contained stand-alone executable.
52 To install, simply download a
53 <a href="http://www.fossil-scm.org/download.html">precompiled binary</a>
54 for Linux, Mac, OpenBSD, or Windows and put it on your $PATH.
55 [./build.wiki | Easy-to-compile source code] is also available.
56
57 4. <b>Simple Networking</b> -
@@ -68,11 +68,11 @@
68 [./server.wiki | server configurations].
69
70 6. <b>Autosync</b> -
71 Fossil supports [./concepts.wiki#workflow | "autosync" mode]
72 which helps to keep projects moving
73 forward by reducing the amount of needless
74 [./branching.wiki | forking and merging] often
75 associated with distributed projects.
76
77 7. <b>Robust &amp; Reliable</b> -
78 Fossil stores content using an [./fileformat.wiki | enduring file format]
@@ -85,47 +85,48 @@
85
86 <hr>
87 <h3>Links For Fossil Users:</h3>
88
89 * "Fuel" is cross-platform GUI front-end for Fossil
90 written in Qt. [http://fuelscm.org/].
91 Fuel is an independent project run by a different group of
92 developers.
93 * [./reviews.wiki | Testimonials] from satisfied Fossil users and
94 [./quotes.wiki | Quotes] about Fossil and other DVCSes.
95 * [./faq.wiki | FAQ]
96 * The [./concepts.wiki | concepts] behind Fossil.
97 * [./quickstart.wiki | Quick Start] guide to using Fossil.
98 * [./qandc.wiki | Questions &amp; Criticisms] directed at Fossil.
99 * [./build.wiki | Compiling and Installing]
100 * Fossil supports [./embeddeddoc.wiki | embedded documentation]
101 that is versioned along with project source code.
102 * Fossil uses an [./fileformat.wiki | enduring file format] that is
103 designed to be readable, searchable, and extensible by people
104 not yet born.
105 * A tutorial on [./branching.wiki | branching], what it means and how
106 to do it using Fossil.
107 * The [./selfcheck.wiki | automatic self-check] mechanism
108 helps insure project integrity.
109 * Fossil contains a [./wikitheory.wiki | built-in wiki].
110 * An [./event.wiki | Event] is a special kind of wiki page associated
111 with a point in time rather than a name.
112 * [./settings.wiki | Settings] control the behaviour of Fossil.
113 * [./ssl.wiki | Use SSL] to encrypt communication with the server.
114 * There is a
115 [http://lists.fossil-scm.org:8080/cgi-bin/mailman/listinfo/fossil-users | mailing list]
116 (with publicly readable
117 [http://www.mail-archive.com/[email protected] | archives])
118 available for discussing Fossil issues.
119 * [./stats.wiki | Performance statistics] taken from real-world projects
120 hosted on Fossil.
121 * How to [./shunning.wiki | delete content] from a Fossil repository.
122 * How Fossil does [./password.wiki | password management].
123 * On-line [/help | help].
124 * Documentation on the
125 [http://www.sqliteconcepts.org/THManual.pdf | TH1 scripting language] used
126 to configure the ticketing subsystem and the [./th1.md | extra commands]
127 provided by Fossil itself.
128 * A free hosting server for Fossil repositories is available at
129 [http://chiselapp.com/].
130 * How to [./server.wiki | set up a server] for your repository.
131 * Customizing the [./custom_ticket.wiki | ticket system].
132 * Methods to [./checkin_names.wiki | identify a specific check-in].
133
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -224,20 +224,22 @@
224224
225225
Some files require special C-preprocessor macro definitions.
226226
When compiling sqlite.c, the following macros are recommended:
227227
228228
* -DSQLITE_OMIT_LOAD_EXTENSION=1
229
+ * -DSQLITE_ENABLE_DBSTAT_VTAB=1
229230
* -DSQLITE_ENABLE_FTS4=1
230231
* -DSQLITE_ENABLE_LOCKING_STYLE=0
231232
* -DSQLITE_THREADSAFE=0
232233
* -DSQLITE_DEFAULT_FILE_FORMAT=4
233234
* -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
234235
235
-The first two symbol definitions above are required; the others are merely
236
-recommended. Extension loading is omitted as a security measure. FTS4 is
237
-needed for the search feature. Fossil is single-threaded so mutexing is
238
-disabled in SQLite as a performance enhancement. The
236
+The first three symbol definitions above are required; the others are merely
237
+recommended. Extension loading is omitted as a security measure. The dbstat
238
+virtual table is needed for the [/help?cmd=/repo-tabsize|/repo-tabsize] page.
239
+FTS4 is needed for the search feature. Fossil is single-threaded so mutexing
240
+is disabled in SQLite as a performance enhancement. The
239241
SQLITE_ENABLE_EXPLAIN_COMMENTS option makes the output of "EXPLAIN" queries
240242
in the "[/help?cmd=sqlite3|fossil sql]" command much more readable.
241243
242244
When compiling the shell.c source file, these macros are required:
243245
244246
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -224,20 +224,22 @@
224
225 Some files require special C-preprocessor macro definitions.
226 When compiling sqlite.c, the following macros are recommended:
227
228 * -DSQLITE_OMIT_LOAD_EXTENSION=1
 
229 * -DSQLITE_ENABLE_FTS4=1
230 * -DSQLITE_ENABLE_LOCKING_STYLE=0
231 * -DSQLITE_THREADSAFE=0
232 * -DSQLITE_DEFAULT_FILE_FORMAT=4
233 * -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
234
235 The first two symbol definitions above are required; the others are merely
236 recommended. Extension loading is omitted as a security measure. FTS4 is
237 needed for the search feature. Fossil is single-threaded so mutexing is
238 disabled in SQLite as a performance enhancement. The
 
239 SQLITE_ENABLE_EXPLAIN_COMMENTS option makes the output of "EXPLAIN" queries
240 in the "[/help?cmd=sqlite3|fossil sql]" command much more readable.
241
242 When compiling the shell.c source file, these macros are required:
243
244
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -224,20 +224,22 @@
224
225 Some files require special C-preprocessor macro definitions.
226 When compiling sqlite.c, the following macros are recommended:
227
228 * -DSQLITE_OMIT_LOAD_EXTENSION=1
229 * -DSQLITE_ENABLE_DBSTAT_VTAB=1
230 * -DSQLITE_ENABLE_FTS4=1
231 * -DSQLITE_ENABLE_LOCKING_STYLE=0
232 * -DSQLITE_THREADSAFE=0
233 * -DSQLITE_DEFAULT_FILE_FORMAT=4
234 * -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
235
236 The first three symbol definitions above are required; the others are merely
237 recommended. Extension loading is omitted as a security measure. The dbstat
238 virtual table is needed for the [/help?cmd=/repo-tabsize|/repo-tabsize] page.
239 FTS4 is needed for the search feature. Fossil is single-threaded so mutexing
240 is disabled in SQLite as a performance enhancement. The
241 SQLITE_ENABLE_EXPLAIN_COMMENTS option makes the output of "EXPLAIN" queries
242 in the "[/help?cmd=sqlite3|fossil sql]" command much more readable.
243
244 When compiling the shell.c source file, these macros are required:
245
246
+3 -4
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -32,16 +32,15 @@
3232
3333
<blockquote>
3434
<i>Nick Farina at [http://nfarina.com/post/9868516270/git-is-simpler]</i>
3535
</blockquote>
3636
37
-<li>We've been using git and github for a few months now, and it's not
38
-intuitive... I'm hoping someone will make a set of standard wrappers/GUI
39
-for making git bearable.
37
+<li>Initial revision of "git", The information manager from hell
4038
4139
<blockquote>
42
-<i>maro at [http://news.ycombinator.com/item?id=1433387]</i>
40
+<i>Linus Torvalds - 2005-04-07 22:13:13<br>
41
+Commit comment on the very first source-code check-in for git
4342
</blockquote>
4443
4544
<li>I've been experimenting a lot with git at work.
4645
Damn, it's complicated.
4746
It has things to trip you up with that sane people just wouldn't ever both with
4847
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -32,16 +32,15 @@
32
33 <blockquote>
34 <i>Nick Farina at [http://nfarina.com/post/9868516270/git-is-simpler]</i>
35 </blockquote>
36
37 <li>We've been using git and github for a few months now, and it's not
38 intuitive... I'm hoping someone will make a set of standard wrappers/GUI
39 for making git bearable.
40
41 <blockquote>
42 <i>maro at [http://news.ycombinator.com/item?id=1433387]</i>
 
43 </blockquote>
44
45 <li>I've been experimenting a lot with git at work.
46 Damn, it's complicated.
47 It has things to trip you up with that sane people just wouldn't ever both with
48
--- www/quotes.wiki
+++ www/quotes.wiki
@@ -32,16 +32,15 @@
32
33 <blockquote>
34 <i>Nick Farina at [http://nfarina.com/post/9868516270/git-is-simpler]</i>
35 </blockquote>
36
37 <li>Initial revision of "git", The information manager from hell
 
 
38
39 <blockquote>
40 <i>Linus Torvalds - 2005-04-07 22:13:13<br>
41 Commit comment on the very first source-code check-in for git
42 </blockquote>
43
44 <li>I've been experimenting a lot with git at work.
45 Damn, it's complicated.
46 It has things to trip you up with that sane people just wouldn't ever both with
47
+10
--- www/th1.md
+++ www/th1.md
@@ -96,10 +96,11 @@
9696
* info exists VARNAME
9797
* info vars
9898
* lindex LIST INDEX
9999
* list ARG ...
100100
* llength LIST
101
+ * lsearch LIST STRING
101102
* proc NAME ARG-LIST BODY-SCRIPT
102103
* rename OLD NEW
103104
* return ?-code CODE? ?VALUE?
104105
* set VARNAME VALUE
105106
* string compare STR1 STR2
@@ -129,10 +130,11 @@
129130
* combobox
130131
* date
131132
* decorate
132133
* enable_output
133134
* getParameter
135
+ * glob_match
134136
* globalState
135137
* hascap
136138
* hasfeature
137139
* html
138140
* htmlize
@@ -244,10 +246,18 @@
244246
* getParameter NAME ?DEFAULT?
245247
246248
Returns the value of the specified query parameter or the specified
247249
default value when there is no matching query parameter.
248250
251
+<a name="glob_match"></a>TH1 glob_match Command
252
+-----------------------------------------------
253
+
254
+ * glob_match ?-one? ?--? patternList string
255
+
256
+Checks the string against the specified glob pattern -OR- list of glob
257
+patterns and returns non-zero if there is a match.
258
+
249259
<a name="globalState"></a>TH1 globalState Command
250260
-------------------------------------------------
251261
252262
* globalState NAME ?DEFAULT?
253263
254264
--- www/th1.md
+++ www/th1.md
@@ -96,10 +96,11 @@
96 * info exists VARNAME
97 * info vars
98 * lindex LIST INDEX
99 * list ARG ...
100 * llength LIST
 
101 * proc NAME ARG-LIST BODY-SCRIPT
102 * rename OLD NEW
103 * return ?-code CODE? ?VALUE?
104 * set VARNAME VALUE
105 * string compare STR1 STR2
@@ -129,10 +130,11 @@
129 * combobox
130 * date
131 * decorate
132 * enable_output
133 * getParameter
 
134 * globalState
135 * hascap
136 * hasfeature
137 * html
138 * htmlize
@@ -244,10 +246,18 @@
244 * getParameter NAME ?DEFAULT?
245
246 Returns the value of the specified query parameter or the specified
247 default value when there is no matching query parameter.
248
 
 
 
 
 
 
 
 
249 <a name="globalState"></a>TH1 globalState Command
250 -------------------------------------------------
251
252 * globalState NAME ?DEFAULT?
253
254
--- www/th1.md
+++ www/th1.md
@@ -96,10 +96,11 @@
96 * info exists VARNAME
97 * info vars
98 * lindex LIST INDEX
99 * list ARG ...
100 * llength LIST
101 * lsearch LIST STRING
102 * proc NAME ARG-LIST BODY-SCRIPT
103 * rename OLD NEW
104 * return ?-code CODE? ?VALUE?
105 * set VARNAME VALUE
106 * string compare STR1 STR2
@@ -129,10 +130,11 @@
130 * combobox
131 * date
132 * decorate
133 * enable_output
134 * getParameter
135 * glob_match
136 * globalState
137 * hascap
138 * hasfeature
139 * html
140 * htmlize
@@ -244,10 +246,18 @@
246 * getParameter NAME ?DEFAULT?
247
248 Returns the value of the specified query parameter or the specified
249 default value when there is no matching query parameter.
250
251 <a name="glob_match"></a>TH1 glob_match Command
252 -----------------------------------------------
253
254 * glob_match ?-one? ?--? patternList string
255
256 Checks the string against the specified glob pattern -OR- list of glob
257 patterns and returns non-zero if there is a match.
258
259 <a name="globalState"></a>TH1 globalState Command
260 -------------------------------------------------
261
262 * globalState NAME ?DEFAULT?
263
264

Keyboard Shortcuts

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