Fossil SCM

merge trunk

jan.nijtmans 2013-02-17 21:37 improve_commit_warning merge
Commit fdf9050c4b154c80aed62d2a64c3b636c639d38d
+6 -5
--- src/blob.c
+++ src/blob.c
@@ -1150,25 +1150,26 @@
11501150
** done. If useMbcs is false and there is no BOM, the input string is assumed
11511151
** to be UTF-8 already, so no conversion is done.
11521152
*/
11531153
void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
11541154
char *zUtf8;
1155
- int bomSize = starts_with_bom(pBlob);
1156
- if( bomSize == 3 ){
1155
+ int bomSize = 0;
1156
+ int bomReverse = 0;
1157
+ if( starts_with_utf8_bom(pBlob, &bomSize) ){
11571158
struct Blob temp;
11581159
zUtf8 = blob_str(pBlob) + bomSize;
11591160
blob_zero(&temp);
11601161
blob_append(&temp, zUtf8, -1);
11611162
blob_swap(pBlob, &temp);
11621163
blob_reset(&temp);
11631164
#ifdef _WIN32
1164
- }else if( bomSize == 2 ){
1165
+ }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
11651166
zUtf8 = blob_buffer(pBlob);
1166
- if (*((unsigned short *)zUtf8) == 0xfffe) {
1167
+ if( bomReverse ){
11671168
/* Found BOM, but with reversed bytes */
11681169
unsigned int i = blob_size(pBlob);
1169
- while( i > 0 ){
1170
+ while( i>0 ){
11701171
/* swap bytes of unicode representation */
11711172
char zTemp = zUtf8[--i];
11721173
zUtf8[i] = zUtf8[i-1];
11731174
zUtf8[--i] = zTemp;
11741175
}
11751176
--- src/blob.c
+++ src/blob.c
@@ -1150,25 +1150,26 @@
1150 ** done. If useMbcs is false and there is no BOM, the input string is assumed
1151 ** to be UTF-8 already, so no conversion is done.
1152 */
1153 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1154 char *zUtf8;
1155 int bomSize = starts_with_bom(pBlob);
1156 if( bomSize == 3 ){
 
1157 struct Blob temp;
1158 zUtf8 = blob_str(pBlob) + bomSize;
1159 blob_zero(&temp);
1160 blob_append(&temp, zUtf8, -1);
1161 blob_swap(pBlob, &temp);
1162 blob_reset(&temp);
1163 #ifdef _WIN32
1164 }else if( bomSize == 2 ){
1165 zUtf8 = blob_buffer(pBlob);
1166 if (*((unsigned short *)zUtf8) == 0xfffe) {
1167 /* Found BOM, but with reversed bytes */
1168 unsigned int i = blob_size(pBlob);
1169 while( i > 0 ){
1170 /* swap bytes of unicode representation */
1171 char zTemp = zUtf8[--i];
1172 zUtf8[i] = zUtf8[i-1];
1173 zUtf8[--i] = zTemp;
1174 }
1175
--- src/blob.c
+++ src/blob.c
@@ -1150,25 +1150,26 @@
1150 ** done. If useMbcs is false and there is no BOM, the input string is assumed
1151 ** to be UTF-8 already, so no conversion is done.
1152 */
1153 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1154 char *zUtf8;
1155 int bomSize = 0;
1156 int bomReverse = 0;
1157 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1158 struct Blob temp;
1159 zUtf8 = blob_str(pBlob) + bomSize;
1160 blob_zero(&temp);
1161 blob_append(&temp, zUtf8, -1);
1162 blob_swap(pBlob, &temp);
1163 blob_reset(&temp);
1164 #ifdef _WIN32
1165 }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
1166 zUtf8 = blob_buffer(pBlob);
1167 if( bomReverse ){
1168 /* Found BOM, but with reversed bytes */
1169 unsigned int i = blob_size(pBlob);
1170 while( i>0 ){
1171 /* swap bytes of unicode representation */
1172 char zTemp = zUtf8[--i];
1173 zUtf8[i] = zUtf8[i-1];
1174 zUtf8[--i] = zTemp;
1175 }
1176
+6 -5
--- src/blob.c
+++ src/blob.c
@@ -1150,25 +1150,26 @@
11501150
** done. If useMbcs is false and there is no BOM, the input string is assumed
11511151
** to be UTF-8 already, so no conversion is done.
11521152
*/
11531153
void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
11541154
char *zUtf8;
1155
- int bomSize = starts_with_bom(pBlob);
1156
- if( bomSize == 3 ){
1155
+ int bomSize = 0;
1156
+ int bomReverse = 0;
1157
+ if( starts_with_utf8_bom(pBlob, &bomSize) ){
11571158
struct Blob temp;
11581159
zUtf8 = blob_str(pBlob) + bomSize;
11591160
blob_zero(&temp);
11601161
blob_append(&temp, zUtf8, -1);
11611162
blob_swap(pBlob, &temp);
11621163
blob_reset(&temp);
11631164
#ifdef _WIN32
1164
- }else if( bomSize == 2 ){
1165
+ }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
11651166
zUtf8 = blob_buffer(pBlob);
1166
- if (*((unsigned short *)zUtf8) == 0xfffe) {
1167
+ if( bomReverse ){
11671168
/* Found BOM, but with reversed bytes */
11681169
unsigned int i = blob_size(pBlob);
1169
- while( i > 0 ){
1170
+ while( i>0 ){
11701171
/* swap bytes of unicode representation */
11711172
char zTemp = zUtf8[--i];
11721173
zUtf8[i] = zUtf8[i-1];
11731174
zUtf8[--i] = zTemp;
11741175
}
11751176
--- src/blob.c
+++ src/blob.c
@@ -1150,25 +1150,26 @@
1150 ** done. If useMbcs is false and there is no BOM, the input string is assumed
1151 ** to be UTF-8 already, so no conversion is done.
1152 */
1153 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1154 char *zUtf8;
1155 int bomSize = starts_with_bom(pBlob);
1156 if( bomSize == 3 ){
 
1157 struct Blob temp;
1158 zUtf8 = blob_str(pBlob) + bomSize;
1159 blob_zero(&temp);
1160 blob_append(&temp, zUtf8, -1);
1161 blob_swap(pBlob, &temp);
1162 blob_reset(&temp);
1163 #ifdef _WIN32
1164 }else if( bomSize == 2 ){
1165 zUtf8 = blob_buffer(pBlob);
1166 if (*((unsigned short *)zUtf8) == 0xfffe) {
1167 /* Found BOM, but with reversed bytes */
1168 unsigned int i = blob_size(pBlob);
1169 while( i > 0 ){
1170 /* swap bytes of unicode representation */
1171 char zTemp = zUtf8[--i];
1172 zUtf8[i] = zUtf8[i-1];
1173 zUtf8[--i] = zTemp;
1174 }
1175
--- src/blob.c
+++ src/blob.c
@@ -1150,25 +1150,26 @@
1150 ** done. If useMbcs is false and there is no BOM, the input string is assumed
1151 ** to be UTF-8 already, so no conversion is done.
1152 */
1153 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1154 char *zUtf8;
1155 int bomSize = 0;
1156 int bomReverse = 0;
1157 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1158 struct Blob temp;
1159 zUtf8 = blob_str(pBlob) + bomSize;
1160 blob_zero(&temp);
1161 blob_append(&temp, zUtf8, -1);
1162 blob_swap(pBlob, &temp);
1163 blob_reset(&temp);
1164 #ifdef _WIN32
1165 }else if( starts_with_utf16_bom(pBlob, &bomSize, &bomReverse) ){
1166 zUtf8 = blob_buffer(pBlob);
1167 if( bomReverse ){
1168 /* Found BOM, but with reversed bytes */
1169 unsigned int i = blob_size(pBlob);
1170 while( i>0 ){
1171 /* swap bytes of unicode representation */
1172 char zTemp = zUtf8[--i];
1173 zUtf8[i] = zUtf8[i-1];
1174 zUtf8[--i] = zTemp;
1175 }
1176
+19 -13
--- 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.
@@ -899,17 +900,17 @@
899900
int binOk, /* Non-zero if binary warnings should be disabled. */
900901
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() */
904
- int fUnicode; /* 1 if blob starts with UTF-16 BOM */
905
+ 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_bom(p) == 2);
911
+ fUnicode = starts_with_utf16_bom(p, 0, 0);
911912
eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
912913
if( eType<-2){
913914
const char *zWarning;
914915
const char *zDisable;
915916
const char *zConvert;
@@ -1244,11 +1245,16 @@
12441245
** After the following function call has returned, the Global.aCommitFile[]
12451246
** array is allocated to contain the "id" field from the vfile table
12461247
** for each file to be committed. Or, if aCommitFile is NULL, all files
12471248
** should be committed.
12481249
*/
1249
- select_commit_files();
1250
+ if ( select_commit_files() ){
1251
+ blob_zero(&ans);
1252
+ prompt_user("continue (y/N)? ", &ans);
1253
+ cReply = blob_str(&ans)[0];
1254
+ if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
1255
+ }
12501256
isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
12511257
if( g.aCommitFile && isAMerge ){
12521258
fossil_fatal("cannot do a partial commit of a merge");
12531259
}
12541260
12551261
--- 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.
@@ -899,17 +900,17 @@
899 int binOk, /* Non-zero if binary warnings should be disabled. */
900 int encodingOk, /* Non-zero if encoding 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; /* 1 if blob starts with UTF-16 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_bom(p) == 2);
911 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
912 if( eType<-2){
913 const char *zWarning;
914 const char *zDisable;
915 const char *zConvert;
@@ -1244,11 +1245,16 @@
1244 ** After the following function call has returned, the Global.aCommitFile[]
1245 ** array is allocated to contain the "id" field from the vfile table
1246 ** for each file to be committed. Or, if aCommitFile is NULL, all files
1247 ** should be committed.
1248 */
1249 select_commit_files();
 
 
 
 
 
1250 isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
1251 if( g.aCommitFile && isAMerge ){
1252 fossil_fatal("cannot do a partial commit of a merge");
1253 }
1254
1255
--- 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.
@@ -899,17 +900,17 @@
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<-2){
914 const char *zWarning;
915 const char *zDisable;
916 const char *zConvert;
@@ -1244,11 +1245,16 @@
1245 ** After the following function call has returned, the Global.aCommitFile[]
1246 ** array is allocated to contain the "id" field from the vfile table
1247 ** for each file to be committed. Or, if aCommitFile is NULL, all files
1248 ** should be committed.
1249 */
1250 if ( select_commit_files() ){
1251 blob_zero(&ans);
1252 prompt_user("continue (y/N)? ", &ans);
1253 cReply = blob_str(&ans)[0];
1254 if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
1255 }
1256 isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
1257 if( g.aCommitFile && isAMerge ){
1258 fossil_fatal("cannot do a partial commit of a merge");
1259 }
1260
1261
+19 -13
--- 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.
@@ -899,17 +900,17 @@
899900
int binOk, /* Non-zero if binary warnings should be disabled. */
900901
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() */
904
- int fUnicode; /* 1 if blob starts with UTF-16 BOM */
905
+ 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_bom(p) == 2);
911
+ fUnicode = starts_with_utf16_bom(p, 0, 0);
911912
eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
912913
if( eType<-2){
913914
const char *zWarning;
914915
const char *zDisable;
915916
const char *zConvert;
@@ -1244,11 +1245,16 @@
12441245
** After the following function call has returned, the Global.aCommitFile[]
12451246
** array is allocated to contain the "id" field from the vfile table
12461247
** for each file to be committed. Or, if aCommitFile is NULL, all files
12471248
** should be committed.
12481249
*/
1249
- select_commit_files();
1250
+ if ( select_commit_files() ){
1251
+ blob_zero(&ans);
1252
+ prompt_user("continue (y/N)? ", &ans);
1253
+ cReply = blob_str(&ans)[0];
1254
+ if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
1255
+ }
12501256
isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
12511257
if( g.aCommitFile && isAMerge ){
12521258
fossil_fatal("cannot do a partial commit of a merge");
12531259
}
12541260
12551261
--- 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.
@@ -899,17 +900,17 @@
899 int binOk, /* Non-zero if binary warnings should be disabled. */
900 int encodingOk, /* Non-zero if encoding 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; /* 1 if blob starts with UTF-16 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_bom(p) == 2);
911 eType = fUnicode ? looks_like_utf16(p) : looks_like_utf8(p);
912 if( eType<-2){
913 const char *zWarning;
914 const char *zDisable;
915 const char *zConvert;
@@ -1244,11 +1245,16 @@
1244 ** After the following function call has returned, the Global.aCommitFile[]
1245 ** array is allocated to contain the "id" field from the vfile table
1246 ** for each file to be committed. Or, if aCommitFile is NULL, all files
1247 ** should be committed.
1248 */
1249 select_commit_files();
 
 
 
 
 
1250 isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
1251 if( g.aCommitFile && isAMerge ){
1252 fossil_fatal("cannot do a partial commit of a merge");
1253 }
1254
1255
--- 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.
@@ -899,17 +900,17 @@
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<-2){
914 const char *zWarning;
915 const char *zDisable;
916 const char *zConvert;
@@ -1244,11 +1245,16 @@
1245 ** After the following function call has returned, the Global.aCommitFile[]
1246 ** array is allocated to contain the "id" field from the vfile table
1247 ** for each file to be committed. Or, if aCommitFile is NULL, all files
1248 ** should be committed.
1249 */
1250 if ( select_commit_files() ){
1251 blob_zero(&ans);
1252 prompt_user("continue (y/N)? ", &ans);
1253 cReply = blob_str(&ans)[0];
1254 if( cReply!='y' && cReply!='Y' ) fossil_exit(1);;
1255 }
1256 isAMerge = db_exists("SELECT 1 FROM vmerge WHERE id=0");
1257 if( g.aCommitFile && isAMerge ){
1258 fossil_fatal("cannot do a partial commit of a merge");
1259 }
1260
1261
--- 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
+70 -24
--- 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))&3) == 0)
5663
#endif /* INTERFACE */
5764
5865
/*
5966
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -230,13 +237,12 @@
230237
** The only code points that this function cares about are the NUL character,
231238
** carriage-return, and line-feed.
232239
**
233240
************************************ WARNING **********************************
234241
*/
235
-
236242
int looks_like_utf8(const Blob *pContent){
237
- unsigned char *z = (unsigned char *) blob_buffer(pContent);
243
+ const unsigned char *z = (unsigned char *) blob_buffer(pContent);
238244
unsigned int n = blob_size(pContent);
239245
unsigned int j;
240246
unsigned char c;
241247
int result = 0; /* Assume UTF-8 text with no CR/NL */
242248
@@ -378,31 +384,52 @@
378384
if( pnByte ) *pnByte = 3;
379385
return bom;
380386
}
381387
382388
/*
383
-** This function returns detected BOM size if the blob starts with
384
-** a UTF-8, UTF-16le or UTF-16be byte-order-mark (BOM).
389
+** This function returns non-zero if the blob starts with a UTF-8
390
+** byte-order-mark (BOM).
385391
*/
386
-int starts_with_bom(const Blob *pContent){
392
+int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
387393
const char *z = blob_buffer(pContent);
388
- int c1, bomSize = 0;
394
+ int bomSize = 0;
389395
const unsigned char *bom = get_utf8_bom(&bomSize);
390396
391
- if( (blob_size(pContent)>=bomSize)
392
- && (memcmp(z, bom, bomSize)==0) ){
393
- return bomSize;
394
- }
395
- /* Only accept UTF-16 BOM if the blob has an even number of bytes */
396
- if( (blob_size(pContent)<2) || (blob_size(pContent)&1) ) return 0;
397
- c1 = *((unsigned short *)z);
398
- if( (c1==0xfffe) || (c1==0xfeff) ){
399
- if( blob_size(pContent)>=4 ){
400
- /* For UTF-32 BOM, always return 0. */
401
- if( ((unsigned short *)z)[1] == 0 ) return 0;
402
- }
403
- return 2;
397
+ if( pnByte ) *pnByte = bomSize;
398
+ if( blob_size(pContent)<bomSize ) return 0;
399
+ return memcmp(z, bom, bomSize)==0;
400
+}
401
+
402
+/*
403
+** This function returns non-zero if the blob starts with a UTF-16
404
+** byte-order-mark (BOM), either in the endianness of the machine
405
+** or in reversed byte order.
406
+*/
407
+int starts_with_utf16_bom(
408
+ const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
409
+ int *pnByte, /* OUT: The number of bytes used for the BOM. */
410
+ int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
411
+){
412
+ const char *z = blob_buffer(pContent);
413
+ int bomSize = 2;
414
+ static const unsigned short bom = 0xfeff;
415
+ static const unsigned short bom_reversed = 0xfffe;
416
+ static const unsigned short null = 0;
417
+ int size;
418
+
419
+ if( pnByte ) *pnByte = bomSize;
420
+ if( pbReverse ) *pbReverse = -1; /* Unknown. */
421
+ size = blob_size(pContent);
422
+ if( (size<bomSize) || (size%2) ) return 0;
423
+ if( memcmp(z, &bom_reversed, bomSize)==0 ){
424
+ if( pbReverse ) *pbReverse = 1;
425
+ if( size<(2*bomSize) ) return 1;
426
+ if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
427
+ }else if( memcmp(z, &bom, bomSize)==0 ){
428
+ if( pbReverse ) *pbReverse = 0;
429
+ if( size<(2*bomSize) ) return 1;
430
+ if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
404431
}
405432
return 0;
406433
}
407434
408435
/*
@@ -924,12 +951,12 @@
924951
&& zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
925952
nSuffix++;
926953
}
927954
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
928955
}
929
- if( nPrefix+nSuffix > nLeft ) nSuffix = nLeft - nPrefix;
930
- if( nPrefix+nSuffix > nRight ) nSuffix = nRight - nPrefix;
956
+ if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
957
+ if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
931958
932959
/* A single chunk of text inserted on the right */
933960
if( nPrefix+nSuffix==nLeft ){
934961
sbsWriteLineno(p, lnLeft);
935962
p->iStart2 = p->iEnd2 = 0;
@@ -1946,11 +1973,30 @@
19461973
return 0;
19471974
}
19481975
19491976
/* Compute the difference */
19501977
diff_all(&c);
1951
- if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
1978
+ if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
1979
+ int i, m, n;
1980
+ int *a = c.aEdit;
1981
+ int mx = c.nEdit;
1982
+ for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1983
+ if( n>10000 ){
1984
+ fossil_free(c.aFrom);
1985
+ fossil_free(c.aTo);
1986
+ fossil_free(c.aEdit);
1987
+ if( diffFlags & DIFF_HTML ){
1988
+ blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
1989
+ }else{
1990
+ blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
1991
+ }
1992
+ return 0;
1993
+ }
1994
+ }
1995
+ if( (diffFlags & DIFF_NOOPT)==0 ){
1996
+ diff_optimize(&c);
1997
+ }
19521998
19531999
if( pOut ){
19542000
/* Compute a context or side-by-side diff into pOut */
19552001
if( diffFlags & DIFF_SIDEBYSIDE ){
19562002
sbsDiff(&c, pOut, pRe, diffFlags);
@@ -2366,11 +2412,11 @@
23662412
if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
23672413
iLimit = atoi(zLimit);
23682414
showLog = find_option("log",0,0)!=0;
23692415
fileVers = find_option("filevers",0,0)!=0;
23702416
db_must_be_within_tree();
2371
- if( g.argc<3 ){
2417
+ if (g.argc<3) {
23722418
usage("FILENAME");
23732419
}
23742420
file_tree_name(g.argv[2], &treename, 1);
23752421
zFilename = blob_str(&treename);
23762422
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
@@ -2380,11 +2426,11 @@
23802426
fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
23812427
if( fid==0 ){
23822428
fossil_fatal("not part of current checkout: %s", zFilename);
23832429
}
23842430
cid = db_lget_int("checkout", 0);
2385
- if( cid == 0 ){
2431
+ if (cid == 0){
23862432
fossil_fatal("Not in a checkout");
23872433
}
23882434
if( iLimit<=0 ) iLimit = 1000000000;
23892435
compute_direct_ancestors(cid, iLimit);
23902436
mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
23912437
--- 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))&3) == 0)
56 #endif /* INTERFACE */
57
58 /*
59 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -230,13 +237,12 @@
230 ** The only code points that this function cares about are the NUL character,
231 ** carriage-return, and line-feed.
232 **
233 ************************************ WARNING **********************************
234 */
235
236 int looks_like_utf8(const Blob *pContent){
237 unsigned char *z = (unsigned char *) blob_buffer(pContent);
238 unsigned int n = blob_size(pContent);
239 unsigned int j;
240 unsigned char c;
241 int result = 0; /* Assume UTF-8 text with no CR/NL */
242
@@ -378,31 +384,52 @@
378 if( pnByte ) *pnByte = 3;
379 return bom;
380 }
381
382 /*
383 ** This function returns detected BOM size if the blob starts with
384 ** a UTF-8, UTF-16le or UTF-16be byte-order-mark (BOM).
385 */
386 int starts_with_bom(const Blob *pContent){
387 const char *z = blob_buffer(pContent);
388 int c1, bomSize = 0;
389 const unsigned char *bom = get_utf8_bom(&bomSize);
390
391 if( (blob_size(pContent)>=bomSize)
392 && (memcmp(z, bom, bomSize)==0) ){
393 return bomSize;
394 }
395 /* Only accept UTF-16 BOM if the blob has an even number of bytes */
396 if( (blob_size(pContent)<2) || (blob_size(pContent)&1) ) return 0;
397 c1 = *((unsigned short *)z);
398 if( (c1==0xfffe) || (c1==0xfeff) ){
399 if( blob_size(pContent)>=4 ){
400 /* For UTF-32 BOM, always return 0. */
401 if( ((unsigned short *)z)[1] == 0 ) return 0;
402 }
403 return 2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404 }
405 return 0;
406 }
407
408 /*
@@ -924,12 +951,12 @@
924 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
925 nSuffix++;
926 }
927 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
928 }
929 if( nPrefix+nSuffix > nLeft ) nSuffix = nLeft - nPrefix;
930 if( nPrefix+nSuffix > nRight ) nSuffix = nRight - nPrefix;
931
932 /* A single chunk of text inserted on the right */
933 if( nPrefix+nSuffix==nLeft ){
934 sbsWriteLineno(p, lnLeft);
935 p->iStart2 = p->iEnd2 = 0;
@@ -1946,11 +1973,30 @@
1946 return 0;
1947 }
1948
1949 /* Compute the difference */
1950 diff_all(&c);
1951 if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1952
1953 if( pOut ){
1954 /* Compute a context or side-by-side diff into pOut */
1955 if( diffFlags & DIFF_SIDEBYSIDE ){
1956 sbsDiff(&c, pOut, pRe, diffFlags);
@@ -2366,11 +2412,11 @@
2366 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2367 iLimit = atoi(zLimit);
2368 showLog = find_option("log",0,0)!=0;
2369 fileVers = find_option("filevers",0,0)!=0;
2370 db_must_be_within_tree();
2371 if( g.argc<3 ){
2372 usage("FILENAME");
2373 }
2374 file_tree_name(g.argv[2], &treename, 1);
2375 zFilename = blob_str(&treename);
2376 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
@@ -2380,11 +2426,11 @@
2380 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
2381 if( fid==0 ){
2382 fossil_fatal("not part of current checkout: %s", zFilename);
2383 }
2384 cid = db_lget_int("checkout", 0);
2385 if( cid == 0 ){
2386 fossil_fatal("Not in a checkout");
2387 }
2388 if( iLimit<=0 ) iLimit = 1000000000;
2389 compute_direct_ancestors(cid, iLimit);
2390 mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
2391
--- 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))&3) == 0)
63 #endif /* INTERFACE */
64
65 /*
66 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -230,13 +237,12 @@
237 ** The only code points that this function cares about are the NUL character,
238 ** carriage-return, and line-feed.
239 **
240 ************************************ WARNING **********************************
241 */
 
242 int looks_like_utf8(const Blob *pContent){
243 const unsigned char *z = (unsigned char *) blob_buffer(pContent);
244 unsigned int n = blob_size(pContent);
245 unsigned int j;
246 unsigned char c;
247 int result = 0; /* Assume UTF-8 text with no CR/NL */
248
@@ -378,31 +384,52 @@
384 if( pnByte ) *pnByte = 3;
385 return bom;
386 }
387
388 /*
389 ** This function returns non-zero if the blob starts with a UTF-8
390 ** byte-order-mark (BOM).
391 */
392 int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
393 const char *z = blob_buffer(pContent);
394 int bomSize = 0;
395 const unsigned char *bom = get_utf8_bom(&bomSize);
396
397 if( pnByte ) *pnByte = bomSize;
398 if( blob_size(pContent)<bomSize ) return 0;
399 return memcmp(z, bom, bomSize)==0;
400 }
401
402 /*
403 ** This function returns non-zero if the blob starts with a UTF-16
404 ** byte-order-mark (BOM), either in the endianness of the machine
405 ** or in reversed byte order.
406 */
407 int starts_with_utf16_bom(
408 const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
409 int *pnByte, /* OUT: The number of bytes used for the BOM. */
410 int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
411 ){
412 const char *z = blob_buffer(pContent);
413 int bomSize = 2;
414 static const unsigned short bom = 0xfeff;
415 static const unsigned short bom_reversed = 0xfffe;
416 static const unsigned short null = 0;
417 int size;
418
419 if( pnByte ) *pnByte = bomSize;
420 if( pbReverse ) *pbReverse = -1; /* Unknown. */
421 size = blob_size(pContent);
422 if( (size<bomSize) || (size%2) ) return 0;
423 if( memcmp(z, &bom_reversed, bomSize)==0 ){
424 if( pbReverse ) *pbReverse = 1;
425 if( size<(2*bomSize) ) return 1;
426 if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
427 }else if( memcmp(z, &bom, bomSize)==0 ){
428 if( pbReverse ) *pbReverse = 0;
429 if( size<(2*bomSize) ) return 1;
430 if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
431 }
432 return 0;
433 }
434
435 /*
@@ -924,12 +951,12 @@
951 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
952 nSuffix++;
953 }
954 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
955 }
956 if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
957 if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
958
959 /* A single chunk of text inserted on the right */
960 if( nPrefix+nSuffix==nLeft ){
961 sbsWriteLineno(p, lnLeft);
962 p->iStart2 = p->iEnd2 = 0;
@@ -1946,11 +1973,30 @@
1973 return 0;
1974 }
1975
1976 /* Compute the difference */
1977 diff_all(&c);
1978 if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
1979 int i, m, n;
1980 int *a = c.aEdit;
1981 int mx = c.nEdit;
1982 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1983 if( n>10000 ){
1984 fossil_free(c.aFrom);
1985 fossil_free(c.aTo);
1986 fossil_free(c.aEdit);
1987 if( diffFlags & DIFF_HTML ){
1988 blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
1989 }else{
1990 blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
1991 }
1992 return 0;
1993 }
1994 }
1995 if( (diffFlags & DIFF_NOOPT)==0 ){
1996 diff_optimize(&c);
1997 }
1998
1999 if( pOut ){
2000 /* Compute a context or side-by-side diff into pOut */
2001 if( diffFlags & DIFF_SIDEBYSIDE ){
2002 sbsDiff(&c, pOut, pRe, diffFlags);
@@ -2366,11 +2412,11 @@
2412 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2413 iLimit = atoi(zLimit);
2414 showLog = find_option("log",0,0)!=0;
2415 fileVers = find_option("filevers",0,0)!=0;
2416 db_must_be_within_tree();
2417 if (g.argc<3) {
2418 usage("FILENAME");
2419 }
2420 file_tree_name(g.argv[2], &treename, 1);
2421 zFilename = blob_str(&treename);
2422 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
@@ -2380,11 +2426,11 @@
2426 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
2427 if( fid==0 ){
2428 fossil_fatal("not part of current checkout: %s", zFilename);
2429 }
2430 cid = db_lget_int("checkout", 0);
2431 if (cid == 0){
2432 fossil_fatal("Not in a checkout");
2433 }
2434 if( iLimit<=0 ) iLimit = 1000000000;
2435 compute_direct_ancestors(cid, iLimit);
2436 mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
2437
+70 -24
--- 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))&3) == 0)
5663
#endif /* INTERFACE */
5764
5865
/*
5966
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -230,13 +237,12 @@
230237
** The only code points that this function cares about are the NUL character,
231238
** carriage-return, and line-feed.
232239
**
233240
************************************ WARNING **********************************
234241
*/
235
-
236242
int looks_like_utf8(const Blob *pContent){
237
- unsigned char *z = (unsigned char *) blob_buffer(pContent);
243
+ const unsigned char *z = (unsigned char *) blob_buffer(pContent);
238244
unsigned int n = blob_size(pContent);
239245
unsigned int j;
240246
unsigned char c;
241247
int result = 0; /* Assume UTF-8 text with no CR/NL */
242248
@@ -378,31 +384,52 @@
378384
if( pnByte ) *pnByte = 3;
379385
return bom;
380386
}
381387
382388
/*
383
-** This function returns detected BOM size if the blob starts with
384
-** a UTF-8, UTF-16le or UTF-16be byte-order-mark (BOM).
389
+** This function returns non-zero if the blob starts with a UTF-8
390
+** byte-order-mark (BOM).
385391
*/
386
-int starts_with_bom(const Blob *pContent){
392
+int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
387393
const char *z = blob_buffer(pContent);
388
- int c1, bomSize = 0;
394
+ int bomSize = 0;
389395
const unsigned char *bom = get_utf8_bom(&bomSize);
390396
391
- if( (blob_size(pContent)>=bomSize)
392
- && (memcmp(z, bom, bomSize)==0) ){
393
- return bomSize;
394
- }
395
- /* Only accept UTF-16 BOM if the blob has an even number of bytes */
396
- if( (blob_size(pContent)<2) || (blob_size(pContent)&1) ) return 0;
397
- c1 = *((unsigned short *)z);
398
- if( (c1==0xfffe) || (c1==0xfeff) ){
399
- if( blob_size(pContent)>=4 ){
400
- /* For UTF-32 BOM, always return 0. */
401
- if( ((unsigned short *)z)[1] == 0 ) return 0;
402
- }
403
- return 2;
397
+ if( pnByte ) *pnByte = bomSize;
398
+ if( blob_size(pContent)<bomSize ) return 0;
399
+ return memcmp(z, bom, bomSize)==0;
400
+}
401
+
402
+/*
403
+** This function returns non-zero if the blob starts with a UTF-16
404
+** byte-order-mark (BOM), either in the endianness of the machine
405
+** or in reversed byte order.
406
+*/
407
+int starts_with_utf16_bom(
408
+ const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
409
+ int *pnByte, /* OUT: The number of bytes used for the BOM. */
410
+ int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
411
+){
412
+ const char *z = blob_buffer(pContent);
413
+ int bomSize = 2;
414
+ static const unsigned short bom = 0xfeff;
415
+ static const unsigned short bom_reversed = 0xfffe;
416
+ static const unsigned short null = 0;
417
+ int size;
418
+
419
+ if( pnByte ) *pnByte = bomSize;
420
+ if( pbReverse ) *pbReverse = -1; /* Unknown. */
421
+ size = blob_size(pContent);
422
+ if( (size<bomSize) || (size%2) ) return 0;
423
+ if( memcmp(z, &bom_reversed, bomSize)==0 ){
424
+ if( pbReverse ) *pbReverse = 1;
425
+ if( size<(2*bomSize) ) return 1;
426
+ if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
427
+ }else if( memcmp(z, &bom, bomSize)==0 ){
428
+ if( pbReverse ) *pbReverse = 0;
429
+ if( size<(2*bomSize) ) return 1;
430
+ if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
404431
}
405432
return 0;
406433
}
407434
408435
/*
@@ -924,12 +951,12 @@
924951
&& zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
925952
nSuffix++;
926953
}
927954
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
928955
}
929
- if( nPrefix+nSuffix > nLeft ) nSuffix = nLeft - nPrefix;
930
- if( nPrefix+nSuffix > nRight ) nSuffix = nRight - nPrefix;
956
+ if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
957
+ if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
931958
932959
/* A single chunk of text inserted on the right */
933960
if( nPrefix+nSuffix==nLeft ){
934961
sbsWriteLineno(p, lnLeft);
935962
p->iStart2 = p->iEnd2 = 0;
@@ -1946,11 +1973,30 @@
19461973
return 0;
19471974
}
19481975
19491976
/* Compute the difference */
19501977
diff_all(&c);
1951
- if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
1978
+ if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
1979
+ int i, m, n;
1980
+ int *a = c.aEdit;
1981
+ int mx = c.nEdit;
1982
+ for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1983
+ if( n>10000 ){
1984
+ fossil_free(c.aFrom);
1985
+ fossil_free(c.aTo);
1986
+ fossil_free(c.aEdit);
1987
+ if( diffFlags & DIFF_HTML ){
1988
+ blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
1989
+ }else{
1990
+ blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
1991
+ }
1992
+ return 0;
1993
+ }
1994
+ }
1995
+ if( (diffFlags & DIFF_NOOPT)==0 ){
1996
+ diff_optimize(&c);
1997
+ }
19521998
19531999
if( pOut ){
19542000
/* Compute a context or side-by-side diff into pOut */
19552001
if( diffFlags & DIFF_SIDEBYSIDE ){
19562002
sbsDiff(&c, pOut, pRe, diffFlags);
@@ -2366,11 +2412,11 @@
23662412
if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
23672413
iLimit = atoi(zLimit);
23682414
showLog = find_option("log",0,0)!=0;
23692415
fileVers = find_option("filevers",0,0)!=0;
23702416
db_must_be_within_tree();
2371
- if( g.argc<3 ){
2417
+ if (g.argc<3) {
23722418
usage("FILENAME");
23732419
}
23742420
file_tree_name(g.argv[2], &treename, 1);
23752421
zFilename = blob_str(&treename);
23762422
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
@@ -2380,11 +2426,11 @@
23802426
fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
23812427
if( fid==0 ){
23822428
fossil_fatal("not part of current checkout: %s", zFilename);
23832429
}
23842430
cid = db_lget_int("checkout", 0);
2385
- if( cid == 0 ){
2431
+ if (cid == 0){
23862432
fossil_fatal("Not in a checkout");
23872433
}
23882434
if( iLimit<=0 ) iLimit = 1000000000;
23892435
compute_direct_ancestors(cid, iLimit);
23902436
mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
23912437
--- 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))&3) == 0)
56 #endif /* INTERFACE */
57
58 /*
59 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -230,13 +237,12 @@
230 ** The only code points that this function cares about are the NUL character,
231 ** carriage-return, and line-feed.
232 **
233 ************************************ WARNING **********************************
234 */
235
236 int looks_like_utf8(const Blob *pContent){
237 unsigned char *z = (unsigned char *) blob_buffer(pContent);
238 unsigned int n = blob_size(pContent);
239 unsigned int j;
240 unsigned char c;
241 int result = 0; /* Assume UTF-8 text with no CR/NL */
242
@@ -378,31 +384,52 @@
378 if( pnByte ) *pnByte = 3;
379 return bom;
380 }
381
382 /*
383 ** This function returns detected BOM size if the blob starts with
384 ** a UTF-8, UTF-16le or UTF-16be byte-order-mark (BOM).
385 */
386 int starts_with_bom(const Blob *pContent){
387 const char *z = blob_buffer(pContent);
388 int c1, bomSize = 0;
389 const unsigned char *bom = get_utf8_bom(&bomSize);
390
391 if( (blob_size(pContent)>=bomSize)
392 && (memcmp(z, bom, bomSize)==0) ){
393 return bomSize;
394 }
395 /* Only accept UTF-16 BOM if the blob has an even number of bytes */
396 if( (blob_size(pContent)<2) || (blob_size(pContent)&1) ) return 0;
397 c1 = *((unsigned short *)z);
398 if( (c1==0xfffe) || (c1==0xfeff) ){
399 if( blob_size(pContent)>=4 ){
400 /* For UTF-32 BOM, always return 0. */
401 if( ((unsigned short *)z)[1] == 0 ) return 0;
402 }
403 return 2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404 }
405 return 0;
406 }
407
408 /*
@@ -924,12 +951,12 @@
924 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
925 nSuffix++;
926 }
927 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
928 }
929 if( nPrefix+nSuffix > nLeft ) nSuffix = nLeft - nPrefix;
930 if( nPrefix+nSuffix > nRight ) nSuffix = nRight - nPrefix;
931
932 /* A single chunk of text inserted on the right */
933 if( nPrefix+nSuffix==nLeft ){
934 sbsWriteLineno(p, lnLeft);
935 p->iStart2 = p->iEnd2 = 0;
@@ -1946,11 +1973,30 @@
1946 return 0;
1947 }
1948
1949 /* Compute the difference */
1950 diff_all(&c);
1951 if( (diffFlags & DIFF_NOOPT)==0 ) diff_optimize(&c);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1952
1953 if( pOut ){
1954 /* Compute a context or side-by-side diff into pOut */
1955 if( diffFlags & DIFF_SIDEBYSIDE ){
1956 sbsDiff(&c, pOut, pRe, diffFlags);
@@ -2366,11 +2412,11 @@
2366 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2367 iLimit = atoi(zLimit);
2368 showLog = find_option("log",0,0)!=0;
2369 fileVers = find_option("filevers",0,0)!=0;
2370 db_must_be_within_tree();
2371 if( g.argc<3 ){
2372 usage("FILENAME");
2373 }
2374 file_tree_name(g.argv[2], &treename, 1);
2375 zFilename = blob_str(&treename);
2376 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
@@ -2380,11 +2426,11 @@
2380 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
2381 if( fid==0 ){
2382 fossil_fatal("not part of current checkout: %s", zFilename);
2383 }
2384 cid = db_lget_int("checkout", 0);
2385 if( cid == 0 ){
2386 fossil_fatal("Not in a checkout");
2387 }
2388 if( iLimit<=0 ) iLimit = 1000000000;
2389 compute_direct_ancestors(cid, iLimit);
2390 mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
2391
--- 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))&3) == 0)
63 #endif /* INTERFACE */
64
65 /*
66 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
@@ -230,13 +237,12 @@
237 ** The only code points that this function cares about are the NUL character,
238 ** carriage-return, and line-feed.
239 **
240 ************************************ WARNING **********************************
241 */
 
242 int looks_like_utf8(const Blob *pContent){
243 const unsigned char *z = (unsigned char *) blob_buffer(pContent);
244 unsigned int n = blob_size(pContent);
245 unsigned int j;
246 unsigned char c;
247 int result = 0; /* Assume UTF-8 text with no CR/NL */
248
@@ -378,31 +384,52 @@
384 if( pnByte ) *pnByte = 3;
385 return bom;
386 }
387
388 /*
389 ** This function returns non-zero if the blob starts with a UTF-8
390 ** byte-order-mark (BOM).
391 */
392 int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
393 const char *z = blob_buffer(pContent);
394 int bomSize = 0;
395 const unsigned char *bom = get_utf8_bom(&bomSize);
396
397 if( pnByte ) *pnByte = bomSize;
398 if( blob_size(pContent)<bomSize ) return 0;
399 return memcmp(z, bom, bomSize)==0;
400 }
401
402 /*
403 ** This function returns non-zero if the blob starts with a UTF-16
404 ** byte-order-mark (BOM), either in the endianness of the machine
405 ** or in reversed byte order.
406 */
407 int starts_with_utf16_bom(
408 const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
409 int *pnByte, /* OUT: The number of bytes used for the BOM. */
410 int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
411 ){
412 const char *z = blob_buffer(pContent);
413 int bomSize = 2;
414 static const unsigned short bom = 0xfeff;
415 static const unsigned short bom_reversed = 0xfffe;
416 static const unsigned short null = 0;
417 int size;
418
419 if( pnByte ) *pnByte = bomSize;
420 if( pbReverse ) *pbReverse = -1; /* Unknown. */
421 size = blob_size(pContent);
422 if( (size<bomSize) || (size%2) ) return 0;
423 if( memcmp(z, &bom_reversed, bomSize)==0 ){
424 if( pbReverse ) *pbReverse = 1;
425 if( size<(2*bomSize) ) return 1;
426 if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
427 }else if( memcmp(z, &bom, bomSize)==0 ){
428 if( pbReverse ) *pbReverse = 0;
429 if( size<(2*bomSize) ) return 1;
430 if( memcmp(z+bomSize, &null, bomSize)!=0 ) return 1;
431 }
432 return 0;
433 }
434
435 /*
@@ -924,12 +951,12 @@
951 && zLeft[nLeft-nSuffix-1]==zRight[nRight-nSuffix-1] ){
952 nSuffix++;
953 }
954 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
955 }
956 if( nPrefix+nSuffix > nLeft ) nPrefix = nLeft - nSuffix;
957 if( nPrefix+nSuffix > nRight ) nPrefix = nRight - nSuffix;
958
959 /* A single chunk of text inserted on the right */
960 if( nPrefix+nSuffix==nLeft ){
961 sbsWriteLineno(p, lnLeft);
962 p->iStart2 = p->iEnd2 = 0;
@@ -1946,11 +1973,30 @@
1973 return 0;
1974 }
1975
1976 /* Compute the difference */
1977 diff_all(&c);
1978 if( (diffFlags & DIFF_NOTTOOBIG)!=0 ){
1979 int i, m, n;
1980 int *a = c.aEdit;
1981 int mx = c.nEdit;
1982 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1983 if( n>10000 ){
1984 fossil_free(c.aFrom);
1985 fossil_free(c.aTo);
1986 fossil_free(c.aEdit);
1987 if( diffFlags & DIFF_HTML ){
1988 blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
1989 }else{
1990 blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
1991 }
1992 return 0;
1993 }
1994 }
1995 if( (diffFlags & DIFF_NOOPT)==0 ){
1996 diff_optimize(&c);
1997 }
1998
1999 if( pOut ){
2000 /* Compute a context or side-by-side diff into pOut */
2001 if( diffFlags & DIFF_SIDEBYSIDE ){
2002 sbsDiff(&c, pOut, pRe, diffFlags);
@@ -2366,11 +2412,11 @@
2412 if( zLimit==0 || zLimit[0]==0 ) zLimit = "-1";
2413 iLimit = atoi(zLimit);
2414 showLog = find_option("log",0,0)!=0;
2415 fileVers = find_option("filevers",0,0)!=0;
2416 db_must_be_within_tree();
2417 if (g.argc<3) {
2418 usage("FILENAME");
2419 }
2420 file_tree_name(g.argv[2], &treename, 1);
2421 zFilename = blob_str(&treename);
2422 fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
@@ -2380,11 +2426,11 @@
2426 fid = db_int(0, "SELECT rid FROM vfile WHERE pathname=%Q", zFilename);
2427 if( fid==0 ){
2428 fossil_fatal("not part of current checkout: %s", zFilename);
2429 }
2430 cid = db_lget_int("checkout", 0);
2431 if (cid == 0){
2432 fossil_fatal("Not in a checkout");
2433 }
2434 if( iLimit<=0 ) iLimit = 1000000000;
2435 compute_direct_ancestors(cid, iLimit);
2436 mid = db_int(0, "SELECT mlink.mid FROM mlink, ancestor "
2437
--- src/http_transport.c
+++ src/http_transport.c
@@ -312,11 +312,11 @@
312312
sqlite3_randomness(sizeof(iRandId), &iRandId);
313313
transport.zOutFile = mprintf("%s-%llu-out.http",
314314
g.zRepositoryName, iRandId);
315315
transport.zInFile = mprintf("%s-%llu-in.http",
316316
g.zRepositoryName, iRandId);
317
- transport.pFile = fopen(transport.zOutFile, "wb");
317
+ transport.pFile = fossil_fopen(transport.zOutFile, "wb");
318318
if( transport.pFile==0 ){
319319
fossil_fatal("cannot output temporary file: %s", transport.zOutFile);
320320
}
321321
transport.isOpen = 1;
322322
}else{
@@ -409,11 +409,11 @@
409409
zCmd = mprintf("\"%s\" http \"%s\" \"%s\" \"%s\" 127.0.0.1 --localauth",
410410
g.nameOfExe, g.urlName, transport.zOutFile, transport.zInFile
411411
);
412412
fossil_system(zCmd);
413413
free(zCmd);
414
- transport.pFile = fopen(transport.zInFile, "rb");
414
+ transport.pFile = fossil_fopen(transport.zInFile, "rb");
415415
}
416416
}
417417
418418
/*
419419
** Log all input to a file. The transport layer will take responsibility
420420
--- src/http_transport.c
+++ src/http_transport.c
@@ -312,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 = 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{
@@ -409,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 = fopen(transport.zInFile, "rb");
415 }
416 }
417
418 /*
419 ** Log all input to a file. The transport layer will take responsibility
420
--- src/http_transport.c
+++ src/http_transport.c
@@ -312,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{
@@ -409,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
420
+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
+1 -4
--- src/main.c
+++ src/main.c
@@ -252,14 +252,11 @@
252252
} cmd;
253253
struct { /* JSON POST data. */
254254
cson_value * v;
255255
cson_object * o;
256256
} post;
257
- struct { /* GET/COOKIE params in JSON mode.
258
- FIXME (stephan): verify that this is
259
- still used and remove if it is not.
260
- */
257
+ struct { /* GET/COOKIE params in JSON mode. */
261258
cson_value * v;
262259
cson_object * o;
263260
} param;
264261
struct {
265262
cson_value * v;
266263
--- src/main.c
+++ src/main.c
@@ -252,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 FIXME (stephan): verify that this is
259 still used and remove if it is not.
260 */
261 cson_value * v;
262 cson_object * o;
263 } param;
264 struct {
265 cson_value * v;
266
--- src/main.c
+++ src/main.c
@@ -252,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
--- 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