Fossil SCM

merge trunk

jan.nijtmans 2013-02-18 08:30 ticket-d17d6e5b17 merge
Commit fdd51b617ce48f2a6727e6d5ec24a0ac0d03f87a
+1
--- auto.def
+++ auto.def
@@ -233,8 +233,9 @@
233233
# Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars
234234
if {![cc-check-functions getpassphrase]} {
235235
# Haiku needs this
236236
cc-check-function-in-lib getpass bsd
237237
}
238
+cc-check-function-in-lib dlopen dl
238239
239240
make-template Makefile.in
240241
make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
241242
--- auto.def
+++ auto.def
@@ -233,8 +233,9 @@
233 # Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars
234 if {![cc-check-functions getpassphrase]} {
235 # Haiku needs this
236 cc-check-function-in-lib getpass bsd
237 }
 
238
239 make-template Makefile.in
240 make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
241
--- auto.def
+++ auto.def
@@ -233,8 +233,9 @@
233 # Check for getpassphrase() for Solaris 10 where getpass() truncates to 10 chars
234 if {![cc-check-functions getpassphrase]} {
235 # Haiku needs this
236 cc-check-function-in-lib getpass bsd
237 }
238 cc-check-function-in-lib dlopen dl
239
240 make-template Makefile.in
241 make-config-header autoconfig.h -auto {USE_* FOSSIL_*}
242
--- compat/zlib/configure
+++ compat/zlib/configure
@@ -814,5 +814,6 @@
814814
/^mandir *=/s#=.*#=$mandir#
815815
/^LDFLAGS *=/s#=.*#=$LDFLAGS#
816816
" | sed -e "
817817
s/\@VERSION\@/$VER/g;
818818
" > zlib.pc
819
+#
819820
--- compat/zlib/configure
+++ compat/zlib/configure
@@ -814,5 +814,6 @@
814 /^mandir *=/s#=.*#=$mandir#
815 /^LDFLAGS *=/s#=.*#=$LDFLAGS#
816 " | sed -e "
817 s/\@VERSION\@/$VER/g;
818 " > zlib.pc
 
819
--- compat/zlib/configure
+++ compat/zlib/configure
@@ -814,5 +814,6 @@
814 /^mandir *=/s#=.*#=$mandir#
815 /^LDFLAGS *=/s#=.*#=$LDFLAGS#
816 " | sed -e "
817 s/\@VERSION\@/$VER/g;
818 " > zlib.pc
819 #
820
--- compat/zlib/configure
+++ compat/zlib/configure
@@ -814,5 +814,6 @@
814814
/^mandir *=/s#=.*#=$mandir#
815815
/^LDFLAGS *=/s#=.*#=$LDFLAGS#
816816
" | sed -e "
817817
s/\@VERSION\@/$VER/g;
818818
" > zlib.pc
819
+#
819820
--- compat/zlib/configure
+++ compat/zlib/configure
@@ -814,5 +814,6 @@
814 /^mandir *=/s#=.*#=$mandir#
815 /^LDFLAGS *=/s#=.*#=$LDFLAGS#
816 " | sed -e "
817 s/\@VERSION\@/$VER/g;
818 " > zlib.pc
 
819
--- compat/zlib/configure
+++ compat/zlib/configure
@@ -814,5 +814,6 @@
814 /^mandir *=/s#=.*#=$mandir#
815 /^LDFLAGS *=/s#=.*#=$LDFLAGS#
816 " | sed -e "
817 s/\@VERSION\@/$VER/g;
818 " > zlib.pc
819 #
820
+11 -15
--- src/blob.c
+++ src/blob.c
@@ -1096,34 +1096,30 @@
10961096
** to be UTF-8 already, so no conversion is done.
10971097
*/
10981098
void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
10991099
char *zUtf8;
11001100
int bomSize = 0;
1101
+ int bomReverse = 0;
11011102
if( starts_with_utf8_bom(pBlob, &bomSize) ){
11021103
struct Blob temp;
11031104
zUtf8 = blob_str(pBlob) + bomSize;
11041105
blob_zero(&temp);
11051106
blob_append(&temp, zUtf8, -1);
11061107
blob_swap(pBlob, &temp);
11071108
blob_reset(&temp);
11081109
#ifdef _WIN32
1109
- }else if( starts_with_utf16le_bom(pBlob, &bomSize) ){
1110
- /* Make sure the blob contains two terminating 0-bytes */
1111
- blob_append(pBlob, "", 1);
1112
- zUtf8 = blob_str(pBlob) + bomSize;
1113
- zUtf8 = fossil_unicode_to_utf8(zUtf8);
1114
- blob_zero(pBlob);
1115
- blob_append(pBlob, zUtf8, -1);
1116
- fossil_unicode_free(zUtf8);
1117
- }else if( starts_with_utf16be_bom(pBlob, &bomSize) ){
1118
- unsigned int i = blob_size(pBlob);
1110
+ }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
11191111
zUtf8 = blob_buffer(pBlob);
1120
- while( i > 0 ){
1121
- /* swap bytes of unicode representation */
1122
- char zTemp = zUtf8[--i];
1123
- zUtf8[i] = zUtf8[i-1];
1124
- zUtf8[--i] = zTemp;
1112
+ if( bomReverse ){
1113
+ /* Found BOM, but with reversed bytes */
1114
+ unsigned int i = blob_size(pBlob);
1115
+ while( i>0 ){
1116
+ /* swap bytes of unicode representation */
1117
+ char zTemp = zUtf8[--i];
1118
+ zUtf8[i] = zUtf8[i-1];
1119
+ zUtf8[--i] = zTemp;
1120
+ }
11251121
}
11261122
/* Make sure the blob contains two terminating 0-bytes */
11271123
blob_append(pBlob, "", 1);
11281124
zUtf8 = blob_str(pBlob) + bomSize;
11291125
zUtf8 = fossil_unicode_to_utf8(zUtf8);
11301126
--- src/blob.c
+++ src/blob.c
@@ -1096,34 +1096,30 @@
1096 ** to be UTF-8 already, so no conversion is done.
1097 */
1098 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1099 char *zUtf8;
1100 int bomSize = 0;
 
1101 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1102 struct Blob temp;
1103 zUtf8 = blob_str(pBlob) + bomSize;
1104 blob_zero(&temp);
1105 blob_append(&temp, zUtf8, -1);
1106 blob_swap(pBlob, &temp);
1107 blob_reset(&temp);
1108 #ifdef _WIN32
1109 }else if( starts_with_utf16le_bom(pBlob, &bomSize) ){
1110 /* Make sure the blob contains two terminating 0-bytes */
1111 blob_append(pBlob, "", 1);
1112 zUtf8 = blob_str(pBlob) + bomSize;
1113 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1114 blob_zero(pBlob);
1115 blob_append(pBlob, zUtf8, -1);
1116 fossil_unicode_free(zUtf8);
1117 }else if( starts_with_utf16be_bom(pBlob, &bomSize) ){
1118 unsigned int i = blob_size(pBlob);
1119 zUtf8 = blob_buffer(pBlob);
1120 while( i > 0 ){
1121 /* swap bytes of unicode representation */
1122 char zTemp = zUtf8[--i];
1123 zUtf8[i] = zUtf8[i-1];
1124 zUtf8[--i] = zTemp;
 
 
 
 
1125 }
1126 /* Make sure the blob contains two terminating 0-bytes */
1127 blob_append(pBlob, "", 1);
1128 zUtf8 = blob_str(pBlob) + bomSize;
1129 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1130
--- src/blob.c
+++ src/blob.c
@@ -1096,34 +1096,30 @@
1096 ** to be UTF-8 already, so no conversion is done.
1097 */
1098 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1099 char *zUtf8;
1100 int bomSize = 0;
1101 int bomReverse = 0;
1102 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1103 struct Blob temp;
1104 zUtf8 = blob_str(pBlob) + bomSize;
1105 blob_zero(&temp);
1106 blob_append(&temp, zUtf8, -1);
1107 blob_swap(pBlob, &temp);
1108 blob_reset(&temp);
1109 #ifdef _WIN32
1110 }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
 
 
 
 
 
 
 
 
 
1111 zUtf8 = blob_buffer(pBlob);
1112 if( bomReverse ){
1113 /* Found BOM, but with reversed bytes */
1114 unsigned int i = blob_size(pBlob);
1115 while( i>0 ){
1116 /* swap bytes of unicode representation */
1117 char zTemp = zUtf8[--i];
1118 zUtf8[i] = zUtf8[i-1];
1119 zUtf8[--i] = zTemp;
1120 }
1121 }
1122 /* Make sure the blob contains two terminating 0-bytes */
1123 blob_append(pBlob, "", 1);
1124 zUtf8 = blob_str(pBlob) + bomSize;
1125 zUtf8 = fossil_unicode_to_utf8(zUtf8);
1126
+36 -24
--- src/checkin.c
+++ src/checkin.c
@@ -209,15 +209,10 @@
209209
show_common_info(vid, "checkout:", 1, 1);
210210
}
211211
db_record_repository_filename(0);
212212
changes_cmd();
213213
}
214
-
215
-/*
216
-** Implementation of the checkin_mtime SQL function
217
-*/
218
-
219214
220215
/*
221216
** COMMAND: ls
222217
**
223218
** Usage: %fossil ls ?OPTIONS? ?VERSION?
@@ -616,30 +611,36 @@
616611
** of the array.
617612
**
618613
** If there were no arguments passed to [commit], aCommitFile is not
619614
** allocated and remains NULL. Other parts of the code interpret this
620615
** to mean "all files".
616
+**
617
+** Returns 1 if there was a warning, 0 otherwise.
621618
*/
622
-void select_commit_files(void){
619
+int select_commit_files(void){
620
+ int result = 0;
623621
if( g.argc>2 ){
624
- int ii;
622
+ int ii, jj=0;
625623
Blob b;
626624
blob_zero(&b);
627625
g.aCommitFile = fossil_malloc(sizeof(int)*(g.argc-1));
628626
629627
for(ii=2; ii<g.argc; ii++){
630628
int iId;
631629
file_tree_name(g.argv[ii], &b, 1);
632630
iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
633631
if( iId<0 ){
634
- fossil_fatal("fossil knows nothing about: %s", g.argv[ii]);
632
+ fossil_warning("fossil knows nothing about: %s", g.argv[ii]);
633
+ result = 1;
634
+ } else {
635
+ g.aCommitFile[jj++] = iId;
635636
}
636
- g.aCommitFile[ii-2] = iId;
637637
blob_reset(&b);
638638
}
639
- g.aCommitFile[ii-2] = 0;
639
+ g.aCommitFile[jj] = 0;
640640
}
641
+ return result;
641642
}
642643
643644
/*
644645
** Make sure the current check-in with timestamp zDate is younger than its
645646
** ancestor identified rid and zUuid. Throw a fatal error if not.
@@ -895,58 +896,64 @@
895896
*/
896897
static int commit_warning(
897898
Blob *p, /* The content of the file being committed. */
898899
int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */
899900
int binOk, /* Non-zero if binary warnings should be disabled. */
900
- int unicodeOk, /* Non-zero if unicode warnings should be disabled. */
901
+ int encodingOk, /* Non-zero if encoding warnings should be disabled. */
901902
const char *zFilename /* The full name of the file being committed. */
902903
){
903904
int eType; /* return value of looks_like_utf8/utf16() */
904905
int fUnicode; /* return value of starts_with_utf16_bom() */
905906
char *zMsg; /* Warning message */
906907
Blob fname; /* Relative pathname of the file */
907908
static int allOk = 0; /* Set to true to disable this routine */
908909
909910
if( allOk ) return 0;
910
- fUnicode = starts_with_utf16_bom(p, 0);
911
+ fUnicode = starts_with_utf16_bom(p, 0, 0);
911912
eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
912913
if( eType==0 || eType==-1 || fUnicode ){
913914
const char *zWarning;
915
+ const char *zDisable;
914916
const char *zConvert = "c=convert/";
915917
Blob ans;
916918
char cReply;
917919
918920
if( eType==-1 && fUnicode ){
919
- if ( crnlOk && unicodeOk ){
920
- return 0; /* We don't want Unicode/CR/NL warnings for this file. */
921
+ if ( crnlOk && encodingOk ){
922
+ return 0; /* We don't want CR/NL and Unicode warnings for this file. */
921923
}
922
- zWarning = "Unicode and CR/NL line endings";
924
+ zWarning = "CR/NL line endings and Unicode";
925
+ zDisable = "\"crnl-glob\" and \"encoding-glob\" settings";
923926
}else if( eType==-1 ){
924927
if( crnlOk ){
925928
return 0; /* We don't want CR/NL warnings for this file. */
926929
}
927930
zWarning = "CR/NL line endings";
931
+ zDisable = "\"crnl-glob\" setting";
928932
}else if( eType==0 ){
929933
if( binOk ){
930934
return 0; /* We don't want binary warnings for this file. */
931935
}
932936
zWarning = "binary data";
937
+ zDisable = "\"binary-glob\" setting";
933938
zConvert = ""; /* We cannot convert binary files. */
934939
}else{
935
- if ( unicodeOk ){
936
- return 0; /* We don't want unicode warnings for this file. */
940
+ if ( encodingOk ){
941
+ return 0; /* We don't want encoding warnings for this file. */
937942
}
938943
zWarning = "Unicode";
944
+ zDisable = "\"encoding-glob\" setting";
939945
#ifndef _WIN32
940946
zConvert = ""; /* On Unix, we cannot easily convert Unicode files. */
941947
#endif
942948
}
943949
file_relative_name(zFilename, &fname, 0);
944950
blob_zero(&ans);
945951
zMsg = mprintf(
946
- "%s contains %s. commit anyhow (a=all/%sy/N)? ",
947
- blob_str(&fname), zWarning, zConvert);
952
+ "%s contains %s. Use --no-warnings or the %s to disable this warning.\n"
953
+ "Commit anyhow (a=all/%sy/N)? ",
954
+ blob_str(&fname), zWarning, zDisable, zConvert);
948955
prompt_user(zMsg, &ans);
949956
fossil_free(zMsg);
950957
cReply = blob_str(&ans)[0];
951958
if( cReply=='a' || cReply=='A' ){
952959
allOk = 1;
@@ -1193,11 +1200,16 @@
11931200
** After the following function call has returned, the Global.aCommitFile[]
11941201
** array is allocated to contain the "id" field from the vfile table
11951202
** for each file to be committed. Or, if aCommitFile is NULL, all files
11961203
** should be committed.
11971204
*/
1198
- select_commit_files();
1205
+ if ( select_commit_files() ){
1206
+ blob_zero(&ans);
1207
+ prompt_user("continue (y/N)? ", &ans);
1208
+ cReply = blob_str(&ans)[0];
1209
+ if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
1210
+ }
11991211
isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
12001212
if( g.aCommitFile && isAMerge ){
12011213
fossil_fatal("cannot do a partial commit of a merge");
12021214
}
12031215
@@ -1314,25 +1326,25 @@
13141326
"SELECT id, %Q || pathname, mrid, %s, chnged, %s, %s FROM vfile "
13151327
"WHERE chnged==1 AND NOT deleted AND is_selected(id)",
13161328
g.zLocalRoot,
13171329
glob_expr("pathname", db_get("crnl-glob","")),
13181330
glob_expr("pathname", db_get("binary-glob","")),
1319
- glob_expr("pathname", db_get("unicode-glob",""))
1331
+ glob_expr("pathname", db_get("encoding-glob",""))
13201332
);
13211333
while( db_step(&q)==SQLITE_ROW ){
13221334
int id, rid;
13231335
const char *zFullname;
13241336
Blob content;
1325
- int crnlOk, binOk, unicodeOk, chnged;
1337
+ int crnlOk, binOk, encodingOk, chnged;
13261338
13271339
id = db_column_int(&q, 0);
13281340
zFullname = db_column_text(&q, 1);
13291341
rid = db_column_int(&q, 2);
13301342
crnlOk = db_column_int(&q, 3);
13311343
chnged = db_column_int(&q, 4);
13321344
binOk = db_column_int(&q, 5);
1333
- unicodeOk = db_column_int(&q, 6);
1345
+ encodingOk = db_column_int(&q, 6);
13341346
13351347
blob_zero(&content);
13361348
if( file_wd_islink(zFullname) ){
13371349
/* Instead of file content, put link destination path */
13381350
blob_read_link(&content, zFullname);
@@ -1340,11 +1352,11 @@
13401352
blob_read_from_file(&content, zFullname);
13411353
}
13421354
/* Do not emit any warnings when they are disabled. */
13431355
if( !noWarningFlag ){
13441356
abortCommit |= commit_warning(&content, crnlOk, binOk,
1345
- unicodeOk, zFullname);
1357
+ encodingOk, zFullname);
13461358
}
13471359
if( chnged==1 && contains_merge_marker(&content) ){
13481360
Blob fname; /* Relative pathname of the file */
13491361
13501362
nConflict++;
13511363
--- src/checkin.c
+++ src/checkin.c
@@ -209,15 +209,10 @@
209 show_common_info(vid, "checkout:", 1, 1);
210 }
211 db_record_repository_filename(0);
212 changes_cmd();
213 }
214
215 /*
216 ** Implementation of the checkin_mtime SQL function
217 */
218
219
220 /*
221 ** COMMAND: ls
222 **
223 ** Usage: %fossil ls ?OPTIONS? ?VERSION?
@@ -616,30 +611,36 @@
616 ** of the array.
617 **
618 ** If there were no arguments passed to [commit], aCommitFile is not
619 ** allocated and remains NULL. Other parts of the code interpret this
620 ** to mean "all files".
 
 
621 */
622 void select_commit_files(void){
 
623 if( g.argc>2 ){
624 int ii;
625 Blob b;
626 blob_zero(&b);
627 g.aCommitFile = fossil_malloc(sizeof(int)*(g.argc-1));
628
629 for(ii=2; ii<g.argc; ii++){
630 int iId;
631 file_tree_name(g.argv[ii], &b, 1);
632 iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
633 if( iId<0 ){
634 fossil_fatal("fossil knows nothing about: %s", g.argv[ii]);
 
 
 
635 }
636 g.aCommitFile[ii-2] = iId;
637 blob_reset(&b);
638 }
639 g.aCommitFile[ii-2] = 0;
640 }
 
641 }
642
643 /*
644 ** Make sure the current check-in with timestamp zDate is younger than its
645 ** ancestor identified rid and zUuid. Throw a fatal error if not.
@@ -895,58 +896,64 @@
895 */
896 static int commit_warning(
897 Blob *p, /* The content of the file being committed. */
898 int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */
899 int binOk, /* Non-zero if binary warnings should be disabled. */
900 int unicodeOk, /* Non-zero if unicode warnings should be disabled. */
901 const char *zFilename /* The full name of the file being committed. */
902 ){
903 int eType; /* return value of looks_like_utf8/utf16() */
904 int fUnicode; /* return value of starts_with_utf16_bom() */
905 char *zMsg; /* Warning message */
906 Blob fname; /* Relative pathname of the file */
907 static int allOk = 0; /* Set to true to disable this routine */
908
909 if( allOk ) return 0;
910 fUnicode = starts_with_utf16_bom(p, 0);
911 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
912 if( eType==0 || eType==-1 || fUnicode ){
913 const char *zWarning;
 
914 const char *zConvert = "c=convert/";
915 Blob ans;
916 char cReply;
917
918 if( eType==-1 && fUnicode ){
919 if ( crnlOk && unicodeOk ){
920 return 0; /* We don't want Unicode/CR/NL warnings for this file. */
921 }
922 zWarning = "Unicode and CR/NL line endings";
 
923 }else if( eType==-1 ){
924 if( crnlOk ){
925 return 0; /* We don't want CR/NL warnings for this file. */
926 }
927 zWarning = "CR/NL line endings";
 
928 }else if( eType==0 ){
929 if( binOk ){
930 return 0; /* We don't want binary warnings for this file. */
931 }
932 zWarning = "binary data";
 
933 zConvert = ""; /* We cannot convert binary files. */
934 }else{
935 if ( unicodeOk ){
936 return 0; /* We don't want unicode warnings for this file. */
937 }
938 zWarning = "Unicode";
 
939 #ifndef _WIN32
940 zConvert = ""; /* On Unix, we cannot easily convert Unicode files. */
941 #endif
942 }
943 file_relative_name(zFilename, &fname, 0);
944 blob_zero(&ans);
945 zMsg = mprintf(
946 "%s contains %s. commit anyhow (a=all/%sy/N)? ",
947 blob_str(&fname), zWarning, zConvert);
 
948 prompt_user(zMsg, &ans);
949 fossil_free(zMsg);
950 cReply = blob_str(&ans)[0];
951 if( cReply=='a' || cReply=='A' ){
952 allOk = 1;
@@ -1193,11 +1200,16 @@
1193 ** After the following function call has returned, the Global.aCommitFile[]
1194 ** array is allocated to contain the "id" field from the vfile table
1195 ** for each file to be committed. Or, if aCommitFile is NULL, all files
1196 ** should be committed.
1197 */
1198 select_commit_files();
 
 
 
 
 
1199 isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
1200 if( g.aCommitFile && isAMerge ){
1201 fossil_fatal("cannot do a partial commit of a merge");
1202 }
1203
@@ -1314,25 +1326,25 @@
1314 "SELECT id, %Q || pathname, mrid, %s, chnged, %s, %s FROM vfile "
1315 "WHERE chnged==1 AND NOT deleted AND is_selected(id)",
1316 g.zLocalRoot,
1317 glob_expr("pathname", db_get("crnl-glob","")),
1318 glob_expr("pathname", db_get("binary-glob","")),
1319 glob_expr("pathname", db_get("unicode-glob",""))
1320 );
1321 while( db_step(&q)==SQLITE_ROW ){
1322 int id, rid;
1323 const char *zFullname;
1324 Blob content;
1325 int crnlOk, binOk, unicodeOk, chnged;
1326
1327 id = db_column_int(&q, 0);
1328 zFullname = db_column_text(&q, 1);
1329 rid = db_column_int(&q, 2);
1330 crnlOk = db_column_int(&q, 3);
1331 chnged = db_column_int(&q, 4);
1332 binOk = db_column_int(&q, 5);
1333 unicodeOk = db_column_int(&q, 6);
1334
1335 blob_zero(&content);
1336 if( file_wd_islink(zFullname) ){
1337 /* Instead of file content, put link destination path */
1338 blob_read_link(&content, zFullname);
@@ -1340,11 +1352,11 @@
1340 blob_read_from_file(&content, zFullname);
1341 }
1342 /* Do not emit any warnings when they are disabled. */
1343 if( !noWarningFlag ){
1344 abortCommit |= commit_warning(&content, crnlOk, binOk,
1345 unicodeOk, zFullname);
1346 }
1347 if( chnged==1 && contains_merge_marker(&content) ){
1348 Blob fname; /* Relative pathname of the file */
1349
1350 nConflict++;
1351
--- src/checkin.c
+++ src/checkin.c
@@ -209,15 +209,10 @@
209 show_common_info(vid, "checkout:", 1, 1);
210 }
211 db_record_repository_filename(0);
212 changes_cmd();
213 }
 
 
 
 
 
214
215 /*
216 ** COMMAND: ls
217 **
218 ** Usage: %fossil ls ?OPTIONS? ?VERSION?
@@ -616,30 +611,36 @@
611 ** of the array.
612 **
613 ** If there were no arguments passed to [commit], aCommitFile is not
614 ** allocated and remains NULL. Other parts of the code interpret this
615 ** to mean "all files".
616 **
617 ** Returns 1 if there was a warning, 0 otherwise.
618 */
619 int select_commit_files(void){
620 int result = 0;
621 if( g.argc>2 ){
622 int ii, jj=0;
623 Blob b;
624 blob_zero(&b);
625 g.aCommitFile = fossil_malloc(sizeof(int)*(g.argc-1));
626
627 for(ii=2; ii<g.argc; ii++){
628 int iId;
629 file_tree_name(g.argv[ii], &b, 1);
630 iId = db_int(-1, "SELECT id FROM vfile WHERE pathname=%Q", blob_str(&b));
631 if( iId<0 ){
632 fossil_warning("fossil knows nothing about: %s", g.argv[ii]);
633 result = 1;
634 } else {
635 g.aCommitFile[jj++] = iId;
636 }
 
637 blob_reset(&b);
638 }
639 g.aCommitFile[jj] = 0;
640 }
641 return result;
642 }
643
644 /*
645 ** Make sure the current check-in with timestamp zDate is younger than its
646 ** ancestor identified rid and zUuid. Throw a fatal error if not.
@@ -895,58 +896,64 @@
896 */
897 static int commit_warning(
898 Blob *p, /* The content of the file being committed. */
899 int crnlOk, /* Non-zero if CR/NL warnings should be disabled. */
900 int binOk, /* Non-zero if binary warnings should be disabled. */
901 int encodingOk, /* Non-zero if encoding warnings should be disabled. */
902 const char *zFilename /* The full name of the file being committed. */
903 ){
904 int eType; /* return value of looks_like_utf8/utf16() */
905 int fUnicode; /* return value of starts_with_utf16_bom() */
906 char *zMsg; /* Warning message */
907 Blob fname; /* Relative pathname of the file */
908 static int allOk = 0; /* Set to true to disable this routine */
909
910 if( allOk ) return 0;
911 fUnicode = starts_with_utf16_bom(p, 0, 0);
912 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
913 if( eType==0 || eType==-1 || fUnicode ){
914 const char *zWarning;
915 const char *zDisable;
916 const char *zConvert = "c=convert/";
917 Blob ans;
918 char cReply;
919
920 if( eType==-1 && fUnicode ){
921 if ( crnlOk && encodingOk ){
922 return 0; /* We don't want CR/NL and Unicode warnings for this file. */
923 }
924 zWarning = "CR/NL line endings and Unicode";
925 zDisable = "\"crnl-glob\" and \"encoding-glob\" settings";
926 }else if( eType==-1 ){
927 if( crnlOk ){
928 return 0; /* We don't want CR/NL warnings for this file. */
929 }
930 zWarning = "CR/NL line endings";
931 zDisable = "\"crnl-glob\" setting";
932 }else if( eType==0 ){
933 if( binOk ){
934 return 0; /* We don't want binary warnings for this file. */
935 }
936 zWarning = "binary data";
937 zDisable = "\"binary-glob\" setting";
938 zConvert = ""; /* We cannot convert binary files. */
939 }else{
940 if ( encodingOk ){
941 return 0; /* We don't want encoding warnings for this file. */
942 }
943 zWarning = "Unicode";
944 zDisable = "\"encoding-glob\" setting";
945 #ifndef _WIN32
946 zConvert = ""; /* On Unix, we cannot easily convert Unicode files. */
947 #endif
948 }
949 file_relative_name(zFilename, &fname, 0);
950 blob_zero(&ans);
951 zMsg = mprintf(
952 "%s contains %s. Use --no-warnings or the %s to disable this warning.\n"
953 "Commit anyhow (a=all/%sy/N)? ",
954 blob_str(&fname), zWarning, zDisable, zConvert);
955 prompt_user(zMsg, &ans);
956 fossil_free(zMsg);
957 cReply = blob_str(&ans)[0];
958 if( cReply=='a' || cReply=='A' ){
959 allOk = 1;
@@ -1193,11 +1200,16 @@
1200 ** After the following function call has returned, the Global.aCommitFile[]
1201 ** array is allocated to contain the "id" field from the vfile table
1202 ** for each file to be committed. Or, if aCommitFile is NULL, all files
1203 ** should be committed.
1204 */
1205 if ( select_commit_files() ){
1206 blob_zero(&ans);
1207 prompt_user("continue (y/N)? ", &ans);
1208 cReply = blob_str(&ans)[0];
1209 if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
1210 }
1211 isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
1212 if( g.aCommitFile && isAMerge ){
1213 fossil_fatal("cannot do a partial commit of a merge");
1214 }
1215
@@ -1314,25 +1326,25 @@
1326 "SELECT id, %Q || pathname, mrid, %s, chnged, %s, %s FROM vfile "
1327 "WHERE chnged==1 AND NOT deleted AND is_selected(id)",
1328 g.zLocalRoot,
1329 glob_expr("pathname", db_get("crnl-glob","")),
1330 glob_expr("pathname", db_get("binary-glob","")),
1331 glob_expr("pathname", db_get("encoding-glob",""))
1332 );
1333 while( db_step(&q)==SQLITE_ROW ){
1334 int id, rid;
1335 const char *zFullname;
1336 Blob content;
1337 int crnlOk, binOk, encodingOk, chnged;
1338
1339 id = db_column_int(&q, 0);
1340 zFullname = db_column_text(&q, 1);
1341 rid = db_column_int(&q, 2);
1342 crnlOk = db_column_int(&q, 3);
1343 chnged = db_column_int(&q, 4);
1344 binOk = db_column_int(&q, 5);
1345 encodingOk = db_column_int(&q, 6);
1346
1347 blob_zero(&content);
1348 if( file_wd_islink(zFullname) ){
1349 /* Instead of file content, put link destination path */
1350 blob_read_link(&content, zFullname);
@@ -1340,11 +1352,11 @@
1352 blob_read_from_file(&content, zFullname);
1353 }
1354 /* Do not emit any warnings when they are disabled. */
1355 if( !noWarningFlag ){
1356 abortCommit |= commit_warning(&content, crnlOk, binOk,
1357 encodingOk, zFullname);
1358 }
1359 if( chnged==1 && contains_merge_marker(&content) ){
1360 Blob fname; /* Relative pathname of the file */
1361
1362 nConflict++;
1363
+1 -1
--- src/configure.c
+++ src/configure.c
@@ -103,11 +103,11 @@
103103
{ "project-description", CONFIGSET_PROJ },
104104
{ "manifest", CONFIGSET_PROJ },
105105
{ "binary-glob", CONFIGSET_PROJ },
106106
{ "ignore-glob", CONFIGSET_PROJ },
107107
{ "crnl-glob", CONFIGSET_PROJ },
108
- { "unicode-glob", CONFIGSET_PROJ },
108
+ { "encoding-glob", CONFIGSET_PROJ },
109109
{ "empty-dirs", CONFIGSET_PROJ },
110110
{ "allow-symlinks", CONFIGSET_PROJ },
111111
112112
{ "ticket-table", CONFIGSET_TKT },
113113
{ "ticket-common", CONFIGSET_TKT },
114114
--- src/configure.c
+++ src/configure.c
@@ -103,11 +103,11 @@
103 { "project-description", CONFIGSET_PROJ },
104 { "manifest", CONFIGSET_PROJ },
105 { "binary-glob", CONFIGSET_PROJ },
106 { "ignore-glob", CONFIGSET_PROJ },
107 { "crnl-glob", CONFIGSET_PROJ },
108 { "unicode-glob", CONFIGSET_PROJ },
109 { "empty-dirs", CONFIGSET_PROJ },
110 { "allow-symlinks", CONFIGSET_PROJ },
111
112 { "ticket-table", CONFIGSET_TKT },
113 { "ticket-common", CONFIGSET_TKT },
114
--- src/configure.c
+++ src/configure.c
@@ -103,11 +103,11 @@
103 { "project-description", CONFIGSET_PROJ },
104 { "manifest", CONFIGSET_PROJ },
105 { "binary-glob", CONFIGSET_PROJ },
106 { "ignore-glob", CONFIGSET_PROJ },
107 { "crnl-glob", CONFIGSET_PROJ },
108 { "encoding-glob", CONFIGSET_PROJ },
109 { "empty-dirs", CONFIGSET_PROJ },
110 { "allow-symlinks", CONFIGSET_PROJ },
111
112 { "ticket-table", CONFIGSET_TKT },
113 { "ticket-common", CONFIGSET_TKT },
114
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -4349,11 +4349,11 @@
43494349
{
43504350
return 0;
43514351
}
43524352
else
43534353
{
4354
- unsigned char * x = (unsigned char *)realloc( buf->mem, n );
4354
+ unsigned char * x = (unsigned char *)cson_realloc( buf->mem, n, "cson_buffer::mem" );
43554355
if( ! x ) return cson_rc.AllocError;
43564356
memset( x + buf->used, 0, n - buf->used );
43574357
buf->mem = x;
43584358
buf->capacity = n;
43594359
++buf->timesExpanded;
43604360
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -4349,11 +4349,11 @@
4349 {
4350 return 0;
4351 }
4352 else
4353 {
4354 unsigned char * x = (unsigned char *)realloc( buf->mem, n );
4355 if( ! x ) return cson_rc.AllocError;
4356 memset( x + buf->used, 0, n - buf->used );
4357 buf->mem = x;
4358 buf->capacity = n;
4359 ++buf->timesExpanded;
4360
--- src/cson_amalgamation.c
+++ src/cson_amalgamation.c
@@ -4349,11 +4349,11 @@
4349 {
4350 return 0;
4351 }
4352 else
4353 {
4354 unsigned char * x = (unsigned char *)cson_realloc( buf->mem, n, "cson_buffer::mem" );
4355 if( ! x ) return cson_rc.AllocError;
4356 memset( x + buf->used, 0, n - buf->used );
4357 buf->mem = x;
4358 buf->capacity = n;
4359 ++buf->timesExpanded;
4360
+11 -10
--- src/db.c
+++ src/db.c
@@ -2064,16 +2064,17 @@
20642064
{ "default-perms", 0, 16, 0, "u" },
20652065
{ "diff-binary", 0, 0, 0, "on" },
20662066
{ "diff-command", 0, 40, 0, "" },
20672067
{ "dont-push", 0, 0, 0, "off" },
20682068
{ "editor", 0, 32, 0, "" },
2069
+ { "empty-dirs", 0, 40, 1, "" },
2070
+ { "encoding-glob", 0, 40, 1, "" },
20692071
{ "gdiff-command", 0, 40, 0, "gdiff" },
20702072
{ "gmerge-command",0, 40, 0, "" },
2073
+ { "http-port", 0, 16, 0, "8080" },
20712074
{ "https-login", 0, 0, 0, "off" },
20722075
{ "ignore-glob", 0, 40, 1, "" },
2073
- { "empty-dirs", 0, 40, 1, "" },
2074
- { "http-port", 0, 16, 0, "8080" },
20752076
{ "localauth", 0, 0, 0, "off" },
20762077
{ "main-branch", 0, 40, 0, "trunk" },
20772078
{ "manifest", 0, 0, 1, "off" },
20782079
#ifdef FOSSIL_ENABLE_MARKDOWN
20792080
{ "markdown", 0, 0, 0, "off" },
@@ -2083,19 +2084,18 @@
20832084
{ "pgp-command", 0, 40, 0, "gpg --clearsign -o " },
20842085
{ "proxy", 0, 32, 0, "off" },
20852086
{ "relative-paths",0, 0, 0, "on" },
20862087
{ "repo-cksum", 0, 0, 0, "on" },
20872088
{ "self-register", 0, 0, 0, "off" },
2089
+ { "ssh-command", 0, 40, 0, "" },
20882090
{ "ssl-ca-location",0, 40, 0, "" },
20892091
{ "ssl-identity", 0, 40, 0, "" },
2090
- { "ssh-command", 0, 40, 0, "" },
2091
- { "th1-setup", 0, 40, 0, "" },
20922092
#ifdef FOSSIL_ENABLE_TCL
20932093
{ "tcl", 0, 0, 0, "off" },
20942094
{ "tcl-setup", 0, 40, 0, "" },
20952095
#endif
2096
- { "unicode-glob", 0, 40, 1, "" },
2096
+ { "th1-setup", 0, 40, 0, "" },
20972097
{ "web-browser", 0, 32, 0, "" },
20982098
{ "white-foreground", 0, 0, 0, "off" },
20992099
{ 0,0,0,0,0 }
21002100
};
21012101
@@ -2179,10 +2179,16 @@
21792179
**
21802180
** empty-dirs A comma or newline-separated list of pathnames. On
21812181
** (versionable) update and checkout commands, if no file or directory
21822182
** exists with that name, an empty directory will be
21832183
** created.
2184
+**
2185
+** encoding-glob The VALUE is a comma or newline-separated list of GLOB
2186
+** (versionable) patterns specifying files that the "commit" command will
2187
+** ignore when issuing warnings about text files that may
2188
+** use another encoding than ASCII or UTF-8. Set to "*"
2189
+** to disable encoding checking.
21842190
**
21852191
** gdiff-command External command to run when performing a graphical
21862192
** diff. If undefined, text diff will be used.
21872193
**
21882194
** gmerge-command A graphical merge conflict resolver command operating
@@ -2278,15 +2284,10 @@
22782284
**
22792285
** th1-setup This is the setup script to be evaluated after creating
22802286
** and initializing the TH1 interpreter. By default, this
22812287
** is empty and no extra setup is performed.
22822288
**
2283
-** unicode-glob The VALUE is a comma or newline-separated list of GLOB
2284
-** (versionable) patterns specifying files that the "commit" command will
2285
-** ignore when issuing warnings about text files that may
2286
-** contain Unicode. Set to "*" to disable Unicode checking.
2287
-**
22882289
** web-browser A shell command used to launch your preferred
22892290
** web browser when given a URL as an argument.
22902291
** Defaults to "start" on windows, "open" on Mac,
22912292
** and "firefox" on Unix.
22922293
**
22932294
--- src/db.c
+++ src/db.c
@@ -2064,16 +2064,17 @@
2064 { "default-perms", 0, 16, 0, "u" },
2065 { "diff-binary", 0, 0, 0, "on" },
2066 { "diff-command", 0, 40, 0, "" },
2067 { "dont-push", 0, 0, 0, "off" },
2068 { "editor", 0, 32, 0, "" },
 
 
2069 { "gdiff-command", 0, 40, 0, "gdiff" },
2070 { "gmerge-command",0, 40, 0, "" },
 
2071 { "https-login", 0, 0, 0, "off" },
2072 { "ignore-glob", 0, 40, 1, "" },
2073 { "empty-dirs", 0, 40, 1, "" },
2074 { "http-port", 0, 16, 0, "8080" },
2075 { "localauth", 0, 0, 0, "off" },
2076 { "main-branch", 0, 40, 0, "trunk" },
2077 { "manifest", 0, 0, 1, "off" },
2078 #ifdef FOSSIL_ENABLE_MARKDOWN
2079 { "markdown", 0, 0, 0, "off" },
@@ -2083,19 +2084,18 @@
2083 { "pgp-command", 0, 40, 0, "gpg --clearsign -o " },
2084 { "proxy", 0, 32, 0, "off" },
2085 { "relative-paths",0, 0, 0, "on" },
2086 { "repo-cksum", 0, 0, 0, "on" },
2087 { "self-register", 0, 0, 0, "off" },
 
2088 { "ssl-ca-location",0, 40, 0, "" },
2089 { "ssl-identity", 0, 40, 0, "" },
2090 { "ssh-command", 0, 40, 0, "" },
2091 { "th1-setup", 0, 40, 0, "" },
2092 #ifdef FOSSIL_ENABLE_TCL
2093 { "tcl", 0, 0, 0, "off" },
2094 { "tcl-setup", 0, 40, 0, "" },
2095 #endif
2096 { "unicode-glob", 0, 40, 1, "" },
2097 { "web-browser", 0, 32, 0, "" },
2098 { "white-foreground", 0, 0, 0, "off" },
2099 { 0,0,0,0,0 }
2100 };
2101
@@ -2179,10 +2179,16 @@
2179 **
2180 ** empty-dirs A comma or newline-separated list of pathnames. On
2181 ** (versionable) update and checkout commands, if no file or directory
2182 ** exists with that name, an empty directory will be
2183 ** created.
 
 
 
 
 
 
2184 **
2185 ** gdiff-command External command to run when performing a graphical
2186 ** diff. If undefined, text diff will be used.
2187 **
2188 ** gmerge-command A graphical merge conflict resolver command operating
@@ -2278,15 +2284,10 @@
2278 **
2279 ** th1-setup This is the setup script to be evaluated after creating
2280 ** and initializing the TH1 interpreter. By default, this
2281 ** is empty and no extra setup is performed.
2282 **
2283 ** unicode-glob The VALUE is a comma or newline-separated list of GLOB
2284 ** (versionable) patterns specifying files that the "commit" command will
2285 ** ignore when issuing warnings about text files that may
2286 ** contain Unicode. Set to "*" to disable Unicode checking.
2287 **
2288 ** web-browser A shell command used to launch your preferred
2289 ** web browser when given a URL as an argument.
2290 ** Defaults to "start" on windows, "open" on Mac,
2291 ** and "firefox" on Unix.
2292 **
2293
--- src/db.c
+++ src/db.c
@@ -2064,16 +2064,17 @@
2064 { "default-perms", 0, 16, 0, "u" },
2065 { "diff-binary", 0, 0, 0, "on" },
2066 { "diff-command", 0, 40, 0, "" },
2067 { "dont-push", 0, 0, 0, "off" },
2068 { "editor", 0, 32, 0, "" },
2069 { "empty-dirs", 0, 40, 1, "" },
2070 { "encoding-glob", 0, 40, 1, "" },
2071 { "gdiff-command", 0, 40, 0, "gdiff" },
2072 { "gmerge-command",0, 40, 0, "" },
2073 { "http-port", 0, 16, 0, "8080" },
2074 { "https-login", 0, 0, 0, "off" },
2075 { "ignore-glob", 0, 40, 1, "" },
 
 
2076 { "localauth", 0, 0, 0, "off" },
2077 { "main-branch", 0, 40, 0, "trunk" },
2078 { "manifest", 0, 0, 1, "off" },
2079 #ifdef FOSSIL_ENABLE_MARKDOWN
2080 { "markdown", 0, 0, 0, "off" },
@@ -2083,19 +2084,18 @@
2084 { "pgp-command", 0, 40, 0, "gpg --clearsign -o " },
2085 { "proxy", 0, 32, 0, "off" },
2086 { "relative-paths",0, 0, 0, "on" },
2087 { "repo-cksum", 0, 0, 0, "on" },
2088 { "self-register", 0, 0, 0, "off" },
2089 { "ssh-command", 0, 40, 0, "" },
2090 { "ssl-ca-location",0, 40, 0, "" },
2091 { "ssl-identity", 0, 40, 0, "" },
 
 
2092 #ifdef FOSSIL_ENABLE_TCL
2093 { "tcl", 0, 0, 0, "off" },
2094 { "tcl-setup", 0, 40, 0, "" },
2095 #endif
2096 { "th1-setup", 0, 40, 0, "" },
2097 { "web-browser", 0, 32, 0, "" },
2098 { "white-foreground", 0, 0, 0, "off" },
2099 { 0,0,0,0,0 }
2100 };
2101
@@ -2179,10 +2179,16 @@
2179 **
2180 ** empty-dirs A comma or newline-separated list of pathnames. On
2181 ** (versionable) update and checkout commands, if no file or directory
2182 ** exists with that name, an empty directory will be
2183 ** created.
2184 **
2185 ** encoding-glob The VALUE is a comma or newline-separated list of GLOB
2186 ** (versionable) patterns specifying files that the "commit" command will
2187 ** ignore when issuing warnings about text files that may
2188 ** use another encoding than ASCII or UTF-8. Set to "*"
2189 ** to disable encoding checking.
2190 **
2191 ** gdiff-command External command to run when performing a graphical
2192 ** diff. If undefined, text diff will be used.
2193 **
2194 ** gmerge-command A graphical merge conflict resolver command operating
@@ -2278,15 +2284,10 @@
2284 **
2285 ** th1-setup This is the setup script to be evaluated after creating
2286 ** and initializing the TH1 interpreter. By default, this
2287 ** is empty and no extra setup is performed.
2288 **
 
 
 
 
 
2289 ** web-browser A shell command used to launch your preferred
2290 ** web browser when given a URL as an argument.
2291 ** Defaults to "start" on windows, "open" on Mac,
2292 ** and "firefox" on Unix.
2293 **
2294
+57 -51
--- src/diff.c
+++ src/diff.c
@@ -39,10 +39,11 @@
3939
#define DIFF_LINENO ((u64)0x20000000) /* Show line numbers */
4040
#define DIFF_WS_WARNING ((u64)0x40000000) /* Warn about whitespace */
4141
#define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
4242
#define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
4343
#define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44
+#define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
4445
4546
/*
4647
** These error messages are shared in multiple locations. They are defined
4748
** here for consistency.
4849
*/
@@ -50,10 +51,16 @@
5051
"cannot compute difference between binary files\n"
5152
5253
#define DIFF_CANNOT_COMPUTE_SYMLINK \
5354
"cannot compute difference between symlink and regular file\n"
5455
56
+#define DIFF_TOO_MANY_CHANGES_TXT \
57
+ "more than 10,000 changes\n"
58
+
59
+#define DIFF_TOO_MANY_CHANGES_HTML \
60
+ "<p class='generalError'>More than 10,000 changes</p>\n"
61
+
5562
#define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
5663
#endif /* INTERFACE */
5764
5865
/*
5966
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -354,58 +361,38 @@
354361
if( blob_size(pContent)<bomSize ) return 0;
355362
return memcmp(z, bom, bomSize)==0;
356363
}
357364
358365
/*
359
-** This function returns non-zero if the blob starts with a UTF-16le or
360
-** UTF-16be byte-order-mark (BOM).
361
-*/
362
-int starts_with_utf16_bom(const Blob *pContent, int *pnByte){
363
- const char *z = blob_buffer(pContent);
364
- int c1, c2;
365
-
366
- if( pnByte ) *pnByte = 2;
367
- if( blob_size(pContent)<2 ) return 0;
368
- c1 = z[0]; c2 = z[1];
369
- if( (c1==(char)0xff) && (c2==(char)0xfe) ){
370
- return 1;
371
- }else if( (c1==(char)0xfe) && (c2==(char)0xff) ){
372
- return 1;
373
- }
374
- return 0;
375
-}
376
-
377
-/*
378
-** This function returns non-zero if the blob starts with a UTF-16le
379
-** byte-order-mark (BOM).
380
-*/
381
-int starts_with_utf16le_bom(const Blob *pContent, int *pnByte){
382
- const char *z = blob_buffer(pContent);
383
- int c1, c2;
384
-
385
- if( pnByte ) *pnByte = 2;
386
- if( blob_size(pContent)<2 ) return 0;
387
- c1 = z[0]; c2 = z[1];
388
- if( (c1==(char)0xff) && (c2==(char)0xfe) ){
389
- return 1;
390
- }
391
- return 0;
392
-}
393
-
394
-/*
395
-** This function returns non-zero if the blob starts with a UTF-16be
396
-** byte-order-mark (BOM).
397
-*/
398
-int starts_with_utf16be_bom(const Blob *pContent, int *pnByte){
399
- const char *z = blob_buffer(pContent);
400
- int c1, c2;
401
-
402
- if( pnByte ) *pnByte = 2;
403
- if( blob_size(pContent)<2 ) return 0;
404
- c1 = z[0]; c2 = z[1];
405
- if( (c1==(char)0xfe) && (c2==(char)0xff) ){
406
- return 1;
366
+** This function returns non-zero if the blob starts with a UTF-16
367
+** byte-order-mark (BOM), either in the endianness of the machine
368
+** or in reversed byte order.
369
+*/
370
+int starts_with_utf16_bom(
371
+ const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
372
+ int *pnByte, /* OUT: The number of bytes used for the BOM. */
373
+ int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
374
+){
375
+ const char *z = blob_buffer(pContent);
376
+ int bomSize = 2;
377
+ static const unsigned short bom = 0xfeff;
378
+ static const unsigned short bom_reversed = 0xfffe;
379
+ static const unsigned short null = 0;
380
+ int size;
381
+
382
+ if( pnByte ) *pnByte = bomSize;
383
+ if( pbReverse ) *pbReverse = -1; /* Unknown. */
384
+ size = blob_size(pContent);
385
+ if( (size<bomSize) || (size%2) ) return 0;
386
+ if( memcmp(z, &bom_reversed, bomSize)==0 ){
387
+ if( pbReverse ) *pbReverse = 1;
388
+ if( size<(2*bomSize) ) return 1;
389
+ if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
390
+ }else if( memcmp(z, &bom, bomSize)==0 ){
391
+ if( pbReverse ) *pbReverse = 0;
392
+ if( size<(2*bomSize) ) return 1;
393
+ if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
407394
}
408395
return 0;
409396
}
410397
411398
/*
@@ -927,12 +914,12 @@
927914
&& zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
928915
nSuffix++;
929916
}
930917
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
931918
}
932
- if( nPrefix+nSuffix > nLeft ) nSuffix = nLeft - nPrefix;
933
- if( nPrefix+nSuffix > nRight ) nSuffix = nRight - nPrefix;
919
+ if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
920
+ if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
934921
935922
/* A single chunk of text inserted on the right */
936923
if( nPrefix+nSuffix==nLeft ){
937924
sbsWriteLineno(p, lnLeft);
938925
p->iStart2 = p->iEnd2 = 0;
@@ -1949,11 +1936,30 @@
19491936
return 0;
19501937
}
19511938
19521939
/* Compute the difference */
19531940
diff_all(&c);
1954
- if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
1941
+ if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
1942
+ int i, m, n;
1943
+ int *a = c.aEdit;
1944
+ int mx = c.nEdit;
1945
+ for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1946
+ if( n>10000 ){
1947
+ fossil_free(c.aFrom);
1948
+ fossil_free(c.aTo);
1949
+ fossil_free(c.aEdit);
1950
+ if( diffFlags & DIFF_HTML ){
1951
+ blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
1952
+ }else{
1953
+ blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
1954
+ }
1955
+ return 0;
1956
+ }
1957
+ }
1958
+ if( (diffFlags & DIFF_NOOPT)==0 ){
1959
+ diff_optimize(&c);
1960
+ }
19551961
19561962
if( pOut ){
19571963
/* Compute a context or side-by-side diff into pOut */
19581964
if( diffFlags & DIFF_SIDEBYSIDE ){
19591965
sbsDiff(&c, pOut, pRe, diffFlags);
19601966
--- src/diff.c
+++ src/diff.c
@@ -39,10 +39,11 @@
39 #define DIFF_LINENO ((u64)0x20000000) /* Show line numbers */
40 #define DIFF_WS_WARNING ((u64)0x40000000) /* Warn about whitespace */
41 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
 
44
45 /*
46 ** These error messages are shared in multiple locations. They are defined
47 ** here for consistency.
48 */
@@ -50,10 +51,16 @@
50 "cannot compute difference between binary files\n"
51
52 #define DIFF_CANNOT_COMPUTE_SYMLINK \
53 "cannot compute difference between symlink and regular file\n"
54
 
 
 
 
 
 
55 #define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
56 #endif /* INTERFACE */
57
58 /*
59 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -354,58 +361,38 @@
354 if( blob_size(pContent)<bomSize ) return 0;
355 return memcmp(z, bom, bomSize)==0;
356 }
357
358 /*
359 ** This function returns non-zero if the blob starts with a UTF-16le or
360 ** UTF-16be byte-order-mark (BOM).
361 */
362 int starts_with_utf16_bom(const Blob *pContent, int *pnByte){
363 const char *z = blob_buffer(pContent);
364 int c1, c2;
365
366 if( pnByte ) *pnByte = 2;
367 if( blob_size(pContent)<2 ) return 0;
368 c1 = z[0]; c2 = z[1];
369 if( (c1==(char)0xff) && (c2==(char)0xfe) ){
370 return 1;
371 }else if( (c1==(char)0xfe) && (c2==(char)0xff) ){
372 return 1;
373 }
374 return 0;
375 }
376
377 /*
378 ** This function returns non-zero if the blob starts with a UTF-16le
379 ** byte-order-mark (BOM).
380 */
381 int starts_with_utf16le_bom(const Blob *pContent, int *pnByte){
382 const char *z = blob_buffer(pContent);
383 int c1, c2;
384
385 if( pnByte ) *pnByte = 2;
386 if( blob_size(pContent)<2 ) return 0;
387 c1 = z[0]; c2 = z[1];
388 if( (c1==(char)0xff) && (c2==(char)0xfe) ){
389 return 1;
390 }
391 return 0;
392 }
393
394 /*
395 ** This function returns non-zero if the blob starts with a UTF-16be
396 ** byte-order-mark (BOM).
397 */
398 int starts_with_utf16be_bom(const Blob *pContent, int *pnByte){
399 const char *z = blob_buffer(pContent);
400 int c1, c2;
401
402 if( pnByte ) *pnByte = 2;
403 if( blob_size(pContent)<2 ) return 0;
404 c1 = z[0]; c2 = z[1];
405 if( (c1==(char)0xfe) && (c2==(char)0xff) ){
406 return 1;
407 }
408 return 0;
409 }
410
411 /*
@@ -927,12 +914,12 @@
927 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
928 nSuffix++;
929 }
930 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
931 }
932 if( nPrefix+nSuffix > nLeft ) nSuffix = nLeft - nPrefix;
933 if( nPrefix+nSuffix > nRight ) nSuffix = nRight - nPrefix;
934
935 /* A single chunk of text inserted on the right */
936 if( nPrefix+nSuffix==nLeft ){
937 sbsWriteLineno(p, lnLeft);
938 p->iStart2 = p->iEnd2 = 0;
@@ -1949,11 +1936,30 @@
1949 return 0;
1950 }
1951
1952 /* Compute the difference */
1953 diff_all(&c);
1954 if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1955
1956 if( pOut ){
1957 /* Compute a context or side-by-side diff into pOut */
1958 if( diffFlags & DIFF_SIDEBYSIDE ){
1959 sbsDiff(&c, pOut, pRe, diffFlags);
1960
--- src/diff.c
+++ src/diff.c
@@ -39,10 +39,11 @@
39 #define DIFF_LINENO ((u64)0x20000000) /* Show line numbers */
40 #define DIFF_WS_WARNING ((u64)0x40000000) /* Warn about whitespace */
41 #define DIFF_NOOPT (((u64)0x01)<<32) /* Suppress optimizations (debug) */
42 #define DIFF_INVERT (((u64)0x02)<<32) /* Invert the diff (debug) */
43 #define DIFF_CONTEXT_EX (((u64)0x04)<<32) /* Use context even if zero */
44 #define DIFF_NOTTOOBIG (((u64)0x08)<<32) /* Only display if not too big */
45
46 /*
47 ** These error messages are shared in multiple locations. They are defined
48 ** here for consistency.
49 */
@@ -50,10 +51,16 @@
51 "cannot compute difference between binary files\n"
52
53 #define DIFF_CANNOT_COMPUTE_SYMLINK \
54 "cannot compute difference between symlink and regular file\n"
55
56 #define DIFF_TOO_MANY_CHANGES_TXT \
57 "more than 10,000 changes\n"
58
59 #define DIFF_TOO_MANY_CHANGES_HTML \
60 "<p class='generalError'>More than 10,000 changes</p>\n"
61
62 #define looks_like_binary(blob) (looks_like_utf8((blob)) == 0)
63 #endif /* INTERFACE */
64
65 /*
66 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -354,58 +361,38 @@
361 if( blob_size(pContent)<bomSize ) return 0;
362 return memcmp(z, bom, bomSize)==0;
363 }
364
365 /*
366 ** This function returns non-zero if the blob starts with a UTF-16
367 ** byte-order-mark (BOM), either in the endianness of the machine
368 ** or in reversed byte order.
369 */
370 int starts_with_utf16_bom(
371 const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
372 int *pnByte, /* OUT: The number of bytes used for the BOM. */
373 int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
374 ){
375 const char *z = blob_buffer(pContent);
376 int bomSize = 2;
377 static const unsigned short bom = 0xfeff;
378 static const unsigned short bom_reversed = 0xfffe;
379 static const unsigned short null = 0;
380 int size;
381
382 if( pnByte ) *pnByte = bomSize;
383 if( pbReverse ) *pbReverse = -1; /* Unknown. */
384 size = blob_size(pContent);
385 if( (size<bomSize) || (size%2) ) return 0;
386 if( memcmp(z, &bom_reversed, bomSize)==0 ){
387 if( pbReverse ) *pbReverse = 1;
388 if( size<(2*bomSize) ) return 1;
389 if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
390 }else if( memcmp(z, &bom, bomSize)==0 ){
391 if( pbReverse ) *pbReverse = 0;
392 if( size<(2*bomSize) ) return 1;
393 if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394 }
395 return 0;
396 }
397
398 /*
@@ -927,12 +914,12 @@
914 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
915 nSuffix++;
916 }
917 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
918 }
919 if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
920 if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
921
922 /* A single chunk of text inserted on the right */
923 if( nPrefix+nSuffix==nLeft ){
924 sbsWriteLineno(p, lnLeft);
925 p->iStart2 = p->iEnd2 = 0;
@@ -1949,11 +1936,30 @@
1936 return 0;
1937 }
1938
1939 /* Compute the difference */
1940 diff_all(&c);
1941 if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
1942 int i, m, n;
1943 int *a = c.aEdit;
1944 int mx = c.nEdit;
1945 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1946 if( n>10000 ){
1947 fossil_free(c.aFrom);
1948 fossil_free(c.aTo);
1949 fossil_free(c.aEdit);
1950 if( diffFlags & DIFF_HTML ){
1951 blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
1952 }else{
1953 blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
1954 }
1955 return 0;
1956 }
1957 }
1958 if( (diffFlags & DIFF_NOOPT)==0 ){
1959 diff_optimize(&c);
1960 }
1961
1962 if( pOut ){
1963 /* Compute a context or side-by-side diff into pOut */
1964 if( diffFlags & DIFF_SIDEBYSIDE ){
1965 sbsDiff(&c, pOut, pRe, diffFlags);
1966
+6 -2
--- src/http.c
+++ src/http.c
@@ -130,11 +130,11 @@
130130
**
131131
** The server address is contain in the "g" global structure. The
132132
** url_parse() routine should have been called prior to this routine
133133
** in order to fill this structure appropriately.
134134
*/
135
-int http_exchange(Blob *pSend, Blob *pReply, int useLogin){
135
+int http_exchange(Blob *pSend, Blob *pReply, int useLogin, int maxRedirect){
136136
Blob login; /* The login card */
137137
Blob payload; /* The complete payload including login card */
138138
Blob hdr; /* The HTTP request header */
139139
int closeConnection; /* True to close the connection when done */
140140
int iLength; /* Length of the reply payload */
@@ -231,10 +231,14 @@
231231
}else if( c=='k' || c=='K' ){
232232
closeConnection = 0;
233233
}
234234
}else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){
235235
int i, j;
236
+
237
+ if ( --maxRedirect == 0){
238
+ fossil_fatal("redirect limit exceeded");
239
+ }
236240
for(i=9; zLine[i] && zLine[i]==' '; i++){}
237241
if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine);
238242
j = strlen(zLine) - 1;
239243
while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
240244
j -= 4;
@@ -241,11 +245,11 @@
241245
zLine[j] = 0;
242246
}
243247
fossil_print("redirect to %s\n", &zLine[i]);
244248
url_parse(&zLine[i]);
245249
transport_close();
246
- return http_exchange(pSend, pReply, useLogin);
250
+ return http_exchange(pSend, pReply, useLogin, maxRedirect);
247251
}else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
248252
if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
249253
isCompressed = 0;
250254
}else if( fossil_strnicmp(&zLine[14],
251255
"application/x-fossil-uncompressed", -1)==0 ){
252256
--- src/http.c
+++ src/http.c
@@ -130,11 +130,11 @@
130 **
131 ** The server address is contain in the "g" global structure. The
132 ** url_parse() routine should have been called prior to this routine
133 ** in order to fill this structure appropriately.
134 */
135 int http_exchange(Blob *pSend, Blob *pReply, int useLogin){
136 Blob login; /* The login card */
137 Blob payload; /* The complete payload including login card */
138 Blob hdr; /* The HTTP request header */
139 int closeConnection; /* True to close the connection when done */
140 int iLength; /* Length of the reply payload */
@@ -231,10 +231,14 @@
231 }else if( c=='k' || c=='K' ){
232 closeConnection = 0;
233 }
234 }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){
235 int i, j;
 
 
 
 
236 for(i=9; zLine[i] && zLine[i]==' '; i++){}
237 if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine);
238 j = strlen(zLine) - 1;
239 while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
240 j -= 4;
@@ -241,11 +245,11 @@
241 zLine[j] = 0;
242 }
243 fossil_print("redirect to %s\n", &zLine[i]);
244 url_parse(&zLine[i]);
245 transport_close();
246 return http_exchange(pSend, pReply, useLogin);
247 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
248 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
249 isCompressed = 0;
250 }else if( fossil_strnicmp(&zLine[14],
251 "application/x-fossil-uncompressed", -1)==0 ){
252
--- src/http.c
+++ src/http.c
@@ -130,11 +130,11 @@
130 **
131 ** The server address is contain in the "g" global structure. The
132 ** url_parse() routine should have been called prior to this routine
133 ** in order to fill this structure appropriately.
134 */
135 int http_exchange(Blob *pSend, Blob *pReply, int useLogin, int maxRedirect){
136 Blob login; /* The login card */
137 Blob payload; /* The complete payload including login card */
138 Blob hdr; /* The HTTP request header */
139 int closeConnection; /* True to close the connection when done */
140 int iLength; /* Length of the reply payload */
@@ -231,10 +231,14 @@
231 }else if( c=='k' || c=='K' ){
232 closeConnection = 0;
233 }
234 }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){
235 int i, j;
236
237 if ( --maxRedirect == 0){
238 fossil_fatal("redirect limit exceeded");
239 }
240 for(i=9; zLine[i] && zLine[i]==' '; i++){}
241 if( zLine[i]==0 ) fossil_fatal("malformed redirect: %s", zLine);
242 j = strlen(zLine) - 1;
243 while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
244 j -= 4;
@@ -241,11 +245,11 @@
245 zLine[j] = 0;
246 }
247 fossil_print("redirect to %s\n", &zLine[i]);
248 url_parse(&zLine[i]);
249 transport_close();
250 return http_exchange(pSend, pReply, useLogin, maxRedirect);
251 }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
252 if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
253 isCompressed = 0;
254 }else if( fossil_strnicmp(&zLine[14],
255 "application/x-fossil-uncompressed", -1)==0 ){
256
--- src/http_transport.c
+++ src/http_transport.c
@@ -183,10 +183,11 @@
183183
** and run an SSH command to talk to the remote machine.
184184
*/
185185
const char *zSsh; /* The base SSH command */
186186
Blob zCmd; /* The SSH command */
187187
char *zHost; /* The host name to contact */
188
+ int n; /* Size of prefix string */
188189
189190
zSsh = db_get("ssh-command", zDefaultSshCmd);
190191
blob_init(&zCmd, zSsh, -1);
191192
if( g.urlPort!=g.urlDfltPort ){
192193
#ifdef __MINGW32__
@@ -219,22 +220,63 @@
219220
}
220221
#endif
221222
}else{
222223
zHost = mprintf("%s", g.urlName);
223224
}
225
+ n = blob_size(&zCmd);
224226
blob_append(&zCmd, " ", 1);
225227
shell_escape(&zCmd, zHost);
226
- fossil_print(" %s\n", zHost); /* Show the conclusion of the SSH command */
228
+ if( g.urlShell ){
229
+ blob_appendf(&zCmd, " %s", g.urlShell);
230
+ }else{
231
+#if defined(FOSSIL_ENABLE_SSH_FAR_SIDE)
232
+ /* The following works. But only if the fossil on the remote side
233
+ ** is recent enough to support the test-ssh-far-side command. That
234
+ ** command was added on 2013-02-06. We will leave this turned off
235
+ ** until most fossil servers have upgraded to that version or a later
236
+ ** version. The sync will still work as long as the shell on the far
237
+ ** side is bash and not tcsh. And if the default far side shell is
238
+ ** tcsh, then the shell=/bin/bash query parameter can be used as a
239
+ ** work-around. Enable this code after about a year...
240
+ */
241
+ blob_appendf(&zCmd, " exec %s test-ssh-far-side", g.urlFossil);
242
+#endif
243
+ }
244
+ fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
227245
free(zHost);
228246
popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
229247
if( sshPid==0 ){
230248
fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
231249
}
232250
blob_reset(&zCmd);
233251
transport_ssh_startup();
234252
}
235253
}
254
+
255
+/*
256
+** COMMAND: test-ssh-far-side
257
+**
258
+** Read lines of input text, one by one, and evaluate each line using
259
+** system(). The ssh: sync protocol uses this on the far side of the
260
+** SSH link.
261
+*/
262
+void test_ssh_far_side_cmd(void){
263
+ int i = 0;
264
+ int got;
265
+ char zLine[5000];
266
+ while( i<sizeof(zLine) ){
267
+ got = read(0, zLine+i, 1);
268
+ if( got==0 ) return;
269
+ if( zLine[i]=='\n' ){
270
+ zLine[i] = 0;
271
+ system(zLine);
272
+ i = 0;
273
+ }else{
274
+ i++;
275
+ }
276
+ }
277
+}
236278
237279
/*
238280
** Open a connection to the server. The server is defined by the following
239281
** global variables:
240282
**
@@ -251,13 +293,13 @@
251293
Blob cmd;
252294
blob_zero(&cmd);
253295
shell_escape(&cmd, g.urlFossil);
254296
blob_append(&cmd, " test-http ", -1);
255297
shell_escape(&cmd, g.urlPath);
256
- /* printf("%s\n", blob_str(&cmd)); fflush(stdout); */
257
- fprintf(sshOut, "%s\n", blob_str(&cmd));
298
+ fprintf(sshOut, "%s || true\n", blob_str(&cmd));
258299
fflush(sshOut);
300
+ if( g.fSshTrace ) printf("Sent: [%s]\n", blob_str(&cmd));
259301
blob_reset(&cmd);
260302
}else if( g.urlIsHttps ){
261303
#ifdef FOSSIL_ENABLE_SSL
262304
rc = ssl_open();
263305
if( rc==0 ) transport.isOpen = 1;
@@ -270,11 +312,11 @@
270312
sqlite3_randomness(sizeof(iRandId), &iRandId);
271313
transport.zOutFile = mprintf("%s-%llu-out.http",
272314
g.zRepositoryName, iRandId);
273315
transport.zInFile = mprintf("%s-%llu-in.http",
274316
g.zRepositoryName, iRandId);
275
- transport.pFile = fopen(transport.zOutFile, "wb");
317
+ transport.pFile = fossil_fopen(transport.zOutFile, "wb");
276318
if( transport.pFile==0 ){
277319
fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
278320
}
279321
transport.isOpen = 1;
280322
}else{
@@ -367,11 +409,11 @@
367409
zCmd = mprintf("\"%s\" http \"%s\" \"%s\" \"%s\" 127.0.0.1 --localauth",
368410
g.nameOfExe, g.urlName, transport.zOutFile, transport.zInFile
369411
);
370412
fossil_system(zCmd);
371413
free(zCmd);
372
- transport.pFile = fopen(transport.zInFile, "rb");
414
+ transport.pFile = fossil_fopen(transport.zInFile, "rb");
373415
}
374416
}
375417
376418
/*
377419
** Log all input to a file. The transport layer will take responsibility
@@ -403,11 +445,10 @@
403445
int got;
404446
if( sshIn ){
405447
int x;
406448
int wanted = N;
407449
got = 0;
408
- /* printf("want %d bytes...\n", wanted); fflush(stdout); */
409450
while( wanted>0 ){
410451
x = read(sshIn, &zBuf[got], wanted);
411452
if( x<=0 ) break;
412453
got += x;
413454
wanted -= x;
@@ -438,11 +479,14 @@
438479
int transport_receive(char *zBuf, int N){
439480
int onHand; /* Bytes current held in the transport buffer */
440481
int nByte = 0; /* Bytes of content received */
441482
442483
onHand = transport.nUsed - transport.iCursor;
443
- /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout); */
484
+ if( g.fSshTrace){
485
+ printf("Reading %d bytes with %d on hand... ", N, onHand);
486
+ fflush(stdout);
487
+ }
444488
if( onHand>0 ){
445489
int toMove = onHand;
446490
if( toMove>N ) toMove = N;
447491
/* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
448492
memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
@@ -460,10 +504,11 @@
460504
if( got>0 ){
461505
nByte += got;
462506
transport.nRcvd += got;
463507
}
464508
}
509
+ if( g.fSshTrace ) printf("Got %d bytes\n", nByte);
465510
return nByte;
466511
}
467512
468513
/*
469514
** Load up to N new bytes of content into the transport.pBuf buffer.
@@ -532,11 +577,11 @@
532577
}
533578
break;
534579
}
535580
i++;
536581
}
537
- /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
582
+ if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]);
538583
return &transport.pBuf[iStart];
539584
}
540585
541586
void transport_global_shutdown(void){
542587
if( g.urlIsSsh && sshPid ){
543588
--- src/http_transport.c
+++ src/http_transport.c
@@ -183,10 +183,11 @@
183 ** and run an SSH command to talk to the remote machine.
184 */
185 const char *zSsh; /* The base SSH command */
186 Blob zCmd; /* The SSH command */
187 char *zHost; /* The host name to contact */
 
188
189 zSsh = db_get("ssh-command", zDefaultSshCmd);
190 blob_init(&zCmd, zSsh, -1);
191 if( g.urlPort!=g.urlDfltPort ){
192 #ifdef __MINGW32__
@@ -219,22 +220,63 @@
219 }
220 #endif
221 }else{
222 zHost = mprintf("%s", g.urlName);
223 }
 
224 blob_append(&zCmd, " ", 1);
225 shell_escape(&zCmd, zHost);
226 fossil_print(" %s\n", zHost); /* Show the conclusion of the SSH command */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227 free(zHost);
228 popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
229 if( sshPid==0 ){
230 fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
231 }
232 blob_reset(&zCmd);
233 transport_ssh_startup();
234 }
235 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
237 /*
238 ** Open a connection to the server. The server is defined by the following
239 ** global variables:
240 **
@@ -251,13 +293,13 @@
251 Blob cmd;
252 blob_zero(&cmd);
253 shell_escape(&cmd, g.urlFossil);
254 blob_append(&cmd, " test-http ", -1);
255 shell_escape(&cmd, g.urlPath);
256 /* printf("%s\n", blob_str(&cmd)); fflush(stdout); */
257 fprintf(sshOut, "%s\n", blob_str(&cmd));
258 fflush(sshOut);
 
259 blob_reset(&cmd);
260 }else if( g.urlIsHttps ){
261 #ifdef FOSSIL_ENABLE_SSL
262 rc = ssl_open();
263 if( rc==0 ) transport.isOpen = 1;
@@ -270,11 +312,11 @@
270 sqlite3_randomness(sizeof(iRandId), &iRandId);
271 transport.zOutFile = mprintf("%s-%llu-out.http",
272 g.zRepositoryName, iRandId);
273 transport.zInFile = mprintf("%s-%llu-in.http",
274 g.zRepositoryName, iRandId);
275 transport.pFile = fopen(transport.zOutFile, "wb");
276 if( transport.pFile==0 ){
277 fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
278 }
279 transport.isOpen = 1;
280 }else{
@@ -367,11 +409,11 @@
367 zCmd = mprintf("\"%s\" http \"%s\" \"%s\" \"%s\" 127.0.0.1 --localauth",
368 g.nameOfExe, g.urlName, transport.zOutFile, transport.zInFile
369 );
370 fossil_system(zCmd);
371 free(zCmd);
372 transport.pFile = fopen(transport.zInFile, "rb");
373 }
374 }
375
376 /*
377 ** Log all input to a file. The transport layer will take responsibility
@@ -403,11 +445,10 @@
403 int got;
404 if( sshIn ){
405 int x;
406 int wanted = N;
407 got = 0;
408 /* printf("want %d bytes...\n", wanted); fflush(stdout); */
409 while( wanted>0 ){
410 x = read(sshIn, &zBuf[got], wanted);
411 if( x<=0 ) break;
412 got += x;
413 wanted -= x;
@@ -438,11 +479,14 @@
438 int transport_receive(char *zBuf, int N){
439 int onHand; /* Bytes current held in the transport buffer */
440 int nByte = 0; /* Bytes of content received */
441
442 onHand = transport.nUsed - transport.iCursor;
443 /* printf("request %d with %d on hand\n", N, onHand); fflush(stdout); */
 
 
 
444 if( onHand>0 ){
445 int toMove = onHand;
446 if( toMove>N ) toMove = N;
447 /* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
448 memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
@@ -460,10 +504,11 @@
460 if( got>0 ){
461 nByte += got;
462 transport.nRcvd += got;
463 }
464 }
 
465 return nByte;
466 }
467
468 /*
469 ** Load up to N new bytes of content into the transport.pBuf buffer.
@@ -532,11 +577,11 @@
532 }
533 break;
534 }
535 i++;
536 }
537 /* printf("Got line: [%s]\n", &transport.pBuf[iStart]); */
538 return &transport.pBuf[iStart];
539 }
540
541 void transport_global_shutdown(void){
542 if( g.urlIsSsh && sshPid ){
543
--- src/http_transport.c
+++ src/http_transport.c
@@ -183,10 +183,11 @@
183 ** and run an SSH command to talk to the remote machine.
184 */
185 const char *zSsh; /* The base SSH command */
186 Blob zCmd; /* The SSH command */
187 char *zHost; /* The host name to contact */
188 int n; /* Size of prefix string */
189
190 zSsh = db_get("ssh-command", zDefaultSshCmd);
191 blob_init(&zCmd, zSsh, -1);
192 if( g.urlPort!=g.urlDfltPort ){
193 #ifdef __MINGW32__
@@ -219,22 +220,63 @@
220 }
221 #endif
222 }else{
223 zHost = mprintf("%s", g.urlName);
224 }
225 n = blob_size(&zCmd);
226 blob_append(&zCmd, " ", 1);
227 shell_escape(&zCmd, zHost);
228 if( g.urlShell ){
229 blob_appendf(&zCmd, " %s", g.urlShell);
230 }else{
231 #if defined(FOSSIL_ENABLE_SSH_FAR_SIDE)
232 /* The following works. But only if the fossil on the remote side
233 ** is recent enough to support the test-ssh-far-side command. That
234 ** command was added on 2013-02-06. We will leave this turned off
235 ** until most fossil servers have upgraded to that version or a later
236 ** version. The sync will still work as long as the shell on the far
237 ** side is bash and not tcsh. And if the default far side shell is
238 ** tcsh, then the shell=/bin/bash query parameter can be used as a
239 ** work-around. Enable this code after about a year...
240 */
241 blob_appendf(&zCmd, " exec %s test-ssh-far-side", g.urlFossil);
242 #endif
243 }
244 fossil_print("%s\n", blob_str(&zCmd)+n); /* Show tail of SSH command */
245 free(zHost);
246 popen2(blob_str(&zCmd), &sshIn, &sshOut, &sshPid);
247 if( sshPid==0 ){
248 fossil_fatal("cannot start ssh tunnel using [%b]", &zCmd);
249 }
250 blob_reset(&zCmd);
251 transport_ssh_startup();
252 }
253 }
254
255 /*
256 ** COMMAND: test-ssh-far-side
257 **
258 ** Read lines of input text, one by one, and evaluate each line using
259 ** system(). The ssh: sync protocol uses this on the far side of the
260 ** SSH link.
261 */
262 void test_ssh_far_side_cmd(void){
263 int i = 0;
264 int got;
265 char zLine[5000];
266 while( i<sizeof(zLine) ){
267 got = read(0, zLine+i, 1);
268 if( got==0 ) return;
269 if( zLine[i]=='\n' ){
270 zLine[i] = 0;
271 system(zLine);
272 i = 0;
273 }else{
274 i++;
275 }
276 }
277 }
278
279 /*
280 ** Open a connection to the server. The server is defined by the following
281 ** global variables:
282 **
@@ -251,13 +293,13 @@
293 Blob cmd;
294 blob_zero(&cmd);
295 shell_escape(&cmd, g.urlFossil);
296 blob_append(&cmd, " test-http ", -1);
297 shell_escape(&cmd, g.urlPath);
298 fprintf(sshOut, "%s || true\n", blob_str(&cmd));
 
299 fflush(sshOut);
300 if( g.fSshTrace ) printf("Sent: [%s]\n", blob_str(&cmd));
301 blob_reset(&cmd);
302 }else if( g.urlIsHttps ){
303 #ifdef FOSSIL_ENABLE_SSL
304 rc = ssl_open();
305 if( rc==0 ) transport.isOpen = 1;
@@ -270,11 +312,11 @@
312 sqlite3_randomness(sizeof(iRandId), &iRandId);
313 transport.zOutFile = mprintf("%s-%llu-out.http",
314 g.zRepositoryName, iRandId);
315 transport.zInFile = mprintf("%s-%llu-in.http",
316 g.zRepositoryName, iRandId);
317 transport.pFile = fossil_fopen(transport.zOutFile, "wb");
318 if( transport.pFile==0 ){
319 fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
320 }
321 transport.isOpen = 1;
322 }else{
@@ -367,11 +409,11 @@
409 zCmd = mprintf("\"%s\" http \"%s\" \"%s\" \"%s\" 127.0.0.1 --localauth",
410 g.nameOfExe, g.urlName, transport.zOutFile, transport.zInFile
411 );
412 fossil_system(zCmd);
413 free(zCmd);
414 transport.pFile = fossil_fopen(transport.zInFile, "rb");
415 }
416 }
417
418 /*
419 ** Log all input to a file. The transport layer will take responsibility
@@ -403,11 +445,10 @@
445 int got;
446 if( sshIn ){
447 int x;
448 int wanted = N;
449 got = 0;
 
450 while( wanted>0 ){
451 x = read(sshIn, &zBuf[got], wanted);
452 if( x<=0 ) break;
453 got += x;
454 wanted -= x;
@@ -438,11 +479,14 @@
479 int transport_receive(char *zBuf, int N){
480 int onHand; /* Bytes current held in the transport buffer */
481 int nByte = 0; /* Bytes of content received */
482
483 onHand = transport.nUsed - transport.iCursor;
484 if( g.fSshTrace){
485 printf("Reading %d bytes with %d on hand... ", N, onHand);
486 fflush(stdout);
487 }
488 if( onHand>0 ){
489 int toMove = onHand;
490 if( toMove>N ) toMove = N;
491 /* printf("bytes on hand: %d of %d\n", toMove, N); fflush(stdout); */
492 memcpy(zBuf, &transport.pBuf[transport.iCursor], toMove);
@@ -460,10 +504,11 @@
504 if( got>0 ){
505 nByte += got;
506 transport.nRcvd += got;
507 }
508 }
509 if( g.fSshTrace ) printf("Got %d bytes\n", nByte);
510 return nByte;
511 }
512
513 /*
514 ** Load up to N new bytes of content into the transport.pBuf buffer.
@@ -532,11 +577,11 @@
577 }
578 break;
579 }
580 i++;
581 }
582 if( g.fSshTrace ) printf("Got line: [%s]\n", &transport.pBuf[iStart]);
583 return &transport.pBuf[iStart];
584 }
585
586 void transport_global_shutdown(void){
587 if( g.urlIsSsh && sshPid ){
588
+3 -61
--- src/info.c
+++ src/info.c
@@ -314,16 +314,17 @@
314314
}else{
315315
blob_zero(&to);
316316
}
317317
blob_zero(&out);
318318
if( diffFlags & DIFF_SIDEBYSIDE ){
319
- text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML);
319
+ text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
320320
@ <div class="sbsdiff">
321321
@ %s(blob_str(&out))
322322
@ </div>
323323
}else{
324
- text_diff(&from, &to, &out, pRe, diffFlags | DIFF_LINENO | DIFF_HTML);
324
+ text_diff(&from, &to, &out, pRe,
325
+ diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
325326
@ <div class="udiff">
326327
@ %s(blob_str(&out))
327328
@ </div>
328329
}
329330
blob_reset(&from);
@@ -491,15 +492,10 @@
491492
char *zEUser, *zEComment;
492493
const char *zUser;
493494
const char *zComment;
494495
const char *zDate;
495496
const char *zOrigDate;
496
-#if 0
497
- char *zThisBranch;
498
- double thisMtime;
499
- int seenDiffTitle = 0;
500
-#endif
501497
502498
style_header(zTitle);
503499
login_anonymous_available();
504500
free(zTitle);
505501
zEUser = db_text(0,
@@ -510,13 +506,10 @@
510506
TAG_COMMENT, rid);
511507
zUser = db_column_text(&q, 2);
512508
zComment = db_column_text(&q, 3);
513509
zDate = db_column_text(&q,1);
514510
zOrigDate = db_column_text(&q, 4);
515
-#if 0
516
- thisMtime = db_column_double(&q, 5);
517
-#endif
518511
@ <div class="section">Overview</div>
519512
@ <table class="label-value">
520513
@ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
521514
if( g.perm.Setup ){
522515
@ (Record ID: %d(rid))
@@ -581,61 +574,10 @@
581574
const char *zTagName = db_column_text(&q, 0);
582575
@ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
583576
}
584577
db_finalize(&q);
585578
586
-#if 0
587
- /* Select a few other branches to diff against */
588
- zThisBranch = db_text("trunk", "SELECT value FROM tagxref"
589
- " WHERE tagid=%d AND tagtype>0"
590
- " AND rid=%d",
591
- TAG_BRANCH, rid);
592
-
593
- /* Find nearby leaves to offer to diff against */
594
- db_prepare(&q,
595
- "SELECT tagxref.value, blob.uuid, min(%.17g-event.mtime)"
596
- " FROM leaf, event, tagxref, blob"
597
- " WHERE event.mtime BETWEEN %.17g AND %.17g"
598
- " AND event.type='ci'"
599
- " AND event.objid=leaf.rid"
600
- " AND NOT %z"
601
- " AND tagxref.rid=event.objid"
602
- " AND tagxref.tagid=%d AND tagxref.tagtype>0"
603
- " AND tagxref.value!=%Q"
604
- " AND blob.rid=tagxref.rid"
605
- " GROUP BY 1 ORDER BY 3",
606
- thisMtime, thisMtime-7, thisMtime+7,
607
- leaf_is_closed_sql("leaf.rid"),
608
- TAG_BRANCH, zThisBranch
609
- );
610
- while( db_step(&q)==SQLITE_ROW ){
611
- const char *zBr = db_column_text(&q, 0);
612
- const char *zId = db_column_text(&q, 1);
613
- if( !seenDiffTitle ){
614
- @ <tr><th valign="top">Diffs:</th><td valign="top">
615
- seenDiffTitle = 1;
616
- }else{
617
- @ |
618
- }
619
- @ %z(href("%R/vdiff?from=%S&to=%S",zId, zUuid))%h(zBr)</a>
620
- }
621
- db_finalize(&q);
622
-
623
- if( fossil_strcmp(zThisBranch,"trunk")!=0 ){
624
- if( !seenDiffTitle ){
625
- @ <tr><th valign="top">Diffs:</th><td valign="top">
626
- seenDiffTitle = 1;
627
- }else{
628
- @ |
629
- }
630
- @ %z(href("%R/vdiff?from=root:%S&to=%S",zUuid,zUuid))root of
631
- @ this branch</a>
632
- }
633
- if( seenDiffTitle ){
634
- @ </td></tr>
635
- }
636
-#endif
637579
638580
/* The Download: line */
639581
if( g.perm.Zip ){
640582
char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s",
641583
zProjName, zUuid, zUuid);
642584
--- src/info.c
+++ src/info.c
@@ -314,16 +314,17 @@
314 }else{
315 blob_zero(&to);
316 }
317 blob_zero(&out);
318 if( diffFlags & DIFF_SIDEBYSIDE ){
319 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML);
320 @ <div class="sbsdiff">
321 @ %s(blob_str(&out))
322 @ </div>
323 }else{
324 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_LINENO | DIFF_HTML);
 
325 @ <div class="udiff">
326 @ %s(blob_str(&out))
327 @ </div>
328 }
329 blob_reset(&from);
@@ -491,15 +492,10 @@
491 char *zEUser, *zEComment;
492 const char *zUser;
493 const char *zComment;
494 const char *zDate;
495 const char *zOrigDate;
496 #if 0
497 char *zThisBranch;
498 double thisMtime;
499 int seenDiffTitle = 0;
500 #endif
501
502 style_header(zTitle);
503 login_anonymous_available();
504 free(zTitle);
505 zEUser = db_text(0,
@@ -510,13 +506,10 @@
510 TAG_COMMENT, rid);
511 zUser = db_column_text(&q, 2);
512 zComment = db_column_text(&q, 3);
513 zDate = db_column_text(&q,1);
514 zOrigDate = db_column_text(&q, 4);
515 #if 0
516 thisMtime = db_column_double(&q, 5);
517 #endif
518 @ <div class="section">Overview</div>
519 @ <table class="label-value">
520 @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
521 if( g.perm.Setup ){
522 @ (Record ID: %d(rid))
@@ -581,61 +574,10 @@
581 const char *zTagName = db_column_text(&q, 0);
582 @ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
583 }
584 db_finalize(&q);
585
586 #if 0
587 /* Select a few other branches to diff against */
588 zThisBranch = db_text("trunk", "SELECT value FROM tagxref"
589 " WHERE tagid=%d AND tagtype>0"
590 " AND rid=%d",
591 TAG_BRANCH, rid);
592
593 /* Find nearby leaves to offer to diff against */
594 db_prepare(&q,
595 "SELECT tagxref.value, blob.uuid, min(%.17g-event.mtime)"
596 " FROM leaf, event, tagxref, blob"
597 " WHERE event.mtime BETWEEN %.17g AND %.17g"
598 " AND event.type='ci'"
599 " AND event.objid=leaf.rid"
600 " AND NOT %z"
601 " AND tagxref.rid=event.objid"
602 " AND tagxref.tagid=%d AND tagxref.tagtype>0"
603 " AND tagxref.value!=%Q"
604 " AND blob.rid=tagxref.rid"
605 " GROUP BY 1 ORDER BY 3",
606 thisMtime, thisMtime-7, thisMtime+7,
607 leaf_is_closed_sql("leaf.rid"),
608 TAG_BRANCH, zThisBranch
609 );
610 while( db_step(&q)==SQLITE_ROW ){
611 const char *zBr = db_column_text(&q, 0);
612 const char *zId = db_column_text(&q, 1);
613 if( !seenDiffTitle ){
614 @ <tr><th valign="top">Diffs:</th><td valign="top">
615 seenDiffTitle = 1;
616 }else{
617 @ |
618 }
619 @ %z(href("%R/vdiff?from=%S&to=%S",zId, zUuid))%h(zBr)</a>
620 }
621 db_finalize(&q);
622
623 if( fossil_strcmp(zThisBranch,"trunk")!=0 ){
624 if( !seenDiffTitle ){
625 @ <tr><th valign="top">Diffs:</th><td valign="top">
626 seenDiffTitle = 1;
627 }else{
628 @ |
629 }
630 @ %z(href("%R/vdiff?from=root:%S&to=%S",zUuid,zUuid))root of
631 @ this branch</a>
632 }
633 if( seenDiffTitle ){
634 @ </td></tr>
635 }
636 #endif
637
638 /* The Download: line */
639 if( g.perm.Zip ){
640 char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s",
641 zProjName, zUuid, zUuid);
642
--- src/info.c
+++ src/info.c
@@ -314,16 +314,17 @@
314 }else{
315 blob_zero(&to);
316 }
317 blob_zero(&out);
318 if( diffFlags & DIFF_SIDEBYSIDE ){
319 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
320 @ <div class="sbsdiff">
321 @ %s(blob_str(&out))
322 @ </div>
323 }else{
324 text_diff(&from, &to, &out, pRe,
325 diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
326 @ <div class="udiff">
327 @ %s(blob_str(&out))
328 @ </div>
329 }
330 blob_reset(&from);
@@ -491,15 +492,10 @@
492 char *zEUser, *zEComment;
493 const char *zUser;
494 const char *zComment;
495 const char *zDate;
496 const char *zOrigDate;
 
 
 
 
 
497
498 style_header(zTitle);
499 login_anonymous_available();
500 free(zTitle);
501 zEUser = db_text(0,
@@ -510,13 +506,10 @@
506 TAG_COMMENT, rid);
507 zUser = db_column_text(&q, 2);
508 zComment = db_column_text(&q, 3);
509 zDate = db_column_text(&q,1);
510 zOrigDate = db_column_text(&q, 4);
 
 
 
511 @ <div class="section">Overview</div>
512 @ <table class="label-value">
513 @ <tr><th>SHA1&nbsp;Hash:</th><td>%s(zUuid)
514 if( g.perm.Setup ){
515 @ (Record ID: %d(rid))
@@ -581,61 +574,10 @@
574 const char *zTagName = db_column_text(&q, 0);
575 @ | %z(href("%R/timeline?r=%T",zTagName))%h(zTagName)</a>
576 }
577 db_finalize(&q);
578
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
579
580 /* The Download: line */
581 if( g.perm.Zip ){
582 char *zUrl = mprintf("%R/tarball/%t-%S.tar.gz?uuid=%s",
583 zProjName, zUuid, zUuid);
584
--- src/json_detail.h
+++ src/json_detail.h
@@ -199,11 +199,11 @@
199199
char const * requestId;
200200
char const * resultCode;
201201
char const * resultText;
202202
char const * timestamp;
203203
} FossilJsonKeys_;
204
-const FossilJsonKeys_ FossilJsonKeys;
204
+extern const FossilJsonKeys_ FossilJsonKeys;
205205
206206
/*
207207
** A page/command dispatch helper for fossil_json_f() implementations.
208208
** pages must be an array of JsonPageDef commands which we can
209209
** dispatch. The final item in the array MUST have a NULL name
210210
--- src/json_detail.h
+++ src/json_detail.h
@@ -199,11 +199,11 @@
199 char const * requestId;
200 char const * resultCode;
201 char const * resultText;
202 char const * timestamp;
203 } FossilJsonKeys_;
204 const FossilJsonKeys_ FossilJsonKeys;
205
206 /*
207 ** A page/command dispatch helper for fossil_json_f() implementations.
208 ** pages must be an array of JsonPageDef commands which we can
209 ** dispatch. The final item in the array MUST have a NULL name
210
--- src/json_detail.h
+++ src/json_detail.h
@@ -199,11 +199,11 @@
199 char const * requestId;
200 char const * resultCode;
201 char const * resultText;
202 char const * timestamp;
203 } FossilJsonKeys_;
204 extern const FossilJsonKeys_ FossilJsonKeys;
205
206 /*
207 ** A page/command dispatch helper for fossil_json_f() implementations.
208 ** pages must be an array of JsonPageDef commands which we can
209 ** dispatch. The final item in the array MUST have a NULL name
210
+3 -5
--- src/main.c
+++ src/main.c
@@ -170,11 +170,12 @@
170170
char *urlPath; /* Pathname for http: */
171171
char *urlUser; /* User id for http: */
172172
char *urlPasswd; /* Password for http: */
173173
char *urlCanonical; /* Canonical representation of the URL */
174174
char *urlProxyAuth; /* Proxy-Authorizer: string */
175
- char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */
175
+ char *urlFossil; /* The fossil query parameter on ssh: */
176
+ char *urlShell; /* The shell query parameter on ssh: */
176177
int dontKeepUrl; /* Do not persist the URL */
177178
178179
const char *zLogin; /* Login name. "" if not logged in. */
179180
const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */
180181
int useLocalauth; /* No login required if from 127.0.0.1 */
@@ -251,14 +252,11 @@
251252
} cmd;
252253
struct { /* JSON POST data. */
253254
cson_value * v;
254255
cson_object * o;
255256
} post;
256
- struct { /* GET/COOKIE params in JSON mode.
257
- FIXME (stephan): verify that this is
258
- still used and remove if it is not.
259
- */
257
+ struct { /* GET/COOKIE params in JSON mode. */
260258
cson_value * v;
261259
cson_object * o;
262260
} param;
263261
struct {
264262
cson_value * v;
265263
--- src/main.c
+++ src/main.c
@@ -170,11 +170,12 @@
170 char *urlPath; /* Pathname for http: */
171 char *urlUser; /* User id for http: */
172 char *urlPasswd; /* Password for http: */
173 char *urlCanonical; /* Canonical representation of the URL */
174 char *urlProxyAuth; /* Proxy-Authorizer: string */
175 char *urlFossil; /* The path of the ?fossil=path suffix on ssh: */
 
176 int dontKeepUrl; /* Do not persist the URL */
177
178 const char *zLogin; /* Login name. "" if not logged in. */
179 const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */
180 int useLocalauth; /* No login required if from 127.0.0.1 */
@@ -251,14 +252,11 @@
251 } cmd;
252 struct { /* JSON POST data. */
253 cson_value * v;
254 cson_object * o;
255 } post;
256 struct { /* GET/COOKIE params in JSON mode.
257 FIXME (stephan): verify that this is
258 still used and remove if it is not.
259 */
260 cson_value * v;
261 cson_object * o;
262 } param;
263 struct {
264 cson_value * v;
265
--- src/main.c
+++ src/main.c
@@ -170,11 +170,12 @@
170 char *urlPath; /* Pathname for http: */
171 char *urlUser; /* User id for http: */
172 char *urlPasswd; /* Password for http: */
173 char *urlCanonical; /* Canonical representation of the URL */
174 char *urlProxyAuth; /* Proxy-Authorizer: string */
175 char *urlFossil; /* The fossil query parameter on ssh: */
176 char *urlShell; /* The shell query parameter on ssh: */
177 int dontKeepUrl; /* Do not persist the URL */
178
179 const char *zLogin; /* Login name. "" if not logged in. */
180 const char *zSSLIdentity; /* Value of --ssl-identity option, filename of SSL client identity */
181 int useLocalauth; /* No login required if from 127.0.0.1 */
@@ -251,14 +252,11 @@
252 } cmd;
253 struct { /* JSON POST data. */
254 cson_value * v;
255 cson_object * o;
256 } post;
257 struct { /* GET/COOKIE params in JSON mode. */
 
 
 
258 cson_value * v;
259 cson_object * o;
260 } param;
261 struct {
262 cson_value * v;
263
+55 -21
--- src/shell.c
+++ src/shell.c
@@ -1484,10 +1484,16 @@
14841484
{
14851485
extern int sqlite3_add_regexp_func(sqlite3*);
14861486
sqlite3_add_regexp_func(db);
14871487
}
14881488
#endif
1489
+#ifdef SQLITE_ENABLE_SPELLFIX
1490
+ {
1491
+ extern int sqlite3_spellfix1_register(sqlite3*);
1492
+ sqlite3_spellfix1_register(db);
1493
+ }
1494
+#endif
14891495
}
14901496
}
14911497
14921498
/*
14931499
** Do C-language style dequoting.
@@ -1529,21 +1535,22 @@
15291535
15301536
/*
15311537
** Interpret zArg as a boolean value. Return either 0 or 1.
15321538
*/
15331539
static int booleanValue(char *zArg){
1534
- int val = atoi(zArg);
1535
- int j;
1536
- for(j=0; zArg[j]; j++){
1537
- zArg[j] = ToLower(zArg[j]);
1538
- }
1539
- if( strcmp(zArg,"on")==0 ){
1540
- val = 1;
1541
- }else if( strcmp(zArg,"yes")==0 ){
1542
- val = 1;
1543
- }
1544
- return val;
1540
+ int i;
1541
+ for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1542
+ if( i>0 && zArg[i]==0 ) return atoi(zArg);
1543
+ if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1544
+ return 1;
1545
+ }
1546
+ if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1547
+ return 0;
1548
+ }
1549
+ fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1550
+ zArg);
1551
+ return 0;
15451552
}
15461553
15471554
/*
15481555
** Close an output file, assuming it is not stderr or stdout
15491556
*/
@@ -1627,28 +1634,54 @@
16271634
/* Process the input line.
16281635
*/
16291636
if( nArg==0 ) return 0; /* no tokens, no error */
16301637
n = strlen30(azArg[0]);
16311638
c = azArg[0][0];
1632
- if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
1633
- const char *zDestFile;
1634
- const char *zDb;
1639
+ if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1640
+ const char *zDestFile = 0;
1641
+ const char *zDb = 0;
1642
+ const char *zKey = 0;
16351643
sqlite3 *pDest;
16361644
sqlite3_backup *pBackup;
1637
- if( nArg==2 ){
1638
- zDestFile = azArg[1];
1639
- zDb = "main";
1640
- }else{
1641
- zDestFile = azArg[2];
1642
- zDb = azArg[1];
1645
+ int j;
1646
+ for(j=1; j<nArg; j++){
1647
+ const char *z = azArg[j];
1648
+ if( z[0]=='-' ){
1649
+ while( z[0]=='-' ) z++;
1650
+ if( strcmp(z,"key")==0 && j<nArg-1 ){
1651
+ zKey = azArg[++j];
1652
+ }else
1653
+ {
1654
+ fprintf(stderr, "unknown option: %s\n", azArg[j]);
1655
+ return 1;
1656
+ }
1657
+ }else if( zDestFile==0 ){
1658
+ zDestFile = azArg[j];
1659
+ }else if( zDb==0 ){
1660
+ zDb = zDestFile;
1661
+ zDestFile = azArg[j];
1662
+ }else{
1663
+ fprintf(stderr, "too many arguments to .backup\n");
1664
+ return 1;
1665
+ }
1666
+ }
1667
+ if( zDestFile==0 ){
1668
+ fprintf(stderr, "missing FILENAME argument on .backup\n");
1669
+ return 1;
16431670
}
1671
+ if( zDb==0 ) zDb = "main";
16441672
rc = sqlite3_open(zDestFile, &pDest);
16451673
if( rc!=SQLITE_OK ){
16461674
fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
16471675
sqlite3_close(pDest);
16481676
return 1;
16491677
}
1678
+#ifdef SQLITE_HAS_CODEC
1679
+ sqlite3_key(pDest, zKey, (int)strlen(zKey));
1680
+#else
1681
+ (void)zKey;
1682
+#endif
16501683
open_db(p);
16511684
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
16521685
if( pBackup==0 ){
16531686
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
16541687
sqlite3_close(pDest);
@@ -1746,11 +1779,12 @@
17461779
17471780
if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
17481781
p->echoOn = booleanValue(azArg[1]);
17491782
}else
17501783
1751
- if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
1784
+ if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
1785
+ if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc);
17521786
rc = 2;
17531787
}else
17541788
17551789
if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
17561790
int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
17571791
--- src/shell.c
+++ src/shell.c
@@ -1484,10 +1484,16 @@
1484 {
1485 extern int sqlite3_add_regexp_func(sqlite3*);
1486 sqlite3_add_regexp_func(db);
1487 }
1488 #endif
 
 
 
 
 
 
1489 }
1490 }
1491
1492 /*
1493 ** Do C-language style dequoting.
@@ -1529,21 +1535,22 @@
1529
1530 /*
1531 ** Interpret zArg as a boolean value. Return either 0 or 1.
1532 */
1533 static int booleanValue(char *zArg){
1534 int val = atoi(zArg);
1535 int j;
1536 for(j=0; zArg[j]; j++){
1537 zArg[j] = ToLower(zArg[j]);
1538 }
1539 if( strcmp(zArg,"on")==0 ){
1540 val = 1;
1541 }else if( strcmp(zArg,"yes")==0 ){
1542 val = 1;
1543 }
1544 return val;
 
1545 }
1546
1547 /*
1548 ** Close an output file, assuming it is not stderr or stdout
1549 */
@@ -1627,28 +1634,54 @@
1627 /* Process the input line.
1628 */
1629 if( nArg==0 ) return 0; /* no tokens, no error */
1630 n = strlen30(azArg[0]);
1631 c = azArg[0][0];
1632 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 && nArg>1 && nArg<4){
1633 const char *zDestFile;
1634 const char *zDb;
 
1635 sqlite3 *pDest;
1636 sqlite3_backup *pBackup;
1637 if( nArg==2 ){
1638 zDestFile = azArg[1];
1639 zDb = "main";
1640 }else{
1641 zDestFile = azArg[2];
1642 zDb = azArg[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1643 }
 
1644 rc = sqlite3_open(zDestFile, &pDest);
1645 if( rc!=SQLITE_OK ){
1646 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1647 sqlite3_close(pDest);
1648 return 1;
1649 }
 
 
 
 
 
1650 open_db(p);
1651 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1652 if( pBackup==0 ){
1653 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1654 sqlite3_close(pDest);
@@ -1746,11 +1779,12 @@
1746
1747 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
1748 p->echoOn = booleanValue(azArg[1]);
1749 }else
1750
1751 if( c=='e' && strncmp(azArg[0], "exit", n)==0 && nArg==1 ){
 
1752 rc = 2;
1753 }else
1754
1755 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
1756 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
1757
--- src/shell.c
+++ src/shell.c
@@ -1484,10 +1484,16 @@
1484 {
1485 extern int sqlite3_add_regexp_func(sqlite3*);
1486 sqlite3_add_regexp_func(db);
1487 }
1488 #endif
1489 #ifdef SQLITE_ENABLE_SPELLFIX
1490 {
1491 extern int sqlite3_spellfix1_register(sqlite3*);
1492 sqlite3_spellfix1_register(db);
1493 }
1494 #endif
1495 }
1496 }
1497
1498 /*
1499 ** Do C-language style dequoting.
@@ -1529,21 +1535,22 @@
1535
1536 /*
1537 ** Interpret zArg as a boolean value. Return either 0 or 1.
1538 */
1539 static int booleanValue(char *zArg){
1540 int i;
1541 for(i=0; zArg[i]>='0' && zArg[i]<='9'; i++){}
1542 if( i>0 && zArg[i]==0 ) return atoi(zArg);
1543 if( sqlite3_stricmp(zArg, "on")==0 || sqlite3_stricmp(zArg,"yes")==0 ){
1544 return 1;
1545 }
1546 if( sqlite3_stricmp(zArg, "off")==0 || sqlite3_stricmp(zArg,"no")==0 ){
1547 return 0;
1548 }
1549 fprintf(stderr, "ERROR: Not a boolean value: \"%s\". Assuming \"no\".\n",
1550 zArg);
1551 return 0;
1552 }
1553
1554 /*
1555 ** Close an output file, assuming it is not stderr or stdout
1556 */
@@ -1627,28 +1634,54 @@
1634 /* Process the input line.
1635 */
1636 if( nArg==0 ) return 0; /* no tokens, no error */
1637 n = strlen30(azArg[0]);
1638 c = azArg[0][0];
1639 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1640 const char *zDestFile = 0;
1641 const char *zDb = 0;
1642 const char *zKey = 0;
1643 sqlite3 *pDest;
1644 sqlite3_backup *pBackup;
1645 int j;
1646 for(j=1; j<nArg; j++){
1647 const char *z = azArg[j];
1648 if( z[0]=='-' ){
1649 while( z[0]=='-' ) z++;
1650 if( strcmp(z,"key")==0 && j<nArg-1 ){
1651 zKey = azArg[++j];
1652 }else
1653 {
1654 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1655 return 1;
1656 }
1657 }else if( zDestFile==0 ){
1658 zDestFile = azArg[j];
1659 }else if( zDb==0 ){
1660 zDb = zDestFile;
1661 zDestFile = azArg[j];
1662 }else{
1663 fprintf(stderr, "too many arguments to .backup\n");
1664 return 1;
1665 }
1666 }
1667 if( zDestFile==0 ){
1668 fprintf(stderr, "missing FILENAME argument on .backup\n");
1669 return 1;
1670 }
1671 if( zDb==0 ) zDb = "main";
1672 rc = sqlite3_open(zDestFile, &pDest);
1673 if( rc!=SQLITE_OK ){
1674 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1675 sqlite3_close(pDest);
1676 return 1;
1677 }
1678 #ifdef SQLITE_HAS_CODEC
1679 sqlite3_key(pDest, zKey, (int)strlen(zKey));
1680 #else
1681 (void)zKey;
1682 #endif
1683 open_db(p);
1684 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1685 if( pBackup==0 ){
1686 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1687 sqlite3_close(pDest);
@@ -1746,11 +1779,12 @@
1779
1780 if( c=='e' && strncmp(azArg[0], "echo", n)==0 && nArg>1 && nArg<3 ){
1781 p->echoOn = booleanValue(azArg[1]);
1782 }else
1783
1784 if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
1785 if( nArg>1 && (rc = atoi(azArg[1]))!=0 ) exit(rc);
1786 rc = 2;
1787 }else
1788
1789 if( c=='e' && strncmp(azArg[0], "explain", n)==0 && nArg<3 ){
1790 int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
1791
+178 -107
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -673,11 +673,11 @@
673673
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674674
** [sqlite_version()] and [sqlite_source_id()].
675675
*/
676676
#define SQLITE_VERSION "3.7.16"
677677
#define SQLITE_VERSION_NUMBER 3007016
678
-#define SQLITE_SOURCE_ID "2013-01-17 17:20:49 38852f158ab20bb4d7b264af987ec1538052bec3"
678
+#define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
679679
680680
/*
681681
** CAPI3REF: Run-Time Library Version Numbers
682682
** KEYWORDS: sqlite3_version, sqlite3_sourceid
683683
**
@@ -1048,10 +1048,19 @@
10481048
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
10491049
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
10501050
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
10511051
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
10521052
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
1053
+#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
1054
+#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
1055
+#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
1056
+#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
1057
+#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
1058
+#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
1059
+#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
1060
+#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
1061
+#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
10531062
10541063
/*
10551064
** CAPI3REF: Flags For File Open Operations
10561065
**
10571066
** These bit values are intended for use in the
@@ -10018,11 +10027,11 @@
1001810027
#define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
1001910028
/* result set is empty */
1002010029
#define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
1002110030
#define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
1002210031
#define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
10023
- /* 0x00000200 Unused */
10032
+#define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */
1002410033
#define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
1002510034
#define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
1002610035
#define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
1002710036
#define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
1002810037
#define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
@@ -11034,10 +11043,11 @@
1103411043
struct {
1103511044
int nIn; /* Number of entries in aInLoop[] */
1103611045
struct InLoop {
1103711046
int iCur; /* The VDBE cursor used by this IN operator */
1103811047
int addrInTop; /* Top of the IN loop */
11048
+ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
1103911049
} *aInLoop; /* Information about each nested IN operator */
1104011050
} in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
1104111051
Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
1104211052
} u;
1104311053
double rOptCost; /* "Optimal" cost for this level */
@@ -11973,11 +11983,11 @@
1197311983
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
1197411984
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
1197511985
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
1197611986
SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
1197711987
SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
11978
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int);
11988
+SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, int);
1197911989
SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
1198011990
SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
1198111991
SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
1198211992
SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
1198311993
SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
@@ -13208,11 +13218,11 @@
1320813218
Mem *aMem; /* Array of memory cells for parent frame */
1320913219
u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
1321013220
VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
1321113221
void *token; /* Copy of SubProgram.token */
1321213222
i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
13213
- u16 nCursor; /* Number of entries in apCsr */
13223
+ int nCursor; /* Number of entries in apCsr */
1321413224
int pc; /* Program Counter in parent (calling) frame */
1321513225
int nOp; /* Size of aOp array */
1321613226
int nMem; /* Number of entries in aMem */
1321713227
int nOnceFlag; /* Number of entries in aOnceFlag */
1321813228
int nChildMem; /* Number of memory cells for child frame */
@@ -13394,11 +13404,11 @@
1339413404
int nOp; /* Number of instructions in the program */
1339513405
int nOpAlloc; /* Number of slots allocated for aOp[] */
1339613406
int nLabel; /* Number of labels used */
1339713407
int *aLabel; /* Space to hold the labels */
1339813408
u16 nResColumn; /* Number of columns in one row of the result set */
13399
- u16 nCursor; /* Number of slots in apCsr[] */
13409
+ int nCursor; /* Number of slots in apCsr[] */
1340013410
u32 magic; /* Magic number for sanity checking */
1340113411
char *zErrMsg; /* Error message written here */
1340213412
Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
1340313413
VdbeCursor **apCsr; /* One element of this array for each open cursor */
1340413414
Mem *aVar; /* Values for the OP_Variable opcode. */
@@ -31099,11 +31109,11 @@
3109931109
/*
3110031110
** This function outputs the specified (ANSI) string to the Win32 debugger
3110131111
** (if available).
3110231112
*/
3110331113
31104
-SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
31114
+SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
3110531115
char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
3110631116
int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
3110731117
if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
3110831118
assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
3110931119
#if defined(SQLITE_WIN32_HAS_ANSI)
@@ -31732,13 +31742,14 @@
3173231742
3173331743
#if SQLITE_OS_WINCE
3173431744
/*************************************************************************
3173531745
** This section contains code for WinCE only.
3173631746
*/
31747
+#if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
3173731748
/*
31738
-** Windows CE does not have a localtime() function. So create a
31739
-** substitute.
31749
+** The MSVC CRT on Windows CE may not have a localtime() function. So
31750
+** create a substitute.
3174031751
*/
3174131752
/* #include <time.h> */
3174231753
struct tm *__cdecl localtime(const time_t *t)
3174331754
{
3174431755
static struct tm y;
@@ -31758,10 +31769,11 @@
3175831769
y.tm_hour = pTm.wHour;
3175931770
y.tm_min = pTm.wMinute;
3176031771
y.tm_sec = pTm.wSecond;
3176131772
return &y;
3176231773
}
31774
+#endif
3176331775
3176431776
#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
3176531777
3176631778
/*
3176731779
** Acquire a lock on the handle h
@@ -31779,19 +31791,21 @@
3177931791
3178031792
/*
3178131793
** Create the mutex and shared memory used for locking in the file
3178231794
** descriptor pFile
3178331795
*/
31784
-static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
31796
+static int winceCreateLock(const char *zFilename, winFile *pFile){
3178531797
LPWSTR zTok;
3178631798
LPWSTR zName;
31799
+ DWORD lastErrno;
31800
+ BOOL bLogged = FALSE;
3178731801
BOOL bInit = TRUE;
3178831802
3178931803
zName = utf8ToUnicode(zFilename);
3179031804
if( zName==0 ){
3179131805
/* out of memory */
31792
- return FALSE;
31806
+ return SQLITE_IOERR_NOMEM;
3179331807
}
3179431808
3179531809
/* Initialize the local lockdata */
3179631810
memset(&pFile->local, 0, sizeof(pFile->local));
3179731811
@@ -31804,13 +31818,14 @@
3180431818
3180531819
/* Create/open the named mutex */
3180631820
pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
3180731821
if (!pFile->hMutex){
3180831822
pFile->lastErrno = osGetLastError();
31809
- winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
31823
+ winLogError(SQLITE_IOERR, pFile->lastErrno,
31824
+ "winceCreateLock1", zFilename);
3181031825
sqlite3_free(zName);
31811
- return FALSE;
31826
+ return SQLITE_IOERR;
3181231827
}
3181331828
3181431829
/* Acquire the mutex before continuing */
3181531830
winceMutexAcquire(pFile->hMutex);
3181631831
@@ -31823,45 +31838,53 @@
3182331838
PAGE_READWRITE, 0, sizeof(winceLock),
3182431839
zName);
3182531840
3182631841
/* Set a flag that indicates we're the first to create the memory so it
3182731842
** must be zero-initialized */
31828
- if (osGetLastError() == ERROR_ALREADY_EXISTS){
31843
+ lastErrno = osGetLastError();
31844
+ if (lastErrno == ERROR_ALREADY_EXISTS){
3182931845
bInit = FALSE;
3183031846
}
3183131847
3183231848
sqlite3_free(zName);
3183331849
3183431850
/* If we succeeded in making the shared memory handle, map it. */
31835
- if (pFile->hShared){
31851
+ if( pFile->hShared ){
3183631852
pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
3183731853
FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
3183831854
/* If mapping failed, close the shared memory handle and erase it */
31839
- if (!pFile->shared){
31855
+ if( !pFile->shared ){
3184031856
pFile->lastErrno = osGetLastError();
31841
- winLogError(SQLITE_ERROR, pFile->lastErrno,
31842
- "winceCreateLock2", zFilename);
31857
+ winLogError(SQLITE_IOERR, pFile->lastErrno,
31858
+ "winceCreateLock2", zFilename);
31859
+ bLogged = TRUE;
3184331860
osCloseHandle(pFile->hShared);
3184431861
pFile->hShared = NULL;
3184531862
}
3184631863
}
3184731864
3184831865
/* If shared memory could not be created, then close the mutex and fail */
31849
- if (pFile->hShared == NULL){
31866
+ if( pFile->hShared==NULL ){
31867
+ if( !bLogged ){
31868
+ pFile->lastErrno = lastErrno;
31869
+ winLogError(SQLITE_IOERR, pFile->lastErrno,
31870
+ "winceCreateLock3", zFilename);
31871
+ bLogged = TRUE;
31872
+ }
3185031873
winceMutexRelease(pFile->hMutex);
3185131874
osCloseHandle(pFile->hMutex);
3185231875
pFile->hMutex = NULL;
31853
- return FALSE;
31876
+ return SQLITE_IOERR;
3185431877
}
3185531878
3185631879
/* Initialize the shared memory if we're supposed to */
31857
- if (bInit) {
31880
+ if( bInit ){
3185831881
memset(pFile->shared, 0, sizeof(winceLock));
3185931882
}
3186031883
3186131884
winceMutexRelease(pFile->hMutex);
31862
- return TRUE;
31885
+ return SQLITE_OK;
3186331886
}
3186431887
3186531888
/*
3186631889
** Destroy the part of winFile that deals with wince locks
3186731890
*/
@@ -32866,11 +32889,11 @@
3286632889
a[1] = win32IoerrRetryDelay;
3286732890
}
3286832891
return SQLITE_OK;
3286932892
}
3287032893
case SQLITE_FCNTL_TEMPFILENAME: {
32871
- char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
32894
+ char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
3287232895
if( zTFile ){
3287332896
getTempname(pFile->pVfs->mxPathname, zTFile);
3287432897
*(char**)pArg = zTFile;
3287532898
}
3287632899
return SQLITE_OK;
@@ -33802,10 +33825,11 @@
3380233825
/* If the second argument to this function is NULL, generate a
3380333826
** temporary file name to use
3380433827
*/
3380533828
if( !zUtf8Name ){
3380633829
assert(isDelete && !isOpenJournal);
33830
+ memset(zTmpname, 0, MAX_PATH+2);
3380733831
rc = getTempname(MAX_PATH+2, zTmpname);
3380833832
if( rc!=SQLITE_OK ){
3380933833
return rc;
3381033834
}
3381133835
zUtf8Name = zTmpname;
@@ -33953,15 +33977,15 @@
3395333977
pFile->ctrlFlags |= WINFILE_PSOW;
3395433978
}
3395533979
3395633980
#if SQLITE_OS_WINCE
3395733981
if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
33958
- && !winceCreateLock(zName, pFile)
33982
+ && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
3395933983
){
3396033984
osCloseHandle(h);
3396133985
sqlite3_free(zConverted);
33962
- return SQLITE_CANTOPEN_BKPT;
33986
+ return rc;
3396333987
}
3396433988
if( isTemp ){
3396533989
pFile->zDeleteOnClose = zConverted;
3396633990
}else
3396733991
#endif
@@ -58582,22 +58606,10 @@
5858258606
** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
5858358607
** to version 2.8.7, all this code was combined into the vdbe.c source file.
5858458608
** But that file was getting too big so this subroutines were split out.
5858558609
*/
5858658610
58587
-
58588
-
58589
-/*
58590
-** When debugging the code generator in a symbolic debugger, one can
58591
-** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed
58592
-** as they are added to the instruction stream.
58593
-*/
58594
-#ifdef SQLITE_DEBUG
58595
-SQLITE_PRIVATE int sqlite3VdbeAddopTrace = 0;
58596
-#endif
58597
-
58598
-
5859958611
/*
5860058612
** Create a new virtual database engine.
5860158613
*/
5860258614
SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
5860358615
Vdbe *p;
@@ -58723,11 +58735,13 @@
5872358735
pOp->p3 = p3;
5872458736
pOp->p4.p = 0;
5872558737
pOp->p4type = P4_NOTUSED;
5872658738
#ifdef SQLITE_DEBUG
5872758739
pOp->zComment = 0;
58728
- if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
58740
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
58741
+ sqlite3VdbePrintOp(0, i, &p->aOp[i]);
58742
+ }
5872958743
#endif
5873058744
#ifdef VDBE_PROFILE
5873158745
pOp->cycles = 0;
5873258746
pOp->cnt = 0;
5873358747
#endif
@@ -58942,11 +58956,11 @@
5894258956
if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
5894358957
#ifndef SQLITE_OMIT_FOREIGN_KEY
5894458958
|| (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
5894558959
#endif
5894658960
|| ((opcode==OP_Halt || opcode==OP_HaltIfNull)
58947
- && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
58961
+ && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
5894858962
){
5894958963
hasAbort = 1;
5895058964
break;
5895158965
}
5895258966
}
@@ -59077,11 +59091,11 @@
5907759091
pOut->p4type = P4_NOTUSED;
5907859092
pOut->p4.p = 0;
5907959093
pOut->p5 = 0;
5908059094
#ifdef SQLITE_DEBUG
5908159095
pOut->zComment = 0;
59082
- if( sqlite3VdbeAddopTrace ){
59096
+ if( p->db->flags & SQLITE_VdbeAddopTrace ){
5908359097
sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
5908459098
}
5908559099
#endif
5908659100
}
5908759101
p->nOp += nOp;
@@ -60103,11 +60117,11 @@
6010360117
}
6010460118
zCsr = p->pFree;
6010560119
zEnd = &zCsr[nByte];
6010660120
}while( nByte && !db->mallocFailed );
6010760121
60108
- p->nCursor = (u16)nCursor;
60122
+ p->nCursor = nCursor;
6010960123
p->nOnceFlag = nOnce;
6011060124
if( p->aVar ){
6011160125
p->nVar = (ynVar)nVar;
6011260126
for(n=0; n<nVar; n++){
6011360127
p->aVar[n].flags = MEM_Null;
@@ -60345,11 +60359,11 @@
6034560359
6034660360
/* If there are any write-transactions at all, invoke the commit hook */
6034760361
if( needXcommit && db->xCommitCallback ){
6034860362
rc = db->xCommitCallback(db->pCommitArg);
6034960363
if( rc ){
60350
- return SQLITE_CONSTRAINT;
60364
+ return SQLITE_CONSTRAINT_COMMITHOOK;
6035160365
}
6035260366
}
6035360367
6035460368
/* The simple case - no more than one database file (not counting the
6035560369
** TEMP database) has a transaction active. There is no need for the
@@ -60637,18 +60651,18 @@
6063760651
** handle associated with the VM passed as an argument is about to be
6063860652
** committed. If there are outstanding deferred foreign key constraint
6063960653
** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
6064060654
**
6064160655
** If there are outstanding FK violations and this function returns
60642
-** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
60643
-** an error message to it. Then return SQLITE_ERROR.
60656
+** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY
60657
+** and write an error message to it. Then return SQLITE_ERROR.
6064460658
*/
6064560659
#ifndef SQLITE_OMIT_FOREIGN_KEY
6064660660
SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
6064760661
sqlite3 *db = p->db;
6064860662
if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
60649
- p->rc = SQLITE_CONSTRAINT;
60663
+ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
6065060664
p->errorAction = OE_Abort;
6065160665
sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
6065260666
return SQLITE_ERROR;
6065360667
}
6065460668
return SQLITE_OK;
@@ -60759,11 +60773,11 @@
6075960773
if( rc!=SQLITE_OK ){
6076060774
if( NEVER(p->readOnly) ){
6076160775
sqlite3VdbeLeave(p);
6076260776
return SQLITE_ERROR;
6076360777
}
60764
- rc = SQLITE_CONSTRAINT;
60778
+ rc = SQLITE_CONSTRAINT_FOREIGNKEY;
6076560779
}else{
6076660780
/* The auto-commit flag is true, the vdbe program was successful
6076760781
** or hit an 'OR FAIL' constraint and there are no deferred foreign
6076860782
** key constraints to hold up the transaction. This means a commit
6076960783
** is required. */
@@ -60802,11 +60816,11 @@
6080260816
** current statement error code.
6080360817
*/
6080460818
if( eStatementOp ){
6080560819
rc = sqlite3VdbeCloseStatement(p, eStatementOp);
6080660820
if( rc ){
60807
- if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
60821
+ if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){
6080860822
p->rc = rc;
6080960823
sqlite3DbFree(db, p->zErrMsg);
6081060824
p->zErrMsg = 0;
6081160825
}
6081260826
sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
@@ -61043,11 +61057,11 @@
6104361057
sqlite3DbFree(db, p->aLabel);
6104461058
sqlite3DbFree(db, p->aColName);
6104561059
sqlite3DbFree(db, p->zSql);
6104661060
sqlite3DbFree(db, p->pFree);
6104761061
#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
61048
- sqlite3_free(p->zExplain);
61062
+ sqlite3DbFree(db, p->zExplain);
6104961063
sqlite3DbFree(db, p->pExplain);
6105061064
#endif
6105161065
}
6105261066
6105361067
/*
@@ -64799,11 +64813,11 @@
6479964813
rc = sqlite3VdbeHalt(p);
6480064814
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
6480164815
if( rc==SQLITE_BUSY ){
6480264816
p->rc = rc = SQLITE_BUSY;
6480364817
}else{
64804
- assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT );
64818
+ assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
6480564819
assert( rc==SQLITE_OK || db->nDeferredCons>0 );
6480664820
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
6480764821
}
6480864822
goto vdbe_return;
6480964823
}
@@ -70131,11 +70145,11 @@
7013170145
importVtabErrMsg(p, u.cr.pVtab);
7013270146
if( rc==SQLITE_OK && pOp->p1 ){
7013370147
assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
7013470148
db->lastRowid = lastRowid = u.cr.rowid;
7013570149
}
70136
- if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
70150
+ if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
7013770151
if( pOp->p5==OE_Ignore ){
7013870152
rc = SQLITE_OK;
7013970153
}else{
7014070154
p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
7014170155
}
@@ -72775,12 +72789,12 @@
7277572789
7277672790
pTab = pItem->pTab;
7277772791
assert( pTab!=0 && pTab->zName!=0 );
7277872792
assert( pTab->nCol>0 );
7277972793
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
72780
- ExprList *pEList = pItem->pSelect->pEList;
7278172794
int hit = 0;
72795
+ pEList = pItem->pSelect->pEList;
7278272796
for(j=0; j<pEList->nExpr; j++){
7278372797
if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
7278472798
cnt++;
7278572799
cntTab = 2;
7278672800
pMatch = pItem;
@@ -76776,11 +76790,12 @@
7677676790
assert( !ExprHasProperty(pExpr, EP_IntValue) );
7677776791
if( pExpr->affinity==OE_Ignore ){
7677876792
sqlite3VdbeAddOp4(
7677976793
v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
7678076794
}else{
76781
- sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
76795
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
76796
+ pExpr->affinity, pExpr->u.zToken, 0);
7678276797
}
7678376798
7678476799
break;
7678576800
}
7678676801
#endif
@@ -83247,12 +83262,12 @@
8324783262
if( pIndex->onError!=OE_None ){
8324883263
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
8324983264
sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
8325083265
addr2 = sqlite3VdbeCurrentAddr(v);
8325183266
sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
83252
- sqlite3HaltConstraint(
83253
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
83267
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
83268
+ OE_Abort, "indexed columns are not unique", P4_STATIC
8325483269
);
8325583270
}else{
8325683271
addr2 = sqlite3VdbeCurrentAddr(v);
8325783272
}
8325883273
sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
@@ -83274,12 +83289,12 @@
8327483289
** opcode use the values stored within seems dangerous. However, since
8327583290
** we can be sure that no other temp registers have been allocated
8327683291
** since sqlite3ReleaseTempRange() was called, it is safe to do so.
8327783292
*/
8327883293
sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
83279
- sqlite3HaltConstraint(
83280
- pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
83294
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
83295
+ "indexed columns are not unique", P4_STATIC);
8328183296
}
8328283297
sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
8328383298
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
8328483299
#endif
8328583300
sqlite3ReleaseTempReg(pParse, regRecord);
@@ -84492,16 +84507,23 @@
8449284507
/*
8449384508
** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
8449484509
** error. The onError parameter determines which (if any) of the statement
8449584510
** and/or current transaction is rolled back.
8449684511
*/
84497
-SQLITE_PRIVATE void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
84512
+SQLITE_PRIVATE void sqlite3HaltConstraint(
84513
+ Parse *pParse, /* Parsing context */
84514
+ int errCode, /* extended error code */
84515
+ int onError, /* Constraint type */
84516
+ char *p4, /* Error message */
84517
+ int p4type /* P4_STATIC or P4_TRANSIENT */
84518
+){
8449884519
Vdbe *v = sqlite3GetVdbe(pParse);
84520
+ assert( (errCode&0xff)==SQLITE_CONSTRAINT );
8449984521
if( onError==OE_Abort ){
8450084522
sqlite3MayAbort(pParse);
8450184523
}
84502
- sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
84524
+ sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
8450384525
}
8450484526
8450584527
/*
8450684528
** Check to see if pIndex uses the collating sequence pColl. Return
8450784529
** true if it does and false if it does not.
@@ -87484,12 +87506,13 @@
8748487506
/*
8748587507
** Deferred and Immediate FKs
8748687508
** --------------------------
8748787509
**
8748887510
** Foreign keys in SQLite come in two flavours: deferred and immediate.
87489
-** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
87490
-** is returned and the current statement transaction rolled back. If a
87511
+** If an immediate foreign key constraint is violated,
87512
+** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current
87513
+** statement transaction rolled back. If a
8749187514
** deferred foreign key constraint is violated, no action is taken
8749287515
** immediately. However if the application attempts to commit the
8749387516
** transaction before fixing the constraint violation, the attempt fails.
8749487517
**
8749587518
** Deferred constraints are implemented using a simple counter associated
@@ -87549,11 +87572,12 @@
8754987572
** row is inserted.
8755087573
**
8755187574
** Immediate constraints are usually handled similarly. The only difference
8755287575
** is that the counter used is stored as part of each individual statement
8755387576
** object (struct Vdbe). If, after the statement has run, its immediate
87554
-** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
87577
+** constraint counter is greater than zero,
87578
+** it returns SQLITE_CONSTRAINT_FOREIGNKEY
8755587579
** and the statement transaction is rolled back. An exception is an INSERT
8755687580
** statement that inserts a single row only (no triggers). In this case,
8755787581
** instead of using a counter, an exception is thrown immediately if the
8755887582
** INSERT violates a foreign key constraint. This is necessary as such
8755987583
** an INSERT does not open a statement transaction.
@@ -87889,12 +87913,12 @@
8788987913
/* Special case: If this is an INSERT statement that will insert exactly
8789087914
** one row into the table, raise a constraint immediately instead of
8789187915
** incrementing a counter. This is necessary as the VM code is being
8789287916
** generated for will not open a statement transaction. */
8789387917
assert( nIncr==1 );
87894
- sqlite3HaltConstraint(
87895
- pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
87918
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
87919
+ OE_Abort, "foreign key constraint failed", P4_STATIC
8789687920
);
8789787921
}else{
8789887922
if( nIncr>0 && pFKey->isDeferred==0 ){
8789987923
sqlite3ParseToplevel(pParse)->mayAbort = 1;
8790087924
}
@@ -88130,12 +88154,12 @@
8813088154
/* If the DELETE has generated immediate foreign key constraint
8813188155
** violations, halt the VDBE and return an error at this point, before
8813288156
** any modifications to the schema are made. This is because statement
8813388157
** transactions are not able to rollback schema changes. */
8813488158
sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
88135
- sqlite3HaltConstraint(
88136
- pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
88159
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
88160
+ OE_Abort, "foreign key constraint failed", P4_STATIC
8813788161
);
8813888162
8813988163
if( iSkip ){
8814088164
sqlite3VdbeResolveLabel(v, iSkip);
8814188165
}
@@ -89935,11 +89959,11 @@
8993589959
sqlite3MayAbort(pParse);
8993689960
case OE_Rollback:
8993789961
case OE_Fail: {
8993889962
char *zMsg;
8993989963
sqlite3VdbeAddOp3(v, OP_HaltIfNull,
89940
- SQLITE_CONSTRAINT, onError, regData+i);
89964
+ SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
8994189965
zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
8994289966
pTab->zName, pTab->aCol[i].zName);
8994389967
sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
8994489968
break;
8994589969
}
@@ -89975,11 +89999,12 @@
8997589999
if( zConsName ){
8997690000
zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
8997790001
}else{
8997890002
zConsName = 0;
8997990003
}
89980
- sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
90004
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
90005
+ onError, zConsName, P4_DYNAMIC);
8998190006
}
8998290007
sqlite3VdbeResolveLabel(v, allOk);
8998390008
}
8998490009
}
8998590010
#endif /* !defined(SQLITE_OMIT_CHECK) */
@@ -90006,12 +90031,12 @@
9000690031
/* Fall thru into the next case */
9000790032
}
9000890033
case OE_Rollback:
9000990034
case OE_Abort:
9001090035
case OE_Fail: {
90011
- sqlite3HaltConstraint(
90012
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
90036
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
90037
+ onError, "PRIMARY KEY must be unique", P4_STATIC);
9001390038
break;
9001490039
}
9001590040
case OE_Replace: {
9001690041
/* If there are DELETE triggers on this table and the
9001790042
** recursive-triggers flag is set, call GenerateRowDelete() to
@@ -90134,11 +90159,12 @@
9013490159
sqlite3StrAccumAppend(&errMsg, zCol, -1);
9013590160
}
9013690161
sqlite3StrAccumAppend(&errMsg,
9013790162
pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
9013890163
zErr = sqlite3StrAccumFinish(&errMsg);
90139
- sqlite3HaltConstraint(pParse, onError, zErr, 0);
90164
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
90165
+ onError, zErr, 0);
9014090166
sqlite3DbFree(errMsg.db, zErr);
9014190167
break;
9014290168
}
9014390169
case OE_Ignore: {
9014490170
assert( seenReplace==0 );
@@ -90542,12 +90568,12 @@
9054290568
regData = sqlite3GetTempReg(pParse);
9054390569
regRowid = sqlite3GetTempReg(pParse);
9054490570
if( pDest->iPKey>=0 ){
9054590571
addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
9054690572
addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
90547
- sqlite3HaltConstraint(
90548
- pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
90573
+ sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
90574
+ onError, "PRIMARY KEY must be unique", P4_STATIC);
9054990575
sqlite3VdbeJumpHere(v, addr2);
9055090576
autoIncStep(pParse, regAutoinc, regRowid);
9055190577
}else if( pDest->pIndex==0 ){
9055290578
addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
9055390579
}else{
@@ -91000,10 +91026,24 @@
9100091026
int (*wal_checkpoint)(sqlite3*,const char*);
9100191027
void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
9100291028
int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
9100391029
int (*vtab_config)(sqlite3*,int op,...);
9100491030
int (*vtab_on_conflict)(sqlite3*);
91031
+ /* Version 3.7.16 and later */
91032
+ int (*close_v2)(sqlite3*);
91033
+ const char *(*db_filename)(sqlite3*,const char*);
91034
+ int (*db_readonly)(sqlite3*,const char*);
91035
+ int (*db_release_memory)(sqlite3*);
91036
+ const char *(*errstr)(int);
91037
+ int (*stmt_busy)(sqlite3_stmt*);
91038
+ int (*stmt_readonly)(sqlite3_stmt*);
91039
+ int (*stricmp)(const char*,const char*);
91040
+ int (*uri_boolean)(const char*,const char*,int);
91041
+ sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
91042
+ const char *(*uri_parameter)(const char*,const char*);
91043
+ char *(*vsnprintf)(int,char*,const char*,va_list);
91044
+ int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
9100591045
};
9100691046
9100791047
/*
9100891048
** The following macros redefine the API routines so that they are
9100991049
** redirected throught the global sqlite3_api structure.
@@ -91203,10 +91243,24 @@
9120391243
#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
9120491244
#define sqlite3_wal_hook sqlite3_api->wal_hook
9120591245
#define sqlite3_blob_reopen sqlite3_api->blob_reopen
9120691246
#define sqlite3_vtab_config sqlite3_api->vtab_config
9120791247
#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
91248
+/* Version 3.7.16 and later */
91249
+#define sqlite3_close_v2 sqlite3_api->close_v2
91250
+#define sqlite3_db_filename sqlite3_api->db_filename
91251
+#define sqlite3_db_readonly sqlite3_api->db_readonly
91252
+#define sqlite3_db_release_memory sqlite3_api->db_release_memory
91253
+#define sqlite3_errstr sqlite3_api->errstr
91254
+#define sqlite3_stmt_busy sqlite3_api->stmt_busy
91255
+#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
91256
+#define sqlite3_stricmp sqlite3_api->stricmp
91257
+#define sqlite3_uri_boolean sqlite3_api->uri_boolean
91258
+#define sqlite3_uri_int64 sqlite3_api->uri_int64
91259
+#define sqlite3_uri_parameter sqlite3_api->uri_parameter
91260
+#define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
91261
+#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
9120891262
#endif /* SQLITE_CORE */
9120991263
9121091264
#define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0;
9121191265
#define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v;
9121291266
@@ -92038,10 +92092,13 @@
9203892092
#endif
9203992093
#ifdef SQLITE_DEBUG
9204092094
{ "sql_trace", SQLITE_SqlTrace },
9204192095
{ "vdbe_listing", SQLITE_VdbeListing },
9204292096
{ "vdbe_trace", SQLITE_VdbeTrace },
92097
+ { "vdbe_addoptrace", SQLITE_VdbeAddopTrace},
92098
+ { "vdbe_debug", SQLITE_SqlTrace | SQLITE_VdbeListing
92099
+ | SQLITE_VdbeTrace },
9204392100
#endif
9204492101
#ifndef SQLITE_OMIT_CHECK
9204592102
{ "ignore_check_constraints", SQLITE_IgnoreChecks },
9204692103
#endif
9204792104
/* The following is VERY experimental */
@@ -96198,10 +96255,12 @@
9619896255
switch( p->op ){
9619996256
case TK_ALL: {
9620096257
int addr = 0;
9620196258
int nLimit;
9620296259
assert( !pPrior->pLimit );
96260
+ pPrior->iLimit = p->iLimit;
96261
+ pPrior->iOffset = p->iOffset;
9620396262
pPrior->pLimit = p->pLimit;
9620496263
pPrior->pOffset = p->pOffset;
9620596264
explainSetInteger(iSub1, pParse->iNextSelectId);
9620696265
rc = sqlite3Select(pParse, pPrior, &dest);
9620796266
p->pLimit = 0;
@@ -97454,16 +97513,19 @@
9745497513
*/
9745597514
for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
9745697515
Select *pNew;
9745797516
ExprList *pOrderBy = p->pOrderBy;
9745897517
Expr *pLimit = p->pLimit;
97518
+ Expr *pOffset = p->pOffset;
9745997519
Select *pPrior = p->pPrior;
9746097520
p->pOrderBy = 0;
9746197521
p->pSrc = 0;
9746297522
p->pPrior = 0;
9746397523
p->pLimit = 0;
97524
+ p->pOffset = 0;
9746497525
pNew = sqlite3SelectDup(db, p, 0);
97526
+ p->pOffset = pOffset;
9746597527
p->pLimit = pLimit;
9746697528
p->pOrderBy = pOrderBy;
9746797529
p->pSrc = pSrc;
9746897530
p->op = TK_ALL;
9746997531
p->pRightmost = 0;
@@ -97784,18 +97846,19 @@
9778497846
SrcList *pTabList;
9778597847
ExprList *pEList;
9778697848
struct SrcList_item *pFrom;
9778797849
sqlite3 *db = pParse->db;
9778897850
Expr *pE, *pRight, *pExpr;
97851
+ u16 selFlags = p->selFlags;
9778997852
97853
+ p->selFlags |= SF_Expanded;
9779097854
if( db->mallocFailed ){
9779197855
return WRC_Abort;
9779297856
}
97793
- if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
97857
+ if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
9779497858
return WRC_Prune;
9779597859
}
97796
- p->selFlags |= SF_Expanded;
9779797860
pTabList = p->pSrc;
9779897861
pEList = p->pEList;
9779997862
9780097863
/* Make sure cursor numbers have been assigned to all entries in
9780197864
** the FROM clause of the SELECT statement.
@@ -97834,10 +97897,16 @@
9783497897
}else{
9783597898
/* An ordinary table or view name in the FROM clause */
9783697899
assert( pFrom->pTab==0 );
9783797900
pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
9783897901
if( pTab==0 ) return WRC_Abort;
97902
+ if( pTab->nRef==0xffff ){
97903
+ sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
97904
+ pTab->zName);
97905
+ pFrom->pTab = 0;
97906
+ return WRC_Abort;
97907
+ }
9783997908
pTab->nRef++;
9784097909
#if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
9784197910
if( pTab->pSelect || IsVirtual(pTab) ){
9784297911
/* We reach here if the named table is a really a view */
9784397912
if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
@@ -98146,10 +98215,11 @@
9814698215
NameContext *pOuterNC /* Name context for container */
9814798216
){
9814898217
sqlite3 *db;
9814998218
if( NEVER(p==0) ) return;
9815098219
db = pParse->db;
98220
+ if( db->mallocFailed ) return;
9815198221
if( p->selFlags & SF_HasTypeInfo ) return;
9815298222
sqlite3SelectExpand(pParse, p);
9815398223
if( pParse->nErr || db->mallocFailed ) return;
9815498224
sqlite3ResolveSelectNames(pParse, p, pOuterNC);
9815598225
if( pParse->nErr || db->mallocFailed ) return;
@@ -99231,11 +99301,14 @@
9923199301
SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
9923299302
if( p==0 ){
9923399303
sqlite3ExplainPrintf(pVdbe, "(null-select)");
9923499304
return;
9923599305
}
99236
- while( p->pPrior ) p = p->pPrior;
99306
+ while( p->pPrior ){
99307
+ p->pPrior->pNext = p;
99308
+ p = p->pPrior;
99309
+ }
9923799310
sqlite3ExplainPush(pVdbe);
9923899311
while( p ){
9923999312
explainOneSelect(pVdbe, p);
9924099313
p = p->pNext;
9924199314
if( p==0 ) break;
@@ -102850,11 +102923,10 @@
102850102923
** subclauses points to the WhereClause object for the whole clause.
102851102924
*/
102852102925
struct WhereClause {
102853102926
Parse *pParse; /* The parser context */
102854102927
WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
102855
- Bitmask vmask; /* Bitmask identifying virtual table cursors */
102856102928
WhereClause *pOuter; /* Outer conjunction */
102857102929
u8 op; /* Split operator. TK_AND or TK_OR */
102858102930
u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
102859102931
int nTerm; /* Number of terms */
102860102932
int nSlot; /* Number of entries in a[] */
@@ -103027,11 +103099,10 @@
103027103099
pWC->pMaskSet = pMaskSet;
103028103100
pWC->pOuter = 0;
103029103101
pWC->nTerm = 0;
103030103102
pWC->nSlot = ArraySize(pWC->aStatic);
103031103103
pWC->a = pWC->aStatic;
103032
- pWC->vmask = 0;
103033103104
pWC->wctrlFlags = wctrlFlags;
103034103105
}
103035103106
103036103107
/* Forward reference */
103037103108
static void whereClauseClear(WhereClause*);
@@ -103627,11 +103698,11 @@
103627103698
** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
103628103699
** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
103629103700
**
103630103701
** CASE 1:
103631103702
**
103632
-** If all subterms are of the form T.C=expr for some single column of C
103703
+** If all subterms are of the form T.C=expr for some single column of C and
103633103704
** a single table T (as shown in example B above) then create a new virtual
103634103705
** term that is an equivalent IN expression. In other words, if the term
103635103706
** being analyzed is:
103636103707
**
103637103708
** x = expr1 OR expr2 = x OR x = expr3
@@ -103715,11 +103786,11 @@
103715103786
103716103787
/*
103717103788
** Compute the set of tables that might satisfy cases 1 or 2.
103718103789
*/
103719103790
indexable = ~(Bitmask)0;
103720
- chngToIN = ~(pWC->vmask);
103791
+ chngToIN = ~(Bitmask)0;
103721103792
for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
103722103793
if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
103723103794
WhereAndInfo *pAndInfo;
103724103795
assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
103725103796
chngToIN = 0;
@@ -104982,12 +105053,13 @@
104982105053
Table *pTab = pSrc->pTab;
104983105054
sqlite3_index_info *pIdxInfo;
104984105055
struct sqlite3_index_constraint *pIdxCons;
104985105056
struct sqlite3_index_constraint_usage *pUsage;
104986105057
WhereTerm *pTerm;
104987
- int i, j;
105058
+ int i, j, k;
104988105059
int nOrderBy;
105060
+ int sortOrder; /* Sort order for IN clauses */
104989105061
int bAllowIN; /* Allow IN optimizations */
104990105062
double rCost;
104991105063
104992105064
/* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104993105065
** malloc in allocateIndexInfo() fails and this function returns leaving
@@ -105082,22 +105154,31 @@
105082105154
105083105155
if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105084105156
return;
105085105157
}
105086105158
105159
+ sortOrder = SQLITE_SO_ASC;
105087105160
pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105088105161
for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105089105162
if( pUsage[i].argvIndex>0 ){
105090105163
j = pIdxCons->iTermOffset;
105091105164
pTerm = &pWC->a[j];
105092105165
p->cost.used |= pTerm->prereqRight;
105093
- if( (pTerm->eOperator & WO_IN)!=0 && pUsage[i].omit==0 ){
105094
- /* Do not attempt to use an IN constraint if the virtual table
105095
- ** says that the equivalent EQ constraint cannot be safely omitted.
105096
- ** If we do attempt to use such a constraint, some rows might be
105097
- ** repeated in the output. */
105098
- break;
105166
+ if( (pTerm->eOperator & WO_IN)!=0 ){
105167
+ if( pUsage[i].omit==0 ){
105168
+ /* Do not attempt to use an IN constraint if the virtual table
105169
+ ** says that the equivalent EQ constraint cannot be safely omitted.
105170
+ ** If we do attempt to use such a constraint, some rows might be
105171
+ ** repeated in the output. */
105172
+ break;
105173
+ }
105174
+ for(k=0; k<pIdxInfo->nOrderBy; k++){
105175
+ if( pIdxInfo->aOrderBy[k].iColumn==pIdxCons->iColumn ){
105176
+ sortOrder = pIdxInfo->aOrderBy[k].desc;
105177
+ break;
105178
+ }
105179
+ }
105099105180
}
105100105181
}
105101105182
}
105102105183
if( i>=pIdxInfo->nConstraint ) break;
105103105184
}
@@ -105123,11 +105204,12 @@
105123105204
}else{
105124105205
p->cost.rCost = rCost;
105125105206
}
105126105207
p->cost.plan.u.pVtabIdx = pIdxInfo;
105127105208
if( pIdxInfo->orderByConsumed ){
105128
- p->cost.plan.wsFlags |= WHERE_ORDERED;
105209
+ assert( sortOrder==0 || sortOrder==1 );
105210
+ p->cost.plan.wsFlags |= WHERE_ORDERED + sortOrder*WHERE_REVERSE;
105129105211
p->cost.plan.nOBSat = nOrderBy;
105130105212
}else{
105131105213
p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
105132105214
}
105133105215
p->cost.plan.nEq = 0;
@@ -105720,14 +105802,11 @@
105720105802
pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
105721105803
WO_EQ|WO_ISNULL|WO_IN, pIdx);
105722105804
if( pConstraint==0 ){
105723105805
isEq = 0;
105724105806
}else if( (pConstraint->eOperator & WO_IN)!=0 ){
105725
- /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY
105726
- ** because we do not know in what order the values on the RHS of the IN
105727
- ** operator will occur. */
105728
- break;
105807
+ isEq = 0;
105729105808
}else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){
105730105809
uniqueNotNull = 0;
105731105810
isEq = 1; /* "X IS NULL" means X has only a single value */
105732105811
}else if( pConstraint->prereqRight==0 ){
105733105812
isEq = 1; /* Constraint "X=constant" means X has only a single value */
@@ -106027,12 +106106,12 @@
106027106106
** constraint for all columns in the index, then this search will find
106028106107
** at most a single row. In this case set the WHERE_UNIQUE flag to
106029106108
** indicate this to the caller.
106030106109
**
106031106110
** Otherwise, if the search may find more than one row, test to see if
106032
- ** there is a range constraint on indexed column (pc.plan.nEq+1) that can be
106033
- ** optimized using the index.
106111
+ ** there is a range constraint on indexed column (pc.plan.nEq+1) that
106112
+ ** can be optimized using the index.
106034106113
*/
106035106114
if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
106036106115
testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
106037106116
testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
106038106117
if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
@@ -106369,11 +106448,12 @@
106369106448
#ifndef SQLITE_OMIT_VIRTUALTABLE
106370106449
if( IsVirtual(p->pSrc->pTab) ){
106371106450
sqlite3_index_info *pIdxInfo = 0;
106372106451
p->ppIdxInfo = &pIdxInfo;
106373106452
bestVirtualIndex(p);
106374
- if( pIdxInfo->needToFreeIdxStr ){
106453
+ assert( pIdxInfo!=0 || p->pParse->db->mallocFailed );
106454
+ if( pIdxInfo && pIdxInfo->needToFreeIdxStr ){
106375106455
sqlite3_free(pIdxInfo->idxStr);
106376106456
}
106377106457
sqlite3DbFree(p->pParse->db, pIdxInfo);
106378106458
}else
106379106459
#endif
@@ -106493,16 +106573,17 @@
106493106573
#ifndef SQLITE_OMIT_SUBQUERY
106494106574
}else{
106495106575
int eType;
106496106576
int iTab;
106497106577
struct InLoop *pIn;
106578
+ u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
106498106579
106499106580
assert( pX->op==TK_IN );
106500106581
iReg = iTarget;
106501106582
eType = sqlite3FindInIndex(pParse, pX, 0);
106502106583
iTab = pX->iTable;
106503
- sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
106584
+ sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
106504106585
assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
106505106586
if( pLevel->u.in.nIn==0 ){
106506106587
pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
106507106588
}
106508106589
pLevel->u.in.nIn++;
@@ -106516,10 +106597,11 @@
106516106597
if( eType==IN_INDEX_ROWID ){
106517106598
pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
106518106599
}else{
106519106600
pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
106520106601
}
106602
+ pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
106521106603
sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
106522106604
}else{
106523106605
pLevel->u.in.nIn = 0;
106524106606
}
106525106607
#endif
@@ -106884,12 +106966,12 @@
106884106966
iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106885106967
addrNotFound = pLevel->addrBrk;
106886106968
for(j=1; j<=nConstraint; j++){
106887106969
for(k=0; k<nConstraint; k++){
106888106970
if( aUsage[k].argvIndex==j ){
106889
- WhereTerm *pTerm = &pWC->a[aConstraint[k].iTermOffset];
106890106971
int iTarget = iReg+j+1;
106972
+ pTerm = &pWC->a[aConstraint[k].iTermOffset];
106891106973
if( pTerm->eOperator & WO_IN ){
106892106974
codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106893106975
addrNotFound = pLevel->addrNxt;
106894106976
}else{
106895106977
sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
@@ -107767,28 +107849,17 @@
107767107849
** its Expr.iRightJoinTable value to find the bitmask of the right table
107768107850
** of the join. Subtracting one from the right table bitmask gives a
107769107851
** bitmask for all tables to the left of the join. Knowing the bitmask
107770107852
** for all tables to the left of a left join is important. Ticket #3015.
107771107853
**
107772
- ** Configure the WhereClause.vmask variable so that bits that correspond
107773
- ** to virtual table cursors are set. This is used to selectively disable
107774
- ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
107775
- ** with virtual tables.
107776
- **
107777107854
** Note that bitmasks are created for all pTabList->nSrc tables in
107778107855
** pTabList, not just the first nTabList tables. nTabList is normally
107779107856
** equal to pTabList->nSrc but might be shortened to 1 if the
107780107857
** WHERE_ONETABLE_ONLY flag is set.
107781107858
*/
107782
- assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 );
107783107859
for(ii=0; ii<pTabList->nSrc; ii++){
107784107860
createMask(pMaskSet, pTabList->a[ii].iCursor);
107785
-#ifndef SQLITE_OMIT_VIRTUALTABLE
107786
- if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){
107787
- sWBI.pWC->vmask |= ((Bitmask)1 << ii);
107788
- }
107789
-#endif
107790107861
}
107791107862
#ifndef NDEBUG
107792107863
{
107793107864
Bitmask toTheLeft = 0;
107794107865
for(ii=0; ii<pTabList->nSrc; ii++){
@@ -108268,11 +108339,11 @@
108268108339
struct InLoop *pIn;
108269108340
int j;
108270108341
sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
108271108342
for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
108272108343
sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
108273
- sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
108344
+ sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
108274108345
sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
108275108346
}
108276108347
sqlite3DbFree(db, pLevel->u.in.aInLoop);
108277108348
}
108278108349
sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
108279108350
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -673,11 +673,11 @@
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.16"
677 #define SQLITE_VERSION_NUMBER 3007016
678 #define SQLITE_SOURCE_ID "2013-01-17 17:20:49 38852f158ab20bb4d7b264af987ec1538052bec3"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -1048,10 +1048,19 @@
1048 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
1049 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
1050 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
1051 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
1052 #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
 
 
 
 
 
 
 
 
 
1053
1054 /*
1055 ** CAPI3REF: Flags For File Open Operations
1056 **
1057 ** These bit values are intended for use in the
@@ -10018,11 +10027,11 @@
10018 #define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
10019 /* result set is empty */
10020 #define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
10021 #define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
10022 #define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
10023 /* 0x00000200 Unused */
10024 #define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
10025 #define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
10026 #define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
10027 #define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
10028 #define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
@@ -11034,10 +11043,11 @@
11034 struct {
11035 int nIn; /* Number of entries in aInLoop[] */
11036 struct InLoop {
11037 int iCur; /* The VDBE cursor used by this IN operator */
11038 int addrInTop; /* Top of the IN loop */
 
11039 } *aInLoop; /* Information about each nested IN operator */
11040 } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
11041 Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
11042 } u;
11043 double rOptCost; /* "Optimal" cost for this level */
@@ -11973,11 +11983,11 @@
11973 SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
11974 SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
11975 SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
11976 SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
11977 SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
11978 SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int);
11979 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
11980 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
11981 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
11982 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
11983 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
@@ -13208,11 +13218,11 @@
13208 Mem *aMem; /* Array of memory cells for parent frame */
13209 u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
13210 VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
13211 void *token; /* Copy of SubProgram.token */
13212 i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
13213 u16 nCursor; /* Number of entries in apCsr */
13214 int pc; /* Program Counter in parent (calling) frame */
13215 int nOp; /* Size of aOp array */
13216 int nMem; /* Number of entries in aMem */
13217 int nOnceFlag; /* Number of entries in aOnceFlag */
13218 int nChildMem; /* Number of memory cells for child frame */
@@ -13394,11 +13404,11 @@
13394 int nOp; /* Number of instructions in the program */
13395 int nOpAlloc; /* Number of slots allocated for aOp[] */
13396 int nLabel; /* Number of labels used */
13397 int *aLabel; /* Space to hold the labels */
13398 u16 nResColumn; /* Number of columns in one row of the result set */
13399 u16 nCursor; /* Number of slots in apCsr[] */
13400 u32 magic; /* Magic number for sanity checking */
13401 char *zErrMsg; /* Error message written here */
13402 Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
13403 VdbeCursor **apCsr; /* One element of this array for each open cursor */
13404 Mem *aVar; /* Values for the OP_Variable opcode. */
@@ -31099,11 +31109,11 @@
31099 /*
31100 ** This function outputs the specified (ANSI) string to the Win32 debugger
31101 ** (if available).
31102 */
31103
31104 SQLITE_API void sqlite3_win32_write_debug(char *zBuf, int nBuf){
31105 char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
31106 int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
31107 if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
31108 assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
31109 #if defined(SQLITE_WIN32_HAS_ANSI)
@@ -31732,13 +31742,14 @@
31732
31733 #if SQLITE_OS_WINCE
31734 /*************************************************************************
31735 ** This section contains code for WinCE only.
31736 */
 
31737 /*
31738 ** Windows CE does not have a localtime() function. So create a
31739 ** substitute.
31740 */
31741 /* #include <time.h> */
31742 struct tm *__cdecl localtime(const time_t *t)
31743 {
31744 static struct tm y;
@@ -31758,10 +31769,11 @@
31758 y.tm_hour = pTm.wHour;
31759 y.tm_min = pTm.wMinute;
31760 y.tm_sec = pTm.wSecond;
31761 return &y;
31762 }
 
31763
31764 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
31765
31766 /*
31767 ** Acquire a lock on the handle h
@@ -31779,19 +31791,21 @@
31779
31780 /*
31781 ** Create the mutex and shared memory used for locking in the file
31782 ** descriptor pFile
31783 */
31784 static BOOL winceCreateLock(const char *zFilename, winFile *pFile){
31785 LPWSTR zTok;
31786 LPWSTR zName;
 
 
31787 BOOL bInit = TRUE;
31788
31789 zName = utf8ToUnicode(zFilename);
31790 if( zName==0 ){
31791 /* out of memory */
31792 return FALSE;
31793 }
31794
31795 /* Initialize the local lockdata */
31796 memset(&pFile->local, 0, sizeof(pFile->local));
31797
@@ -31804,13 +31818,14 @@
31804
31805 /* Create/open the named mutex */
31806 pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
31807 if (!pFile->hMutex){
31808 pFile->lastErrno = osGetLastError();
31809 winLogError(SQLITE_ERROR, pFile->lastErrno, "winceCreateLock1", zFilename);
 
31810 sqlite3_free(zName);
31811 return FALSE;
31812 }
31813
31814 /* Acquire the mutex before continuing */
31815 winceMutexAcquire(pFile->hMutex);
31816
@@ -31823,45 +31838,53 @@
31823 PAGE_READWRITE, 0, sizeof(winceLock),
31824 zName);
31825
31826 /* Set a flag that indicates we're the first to create the memory so it
31827 ** must be zero-initialized */
31828 if (osGetLastError() == ERROR_ALREADY_EXISTS){
 
31829 bInit = FALSE;
31830 }
31831
31832 sqlite3_free(zName);
31833
31834 /* If we succeeded in making the shared memory handle, map it. */
31835 if (pFile->hShared){
31836 pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
31837 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
31838 /* If mapping failed, close the shared memory handle and erase it */
31839 if (!pFile->shared){
31840 pFile->lastErrno = osGetLastError();
31841 winLogError(SQLITE_ERROR, pFile->lastErrno,
31842 "winceCreateLock2", zFilename);
 
31843 osCloseHandle(pFile->hShared);
31844 pFile->hShared = NULL;
31845 }
31846 }
31847
31848 /* If shared memory could not be created, then close the mutex and fail */
31849 if (pFile->hShared == NULL){
 
 
 
 
 
 
31850 winceMutexRelease(pFile->hMutex);
31851 osCloseHandle(pFile->hMutex);
31852 pFile->hMutex = NULL;
31853 return FALSE;
31854 }
31855
31856 /* Initialize the shared memory if we're supposed to */
31857 if (bInit) {
31858 memset(pFile->shared, 0, sizeof(winceLock));
31859 }
31860
31861 winceMutexRelease(pFile->hMutex);
31862 return TRUE;
31863 }
31864
31865 /*
31866 ** Destroy the part of winFile that deals with wince locks
31867 */
@@ -32866,11 +32889,11 @@
32866 a[1] = win32IoerrRetryDelay;
32867 }
32868 return SQLITE_OK;
32869 }
32870 case SQLITE_FCNTL_TEMPFILENAME: {
32871 char *zTFile = sqlite3_malloc( pFile->pVfs->mxPathname );
32872 if( zTFile ){
32873 getTempname(pFile->pVfs->mxPathname, zTFile);
32874 *(char**)pArg = zTFile;
32875 }
32876 return SQLITE_OK;
@@ -33802,10 +33825,11 @@
33802 /* If the second argument to this function is NULL, generate a
33803 ** temporary file name to use
33804 */
33805 if( !zUtf8Name ){
33806 assert(isDelete && !isOpenJournal);
 
33807 rc = getTempname(MAX_PATH+2, zTmpname);
33808 if( rc!=SQLITE_OK ){
33809 return rc;
33810 }
33811 zUtf8Name = zTmpname;
@@ -33953,15 +33977,15 @@
33953 pFile->ctrlFlags |= WINFILE_PSOW;
33954 }
33955
33956 #if SQLITE_OS_WINCE
33957 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
33958 && !winceCreateLock(zName, pFile)
33959 ){
33960 osCloseHandle(h);
33961 sqlite3_free(zConverted);
33962 return SQLITE_CANTOPEN_BKPT;
33963 }
33964 if( isTemp ){
33965 pFile->zDeleteOnClose = zConverted;
33966 }else
33967 #endif
@@ -58582,22 +58606,10 @@
58582 ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
58583 ** to version 2.8.7, all this code was combined into the vdbe.c source file.
58584 ** But that file was getting too big so this subroutines were split out.
58585 */
58586
58587
58588
58589 /*
58590 ** When debugging the code generator in a symbolic debugger, one can
58591 ** set the sqlite3VdbeAddopTrace to 1 and all opcodes will be printed
58592 ** as they are added to the instruction stream.
58593 */
58594 #ifdef SQLITE_DEBUG
58595 SQLITE_PRIVATE int sqlite3VdbeAddopTrace = 0;
58596 #endif
58597
58598
58599 /*
58600 ** Create a new virtual database engine.
58601 */
58602 SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
58603 Vdbe *p;
@@ -58723,11 +58735,13 @@
58723 pOp->p3 = p3;
58724 pOp->p4.p = 0;
58725 pOp->p4type = P4_NOTUSED;
58726 #ifdef SQLITE_DEBUG
58727 pOp->zComment = 0;
58728 if( sqlite3VdbeAddopTrace ) sqlite3VdbePrintOp(0, i, &p->aOp[i]);
 
 
58729 #endif
58730 #ifdef VDBE_PROFILE
58731 pOp->cycles = 0;
58732 pOp->cnt = 0;
58733 #endif
@@ -58942,11 +58956,11 @@
58942 if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
58943 #ifndef SQLITE_OMIT_FOREIGN_KEY
58944 || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
58945 #endif
58946 || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
58947 && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
58948 ){
58949 hasAbort = 1;
58950 break;
58951 }
58952 }
@@ -59077,11 +59091,11 @@
59077 pOut->p4type = P4_NOTUSED;
59078 pOut->p4.p = 0;
59079 pOut->p5 = 0;
59080 #ifdef SQLITE_DEBUG
59081 pOut->zComment = 0;
59082 if( sqlite3VdbeAddopTrace ){
59083 sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
59084 }
59085 #endif
59086 }
59087 p->nOp += nOp;
@@ -60103,11 +60117,11 @@
60103 }
60104 zCsr = p->pFree;
60105 zEnd = &zCsr[nByte];
60106 }while( nByte && !db->mallocFailed );
60107
60108 p->nCursor = (u16)nCursor;
60109 p->nOnceFlag = nOnce;
60110 if( p->aVar ){
60111 p->nVar = (ynVar)nVar;
60112 for(n=0; n<nVar; n++){
60113 p->aVar[n].flags = MEM_Null;
@@ -60345,11 +60359,11 @@
60345
60346 /* If there are any write-transactions at all, invoke the commit hook */
60347 if( needXcommit && db->xCommitCallback ){
60348 rc = db->xCommitCallback(db->pCommitArg);
60349 if( rc ){
60350 return SQLITE_CONSTRAINT;
60351 }
60352 }
60353
60354 /* The simple case - no more than one database file (not counting the
60355 ** TEMP database) has a transaction active. There is no need for the
@@ -60637,18 +60651,18 @@
60637 ** handle associated with the VM passed as an argument is about to be
60638 ** committed. If there are outstanding deferred foreign key constraint
60639 ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
60640 **
60641 ** If there are outstanding FK violations and this function returns
60642 ** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write
60643 ** an error message to it. Then return SQLITE_ERROR.
60644 */
60645 #ifndef SQLITE_OMIT_FOREIGN_KEY
60646 SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
60647 sqlite3 *db = p->db;
60648 if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
60649 p->rc = SQLITE_CONSTRAINT;
60650 p->errorAction = OE_Abort;
60651 sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
60652 return SQLITE_ERROR;
60653 }
60654 return SQLITE_OK;
@@ -60759,11 +60773,11 @@
60759 if( rc!=SQLITE_OK ){
60760 if( NEVER(p->readOnly) ){
60761 sqlite3VdbeLeave(p);
60762 return SQLITE_ERROR;
60763 }
60764 rc = SQLITE_CONSTRAINT;
60765 }else{
60766 /* The auto-commit flag is true, the vdbe program was successful
60767 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
60768 ** key constraints to hold up the transaction. This means a commit
60769 ** is required. */
@@ -60802,11 +60816,11 @@
60802 ** current statement error code.
60803 */
60804 if( eStatementOp ){
60805 rc = sqlite3VdbeCloseStatement(p, eStatementOp);
60806 if( rc ){
60807 if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){
60808 p->rc = rc;
60809 sqlite3DbFree(db, p->zErrMsg);
60810 p->zErrMsg = 0;
60811 }
60812 sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
@@ -61043,11 +61057,11 @@
61043 sqlite3DbFree(db, p->aLabel);
61044 sqlite3DbFree(db, p->aColName);
61045 sqlite3DbFree(db, p->zSql);
61046 sqlite3DbFree(db, p->pFree);
61047 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
61048 sqlite3_free(p->zExplain);
61049 sqlite3DbFree(db, p->pExplain);
61050 #endif
61051 }
61052
61053 /*
@@ -64799,11 +64813,11 @@
64799 rc = sqlite3VdbeHalt(p);
64800 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
64801 if( rc==SQLITE_BUSY ){
64802 p->rc = rc = SQLITE_BUSY;
64803 }else{
64804 assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT );
64805 assert( rc==SQLITE_OK || db->nDeferredCons>0 );
64806 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
64807 }
64808 goto vdbe_return;
64809 }
@@ -70131,11 +70145,11 @@
70131 importVtabErrMsg(p, u.cr.pVtab);
70132 if( rc==SQLITE_OK && pOp->p1 ){
70133 assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
70134 db->lastRowid = lastRowid = u.cr.rowid;
70135 }
70136 if( rc==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
70137 if( pOp->p5==OE_Ignore ){
70138 rc = SQLITE_OK;
70139 }else{
70140 p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
70141 }
@@ -72775,12 +72789,12 @@
72775
72776 pTab = pItem->pTab;
72777 assert( pTab!=0 && pTab->zName!=0 );
72778 assert( pTab->nCol>0 );
72779 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
72780 ExprList *pEList = pItem->pSelect->pEList;
72781 int hit = 0;
 
72782 for(j=0; j<pEList->nExpr; j++){
72783 if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
72784 cnt++;
72785 cntTab = 2;
72786 pMatch = pItem;
@@ -76776,11 +76790,12 @@
76776 assert( !ExprHasProperty(pExpr, EP_IntValue) );
76777 if( pExpr->affinity==OE_Ignore ){
76778 sqlite3VdbeAddOp4(
76779 v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
76780 }else{
76781 sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0);
 
76782 }
76783
76784 break;
76785 }
76786 #endif
@@ -83247,12 +83262,12 @@
83247 if( pIndex->onError!=OE_None ){
83248 int j2 = sqlite3VdbeCurrentAddr(v) + 3;
83249 sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
83250 addr2 = sqlite3VdbeCurrentAddr(v);
83251 sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
83252 sqlite3HaltConstraint(
83253 pParse, OE_Abort, "indexed columns are not unique", P4_STATIC
83254 );
83255 }else{
83256 addr2 = sqlite3VdbeCurrentAddr(v);
83257 }
83258 sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
@@ -83274,12 +83289,12 @@
83274 ** opcode use the values stored within seems dangerous. However, since
83275 ** we can be sure that no other temp registers have been allocated
83276 ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
83277 */
83278 sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
83279 sqlite3HaltConstraint(
83280 pParse, OE_Abort, "indexed columns are not unique", P4_STATIC);
83281 }
83282 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
83283 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
83284 #endif
83285 sqlite3ReleaseTempReg(pParse, regRecord);
@@ -84492,16 +84507,23 @@
84492 /*
84493 ** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
84494 ** error. The onError parameter determines which (if any) of the statement
84495 ** and/or current transaction is rolled back.
84496 */
84497 SQLITE_PRIVATE void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){
 
 
 
 
 
 
84498 Vdbe *v = sqlite3GetVdbe(pParse);
 
84499 if( onError==OE_Abort ){
84500 sqlite3MayAbort(pParse);
84501 }
84502 sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type);
84503 }
84504
84505 /*
84506 ** Check to see if pIndex uses the collating sequence pColl. Return
84507 ** true if it does and false if it does not.
@@ -87484,12 +87506,13 @@
87484 /*
87485 ** Deferred and Immediate FKs
87486 ** --------------------------
87487 **
87488 ** Foreign keys in SQLite come in two flavours: deferred and immediate.
87489 ** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT
87490 ** is returned and the current statement transaction rolled back. If a
 
87491 ** deferred foreign key constraint is violated, no action is taken
87492 ** immediately. However if the application attempts to commit the
87493 ** transaction before fixing the constraint violation, the attempt fails.
87494 **
87495 ** Deferred constraints are implemented using a simple counter associated
@@ -87549,11 +87572,12 @@
87549 ** row is inserted.
87550 **
87551 ** Immediate constraints are usually handled similarly. The only difference
87552 ** is that the counter used is stored as part of each individual statement
87553 ** object (struct Vdbe). If, after the statement has run, its immediate
87554 ** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT
 
87555 ** and the statement transaction is rolled back. An exception is an INSERT
87556 ** statement that inserts a single row only (no triggers). In this case,
87557 ** instead of using a counter, an exception is thrown immediately if the
87558 ** INSERT violates a foreign key constraint. This is necessary as such
87559 ** an INSERT does not open a statement transaction.
@@ -87889,12 +87913,12 @@
87889 /* Special case: If this is an INSERT statement that will insert exactly
87890 ** one row into the table, raise a constraint immediately instead of
87891 ** incrementing a counter. This is necessary as the VM code is being
87892 ** generated for will not open a statement transaction. */
87893 assert( nIncr==1 );
87894 sqlite3HaltConstraint(
87895 pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
87896 );
87897 }else{
87898 if( nIncr>0 && pFKey->isDeferred==0 ){
87899 sqlite3ParseToplevel(pParse)->mayAbort = 1;
87900 }
@@ -88130,12 +88154,12 @@
88130 /* If the DELETE has generated immediate foreign key constraint
88131 ** violations, halt the VDBE and return an error at this point, before
88132 ** any modifications to the schema are made. This is because statement
88133 ** transactions are not able to rollback schema changes. */
88134 sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
88135 sqlite3HaltConstraint(
88136 pParse, OE_Abort, "foreign key constraint failed", P4_STATIC
88137 );
88138
88139 if( iSkip ){
88140 sqlite3VdbeResolveLabel(v, iSkip);
88141 }
@@ -89935,11 +89959,11 @@
89935 sqlite3MayAbort(pParse);
89936 case OE_Rollback:
89937 case OE_Fail: {
89938 char *zMsg;
89939 sqlite3VdbeAddOp3(v, OP_HaltIfNull,
89940 SQLITE_CONSTRAINT, onError, regData+i);
89941 zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
89942 pTab->zName, pTab->aCol[i].zName);
89943 sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
89944 break;
89945 }
@@ -89975,11 +89999,12 @@
89975 if( zConsName ){
89976 zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
89977 }else{
89978 zConsName = 0;
89979 }
89980 sqlite3HaltConstraint(pParse, onError, zConsName, P4_DYNAMIC);
 
89981 }
89982 sqlite3VdbeResolveLabel(v, allOk);
89983 }
89984 }
89985 #endif /* !defined(SQLITE_OMIT_CHECK) */
@@ -90006,12 +90031,12 @@
90006 /* Fall thru into the next case */
90007 }
90008 case OE_Rollback:
90009 case OE_Abort:
90010 case OE_Fail: {
90011 sqlite3HaltConstraint(
90012 pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
90013 break;
90014 }
90015 case OE_Replace: {
90016 /* If there are DELETE triggers on this table and the
90017 ** recursive-triggers flag is set, call GenerateRowDelete() to
@@ -90134,11 +90159,12 @@
90134 sqlite3StrAccumAppend(&errMsg, zCol, -1);
90135 }
90136 sqlite3StrAccumAppend(&errMsg,
90137 pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
90138 zErr = sqlite3StrAccumFinish(&errMsg);
90139 sqlite3HaltConstraint(pParse, onError, zErr, 0);
 
90140 sqlite3DbFree(errMsg.db, zErr);
90141 break;
90142 }
90143 case OE_Ignore: {
90144 assert( seenReplace==0 );
@@ -90542,12 +90568,12 @@
90542 regData = sqlite3GetTempReg(pParse);
90543 regRowid = sqlite3GetTempReg(pParse);
90544 if( pDest->iPKey>=0 ){
90545 addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
90546 addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
90547 sqlite3HaltConstraint(
90548 pParse, onError, "PRIMARY KEY must be unique", P4_STATIC);
90549 sqlite3VdbeJumpHere(v, addr2);
90550 autoIncStep(pParse, regAutoinc, regRowid);
90551 }else if( pDest->pIndex==0 ){
90552 addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
90553 }else{
@@ -91000,10 +91026,24 @@
91000 int (*wal_checkpoint)(sqlite3*,const char*);
91001 void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
91002 int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
91003 int (*vtab_config)(sqlite3*,int op,...);
91004 int (*vtab_on_conflict)(sqlite3*);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91005 };
91006
91007 /*
91008 ** The following macros redefine the API routines so that they are
91009 ** redirected throught the global sqlite3_api structure.
@@ -91203,10 +91243,24 @@
91203 #define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
91204 #define sqlite3_wal_hook sqlite3_api->wal_hook
91205 #define sqlite3_blob_reopen sqlite3_api->blob_reopen
91206 #define sqlite3_vtab_config sqlite3_api->vtab_config
91207 #define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91208 #endif /* SQLITE_CORE */
91209
91210 #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0;
91211 #define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v;
91212
@@ -92038,10 +92092,13 @@
92038 #endif
92039 #ifdef SQLITE_DEBUG
92040 { "sql_trace", SQLITE_SqlTrace },
92041 { "vdbe_listing", SQLITE_VdbeListing },
92042 { "vdbe_trace", SQLITE_VdbeTrace },
 
 
 
92043 #endif
92044 #ifndef SQLITE_OMIT_CHECK
92045 { "ignore_check_constraints", SQLITE_IgnoreChecks },
92046 #endif
92047 /* The following is VERY experimental */
@@ -96198,10 +96255,12 @@
96198 switch( p->op ){
96199 case TK_ALL: {
96200 int addr = 0;
96201 int nLimit;
96202 assert( !pPrior->pLimit );
 
 
96203 pPrior->pLimit = p->pLimit;
96204 pPrior->pOffset = p->pOffset;
96205 explainSetInteger(iSub1, pParse->iNextSelectId);
96206 rc = sqlite3Select(pParse, pPrior, &dest);
96207 p->pLimit = 0;
@@ -97454,16 +97513,19 @@
97454 */
97455 for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
97456 Select *pNew;
97457 ExprList *pOrderBy = p->pOrderBy;
97458 Expr *pLimit = p->pLimit;
 
97459 Select *pPrior = p->pPrior;
97460 p->pOrderBy = 0;
97461 p->pSrc = 0;
97462 p->pPrior = 0;
97463 p->pLimit = 0;
 
97464 pNew = sqlite3SelectDup(db, p, 0);
 
97465 p->pLimit = pLimit;
97466 p->pOrderBy = pOrderBy;
97467 p->pSrc = pSrc;
97468 p->op = TK_ALL;
97469 p->pRightmost = 0;
@@ -97784,18 +97846,19 @@
97784 SrcList *pTabList;
97785 ExprList *pEList;
97786 struct SrcList_item *pFrom;
97787 sqlite3 *db = pParse->db;
97788 Expr *pE, *pRight, *pExpr;
 
97789
 
97790 if( db->mallocFailed ){
97791 return WRC_Abort;
97792 }
97793 if( NEVER(p->pSrc==0) || (p->selFlags & SF_Expanded)!=0 ){
97794 return WRC_Prune;
97795 }
97796 p->selFlags |= SF_Expanded;
97797 pTabList = p->pSrc;
97798 pEList = p->pEList;
97799
97800 /* Make sure cursor numbers have been assigned to all entries in
97801 ** the FROM clause of the SELECT statement.
@@ -97834,10 +97897,16 @@
97834 }else{
97835 /* An ordinary table or view name in the FROM clause */
97836 assert( pFrom->pTab==0 );
97837 pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
97838 if( pTab==0 ) return WRC_Abort;
 
 
 
 
 
 
97839 pTab->nRef++;
97840 #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
97841 if( pTab->pSelect || IsVirtual(pTab) ){
97842 /* We reach here if the named table is a really a view */
97843 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
@@ -98146,10 +98215,11 @@
98146 NameContext *pOuterNC /* Name context for container */
98147 ){
98148 sqlite3 *db;
98149 if( NEVER(p==0) ) return;
98150 db = pParse->db;
 
98151 if( p->selFlags & SF_HasTypeInfo ) return;
98152 sqlite3SelectExpand(pParse, p);
98153 if( pParse->nErr || db->mallocFailed ) return;
98154 sqlite3ResolveSelectNames(pParse, p, pOuterNC);
98155 if( pParse->nErr || db->mallocFailed ) return;
@@ -99231,11 +99301,14 @@
99231 SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
99232 if( p==0 ){
99233 sqlite3ExplainPrintf(pVdbe, "(null-select)");
99234 return;
99235 }
99236 while( p->pPrior ) p = p->pPrior;
 
 
 
99237 sqlite3ExplainPush(pVdbe);
99238 while( p ){
99239 explainOneSelect(pVdbe, p);
99240 p = p->pNext;
99241 if( p==0 ) break;
@@ -102850,11 +102923,10 @@
102850 ** subclauses points to the WhereClause object for the whole clause.
102851 */
102852 struct WhereClause {
102853 Parse *pParse; /* The parser context */
102854 WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
102855 Bitmask vmask; /* Bitmask identifying virtual table cursors */
102856 WhereClause *pOuter; /* Outer conjunction */
102857 u8 op; /* Split operator. TK_AND or TK_OR */
102858 u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
102859 int nTerm; /* Number of terms */
102860 int nSlot; /* Number of entries in a[] */
@@ -103027,11 +103099,10 @@
103027 pWC->pMaskSet = pMaskSet;
103028 pWC->pOuter = 0;
103029 pWC->nTerm = 0;
103030 pWC->nSlot = ArraySize(pWC->aStatic);
103031 pWC->a = pWC->aStatic;
103032 pWC->vmask = 0;
103033 pWC->wctrlFlags = wctrlFlags;
103034 }
103035
103036 /* Forward reference */
103037 static void whereClauseClear(WhereClause*);
@@ -103627,11 +103698,11 @@
103627 ** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
103628 ** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
103629 **
103630 ** CASE 1:
103631 **
103632 ** If all subterms are of the form T.C=expr for some single column of C
103633 ** a single table T (as shown in example B above) then create a new virtual
103634 ** term that is an equivalent IN expression. In other words, if the term
103635 ** being analyzed is:
103636 **
103637 ** x = expr1 OR expr2 = x OR x = expr3
@@ -103715,11 +103786,11 @@
103715
103716 /*
103717 ** Compute the set of tables that might satisfy cases 1 or 2.
103718 */
103719 indexable = ~(Bitmask)0;
103720 chngToIN = ~(pWC->vmask);
103721 for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
103722 if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
103723 WhereAndInfo *pAndInfo;
103724 assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
103725 chngToIN = 0;
@@ -104982,12 +105053,13 @@
104982 Table *pTab = pSrc->pTab;
104983 sqlite3_index_info *pIdxInfo;
104984 struct sqlite3_index_constraint *pIdxCons;
104985 struct sqlite3_index_constraint_usage *pUsage;
104986 WhereTerm *pTerm;
104987 int i, j;
104988 int nOrderBy;
 
104989 int bAllowIN; /* Allow IN optimizations */
104990 double rCost;
104991
104992 /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
104993 ** malloc in allocateIndexInfo() fails and this function returns leaving
@@ -105082,22 +105154,31 @@
105082
105083 if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105084 return;
105085 }
105086
 
105087 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105088 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105089 if( pUsage[i].argvIndex>0 ){
105090 j = pIdxCons->iTermOffset;
105091 pTerm = &pWC->a[j];
105092 p->cost.used |= pTerm->prereqRight;
105093 if( (pTerm->eOperator & WO_IN)!=0 && pUsage[i].omit==0 ){
105094 /* Do not attempt to use an IN constraint if the virtual table
105095 ** says that the equivalent EQ constraint cannot be safely omitted.
105096 ** If we do attempt to use such a constraint, some rows might be
105097 ** repeated in the output. */
105098 break;
 
 
 
 
 
 
 
 
105099 }
105100 }
105101 }
105102 if( i>=pIdxInfo->nConstraint ) break;
105103 }
@@ -105123,11 +105204,12 @@
105123 }else{
105124 p->cost.rCost = rCost;
105125 }
105126 p->cost.plan.u.pVtabIdx = pIdxInfo;
105127 if( pIdxInfo->orderByConsumed ){
105128 p->cost.plan.wsFlags |= WHERE_ORDERED;
 
105129 p->cost.plan.nOBSat = nOrderBy;
105130 }else{
105131 p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
105132 }
105133 p->cost.plan.nEq = 0;
@@ -105720,14 +105802,11 @@
105720 pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
105721 WO_EQ|WO_ISNULL|WO_IN, pIdx);
105722 if( pConstraint==0 ){
105723 isEq = 0;
105724 }else if( (pConstraint->eOperator & WO_IN)!=0 ){
105725 /* Constraints of the form: "X IN ..." cannot be used with an ORDER BY
105726 ** because we do not know in what order the values on the RHS of the IN
105727 ** operator will occur. */
105728 break;
105729 }else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){
105730 uniqueNotNull = 0;
105731 isEq = 1; /* "X IS NULL" means X has only a single value */
105732 }else if( pConstraint->prereqRight==0 ){
105733 isEq = 1; /* Constraint "X=constant" means X has only a single value */
@@ -106027,12 +106106,12 @@
106027 ** constraint for all columns in the index, then this search will find
106028 ** at most a single row. In this case set the WHERE_UNIQUE flag to
106029 ** indicate this to the caller.
106030 **
106031 ** Otherwise, if the search may find more than one row, test to see if
106032 ** there is a range constraint on indexed column (pc.plan.nEq+1) that can be
106033 ** optimized using the index.
106034 */
106035 if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
106036 testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
106037 testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
106038 if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
@@ -106369,11 +106448,12 @@
106369 #ifndef SQLITE_OMIT_VIRTUALTABLE
106370 if( IsVirtual(p->pSrc->pTab) ){
106371 sqlite3_index_info *pIdxInfo = 0;
106372 p->ppIdxInfo = &pIdxInfo;
106373 bestVirtualIndex(p);
106374 if( pIdxInfo->needToFreeIdxStr ){
 
106375 sqlite3_free(pIdxInfo->idxStr);
106376 }
106377 sqlite3DbFree(p->pParse->db, pIdxInfo);
106378 }else
106379 #endif
@@ -106493,16 +106573,17 @@
106493 #ifndef SQLITE_OMIT_SUBQUERY
106494 }else{
106495 int eType;
106496 int iTab;
106497 struct InLoop *pIn;
 
106498
106499 assert( pX->op==TK_IN );
106500 iReg = iTarget;
106501 eType = sqlite3FindInIndex(pParse, pX, 0);
106502 iTab = pX->iTable;
106503 sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
106504 assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
106505 if( pLevel->u.in.nIn==0 ){
106506 pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
106507 }
106508 pLevel->u.in.nIn++;
@@ -106516,10 +106597,11 @@
106516 if( eType==IN_INDEX_ROWID ){
106517 pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
106518 }else{
106519 pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
106520 }
 
106521 sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
106522 }else{
106523 pLevel->u.in.nIn = 0;
106524 }
106525 #endif
@@ -106884,12 +106966,12 @@
106884 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106885 addrNotFound = pLevel->addrBrk;
106886 for(j=1; j<=nConstraint; j++){
106887 for(k=0; k<nConstraint; k++){
106888 if( aUsage[k].argvIndex==j ){
106889 WhereTerm *pTerm = &pWC->a[aConstraint[k].iTermOffset];
106890 int iTarget = iReg+j+1;
 
106891 if( pTerm->eOperator & WO_IN ){
106892 codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106893 addrNotFound = pLevel->addrNxt;
106894 }else{
106895 sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
@@ -107767,28 +107849,17 @@
107767 ** its Expr.iRightJoinTable value to find the bitmask of the right table
107768 ** of the join. Subtracting one from the right table bitmask gives a
107769 ** bitmask for all tables to the left of the join. Knowing the bitmask
107770 ** for all tables to the left of a left join is important. Ticket #3015.
107771 **
107772 ** Configure the WhereClause.vmask variable so that bits that correspond
107773 ** to virtual table cursors are set. This is used to selectively disable
107774 ** the OR-to-IN transformation in exprAnalyzeOrTerm(). It is not helpful
107775 ** with virtual tables.
107776 **
107777 ** Note that bitmasks are created for all pTabList->nSrc tables in
107778 ** pTabList, not just the first nTabList tables. nTabList is normally
107779 ** equal to pTabList->nSrc but might be shortened to 1 if the
107780 ** WHERE_ONETABLE_ONLY flag is set.
107781 */
107782 assert( sWBI.pWC->vmask==0 && pMaskSet->n==0 );
107783 for(ii=0; ii<pTabList->nSrc; ii++){
107784 createMask(pMaskSet, pTabList->a[ii].iCursor);
107785 #ifndef SQLITE_OMIT_VIRTUALTABLE
107786 if( ALWAYS(pTabList->a[ii].pTab) && IsVirtual(pTabList->a[ii].pTab) ){
107787 sWBI.pWC->vmask |= ((Bitmask)1 << ii);
107788 }
107789 #endif
107790 }
107791 #ifndef NDEBUG
107792 {
107793 Bitmask toTheLeft = 0;
107794 for(ii=0; ii<pTabList->nSrc; ii++){
@@ -108268,11 +108339,11 @@
108268 struct InLoop *pIn;
108269 int j;
108270 sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
108271 for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
108272 sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
108273 sqlite3VdbeAddOp2(v, OP_Next, pIn->iCur, pIn->addrInTop);
108274 sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
108275 }
108276 sqlite3DbFree(db, pLevel->u.in.aInLoop);
108277 }
108278 sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
108279
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -673,11 +673,11 @@
673 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
674 ** [sqlite_version()] and [sqlite_source_id()].
675 */
676 #define SQLITE_VERSION "3.7.16"
677 #define SQLITE_VERSION_NUMBER 3007016
678 #define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
679
680 /*
681 ** CAPI3REF: Run-Time Library Version Numbers
682 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
683 **
@@ -1048,10 +1048,19 @@
1048 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
1049 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
1050 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
1051 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
1052 #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
1053 #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
1054 #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
1055 #define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
1056 #define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
1057 #define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
1058 #define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
1059 #define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
1060 #define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
1061 #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
1062
1063 /*
1064 ** CAPI3REF: Flags For File Open Operations
1065 **
1066 ** These bit values are intended for use in the
@@ -10018,11 +10027,11 @@
10027 #define SQLITE_NullCallback 0x00000020 /* Invoke the callback once if the */
10028 /* result set is empty */
10029 #define SQLITE_SqlTrace 0x00000040 /* Debug print SQL as it executes */
10030 #define SQLITE_VdbeListing 0x00000080 /* Debug listings of VDBE programs */
10031 #define SQLITE_WriteSchema 0x00000100 /* OK to update SQLITE_MASTER */
10032 #define SQLITE_VdbeAddopTrace 0x00000200 /* Trace sqlite3VdbeAddOp() calls */
10033 #define SQLITE_IgnoreChecks 0x00000400 /* Do not enforce check constraints */
10034 #define SQLITE_ReadUncommitted 0x0000800 /* For shared-cache mode */
10035 #define SQLITE_LegacyFileFmt 0x00001000 /* Create new databases in format 1 */
10036 #define SQLITE_FullFSync 0x00002000 /* Use full fsync on the backend */
10037 #define SQLITE_CkptFullFSync 0x00004000 /* Use full fsync for checkpoint */
@@ -11034,10 +11043,11 @@
11043 struct {
11044 int nIn; /* Number of entries in aInLoop[] */
11045 struct InLoop {
11046 int iCur; /* The VDBE cursor used by this IN operator */
11047 int addrInTop; /* Top of the IN loop */
11048 u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */
11049 } *aInLoop; /* Information about each nested IN operator */
11050 } in; /* Used when plan.wsFlags&WHERE_IN_ABLE */
11051 Index *pCovidx; /* Possible covering index for WHERE_MULTI_OR */
11052 } u;
11053 double rOptCost; /* "Optimal" cost for this level */
@@ -11973,11 +11983,11 @@
11983 SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
11984 SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
11985 SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
11986 SQLITE_PRIVATE void sqlite3MultiWrite(Parse*);
11987 SQLITE_PRIVATE void sqlite3MayAbort(Parse*);
11988 SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, int);
11989 SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
11990 SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
11991 SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
11992 SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*);
11993 SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int);
@@ -13208,11 +13218,11 @@
13218 Mem *aMem; /* Array of memory cells for parent frame */
13219 u8 *aOnceFlag; /* Array of OP_Once flags for parent frame */
13220 VdbeCursor **apCsr; /* Array of Vdbe cursors for parent frame */
13221 void *token; /* Copy of SubProgram.token */
13222 i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */
13223 int nCursor; /* Number of entries in apCsr */
13224 int pc; /* Program Counter in parent (calling) frame */
13225 int nOp; /* Size of aOp array */
13226 int nMem; /* Number of entries in aMem */
13227 int nOnceFlag; /* Number of entries in aOnceFlag */
13228 int nChildMem; /* Number of memory cells for child frame */
@@ -13394,11 +13404,11 @@
13404 int nOp; /* Number of instructions in the program */
13405 int nOpAlloc; /* Number of slots allocated for aOp[] */
13406 int nLabel; /* Number of labels used */
13407 int *aLabel; /* Space to hold the labels */
13408 u16 nResColumn; /* Number of columns in one row of the result set */
13409 int nCursor; /* Number of slots in apCsr[] */
13410 u32 magic; /* Magic number for sanity checking */
13411 char *zErrMsg; /* Error message written here */
13412 Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */
13413 VdbeCursor **apCsr; /* One element of this array for each open cursor */
13414 Mem *aVar; /* Values for the OP_Variable opcode. */
@@ -31099,11 +31109,11 @@
31109 /*
31110 ** This function outputs the specified (ANSI) string to the Win32 debugger
31111 ** (if available).
31112 */
31113
31114 SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){
31115 char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE];
31116 int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */
31117 if( nMin<-1 ) nMin = -1; /* all negative values become -1. */
31118 assert( nMin==-1 || nMin==0 || nMin<SQLITE_WIN32_DBG_BUF_SIZE );
31119 #if defined(SQLITE_WIN32_HAS_ANSI)
@@ -31732,13 +31742,14 @@
31742
31743 #if SQLITE_OS_WINCE
31744 /*************************************************************************
31745 ** This section contains code for WinCE only.
31746 */
31747 #if !defined(SQLITE_MSVC_LOCALTIME_API) || !SQLITE_MSVC_LOCALTIME_API
31748 /*
31749 ** The MSVC CRT on Windows CE may not have a localtime() function. So
31750 ** create a substitute.
31751 */
31752 /* #include <time.h> */
31753 struct tm *__cdecl localtime(const time_t *t)
31754 {
31755 static struct tm y;
@@ -31758,10 +31769,11 @@
31769 y.tm_hour = pTm.wHour;
31770 y.tm_min = pTm.wMinute;
31771 y.tm_sec = pTm.wSecond;
31772 return &y;
31773 }
31774 #endif
31775
31776 #define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)]
31777
31778 /*
31779 ** Acquire a lock on the handle h
@@ -31779,19 +31791,21 @@
31791
31792 /*
31793 ** Create the mutex and shared memory used for locking in the file
31794 ** descriptor pFile
31795 */
31796 static int winceCreateLock(const char *zFilename, winFile *pFile){
31797 LPWSTR zTok;
31798 LPWSTR zName;
31799 DWORD lastErrno;
31800 BOOL bLogged = FALSE;
31801 BOOL bInit = TRUE;
31802
31803 zName = utf8ToUnicode(zFilename);
31804 if( zName==0 ){
31805 /* out of memory */
31806 return SQLITE_IOERR_NOMEM;
31807 }
31808
31809 /* Initialize the local lockdata */
31810 memset(&pFile->local, 0, sizeof(pFile->local));
31811
@@ -31804,13 +31818,14 @@
31818
31819 /* Create/open the named mutex */
31820 pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);
31821 if (!pFile->hMutex){
31822 pFile->lastErrno = osGetLastError();
31823 winLogError(SQLITE_IOERR, pFile->lastErrno,
31824 "winceCreateLock1", zFilename);
31825 sqlite3_free(zName);
31826 return SQLITE_IOERR;
31827 }
31828
31829 /* Acquire the mutex before continuing */
31830 winceMutexAcquire(pFile->hMutex);
31831
@@ -31823,45 +31838,53 @@
31838 PAGE_READWRITE, 0, sizeof(winceLock),
31839 zName);
31840
31841 /* Set a flag that indicates we're the first to create the memory so it
31842 ** must be zero-initialized */
31843 lastErrno = osGetLastError();
31844 if (lastErrno == ERROR_ALREADY_EXISTS){
31845 bInit = FALSE;
31846 }
31847
31848 sqlite3_free(zName);
31849
31850 /* If we succeeded in making the shared memory handle, map it. */
31851 if( pFile->hShared ){
31852 pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,
31853 FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));
31854 /* If mapping failed, close the shared memory handle and erase it */
31855 if( !pFile->shared ){
31856 pFile->lastErrno = osGetLastError();
31857 winLogError(SQLITE_IOERR, pFile->lastErrno,
31858 "winceCreateLock2", zFilename);
31859 bLogged = TRUE;
31860 osCloseHandle(pFile->hShared);
31861 pFile->hShared = NULL;
31862 }
31863 }
31864
31865 /* If shared memory could not be created, then close the mutex and fail */
31866 if( pFile->hShared==NULL ){
31867 if( !bLogged ){
31868 pFile->lastErrno = lastErrno;
31869 winLogError(SQLITE_IOERR, pFile->lastErrno,
31870 "winceCreateLock3", zFilename);
31871 bLogged = TRUE;
31872 }
31873 winceMutexRelease(pFile->hMutex);
31874 osCloseHandle(pFile->hMutex);
31875 pFile->hMutex = NULL;
31876 return SQLITE_IOERR;
31877 }
31878
31879 /* Initialize the shared memory if we're supposed to */
31880 if( bInit ){
31881 memset(pFile->shared, 0, sizeof(winceLock));
31882 }
31883
31884 winceMutexRelease(pFile->hMutex);
31885 return SQLITE_OK;
31886 }
31887
31888 /*
31889 ** Destroy the part of winFile that deals with wince locks
31890 */
@@ -32866,11 +32889,11 @@
32889 a[1] = win32IoerrRetryDelay;
32890 }
32891 return SQLITE_OK;
32892 }
32893 case SQLITE_FCNTL_TEMPFILENAME: {
32894 char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname );
32895 if( zTFile ){
32896 getTempname(pFile->pVfs->mxPathname, zTFile);
32897 *(char**)pArg = zTFile;
32898 }
32899 return SQLITE_OK;
@@ -33802,10 +33825,11 @@
33825 /* If the second argument to this function is NULL, generate a
33826 ** temporary file name to use
33827 */
33828 if( !zUtf8Name ){
33829 assert(isDelete && !isOpenJournal);
33830 memset(zTmpname, 0, MAX_PATH+2);
33831 rc = getTempname(MAX_PATH+2, zTmpname);
33832 if( rc!=SQLITE_OK ){
33833 return rc;
33834 }
33835 zUtf8Name = zTmpname;
@@ -33953,15 +33977,15 @@
33977 pFile->ctrlFlags |= WINFILE_PSOW;
33978 }
33979
33980 #if SQLITE_OS_WINCE
33981 if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
33982 && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK
33983 ){
33984 osCloseHandle(h);
33985 sqlite3_free(zConverted);
33986 return rc;
33987 }
33988 if( isTemp ){
33989 pFile->zDeleteOnClose = zConverted;
33990 }else
33991 #endif
@@ -58582,22 +58606,10 @@
58606 ** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) Prior
58607 ** to version 2.8.7, all this code was combined into the vdbe.c source file.
58608 ** But that file was getting too big so this subroutines were split out.
58609 */
58610
 
 
 
 
 
 
 
 
 
 
 
 
58611 /*
58612 ** Create a new virtual database engine.
58613 */
58614 SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(sqlite3 *db){
58615 Vdbe *p;
@@ -58723,11 +58735,13 @@
58735 pOp->p3 = p3;
58736 pOp->p4.p = 0;
58737 pOp->p4type = P4_NOTUSED;
58738 #ifdef SQLITE_DEBUG
58739 pOp->zComment = 0;
58740 if( p->db->flags & SQLITE_VdbeAddopTrace ){
58741 sqlite3VdbePrintOp(0, i, &p->aOp[i]);
58742 }
58743 #endif
58744 #ifdef VDBE_PROFILE
58745 pOp->cycles = 0;
58746 pOp->cnt = 0;
58747 #endif
@@ -58942,11 +58956,11 @@
58956 if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename
58957 #ifndef SQLITE_OMIT_FOREIGN_KEY
58958 || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1)
58959 #endif
58960 || ((opcode==OP_Halt || opcode==OP_HaltIfNull)
58961 && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
58962 ){
58963 hasAbort = 1;
58964 break;
58965 }
58966 }
@@ -59077,11 +59091,11 @@
59091 pOut->p4type = P4_NOTUSED;
59092 pOut->p4.p = 0;
59093 pOut->p5 = 0;
59094 #ifdef SQLITE_DEBUG
59095 pOut->zComment = 0;
59096 if( p->db->flags & SQLITE_VdbeAddopTrace ){
59097 sqlite3VdbePrintOp(0, i+addr, &p->aOp[i+addr]);
59098 }
59099 #endif
59100 }
59101 p->nOp += nOp;
@@ -60103,11 +60117,11 @@
60117 }
60118 zCsr = p->pFree;
60119 zEnd = &zCsr[nByte];
60120 }while( nByte && !db->mallocFailed );
60121
60122 p->nCursor = nCursor;
60123 p->nOnceFlag = nOnce;
60124 if( p->aVar ){
60125 p->nVar = (ynVar)nVar;
60126 for(n=0; n<nVar; n++){
60127 p->aVar[n].flags = MEM_Null;
@@ -60345,11 +60359,11 @@
60359
60360 /* If there are any write-transactions at all, invoke the commit hook */
60361 if( needXcommit && db->xCommitCallback ){
60362 rc = db->xCommitCallback(db->pCommitArg);
60363 if( rc ){
60364 return SQLITE_CONSTRAINT_COMMITHOOK;
60365 }
60366 }
60367
60368 /* The simple case - no more than one database file (not counting the
60369 ** TEMP database) has a transaction active. There is no need for the
@@ -60637,18 +60651,18 @@
60651 ** handle associated with the VM passed as an argument is about to be
60652 ** committed. If there are outstanding deferred foreign key constraint
60653 ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK.
60654 **
60655 ** If there are outstanding FK violations and this function returns
60656 ** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY
60657 ** and write an error message to it. Then return SQLITE_ERROR.
60658 */
60659 #ifndef SQLITE_OMIT_FOREIGN_KEY
60660 SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
60661 sqlite3 *db = p->db;
60662 if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
60663 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
60664 p->errorAction = OE_Abort;
60665 sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
60666 return SQLITE_ERROR;
60667 }
60668 return SQLITE_OK;
@@ -60759,11 +60773,11 @@
60773 if( rc!=SQLITE_OK ){
60774 if( NEVER(p->readOnly) ){
60775 sqlite3VdbeLeave(p);
60776 return SQLITE_ERROR;
60777 }
60778 rc = SQLITE_CONSTRAINT_FOREIGNKEY;
60779 }else{
60780 /* The auto-commit flag is true, the vdbe program was successful
60781 ** or hit an 'OR FAIL' constraint and there are no deferred foreign
60782 ** key constraints to hold up the transaction. This means a commit
60783 ** is required. */
@@ -60802,11 +60816,11 @@
60816 ** current statement error code.
60817 */
60818 if( eStatementOp ){
60819 rc = sqlite3VdbeCloseStatement(p, eStatementOp);
60820 if( rc ){
60821 if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){
60822 p->rc = rc;
60823 sqlite3DbFree(db, p->zErrMsg);
60824 p->zErrMsg = 0;
60825 }
60826 sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
@@ -61043,11 +61057,11 @@
61057 sqlite3DbFree(db, p->aLabel);
61058 sqlite3DbFree(db, p->aColName);
61059 sqlite3DbFree(db, p->zSql);
61060 sqlite3DbFree(db, p->pFree);
61061 #if defined(SQLITE_ENABLE_TREE_EXPLAIN)
61062 sqlite3DbFree(db, p->zExplain);
61063 sqlite3DbFree(db, p->pExplain);
61064 #endif
61065 }
61066
61067 /*
@@ -64799,11 +64813,11 @@
64813 rc = sqlite3VdbeHalt(p);
64814 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
64815 if( rc==SQLITE_BUSY ){
64816 p->rc = rc = SQLITE_BUSY;
64817 }else{
64818 assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
64819 assert( rc==SQLITE_OK || db->nDeferredCons>0 );
64820 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
64821 }
64822 goto vdbe_return;
64823 }
@@ -70131,11 +70145,11 @@
70145 importVtabErrMsg(p, u.cr.pVtab);
70146 if( rc==SQLITE_OK && pOp->p1 ){
70147 assert( u.cr.nArg>1 && u.cr.apArg[0] && (u.cr.apArg[0]->flags&MEM_Null) );
70148 db->lastRowid = lastRowid = u.cr.rowid;
70149 }
70150 if( (rc&0xff)==SQLITE_CONSTRAINT && pOp->p4.pVtab->bConstraint ){
70151 if( pOp->p5==OE_Ignore ){
70152 rc = SQLITE_OK;
70153 }else{
70154 p->errorAction = ((pOp->p5==OE_Replace) ? OE_Abort : pOp->p5);
70155 }
@@ -72775,12 +72789,12 @@
72789
72790 pTab = pItem->pTab;
72791 assert( pTab!=0 && pTab->zName!=0 );
72792 assert( pTab->nCol>0 );
72793 if( pItem->pSelect && (pItem->pSelect->selFlags & SF_NestedFrom)!=0 ){
 
72794 int hit = 0;
72795 pEList = pItem->pSelect->pEList;
72796 for(j=0; j<pEList->nExpr; j++){
72797 if( sqlite3MatchSpanName(pEList->a[j].zSpan, zCol, zTab, zDb) ){
72798 cnt++;
72799 cntTab = 2;
72800 pMatch = pItem;
@@ -76776,11 +76790,12 @@
76790 assert( !ExprHasProperty(pExpr, EP_IntValue) );
76791 if( pExpr->affinity==OE_Ignore ){
76792 sqlite3VdbeAddOp4(
76793 v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0);
76794 }else{
76795 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER,
76796 pExpr->affinity, pExpr->u.zToken, 0);
76797 }
76798
76799 break;
76800 }
76801 #endif
@@ -83247,12 +83262,12 @@
83262 if( pIndex->onError!=OE_None ){
83263 int j2 = sqlite3VdbeCurrentAddr(v) + 3;
83264 sqlite3VdbeAddOp2(v, OP_Goto, 0, j2);
83265 addr2 = sqlite3VdbeCurrentAddr(v);
83266 sqlite3VdbeAddOp3(v, OP_SorterCompare, iSorter, j2, regRecord);
83267 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
83268 OE_Abort, "indexed columns are not unique", P4_STATIC
83269 );
83270 }else{
83271 addr2 = sqlite3VdbeCurrentAddr(v);
83272 }
83273 sqlite3VdbeAddOp2(v, OP_SorterData, iSorter, regRecord);
@@ -83274,12 +83289,12 @@
83289 ** opcode use the values stored within seems dangerous. However, since
83290 ** we can be sure that no other temp registers have been allocated
83291 ** since sqlite3ReleaseTempRange() was called, it is safe to do so.
83292 */
83293 sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32);
83294 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
83295 "indexed columns are not unique", P4_STATIC);
83296 }
83297 sqlite3VdbeAddOp3(v, OP_IdxInsert, iIdx, regRecord, 0);
83298 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
83299 #endif
83300 sqlite3ReleaseTempReg(pParse, regRecord);
@@ -84492,16 +84507,23 @@
84507 /*
84508 ** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT
84509 ** error. The onError parameter determines which (if any) of the statement
84510 ** and/or current transaction is rolled back.
84511 */
84512 SQLITE_PRIVATE void sqlite3HaltConstraint(
84513 Parse *pParse, /* Parsing context */
84514 int errCode, /* extended error code */
84515 int onError, /* Constraint type */
84516 char *p4, /* Error message */
84517 int p4type /* P4_STATIC or P4_TRANSIENT */
84518 ){
84519 Vdbe *v = sqlite3GetVdbe(pParse);
84520 assert( (errCode&0xff)==SQLITE_CONSTRAINT );
84521 if( onError==OE_Abort ){
84522 sqlite3MayAbort(pParse);
84523 }
84524 sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type);
84525 }
84526
84527 /*
84528 ** Check to see if pIndex uses the collating sequence pColl. Return
84529 ** true if it does and false if it does not.
@@ -87484,12 +87506,13 @@
87506 /*
87507 ** Deferred and Immediate FKs
87508 ** --------------------------
87509 **
87510 ** Foreign keys in SQLite come in two flavours: deferred and immediate.
87511 ** If an immediate foreign key constraint is violated,
87512 ** SQLITE_CONSTRAINT_FOREIGNKEY is returned and the current
87513 ** statement transaction rolled back. If a
87514 ** deferred foreign key constraint is violated, no action is taken
87515 ** immediately. However if the application attempts to commit the
87516 ** transaction before fixing the constraint violation, the attempt fails.
87517 **
87518 ** Deferred constraints are implemented using a simple counter associated
@@ -87549,11 +87572,12 @@
87572 ** row is inserted.
87573 **
87574 ** Immediate constraints are usually handled similarly. The only difference
87575 ** is that the counter used is stored as part of each individual statement
87576 ** object (struct Vdbe). If, after the statement has run, its immediate
87577 ** constraint counter is greater than zero,
87578 ** it returns SQLITE_CONSTRAINT_FOREIGNKEY
87579 ** and the statement transaction is rolled back. An exception is an INSERT
87580 ** statement that inserts a single row only (no triggers). In this case,
87581 ** instead of using a counter, an exception is thrown immediately if the
87582 ** INSERT violates a foreign key constraint. This is necessary as such
87583 ** an INSERT does not open a statement transaction.
@@ -87889,12 +87913,12 @@
87913 /* Special case: If this is an INSERT statement that will insert exactly
87914 ** one row into the table, raise a constraint immediately instead of
87915 ** incrementing a counter. This is necessary as the VM code is being
87916 ** generated for will not open a statement transaction. */
87917 assert( nIncr==1 );
87918 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
87919 OE_Abort, "foreign key constraint failed", P4_STATIC
87920 );
87921 }else{
87922 if( nIncr>0 && pFKey->isDeferred==0 ){
87923 sqlite3ParseToplevel(pParse)->mayAbort = 1;
87924 }
@@ -88130,12 +88154,12 @@
88154 /* If the DELETE has generated immediate foreign key constraint
88155 ** violations, halt the VDBE and return an error at this point, before
88156 ** any modifications to the schema are made. This is because statement
88157 ** transactions are not able to rollback schema changes. */
88158 sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2);
88159 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY,
88160 OE_Abort, "foreign key constraint failed", P4_STATIC
88161 );
88162
88163 if( iSkip ){
88164 sqlite3VdbeResolveLabel(v, iSkip);
88165 }
@@ -89935,11 +89959,11 @@
89959 sqlite3MayAbort(pParse);
89960 case OE_Rollback:
89961 case OE_Fail: {
89962 char *zMsg;
89963 sqlite3VdbeAddOp3(v, OP_HaltIfNull,
89964 SQLITE_CONSTRAINT_NOTNULL, onError, regData+i);
89965 zMsg = sqlite3MPrintf(db, "%s.%s may not be NULL",
89966 pTab->zName, pTab->aCol[i].zName);
89967 sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
89968 break;
89969 }
@@ -89975,11 +89999,12 @@
89999 if( zConsName ){
90000 zConsName = sqlite3MPrintf(db, "constraint %s failed", zConsName);
90001 }else{
90002 zConsName = 0;
90003 }
90004 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,
90005 onError, zConsName, P4_DYNAMIC);
90006 }
90007 sqlite3VdbeResolveLabel(v, allOk);
90008 }
90009 }
90010 #endif /* !defined(SQLITE_OMIT_CHECK) */
@@ -90006,12 +90031,12 @@
90031 /* Fall thru into the next case */
90032 }
90033 case OE_Rollback:
90034 case OE_Abort:
90035 case OE_Fail: {
90036 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
90037 onError, "PRIMARY KEY must be unique", P4_STATIC);
90038 break;
90039 }
90040 case OE_Replace: {
90041 /* If there are DELETE triggers on this table and the
90042 ** recursive-triggers flag is set, call GenerateRowDelete() to
@@ -90134,11 +90159,12 @@
90159 sqlite3StrAccumAppend(&errMsg, zCol, -1);
90160 }
90161 sqlite3StrAccumAppend(&errMsg,
90162 pIdx->nColumn>1 ? " are not unique" : " is not unique", -1);
90163 zErr = sqlite3StrAccumFinish(&errMsg);
90164 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_UNIQUE,
90165 onError, zErr, 0);
90166 sqlite3DbFree(errMsg.db, zErr);
90167 break;
90168 }
90169 case OE_Ignore: {
90170 assert( seenReplace==0 );
@@ -90542,12 +90568,12 @@
90568 regData = sqlite3GetTempReg(pParse);
90569 regRowid = sqlite3GetTempReg(pParse);
90570 if( pDest->iPKey>=0 ){
90571 addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
90572 addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
90573 sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_PRIMARYKEY,
90574 onError, "PRIMARY KEY must be unique", P4_STATIC);
90575 sqlite3VdbeJumpHere(v, addr2);
90576 autoIncStep(pParse, regAutoinc, regRowid);
90577 }else if( pDest->pIndex==0 ){
90578 addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
90579 }else{
@@ -91000,10 +91026,24 @@
91026 int (*wal_checkpoint)(sqlite3*,const char*);
91027 void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*);
91028 int (*blob_reopen)(sqlite3_blob*,sqlite3_int64);
91029 int (*vtab_config)(sqlite3*,int op,...);
91030 int (*vtab_on_conflict)(sqlite3*);
91031 /* Version 3.7.16 and later */
91032 int (*close_v2)(sqlite3*);
91033 const char *(*db_filename)(sqlite3*,const char*);
91034 int (*db_readonly)(sqlite3*,const char*);
91035 int (*db_release_memory)(sqlite3*);
91036 const char *(*errstr)(int);
91037 int (*stmt_busy)(sqlite3_stmt*);
91038 int (*stmt_readonly)(sqlite3_stmt*);
91039 int (*stricmp)(const char*,const char*);
91040 int (*uri_boolean)(const char*,const char*,int);
91041 sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64);
91042 const char *(*uri_parameter)(const char*,const char*);
91043 char *(*vsnprintf)(int,char*,const char*,va_list);
91044 int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*);
91045 };
91046
91047 /*
91048 ** The following macros redefine the API routines so that they are
91049 ** redirected throught the global sqlite3_api structure.
@@ -91203,10 +91243,24 @@
91243 #define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint
91244 #define sqlite3_wal_hook sqlite3_api->wal_hook
91245 #define sqlite3_blob_reopen sqlite3_api->blob_reopen
91246 #define sqlite3_vtab_config sqlite3_api->vtab_config
91247 #define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict
91248 /* Version 3.7.16 and later */
91249 #define sqlite3_close_v2 sqlite3_api->close_v2
91250 #define sqlite3_db_filename sqlite3_api->db_filename
91251 #define sqlite3_db_readonly sqlite3_api->db_readonly
91252 #define sqlite3_db_release_memory sqlite3_api->db_release_memory
91253 #define sqlite3_errstr sqlite3_api->errstr
91254 #define sqlite3_stmt_busy sqlite3_api->stmt_busy
91255 #define sqlite3_stmt_readonly sqlite3_api->stmt_readonly
91256 #define sqlite3_stricmp sqlite3_api->stricmp
91257 #define sqlite3_uri_boolean sqlite3_api->uri_boolean
91258 #define sqlite3_uri_int64 sqlite3_api->uri_int64
91259 #define sqlite3_uri_parameter sqlite3_api->uri_parameter
91260 #define sqlite3_uri_vsnprintf sqlite3_api->vsnprintf
91261 #define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2
91262 #endif /* SQLITE_CORE */
91263
91264 #define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api = 0;
91265 #define SQLITE_EXTENSION_INIT2(v) sqlite3_api = v;
91266
@@ -92038,10 +92092,13 @@
92092 #endif
92093 #ifdef SQLITE_DEBUG
92094 { "sql_trace", SQLITE_SqlTrace },
92095 { "vdbe_listing", SQLITE_VdbeListing },
92096 { "vdbe_trace", SQLITE_VdbeTrace },
92097 { "vdbe_addoptrace", SQLITE_VdbeAddopTrace},
92098 { "vdbe_debug", SQLITE_SqlTrace | SQLITE_VdbeListing
92099 | SQLITE_VdbeTrace },
92100 #endif
92101 #ifndef SQLITE_OMIT_CHECK
92102 { "ignore_check_constraints", SQLITE_IgnoreChecks },
92103 #endif
92104 /* The following is VERY experimental */
@@ -96198,10 +96255,12 @@
96255 switch( p->op ){
96256 case TK_ALL: {
96257 int addr = 0;
96258 int nLimit;
96259 assert( !pPrior->pLimit );
96260 pPrior->iLimit = p->iLimit;
96261 pPrior->iOffset = p->iOffset;
96262 pPrior->pLimit = p->pLimit;
96263 pPrior->pOffset = p->pOffset;
96264 explainSetInteger(iSub1, pParse->iNextSelectId);
96265 rc = sqlite3Select(pParse, pPrior, &dest);
96266 p->pLimit = 0;
@@ -97454,16 +97513,19 @@
97513 */
97514 for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
97515 Select *pNew;
97516 ExprList *pOrderBy = p->pOrderBy;
97517 Expr *pLimit = p->pLimit;
97518 Expr *pOffset = p->pOffset;
97519 Select *pPrior = p->pPrior;
97520 p->pOrderBy = 0;
97521 p->pSrc = 0;
97522 p->pPrior = 0;
97523 p->pLimit = 0;
97524 p->pOffset = 0;
97525 pNew = sqlite3SelectDup(db, p, 0);
97526 p->pOffset = pOffset;
97527 p->pLimit = pLimit;
97528 p->pOrderBy = pOrderBy;
97529 p->pSrc = pSrc;
97530 p->op = TK_ALL;
97531 p->pRightmost = 0;
@@ -97784,18 +97846,19 @@
97846 SrcList *pTabList;
97847 ExprList *pEList;
97848 struct SrcList_item *pFrom;
97849 sqlite3 *db = pParse->db;
97850 Expr *pE, *pRight, *pExpr;
97851 u16 selFlags = p->selFlags;
97852
97853 p->selFlags |= SF_Expanded;
97854 if( db->mallocFailed ){
97855 return WRC_Abort;
97856 }
97857 if( NEVER(p->pSrc==0) || (selFlags & SF_Expanded)!=0 ){
97858 return WRC_Prune;
97859 }
 
97860 pTabList = p->pSrc;
97861 pEList = p->pEList;
97862
97863 /* Make sure cursor numbers have been assigned to all entries in
97864 ** the FROM clause of the SELECT statement.
@@ -97834,10 +97897,16 @@
97897 }else{
97898 /* An ordinary table or view name in the FROM clause */
97899 assert( pFrom->pTab==0 );
97900 pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom);
97901 if( pTab==0 ) return WRC_Abort;
97902 if( pTab->nRef==0xffff ){
97903 sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535",
97904 pTab->zName);
97905 pFrom->pTab = 0;
97906 return WRC_Abort;
97907 }
97908 pTab->nRef++;
97909 #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
97910 if( pTab->pSelect || IsVirtual(pTab) ){
97911 /* We reach here if the named table is a really a view */
97912 if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
@@ -98146,10 +98215,11 @@
98215 NameContext *pOuterNC /* Name context for container */
98216 ){
98217 sqlite3 *db;
98218 if( NEVER(p==0) ) return;
98219 db = pParse->db;
98220 if( db->mallocFailed ) return;
98221 if( p->selFlags & SF_HasTypeInfo ) return;
98222 sqlite3SelectExpand(pParse, p);
98223 if( pParse->nErr || db->mallocFailed ) return;
98224 sqlite3ResolveSelectNames(pParse, p, pOuterNC);
98225 if( pParse->nErr || db->mallocFailed ) return;
@@ -99231,11 +99301,14 @@
99301 SQLITE_PRIVATE void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
99302 if( p==0 ){
99303 sqlite3ExplainPrintf(pVdbe, "(null-select)");
99304 return;
99305 }
99306 while( p->pPrior ){
99307 p->pPrior->pNext = p;
99308 p = p->pPrior;
99309 }
99310 sqlite3ExplainPush(pVdbe);
99311 while( p ){
99312 explainOneSelect(pVdbe, p);
99313 p = p->pNext;
99314 if( p==0 ) break;
@@ -102850,11 +102923,10 @@
102923 ** subclauses points to the WhereClause object for the whole clause.
102924 */
102925 struct WhereClause {
102926 Parse *pParse; /* The parser context */
102927 WhereMaskSet *pMaskSet; /* Mapping of table cursor numbers to bitmasks */
 
102928 WhereClause *pOuter; /* Outer conjunction */
102929 u8 op; /* Split operator. TK_AND or TK_OR */
102930 u16 wctrlFlags; /* Might include WHERE_AND_ONLY */
102931 int nTerm; /* Number of terms */
102932 int nSlot; /* Number of entries in a[] */
@@ -103027,11 +103099,10 @@
103099 pWC->pMaskSet = pMaskSet;
103100 pWC->pOuter = 0;
103101 pWC->nTerm = 0;
103102 pWC->nSlot = ArraySize(pWC->aStatic);
103103 pWC->a = pWC->aStatic;
 
103104 pWC->wctrlFlags = wctrlFlags;
103105 }
103106
103107 /* Forward reference */
103108 static void whereClauseClear(WhereClause*);
@@ -103627,11 +103698,11 @@
103698 ** (D) x=expr1 OR (y>11 AND y<22 AND z LIKE '*hello*')
103699 ** (E) (p.a=1 AND q.b=2 AND r.c=3) OR (p.x=4 AND q.y=5 AND r.z=6)
103700 **
103701 ** CASE 1:
103702 **
103703 ** If all subterms are of the form T.C=expr for some single column of C and
103704 ** a single table T (as shown in example B above) then create a new virtual
103705 ** term that is an equivalent IN expression. In other words, if the term
103706 ** being analyzed is:
103707 **
103708 ** x = expr1 OR expr2 = x OR x = expr3
@@ -103715,11 +103786,11 @@
103786
103787 /*
103788 ** Compute the set of tables that might satisfy cases 1 or 2.
103789 */
103790 indexable = ~(Bitmask)0;
103791 chngToIN = ~(Bitmask)0;
103792 for(i=pOrWc->nTerm-1, pOrTerm=pOrWc->a; i>=0 && indexable; i--, pOrTerm++){
103793 if( (pOrTerm->eOperator & WO_SINGLE)==0 ){
103794 WhereAndInfo *pAndInfo;
103795 assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 );
103796 chngToIN = 0;
@@ -104982,12 +105053,13 @@
105053 Table *pTab = pSrc->pTab;
105054 sqlite3_index_info *pIdxInfo;
105055 struct sqlite3_index_constraint *pIdxCons;
105056 struct sqlite3_index_constraint_usage *pUsage;
105057 WhereTerm *pTerm;
105058 int i, j, k;
105059 int nOrderBy;
105060 int sortOrder; /* Sort order for IN clauses */
105061 int bAllowIN; /* Allow IN optimizations */
105062 double rCost;
105063
105064 /* Make sure wsFlags is initialized to some sane value. Otherwise, if the
105065 ** malloc in allocateIndexInfo() fails and this function returns leaving
@@ -105082,22 +105154,31 @@
105154
105155 if( vtabBestIndex(pParse, pTab, pIdxInfo) ){
105156 return;
105157 }
105158
105159 sortOrder = SQLITE_SO_ASC;
105160 pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
105161 for(i=0; i<pIdxInfo->nConstraint; i++, pIdxCons++){
105162 if( pUsage[i].argvIndex>0 ){
105163 j = pIdxCons->iTermOffset;
105164 pTerm = &pWC->a[j];
105165 p->cost.used |= pTerm->prereqRight;
105166 if( (pTerm->eOperator & WO_IN)!=0 ){
105167 if( pUsage[i].omit==0 ){
105168 /* Do not attempt to use an IN constraint if the virtual table
105169 ** says that the equivalent EQ constraint cannot be safely omitted.
105170 ** If we do attempt to use such a constraint, some rows might be
105171 ** repeated in the output. */
105172 break;
105173 }
105174 for(k=0; k<pIdxInfo->nOrderBy; k++){
105175 if( pIdxInfo->aOrderBy[k].iColumn==pIdxCons->iColumn ){
105176 sortOrder = pIdxInfo->aOrderBy[k].desc;
105177 break;
105178 }
105179 }
105180 }
105181 }
105182 }
105183 if( i>=pIdxInfo->nConstraint ) break;
105184 }
@@ -105123,11 +105204,12 @@
105204 }else{
105205 p->cost.rCost = rCost;
105206 }
105207 p->cost.plan.u.pVtabIdx = pIdxInfo;
105208 if( pIdxInfo->orderByConsumed ){
105209 assert( sortOrder==0 || sortOrder==1 );
105210 p->cost.plan.wsFlags |= WHERE_ORDERED + sortOrder*WHERE_REVERSE;
105211 p->cost.plan.nOBSat = nOrderBy;
105212 }else{
105213 p->cost.plan.nOBSat = p->i ? p->aLevel[p->i-1].plan.nOBSat : 0;
105214 }
105215 p->cost.plan.nEq = 0;
@@ -105720,14 +105802,11 @@
105802 pConstraint = findTerm(p->pWC, base, iColumn, p->notReady,
105803 WO_EQ|WO_ISNULL|WO_IN, pIdx);
105804 if( pConstraint==0 ){
105805 isEq = 0;
105806 }else if( (pConstraint->eOperator & WO_IN)!=0 ){
105807 isEq = 0;
 
 
 
105808 }else if( (pConstraint->eOperator & WO_ISNULL)!=0 ){
105809 uniqueNotNull = 0;
105810 isEq = 1; /* "X IS NULL" means X has only a single value */
105811 }else if( pConstraint->prereqRight==0 ){
105812 isEq = 1; /* Constraint "X=constant" means X has only a single value */
@@ -106027,12 +106106,12 @@
106106 ** constraint for all columns in the index, then this search will find
106107 ** at most a single row. In this case set the WHERE_UNIQUE flag to
106108 ** indicate this to the caller.
106109 **
106110 ** Otherwise, if the search may find more than one row, test to see if
106111 ** there is a range constraint on indexed column (pc.plan.nEq+1) that
106112 ** can be optimized using the index.
106113 */
106114 if( pc.plan.nEq==pProbe->nColumn && pProbe->onError!=OE_None ){
106115 testcase( pc.plan.wsFlags & WHERE_COLUMN_IN );
106116 testcase( pc.plan.wsFlags & WHERE_COLUMN_NULL );
106117 if( (pc.plan.wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){
@@ -106369,11 +106448,12 @@
106448 #ifndef SQLITE_OMIT_VIRTUALTABLE
106449 if( IsVirtual(p->pSrc->pTab) ){
106450 sqlite3_index_info *pIdxInfo = 0;
106451 p->ppIdxInfo = &pIdxInfo;
106452 bestVirtualIndex(p);
106453 assert( pIdxInfo!=0 || p->pParse->db->mallocFailed );
106454 if( pIdxInfo && pIdxInfo->needToFreeIdxStr ){
106455 sqlite3_free(pIdxInfo->idxStr);
106456 }
106457 sqlite3DbFree(p->pParse->db, pIdxInfo);
106458 }else
106459 #endif
@@ -106493,16 +106573,17 @@
106573 #ifndef SQLITE_OMIT_SUBQUERY
106574 }else{
106575 int eType;
106576 int iTab;
106577 struct InLoop *pIn;
106578 u8 bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
106579
106580 assert( pX->op==TK_IN );
106581 iReg = iTarget;
106582 eType = sqlite3FindInIndex(pParse, pX, 0);
106583 iTab = pX->iTable;
106584 sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
106585 assert( pLevel->plan.wsFlags & WHERE_IN_ABLE );
106586 if( pLevel->u.in.nIn==0 ){
106587 pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
106588 }
106589 pLevel->u.in.nIn++;
@@ -106516,10 +106597,11 @@
106597 if( eType==IN_INDEX_ROWID ){
106598 pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iReg);
106599 }else{
106600 pIn->addrInTop = sqlite3VdbeAddOp3(v, OP_Column, iTab, 0, iReg);
106601 }
106602 pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next;
106603 sqlite3VdbeAddOp1(v, OP_IsNull, iReg);
106604 }else{
106605 pLevel->u.in.nIn = 0;
106606 }
106607 #endif
@@ -106884,12 +106966,12 @@
106966 iReg = sqlite3GetTempRange(pParse, nConstraint+2);
106967 addrNotFound = pLevel->addrBrk;
106968 for(j=1; j<=nConstraint; j++){
106969 for(k=0; k<nConstraint; k++){
106970 if( aUsage[k].argvIndex==j ){
 
106971 int iTarget = iReg+j+1;
106972 pTerm = &pWC->a[aConstraint[k].iTermOffset];
106973 if( pTerm->eOperator & WO_IN ){
106974 codeEqualityTerm(pParse, pTerm, pLevel, iTarget);
106975 addrNotFound = pLevel->addrNxt;
106976 }else{
106977 sqlite3ExprCode(pParse, pTerm->pExpr->pRight, iTarget);
@@ -107767,28 +107849,17 @@
107849 ** its Expr.iRightJoinTable value to find the bitmask of the right table
107850 ** of the join. Subtracting one from the right table bitmask gives a
107851 ** bitmask for all tables to the left of the join. Knowing the bitmask
107852 ** for all tables to the left of a left join is important. Ticket #3015.
107853 **
 
 
 
 
 
107854 ** Note that bitmasks are created for all pTabList->nSrc tables in
107855 ** pTabList, not just the first nTabList tables. nTabList is normally
107856 ** equal to pTabList->nSrc but might be shortened to 1 if the
107857 ** WHERE_ONETABLE_ONLY flag is set.
107858 */
 
107859 for(ii=0; ii<pTabList->nSrc; ii++){
107860 createMask(pMaskSet, pTabList->a[ii].iCursor);
 
 
 
 
 
107861 }
107862 #ifndef NDEBUG
107863 {
107864 Bitmask toTheLeft = 0;
107865 for(ii=0; ii<pTabList->nSrc; ii++){
@@ -108268,11 +108339,11 @@
108339 struct InLoop *pIn;
108340 int j;
108341 sqlite3VdbeResolveLabel(v, pLevel->addrNxt);
108342 for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){
108343 sqlite3VdbeJumpHere(v, pIn->addrInTop+1);
108344 sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop);
108345 sqlite3VdbeJumpHere(v, pIn->addrInTop-1);
108346 }
108347 sqlite3DbFree(db, pLevel->u.in.aInLoop);
108348 }
108349 sqlite3VdbeResolveLabel(v, pLevel->addrBrk);
108350
+10 -1
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107107
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108108
** [sqlite_version()] and [sqlite_source_id()].
109109
*/
110110
#define SQLITE_VERSION "3.7.16"
111111
#define SQLITE_VERSION_NUMBER 3007016
112
-#define SQLITE_SOURCE_ID "2013-01-17 17:20:49 38852f158ab20bb4d7b264af987ec1538052bec3"
112
+#define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -482,10 +482,19 @@
482482
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
483483
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
484484
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
485485
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
486486
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
487
+#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
488
+#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
489
+#define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
490
+#define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
491
+#define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
492
+#define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
493
+#define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
494
+#define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
495
+#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
487496
488497
/*
489498
** CAPI3REF: Flags For File Open Operations
490499
**
491500
** These bit values are intended for use in the
492501
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.16"
111 #define SQLITE_VERSION_NUMBER 3007016
112 #define SQLITE_SOURCE_ID "2013-01-17 17:20:49 38852f158ab20bb4d7b264af987ec1538052bec3"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -482,10 +482,19 @@
482 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
483 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
484 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
485 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
486 #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
 
 
 
 
 
 
 
 
 
487
488 /*
489 ** CAPI3REF: Flags For File Open Operations
490 **
491 ** These bit values are intended for use in the
492
--- src/sqlite3.h
+++ src/sqlite3.h
@@ -107,11 +107,11 @@
107 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
108 ** [sqlite_version()] and [sqlite_source_id()].
109 */
110 #define SQLITE_VERSION "3.7.16"
111 #define SQLITE_VERSION_NUMBER 3007016
112 #define SQLITE_SOURCE_ID "2013-02-13 14:04:28 7e10a62d0eb1cb2bdafb6752b78a9d368e9f21f5"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -482,10 +482,19 @@
482 #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
483 #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
484 #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
485 #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
486 #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
487 #define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
488 #define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
489 #define SQLITE_CONSTRAINT_FOREIGNKEY (SQLITE_CONSTRAINT | (3<<8))
490 #define SQLITE_CONSTRAINT_FUNCTION (SQLITE_CONSTRAINT | (4<<8))
491 #define SQLITE_CONSTRAINT_NOTNULL (SQLITE_CONSTRAINT | (5<<8))
492 #define SQLITE_CONSTRAINT_PRIMARYKEY (SQLITE_CONSTRAINT | (6<<8))
493 #define SQLITE_CONSTRAINT_TRIGGER (SQLITE_CONSTRAINT | (7<<8))
494 #define SQLITE_CONSTRAINT_UNIQUE (SQLITE_CONSTRAINT | (8<<8))
495 #define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
496
497 /*
498 ** CAPI3REF: Flags For File Open Operations
499 **
500 ** These bit values are intended for use in the
501
+6 -6
--- src/stat.c
+++ src/stat.c
@@ -156,11 +156,11 @@
156156
int n, m;
157157
int szMax, szAvg;
158158
const char *zDb;
159159
int brief;
160160
char zBuf[100];
161
- const int colWidth = -20 /* printf alignment/width for left column */;
161
+ const int colWidth = -19 /* printf alignment/width for left column */;
162162
brief = find_option("brief", "b",0)!=0;
163163
db_find_and_open_repository(0,0);
164164
fsize = file_size(g.zRepositoryName);
165165
bigSizeName(sizeof(zBuf), zBuf, fsize);
166166
fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
@@ -179,12 +179,12 @@
179179
t = db_column_int64(&q, 0);
180180
szAvg = db_column_int(&q, 1);
181181
szMax = db_column_int(&q, 2);
182182
db_finalize(&q);
183183
bigSizeName(sizeof(zBuf), zBuf, t);
184
- fossil_print( "%*s%d bytes average, "
185
- "%d bytes max, %s total\n",
184
+ fossil_print( "%*s%d average, "
185
+ "%d max, %s total\n",
186186
colWidth, "artifact-sizes:",
187187
szAvg, szMax, zBuf);
188188
if( t/fsize < 5 ){
189189
b = 10;
190190
fsize /= 10;
@@ -214,20 +214,20 @@
214214
n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
215215
" + 0.99");
216216
fossil_print("%*s%d days or approximately %.2f years.\n",
217217
colWidth, "project-age:", n, n/365.2425);
218218
fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
219
- fossil_print("%*s%s %s %s (%s)\n",
219
+ fossil_print("%*s%s %s [%s] (%s)\n",
220220
colWidth, "fossil-version:",
221
- RELEASE_VERSION, MANIFEST_DATE, MANIFEST_VERSION,
221
+ MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
222222
COMPILER_NAME);
223223
fossil_print("%*s%.19s [%.10s] (%s)\n",
224224
colWidth, "sqlite-version:",
225225
SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20],
226226
SQLITE_VERSION);
227227
zDb = db_name("repository");
228
- fossil_print("%*s%d pages, %d bytes/page, %d free pages, "
228
+ fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
229229
"%s, %s mode\n",
230230
colWidth, "database-stats:",
231231
db_int(0, "PRAGMA %s.page_count", zDb),
232232
db_int(0, "PRAGMA %s.page_size", zDb),
233233
db_int(0, "PRAGMA %s.freelist_count", zDb),
234234
--- src/stat.c
+++ src/stat.c
@@ -156,11 +156,11 @@
156 int n, m;
157 int szMax, szAvg;
158 const char *zDb;
159 int brief;
160 char zBuf[100];
161 const int colWidth = -20 /* printf alignment/width for left column */;
162 brief = find_option("brief", "b",0)!=0;
163 db_find_and_open_repository(0,0);
164 fsize = file_size(g.zRepositoryName);
165 bigSizeName(sizeof(zBuf), zBuf, fsize);
166 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
@@ -179,12 +179,12 @@
179 t = db_column_int64(&q, 0);
180 szAvg = db_column_int(&q, 1);
181 szMax = db_column_int(&q, 2);
182 db_finalize(&q);
183 bigSizeName(sizeof(zBuf), zBuf, t);
184 fossil_print( "%*s%d bytes average, "
185 "%d bytes max, %s total\n",
186 colWidth, "artifact-sizes:",
187 szAvg, szMax, zBuf);
188 if( t/fsize < 5 ){
189 b = 10;
190 fsize /= 10;
@@ -214,20 +214,20 @@
214 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
215 " + 0.99");
216 fossil_print("%*s%d days or approximately %.2f years.\n",
217 colWidth, "project-age:", n, n/365.2425);
218 fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
219 fossil_print("%*s%s %s %s (%s)\n",
220 colWidth, "fossil-version:",
221 RELEASE_VERSION, MANIFEST_DATE, MANIFEST_VERSION,
222 COMPILER_NAME);
223 fossil_print("%*s%.19s [%.10s] (%s)\n",
224 colWidth, "sqlite-version:",
225 SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20],
226 SQLITE_VERSION);
227 zDb = db_name("repository");
228 fossil_print("%*s%d pages, %d bytes/page, %d free pages, "
229 "%s, %s mode\n",
230 colWidth, "database-stats:",
231 db_int(0, "PRAGMA %s.page_count", zDb),
232 db_int(0, "PRAGMA %s.page_size", zDb),
233 db_int(0, "PRAGMA %s.freelist_count", zDb),
234
--- src/stat.c
+++ src/stat.c
@@ -156,11 +156,11 @@
156 int n, m;
157 int szMax, szAvg;
158 const char *zDb;
159 int brief;
160 char zBuf[100];
161 const int colWidth = -19 /* printf alignment/width for left column */;
162 brief = find_option("brief", "b",0)!=0;
163 db_find_and_open_repository(0,0);
164 fsize = file_size(g.zRepositoryName);
165 bigSizeName(sizeof(zBuf), zBuf, fsize);
166 fossil_print( "%*s%s\n", colWidth, "repository-size:", zBuf );
@@ -179,12 +179,12 @@
179 t = db_column_int64(&q, 0);
180 szAvg = db_column_int(&q, 1);
181 szMax = db_column_int(&q, 2);
182 db_finalize(&q);
183 bigSizeName(sizeof(zBuf), zBuf, t);
184 fossil_print( "%*s%d average, "
185 "%d max, %s total\n",
186 colWidth, "artifact-sizes:",
187 szAvg, szMax, zBuf);
188 if( t/fsize < 5 ){
189 b = 10;
190 fsize /= 10;
@@ -214,20 +214,20 @@
214 n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
215 " + 0.99");
216 fossil_print("%*s%d days or approximately %.2f years.\n",
217 colWidth, "project-age:", n, n/365.2425);
218 fossil_print("%*s%s\n", colWidth, "project-id:", db_get("project-code",""));
219 fossil_print("%*s%s %s [%s] (%s)\n",
220 colWidth, "fossil-version:",
221 MANIFEST_DATE, MANIFEST_VERSION, RELEASE_VERSION,
222 COMPILER_NAME);
223 fossil_print("%*s%.19s [%.10s] (%s)\n",
224 colWidth, "sqlite-version:",
225 SQLITE_SOURCE_ID, &SQLITE_SOURCE_ID[20],
226 SQLITE_VERSION);
227 zDb = db_name("repository");
228 fossil_print("%*s%d pages, %d bytes/pg, %d free pages, "
229 "%s, %s mode\n",
230 colWidth, "database-stats:",
231 db_int(0, "PRAGMA %s.page_count", zDb),
232 db_int(0, "PRAGMA %s.page_size", zDb),
233 db_int(0, "PRAGMA %s.freelist_count", zDb),
234
+7 -10
--- src/timeline.c
+++ src/timeline.c
@@ -594,13 +594,10 @@
594594
cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
595595
}
596596
cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
597597
graph_free(pGraph);
598598
@ var canvasDiv = gebi("canvas");
599
-#if 0
600
- @ var realCanvas = null;
601
-#endif
602599
@ function drawBox(color,x0,y0,x1,y1){
603600
@ var n = document.createElement("div");
604601
@ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
605602
@ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
606603
@ var w = x1-x0+1;
@@ -637,11 +634,11 @@
637634
@ }
638635
@ return left;
639636
@ }
640637
@ function drawUpArrow(x,y0,y1){
641638
@ drawBox("black",x,y0,x+1,y1);
642
- @ if( y0+8>=y1 ){
639
+ @ if( y0+10>=y1 ){
643640
@ drawBox("black",x-1,y0+1,x+2,y0+2);
644641
@ drawBox("black",x-2,y0+3,x+3,y0+4);
645642
@ }else{
646643
@ drawBox("black",x-1,y0+2,x+2,y0+4);
647644
@ drawBox("black",x-2,y0+5,x+3,y0+7);
@@ -648,28 +645,28 @@
648645
@ }
649646
@ }
650647
@ function drawThinArrow(y,xFrom,xTo){
651648
@ if( xFrom<xTo ){
652649
@ drawBox("black",xFrom,y,xTo,y);
653
- @ drawBox("black",xTo-4,y-1,xTo-2,y+1);
654
- @ if( xTo>xFrom-8 ) drawBox("black",xTo-6,y-2,xTo-5,y+2);
650
+ @ drawBox("black",xTo-3,y-1,xTo-2,y+1);
651
+ @ drawBox("black",xTo-4,y-2,xTo-4,y+2);
655652
@ }else{
656653
@ drawBox("black",xTo,y,xFrom,y);
657
- @ drawBox("black",xTo+2,y-1,xTo+4,y+1);
658
- @ if( xTo+8<xFrom ) drawBox("black",xTo+5,y-2,xTo+6,y+2);
654
+ @ drawBox("black",xTo+2,y-1,xTo+3,y+1);
655
+ @ drawBox("black",xTo+4,y-2,xTo+4,y+2);
659656
@ }
660657
@ }
661658
@ function drawThinLine(x0,y0,x1,y1){
662659
@ drawBox("black",x0,y0,x1,y1);
663660
@ }
664661
@ function drawNode(p, left, btm){
665662
@ drawBox("black",p.x-5,p.y-5,p.x+6,p.y+6);
666663
@ drawBox(p.bg,p.x-4,p.y-4,p.x+5,p.y+5);
667664
@ if( p.u>0 ) drawUpArrow(p.x, rowinfo[p.u-1].y+6, p.y-5);
665
+ @ if( p.f&1 ) drawBox("black",p.x-1,p.y-1,p.x+2,p.y+2);
668666
if( !omitDescenders ){
669667
@ if( p.u==0 ) drawUpArrow(p.x, 0, p.y-5);
670
- @ if( p.f&1 ) drawBox("black",p.x-1,p.y-1,p.x+2,p.y+2);
671668
@ if( p.d ) drawUpArrow(p.x, p.y+6, btm);
672669
}
673670
@ if( p.mo>0 ){
674671
@ var x1 = p.mo + left - 1;
675672
@ var y1 = p.y-3;
@@ -722,11 +719,10 @@
722719
@ while( canvasDiv.hasChildNodes() ){
723720
@ canvasDiv.removeChild(canvasDiv.firstChild);
724721
@ }
725722
@ var canvasY = absoluteY("timelineTable");
726723
@ var left = absoluteX("m"+rowinfo[0].id) - absoluteX("canvas") + 15;
727
- @ var width = nrail*railPitch;
728724
@ for(var i in rowinfo){
729725
@ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
730726
@ rowinfo[i].x = left + rowinfo[i].r*railPitch;
731727
@ }
732728
@ var btm = absoluteY("grbtm") + 10 - canvasY;
@@ -1144,10 +1140,11 @@
11441140
db_multi_exec("%s", blob_str(&sql));
11451141
if( useDividers ) timeline_add_dividers(0, f_rid);
11461142
blob_appendf(&desc, "Parents and children of check-in ");
11471143
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
11481144
blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid);
1145
+ tmFlags |= TIMELINE_DISJOINT;
11491146
}else{
11501147
/* Otherwise, a timeline based on a span of time */
11511148
int n;
11521149
const char *zEType = "timeline item";
11531150
char *zDate;
11541151
--- src/timeline.c
+++ src/timeline.c
@@ -594,13 +594,10 @@
594 cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
595 }
596 cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
597 graph_free(pGraph);
598 @ var canvasDiv = gebi("canvas");
599 #if 0
600 @ var realCanvas = null;
601 #endif
602 @ function drawBox(color,x0,y0,x1,y1){
603 @ var n = document.createElement("div");
604 @ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
605 @ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
606 @ var w = x1-x0+1;
@@ -637,11 +634,11 @@
637 @ }
638 @ return left;
639 @ }
640 @ function drawUpArrow(x,y0,y1){
641 @ drawBox("black",x,y0,x+1,y1);
642 @ if( y0+8>=y1 ){
643 @ drawBox("black",x-1,y0+1,x+2,y0+2);
644 @ drawBox("black",x-2,y0+3,x+3,y0+4);
645 @ }else{
646 @ drawBox("black",x-1,y0+2,x+2,y0+4);
647 @ drawBox("black",x-2,y0+5,x+3,y0+7);
@@ -648,28 +645,28 @@
648 @ }
649 @ }
650 @ function drawThinArrow(y,xFrom,xTo){
651 @ if( xFrom<xTo ){
652 @ drawBox("black",xFrom,y,xTo,y);
653 @ drawBox("black",xTo-4,y-1,xTo-2,y+1);
654 @ if( xTo>xFrom-8 ) drawBox("black",xTo-6,y-2,xTo-5,y+2);
655 @ }else{
656 @ drawBox("black",xTo,y,xFrom,y);
657 @ drawBox("black",xTo+2,y-1,xTo+4,y+1);
658 @ if( xTo+8<xFrom ) drawBox("black",xTo+5,y-2,xTo+6,y+2);
659 @ }
660 @ }
661 @ function drawThinLine(x0,y0,x1,y1){
662 @ drawBox("black",x0,y0,x1,y1);
663 @ }
664 @ function drawNode(p, left, btm){
665 @ drawBox("black",p.x-5,p.y-5,p.x+6,p.y+6);
666 @ drawBox(p.bg,p.x-4,p.y-4,p.x+5,p.y+5);
667 @ if( p.u>0 ) drawUpArrow(p.x, rowinfo[p.u-1].y+6, p.y-5);
 
668 if( !omitDescenders ){
669 @ if( p.u==0 ) drawUpArrow(p.x, 0, p.y-5);
670 @ if( p.f&1 ) drawBox("black",p.x-1,p.y-1,p.x+2,p.y+2);
671 @ if( p.d ) drawUpArrow(p.x, p.y+6, btm);
672 }
673 @ if( p.mo>0 ){
674 @ var x1 = p.mo + left - 1;
675 @ var y1 = p.y-3;
@@ -722,11 +719,10 @@
722 @ while( canvasDiv.hasChildNodes() ){
723 @ canvasDiv.removeChild(canvasDiv.firstChild);
724 @ }
725 @ var canvasY = absoluteY("timelineTable");
726 @ var left = absoluteX("m"+rowinfo[0].id) - absoluteX("canvas") + 15;
727 @ var width = nrail*railPitch;
728 @ for(var i in rowinfo){
729 @ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
730 @ rowinfo[i].x = left + rowinfo[i].r*railPitch;
731 @ }
732 @ var btm = absoluteY("grbtm") + 10 - canvasY;
@@ -1144,10 +1140,11 @@
1144 db_multi_exec("%s", blob_str(&sql));
1145 if( useDividers ) timeline_add_dividers(0, f_rid);
1146 blob_appendf(&desc, "Parents and children of check-in ");
1147 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
1148 blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid);
 
1149 }else{
1150 /* Otherwise, a timeline based on a span of time */
1151 int n;
1152 const char *zEType = "timeline item";
1153 char *zDate;
1154
--- src/timeline.c
+++ src/timeline.c
@@ -594,13 +594,10 @@
594 cgi_printf("],h:\"%s\"}%s", pRow->zUuid, pRow->pNext ? ",\n" : "];\n");
595 }
596 cgi_printf("var nrail = %d\n", pGraph->mxRail+1);
597 graph_free(pGraph);
598 @ var canvasDiv = gebi("canvas");
 
 
 
599 @ function drawBox(color,x0,y0,x1,y1){
600 @ var n = document.createElement("div");
601 @ if( x0>x1 ){ var t=x0; x0=x1; x1=t; }
602 @ if( y0>y1 ){ var t=y0; y0=y1; y1=t; }
603 @ var w = x1-x0+1;
@@ -637,11 +634,11 @@
634 @ }
635 @ return left;
636 @ }
637 @ function drawUpArrow(x,y0,y1){
638 @ drawBox("black",x,y0,x+1,y1);
639 @ if( y0+10>=y1 ){
640 @ drawBox("black",x-1,y0+1,x+2,y0+2);
641 @ drawBox("black",x-2,y0+3,x+3,y0+4);
642 @ }else{
643 @ drawBox("black",x-1,y0+2,x+2,y0+4);
644 @ drawBox("black",x-2,y0+5,x+3,y0+7);
@@ -648,28 +645,28 @@
645 @ }
646 @ }
647 @ function drawThinArrow(y,xFrom,xTo){
648 @ if( xFrom<xTo ){
649 @ drawBox("black",xFrom,y,xTo,y);
650 @ drawBox("black",xTo-3,y-1,xTo-2,y+1);
651 @ drawBox("black",xTo-4,y-2,xTo-4,y+2);
652 @ }else{
653 @ drawBox("black",xTo,y,xFrom,y);
654 @ drawBox("black",xTo+2,y-1,xTo+3,y+1);
655 @ drawBox("black",xTo+4,y-2,xTo+4,y+2);
656 @ }
657 @ }
658 @ function drawThinLine(x0,y0,x1,y1){
659 @ drawBox("black",x0,y0,x1,y1);
660 @ }
661 @ function drawNode(p, left, btm){
662 @ drawBox("black",p.x-5,p.y-5,p.x+6,p.y+6);
663 @ drawBox(p.bg,p.x-4,p.y-4,p.x+5,p.y+5);
664 @ if( p.u>0 ) drawUpArrow(p.x, rowinfo[p.u-1].y+6, p.y-5);
665 @ if( p.f&1 ) drawBox("black",p.x-1,p.y-1,p.x+2,p.y+2);
666 if( !omitDescenders ){
667 @ if( p.u==0 ) drawUpArrow(p.x, 0, p.y-5);
 
668 @ if( p.d ) drawUpArrow(p.x, p.y+6, btm);
669 }
670 @ if( p.mo>0 ){
671 @ var x1 = p.mo + left - 1;
672 @ var y1 = p.y-3;
@@ -722,11 +719,10 @@
719 @ while( canvasDiv.hasChildNodes() ){
720 @ canvasDiv.removeChild(canvasDiv.firstChild);
721 @ }
722 @ var canvasY = absoluteY("timelineTable");
723 @ var left = absoluteX("m"+rowinfo[0].id) - absoluteX("canvas") + 15;
 
724 @ for(var i in rowinfo){
725 @ rowinfo[i].y = absoluteY("m"+rowinfo[i].id) + 10 - canvasY;
726 @ rowinfo[i].x = left + rowinfo[i].r*railPitch;
727 @ }
728 @ var btm = absoluteY("grbtm") + 10 - canvasY;
@@ -1144,10 +1140,11 @@
1140 db_multi_exec("%s", blob_str(&sql));
1141 if( useDividers ) timeline_add_dividers(0, f_rid);
1142 blob_appendf(&desc, "Parents and children of check-in ");
1143 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", f_rid);
1144 blob_appendf(&desc, "%z[%.10s]</a>", href("%R/info/%s", zUuid), zUuid);
1145 tmFlags |= TIMELINE_DISJOINT;
1146 }else{
1147 /* Otherwise, a timeline based on a span of time */
1148 int n;
1149 const char *zEType = "timeline item";
1150 char *zDate;
1151
+3 -1
--- src/tkt.c
+++ src/tkt.c
@@ -210,11 +210,13 @@
210210
}
211211
aUsed = fossil_malloc( nField );
212212
memset(aUsed, 0, nField);
213213
for(i=0; i<p->nField; i++){
214214
const char *zName = p->aField[i].zName;
215
- if( (j = fieldId(zName))<0 ) continue;
215
+ const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
216
+ j = fieldId(zBaseName);
217
+ if( j<0 ) continue;
216218
aUsed[j] = 1;
217219
if( aField[j].mUsed & USEDBY_TICKET ){
218220
if( zName[0]=='+' ){
219221
zName++;
220222
blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
221223
--- src/tkt.c
+++ src/tkt.c
@@ -210,11 +210,13 @@
210 }
211 aUsed = fossil_malloc( nField );
212 memset(aUsed, 0, nField);
213 for(i=0; i<p->nField; i++){
214 const char *zName = p->aField[i].zName;
215 if( (j = fieldId(zName))<0 ) continue;
 
 
216 aUsed[j] = 1;
217 if( aField[j].mUsed & USEDBY_TICKET ){
218 if( zName[0]=='+' ){
219 zName++;
220 blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
221
--- src/tkt.c
+++ src/tkt.c
@@ -210,11 +210,13 @@
210 }
211 aUsed = fossil_malloc( nField );
212 memset(aUsed, 0, nField);
213 for(i=0; i<p->nField; i++){
214 const char *zName = p->aField[i].zName;
215 const char *zBaseName = zName[0]=='+' ? zName+1 : zName;
216 j = fieldId(zBaseName);
217 if( j<0 ) continue;
218 aUsed[j] = 1;
219 if( aField[j].mUsed & USEDBY_TICKET ){
220 if( zName[0]=='+' ){
221 zName++;
222 blob_appendf(&sql1,", %s=coalesce(%s,'') || %Q",
223
+10 -1
--- src/url.c
+++ src/url.c
@@ -63,10 +63,11 @@
6363
|| strncmp(zUrl, "ssh://", 6)==0
6464
){
6565
int iStart;
6666
char *zLogin;
6767
char *zExe;
68
+ char cQuerySep = '?';
6869
6970
g.urlIsFile = 0;
7071
if( zUrl[4]=='s' ){
7172
g.urlIsHttps = 1;
7273
g.urlProtocol = "https";
@@ -75,10 +76,11 @@
7576
}else if( zUrl[0]=='s' ){
7677
g.urlIsSsh = 1;
7778
g.urlProtocol = "ssh";
7879
g.urlDfltPort = 22;
7980
g.urlFossil = "fossil";
81
+ g.urlShell = 0;
8082
iStart = 6;
8183
}else{
8284
g.urlIsHttps = 0;
8385
g.urlProtocol = "http";
8486
g.urlDfltPort = 80;
@@ -144,11 +146,18 @@
144146
i++;
145147
}
146148
if( fossil_strcmp(zName,"fossil")==0 ){
147149
g.urlFossil = zValue;
148150
dehttpize(g.urlFossil);
149
- zExe = mprintf("?fossil=%T", g.urlFossil);
151
+ zExe = mprintf("%cfossil=%T", cQuerySep, g.urlFossil);
152
+ cQuerySep = '&';
153
+ }
154
+ if( fossil_strcmp(zName,"shell")==0 ){
155
+ g.urlShell = zValue;
156
+ dehttpize(g.urlShell);
157
+ zExe = mprintf("%cshell=%T", cQuerySep, g.urlFossil);
158
+ cQuerySep = '&';
150159
}
151160
}
152161
153162
dehttpize(g.urlPath);
154163
if( g.urlDfltPort==g.urlPort ){
155164
--- src/url.c
+++ src/url.c
@@ -63,10 +63,11 @@
63 || strncmp(zUrl, "ssh://", 6)==0
64 ){
65 int iStart;
66 char *zLogin;
67 char *zExe;
 
68
69 g.urlIsFile = 0;
70 if( zUrl[4]=='s' ){
71 g.urlIsHttps = 1;
72 g.urlProtocol = "https";
@@ -75,10 +76,11 @@
75 }else if( zUrl[0]=='s' ){
76 g.urlIsSsh = 1;
77 g.urlProtocol = "ssh";
78 g.urlDfltPort = 22;
79 g.urlFossil = "fossil";
 
80 iStart = 6;
81 }else{
82 g.urlIsHttps = 0;
83 g.urlProtocol = "http";
84 g.urlDfltPort = 80;
@@ -144,11 +146,18 @@
144 i++;
145 }
146 if( fossil_strcmp(zName,"fossil")==0 ){
147 g.urlFossil = zValue;
148 dehttpize(g.urlFossil);
149 zExe = mprintf("?fossil=%T", g.urlFossil);
 
 
 
 
 
 
 
150 }
151 }
152
153 dehttpize(g.urlPath);
154 if( g.urlDfltPort==g.urlPort ){
155
--- src/url.c
+++ src/url.c
@@ -63,10 +63,11 @@
63 || strncmp(zUrl, "ssh://", 6)==0
64 ){
65 int iStart;
66 char *zLogin;
67 char *zExe;
68 char cQuerySep = '?';
69
70 g.urlIsFile = 0;
71 if( zUrl[4]=='s' ){
72 g.urlIsHttps = 1;
73 g.urlProtocol = "https";
@@ -75,10 +76,11 @@
76 }else if( zUrl[0]=='s' ){
77 g.urlIsSsh = 1;
78 g.urlProtocol = "ssh";
79 g.urlDfltPort = 22;
80 g.urlFossil = "fossil";
81 g.urlShell = 0;
82 iStart = 6;
83 }else{
84 g.urlIsHttps = 0;
85 g.urlProtocol = "http";
86 g.urlDfltPort = 80;
@@ -144,11 +146,18 @@
146 i++;
147 }
148 if( fossil_strcmp(zName,"fossil")==0 ){
149 g.urlFossil = zValue;
150 dehttpize(g.urlFossil);
151 zExe = mprintf("%cfossil=%T", cQuerySep, g.urlFossil);
152 cQuerySep = '&';
153 }
154 if( fossil_strcmp(zName,"shell")==0 ){
155 g.urlShell = zValue;
156 dehttpize(g.urlShell);
157 zExe = mprintf("%cshell=%T", cQuerySep, g.urlFossil);
158 cQuerySep = '&';
159 }
160 }
161
162 dehttpize(g.urlPath);
163 if( g.urlDfltPort==g.urlPort ){
164
+8 -1
--- src/xfer.c
+++ src/xfer.c
@@ -20,10 +20,16 @@
2020
#include "config.h"
2121
#include "xfer.h"
2222
2323
#include <time.h>
2424
25
+/*
26
+** Maximum number of HTTP redirects that any http_exchange() call will
27
+** follow before throwing a fatal error. Most browsers use a limit of 20.
28
+*/
29
+#define MAX_REDIRECTS 20
30
+
2531
/*
2632
** This structure holds information about the current state of either
2733
** a client or a server that is participating in xfer.
2834
*/
2935
typedef struct Xfer Xfer;
@@ -1480,11 +1486,12 @@
14801486
xfer.nIGotSent = 0;
14811487
if( syncFlags & SYNC_VERBOSE ){
14821488
fossil_print("waiting for server...");
14831489
}
14841490
fflush(stdout);
1485
- if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
1491
+ if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0,
1492
+ MAX_REDIRECTS) ){
14861493
nErr++;
14871494
break;
14881495
}
14891496
lastPctDone = -1;
14901497
blob_reset(&send);
14911498
--- src/xfer.c
+++ src/xfer.c
@@ -20,10 +20,16 @@
20 #include "config.h"
21 #include "xfer.h"
22
23 #include <time.h>
24
 
 
 
 
 
 
25 /*
26 ** This structure holds information about the current state of either
27 ** a client or a server that is participating in xfer.
28 */
29 typedef struct Xfer Xfer;
@@ -1480,11 +1486,12 @@
1480 xfer.nIGotSent = 0;
1481 if( syncFlags & SYNC_VERBOSE ){
1482 fossil_print("waiting for server...");
1483 }
1484 fflush(stdout);
1485 if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0) ){
 
1486 nErr++;
1487 break;
1488 }
1489 lastPctDone = -1;
1490 blob_reset(&send);
1491
--- src/xfer.c
+++ src/xfer.c
@@ -20,10 +20,16 @@
20 #include "config.h"
21 #include "xfer.h"
22
23 #include <time.h>
24
25 /*
26 ** Maximum number of HTTP redirects that any http_exchange() call will
27 ** follow before throwing a fatal error. Most browsers use a limit of 20.
28 */
29 #define MAX_REDIRECTS 20
30
31 /*
32 ** This structure holds information about the current state of either
33 ** a client or a server that is participating in xfer.
34 */
35 typedef struct Xfer Xfer;
@@ -1480,11 +1486,12 @@
1486 xfer.nIGotSent = 0;
1487 if( syncFlags & SYNC_VERBOSE ){
1488 fossil_print("waiting for server...");
1489 }
1490 fflush(stdout);
1491 if( http_exchange(&send, &recv, (syncFlags & SYNC_CLONE)==0 || nCycle>0,
1492 MAX_REDIRECTS) ){
1493 nErr++;
1494 break;
1495 }
1496 lastPctDone = -1;
1497 blob_reset(&send);
1498
+2 -2
--- www/build.wiki
+++ www/build.wiki
@@ -54,11 +54,11 @@
5454
</ol>
5555
5656
<h2>2.0 Compiling</h2>
5757
5858
<ol>
59
-<li value="6">
59
+<li value="5">
6060
<p>Unpack the ZIP or tarball you downloaded then
6161
<b>cd</b> into the directory created.</p></li>
6262
6363
<li><i>(Optional, unix only)</i>
6464
Run <b>./configure</b> to construct a makefile.
@@ -101,11 +101,11 @@
101101
</ol>
102102
103103
<h2>3.0 Installing</h2>
104104
105105
<ol>
106
-<li value="9">
106
+<li value="8">
107107
<p>The finished binary is named "fossil" (or "fossil.exe" on windows).
108108
Put this binary in a
109109
directory that is somewhere on your PATH environment variable.
110110
It does not matter where.</p>
111111
112112
--- www/build.wiki
+++ www/build.wiki
@@ -54,11 +54,11 @@
54 </ol>
55
56 <h2>2.0 Compiling</h2>
57
58 <ol>
59 <li value="6">
60 <p>Unpack the ZIP or tarball you downloaded then
61 <b>cd</b> into the directory created.</p></li>
62
63 <li><i>(Optional, unix only)</i>
64 Run <b>./configure</b> to construct a makefile.
@@ -101,11 +101,11 @@
101 </ol>
102
103 <h2>3.0 Installing</h2>
104
105 <ol>
106 <li value="9">
107 <p>The finished binary is named "fossil" (or "fossil.exe" on windows).
108 Put this binary in a
109 directory that is somewhere on your PATH environment variable.
110 It does not matter where.</p>
111
112
--- www/build.wiki
+++ www/build.wiki
@@ -54,11 +54,11 @@
54 </ol>
55
56 <h2>2.0 Compiling</h2>
57
58 <ol>
59 <li value="5">
60 <p>Unpack the ZIP or tarball you downloaded then
61 <b>cd</b> into the directory created.</p></li>
62
63 <li><i>(Optional, unix only)</i>
64 Run <b>./configure</b> to construct a makefile.
@@ -101,11 +101,11 @@
101 </ol>
102
103 <h2>3.0 Installing</h2>
104
105 <ol>
106 <li value="8">
107 <p>The finished binary is named "fossil" (or "fossil.exe" on windows).
108 Put this binary in a
109 directory that is somewhere on your PATH environment variable.
110 It does not matter where.</p>
111
112
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,8 @@
11
<title>Change Log</title>
22
3
-<h2>Changes For Version 1.25 (2012-12-19)</h2>
3
+<h2>Changes For Version 1.25 (2013-02-16)</h2>
44
* Enhancements to ticket processing. There are now two tables: TICKET and
55
TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact.
66
Fields from ticket artifacts go into either or both of TICKET and
77
TICKETCHNG, whichever contain matching column names. Default ticket
88
edit and viewing scripts are updated to use TICKETCHNG. The TH1
@@ -81,10 +81,16 @@
8181
use those sources when compiling on (windows) systems that do not have
8282
a zlib library installed by default.
8383
* Prompt the user with the option to convert non-UTF8 files into UTF8
8484
when committing.
8585
* Allow the characters <nowiki>*[]?</nowiki> in filenames.
86
+ * Allow the --context option on diff commands to have a value of 0.
87
+ * Added the "dbstat" command.
88
+ * Enhanced "fossil merge" so that if the VERSION argument is omitted, Fossil
89
+ tries to merge any forks of the current branch.
90
+ * Improved detection of forks in a commit race.
91
+ * Added the --analyze option to "fossil rebuild".
8692
8793
<h2>Changes For Version 1.24 (2012-10-22)</h2>
8894
* Added support for WYSIWYG editing of wiki pages. WYSIWYG is turned off
8995
by default and can be turned on by setting a configuration option.
9096
* Allow style= attribute to occur in HTML markup on wiki pages.
9197
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,8 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.25 (2012-12-19)</h2>
4 * Enhancements to ticket processing. There are now two tables: TICKET and
5 TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact.
6 Fields from ticket artifacts go into either or both of TICKET and
7 TICKETCHNG, whichever contain matching column names. Default ticket
8 edit and viewing scripts are updated to use TICKETCHNG. The TH1
@@ -81,10 +81,16 @@
81 use those sources when compiling on (windows) systems that do not have
82 a zlib library installed by default.
83 * Prompt the user with the option to convert non-UTF8 files into UTF8
84 when committing.
85 * Allow the characters <nowiki>*[]?</nowiki> in filenames.
 
 
 
 
 
 
86
87 <h2>Changes For Version 1.24 (2012-10-22)</h2>
88 * Added support for WYSIWYG editing of wiki pages. WYSIWYG is turned off
89 by default and can be turned on by setting a configuration option.
90 * Allow style= attribute to occur in HTML markup on wiki pages.
91
--- www/changes.wiki
+++ www/changes.wiki
@@ -1,8 +1,8 @@
1 <title>Change Log</title>
2
3 <h2>Changes For Version 1.25 (2013-02-16)</h2>
4 * Enhancements to ticket processing. There are now two tables: TICKET and
5 TICKETCHNG. There is one row in TICKETCHNG for each ticket artifact.
6 Fields from ticket artifacts go into either or both of TICKET and
7 TICKETCHNG, whichever contain matching column names. Default ticket
8 edit and viewing scripts are updated to use TICKETCHNG. The TH1
@@ -81,10 +81,16 @@
81 use those sources when compiling on (windows) systems that do not have
82 a zlib library installed by default.
83 * Prompt the user with the option to convert non-UTF8 files into UTF8
84 when committing.
85 * Allow the characters <nowiki>*[]?</nowiki> in filenames.
86 * Allow the --context option on diff commands to have a value of 0.
87 * Added the "dbstat" command.
88 * Enhanced "fossil merge" so that if the VERSION argument is omitted, Fossil
89 tries to merge any forks of the current branch.
90 * Improved detection of forks in a commit race.
91 * Added the --analyze option to "fossil rebuild".
92
93 <h2>Changes For Version 1.24 (2012-10-22)</h2>
94 * Added support for WYSIWYG editing of wiki pages. WYSIWYG is turned off
95 by default and can be turned on by setting a configuration option.
96 * Allow style= attribute to occur in HTML markup on wiki pages.
97
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -49,10 +49,11 @@
4949
ssl.wiki {Using SSL with Fossil}
5050
sync.wiki {The Fossil Sync Protocol}
5151
tech_overview.wiki {A Technical Overview Of The Design And Implementation
5252
Of Fossil}
5353
tech_overview.wiki {SQLite Databases Used By Fossil}
54
+ tickets.wiki {The Fossil Ticket System}
5455
theory1.wiki {Thoughts On The Design Of The Fossil DVCS}
5556
webui.wiki {The Fossil Web Interface}
5657
wikitheory.wiki {Wiki In Fossil}
5758
}
5859
5960
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -49,10 +49,11 @@
49 ssl.wiki {Using SSL with Fossil}
50 sync.wiki {The Fossil Sync Protocol}
51 tech_overview.wiki {A Technical Overview Of The Design And Implementation
52 Of Fossil}
53 tech_overview.wiki {SQLite Databases Used By Fossil}
 
54 theory1.wiki {Thoughts On The Design Of The Fossil DVCS}
55 webui.wiki {The Fossil Web Interface}
56 wikitheory.wiki {Wiki In Fossil}
57 }
58
59
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -49,10 +49,11 @@
49 ssl.wiki {Using SSL with Fossil}
50 sync.wiki {The Fossil Sync Protocol}
51 tech_overview.wiki {A Technical Overview Of The Design And Implementation
52 Of Fossil}
53 tech_overview.wiki {SQLite Databases Used By Fossil}
54 tickets.wiki {The Fossil Ticket System}
55 theory1.wiki {Thoughts On The Design Of The Fossil DVCS}
56 webui.wiki {The Fossil Web Interface}
57 wikitheory.wiki {Wiki In Fossil}
58 }
59
60
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -136,18 +136,21 @@
136136
<li><a href="style.wiki">Style Guidelines &mdash; Source Code</a></li>
137137
<li><a href="foss-cklist.wiki">Successful Open-Source Projects &mdash; Checklist For</a></li>
138138
<li><a href="sync.wiki">Sync Protocol &mdash; The Fossil</a></li>
139139
<li><a href="private.wiki">Syncing, and Deleting Private Branches &mdash; Creating,</a></li>
140140
<li><a href="custom_ticket.wiki">System &mdash; Customizing The Ticket</a></li>
141
+<li><a href="tickets.wiki">System &mdash; The Fossil Ticket</a></li>
141142
<li><a href="branching.wiki">Tagging &mdash; Branching, Forking, Merging, and</a></li>
142143
<li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &mdash; A</a></li>
143144
<li><a href="../test/release-checklist.wiki">Testing Checklist &mdash; Pre-Release</a></li>
144145
<li><a href="makefile.wiki">The Fossil Build Process</a></li>
145146
<li><a href="sync.wiki">The Fossil Sync Protocol</a></li>
147
+<li><a href="tickets.wiki">The Fossil Ticket System</a></li>
146148
<li><a href="webui.wiki">The Fossil Web Interface</a></li>
147149
<li><a href="theory1.wiki">Thoughts On The Design Of The Fossil DVCS</a></li>
148150
<li><a href="custom_ticket.wiki">Ticket System &mdash; Customizing The</a></li>
151
+<li><a href="tickets.wiki">Ticket System &mdash; The Fossil</a></li>
149152
<li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
150153
<li><a href="fiveminutes.wiki">Update and Running in 5 Minutes as a Single User</a></li>
151154
<li><a href="fiveminutes.wiki">User &mdash; Update and Running in 5 Minutes as a Single</a></li>
152155
<li><a href="ssl.wiki">Using SSL with Fossil</a></li>
153156
<li><a href="checkin_names.wiki">Version Names &mdash; Checkin And</a></li>
154157
155158
ADDED www/tickets.wiki
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -136,18 +136,21 @@
136 <li><a href="style.wiki">Style Guidelines &mdash; Source Code</a></li>
137 <li><a href="foss-cklist.wiki">Successful Open-Source Projects &mdash; Checklist For</a></li>
138 <li><a href="sync.wiki">Sync Protocol &mdash; The Fossil</a></li>
139 <li><a href="private.wiki">Syncing, and Deleting Private Branches &mdash; Creating,</a></li>
140 <li><a href="custom_ticket.wiki">System &mdash; Customizing The Ticket</a></li>
 
141 <li><a href="branching.wiki">Tagging &mdash; Branching, Forking, Merging, and</a></li>
142 <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &mdash; A</a></li>
143 <li><a href="../test/release-checklist.wiki">Testing Checklist &mdash; Pre-Release</a></li>
144 <li><a href="makefile.wiki">The Fossil Build Process</a></li>
145 <li><a href="sync.wiki">The Fossil Sync Protocol</a></li>
 
146 <li><a href="webui.wiki">The Fossil Web Interface</a></li>
147 <li><a href="theory1.wiki">Thoughts On The Design Of The Fossil DVCS</a></li>
148 <li><a href="custom_ticket.wiki">Ticket System &mdash; Customizing The</a></li>
 
149 <li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
150 <li><a href="fiveminutes.wiki">Update and Running in 5 Minutes as a Single User</a></li>
151 <li><a href="fiveminutes.wiki">User &mdash; Update and Running in 5 Minutes as a Single</a></li>
152 <li><a href="ssl.wiki">Using SSL with Fossil</a></li>
153 <li><a href="checkin_names.wiki">Version Names &mdash; Checkin And</a></li>
154
155 DDED www/tickets.wiki
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -136,18 +136,21 @@
136 <li><a href="style.wiki">Style Guidelines &mdash; Source Code</a></li>
137 <li><a href="foss-cklist.wiki">Successful Open-Source Projects &mdash; Checklist For</a></li>
138 <li><a href="sync.wiki">Sync Protocol &mdash; The Fossil</a></li>
139 <li><a href="private.wiki">Syncing, and Deleting Private Branches &mdash; Creating,</a></li>
140 <li><a href="custom_ticket.wiki">System &mdash; Customizing The Ticket</a></li>
141 <li><a href="tickets.wiki">System &mdash; The Fossil Ticket</a></li>
142 <li><a href="branching.wiki">Tagging &mdash; Branching, Forking, Merging, and</a></li>
143 <li><a href="tech_overview.wiki">Technical Overview Of The Design And Implementation Of Fossil &mdash; A</a></li>
144 <li><a href="../test/release-checklist.wiki">Testing Checklist &mdash; Pre-Release</a></li>
145 <li><a href="makefile.wiki">The Fossil Build Process</a></li>
146 <li><a href="sync.wiki">The Fossil Sync Protocol</a></li>
147 <li><a href="tickets.wiki">The Fossil Ticket System</a></li>
148 <li><a href="webui.wiki">The Fossil Web Interface</a></li>
149 <li><a href="theory1.wiki">Thoughts On The Design Of The Fossil DVCS</a></li>
150 <li><a href="custom_ticket.wiki">Ticket System &mdash; Customizing The</a></li>
151 <li><a href="tickets.wiki">Ticket System &mdash; The Fossil</a></li>
152 <li><a href="bugtheory.wiki">Tracking In Fossil &mdash; Bug</a></li>
153 <li><a href="fiveminutes.wiki">Update and Running in 5 Minutes as a Single User</a></li>
154 <li><a href="fiveminutes.wiki">User &mdash; Update and Running in 5 Minutes as a Single</a></li>
155 <li><a href="ssl.wiki">Using SSL with Fossil</a></li>
156 <li><a href="checkin_names.wiki">Version Names &mdash; Checkin And</a></li>
157
158 DDED www/tickets.wiki
--- a/www/tickets.wiki
+++ b/www/tickets.wiki
@@ -0,0 +1,69 @@
1
+<title>The Fossil <title>The Fossil Ticket System</title>
2
+
3
+<h2>1.0 File Format</h2>
4
+
5
+At its lowest level, the tickets of Fossil consist solely of
6
+[./fileformi REFERENCES ticket,
7
+ tkt_rid INTEGER REFERENCES blob,
8
+ tkt_mtime DATE,
9
+ -- Add as many fields as required below this line
10
+ login TEXT,
11
+ username TEXT,
12
+ mimetype TEXT,
13
+ icomment TEXT
14
+);
15
+CREATE INDEX ticketchng_idx1 ON ticketchng(tkt_id, tkt_mtime);
16
+</verbatim>
17
+
18
+Generally speaking, there is one row in the TICKETCHNG table for each
19
+change to each ticket. In other words, there i
20
+<b>tkt_c
21
+Generally speaking, therow in the
22
+TICKETCHNG table for each low-level ticket change artifact. The
23
+TICKET table, on the other hand, contains a summary of the current
24
+status of each ticket.
25
+
26
+Fields of the TICKET and TICKETCHNG tables that begin with "tkt_" are
27
+used internally by Fossil. The logic inside of Fossil that converts
28
+ticket change artifacts into row data for the two ticket tables expects
29
+the "tkt_" fields to always be present. All of the other fields of the
30
+TICKET and TICKETCHNG tables are "user defined" in the sense that they
31
+can be anything the administrator of the system wants them to be. The
32
+user-defined fields should correspond to keys in the key/value pairs of
33
+the ticket change artifacts.
34
+
35
+The <b>tkt_id</b> fields of TICKET and TICKETCHNG are an integer key
36
+used to uniquely identify the ticket to which the row belongs. These
37
+keys are for internal use only and may change when doing a "fossil rebuild".
38
+
39
+The <b>tkt_uuid</b> field is the unique hexadecimal identifier for the ticket.
40
+Ticket identifiersy the hash of any identifjst et, Fossil uses
41
+a (high-quality) pseudo-random number generator to create the ticket
42
+number. The ticket numbers are large so that the chance of collision
43
+between any two tickets is vanishingly small.
44
+
45
+The <b>tkt_mtime</b> field of TICKET shows the time (as a Julian day number)
46
+of the most recent ticket change artifact for that ticket. The
47
+<b>tkt_mtime</b> field of TICKETCHNG shows the timestamp on the ticket
48
+change artifact that the TICKETCHNG row refers to. The
49
+<b>tkt_ctime</b> field of TICKET is the time of the oldest ticket ch+16:26:29 | 2012-11-27]) icket, thus holding the time that the ticket was
50
+created.
51
+
52
+The <b>tkt_rid</b> field of TICKETCHNG is the integer primary key in the
53
+BLOB table of the ticket change artifact that gave rise to the row in the
54
+TICKETCHNG table.
55
+
56
+All the other fields of the TICKET and TICKETCHNG tables are available
57
+for customization for individual projects. None of the remaining fields
58
+are required, but all of them are needed in order to use the default
59
+ticket creating, viewing, and editing scripts. It is recommended that
60
+the other fields be retained andhat customizations be restricted to
61
+adding new fields above and beyond the default.
62
+
63
+< s To Tables</h3>
64
+
65
+Each row in the TICKETCHNG table corresponds to a single ticket change
66
+artifact. The tkt_id field is the integer primary key of the TICKET
67
+table entry for the corresponding ticket. The tkt_rid field is the
68
+integer primary key for the BLOB table entry that contains the low-level
69
+artifact text. The tkt_mtime fieldstamp order.
--- a/www/tickets.wiki
+++ b/www/tickets.wiki
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/www/tickets.wiki
+++ b/www/tickets.wiki
@@ -0,0 +1,69 @@
1 <title>The Fossil <title>The Fossil Ticket System</title>
2
3 <h2>1.0 File Format</h2>
4
5 At its lowest level, the tickets of Fossil consist solely of
6 [./fileformi REFERENCES ticket,
7 tkt_rid INTEGER REFERENCES blob,
8 tkt_mtime DATE,
9 -- Add as many fields as required below this line
10 login TEXT,
11 username TEXT,
12 mimetype TEXT,
13 icomment TEXT
14 );
15 CREATE INDEX ticketchng_idx1 ON ticketchng(tkt_id, tkt_mtime);
16 </verbatim>
17
18 Generally speaking, there is one row in the TICKETCHNG table for each
19 change to each ticket. In other words, there i
20 <b>tkt_c
21 Generally speaking, therow in the
22 TICKETCHNG table for each low-level ticket change artifact. The
23 TICKET table, on the other hand, contains a summary of the current
24 status of each ticket.
25
26 Fields of the TICKET and TICKETCHNG tables that begin with "tkt_" are
27 used internally by Fossil. The logic inside of Fossil that converts
28 ticket change artifacts into row data for the two ticket tables expects
29 the "tkt_" fields to always be present. All of the other fields of the
30 TICKET and TICKETCHNG tables are "user defined" in the sense that they
31 can be anything the administrator of the system wants them to be. The
32 user-defined fields should correspond to keys in the key/value pairs of
33 the ticket change artifacts.
34
35 The <b>tkt_id</b> fields of TICKET and TICKETCHNG are an integer key
36 used to uniquely identify the ticket to which the row belongs. These
37 keys are for internal use only and may change when doing a "fossil rebuild".
38
39 The <b>tkt_uuid</b> field is the unique hexadecimal identifier for the ticket.
40 Ticket identifiersy the hash of any identifjst et, Fossil uses
41 a (high-quality) pseudo-random number generator to create the ticket
42 number. The ticket numbers are large so that the chance of collision
43 between any two tickets is vanishingly small.
44
45 The <b>tkt_mtime</b> field of TICKET shows the time (as a Julian day number)
46 of the most recent ticket change artifact for that ticket. The
47 <b>tkt_mtime</b> field of TICKETCHNG shows the timestamp on the ticket
48 change artifact that the TICKETCHNG row refers to. The
49 <b>tkt_ctime</b> field of TICKET is the time of the oldest ticket ch+16:26:29 | 2012-11-27]) icket, thus holding the time that the ticket was
50 created.
51
52 The <b>tkt_rid</b> field of TICKETCHNG is the integer primary key in the
53 BLOB table of the ticket change artifact that gave rise to the row in the
54 TICKETCHNG table.
55
56 All the other fields of the TICKET and TICKETCHNG tables are available
57 for customization for individual projects. None of the remaining fields
58 are required, but all of them are needed in order to use the default
59 ticket creating, viewing, and editing scripts. It is recommended that
60 the other fields be retained andhat customizations be restricted to
61 adding new fields above and beyond the default.
62
63 < s To Tables</h3>
64
65 Each row in the TICKETCHNG table corresponds to a single ticket change
66 artifact. The tkt_id field is the integer primary key of the TICKET
67 table entry for the corresponding ticket. The tkt_rid field is the
68 integer primary key for the BLOB table entry that contains the low-level
69 artifact text. The tkt_mtime fieldstamp order.

Keyboard Shortcuts

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