Fossil SCM

Merge with trunk.

isaac.jurado 2013-08-08 18:57 git-better-import merge
Commit 9a023e0d6cb1b195d2ca95724beb79d20d470596
+2
--- src/blob.c
+++ src/blob.c
@@ -1096,11 +1096,13 @@
10961096
** to be UTF-8 already, so no conversion is done.
10971097
*/
10981098
void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
10991099
char *zUtf8;
11001100
int bomSize = 0;
1101
+#if defined(_WIN32) || defined(__CYGWIN__)
11011102
int bomReverse = 0;
1103
+#endif
11021104
if( starts_with_utf8_bom(pBlob, &bomSize) ){
11031105
struct Blob temp;
11041106
zUtf8 = blob_str(pBlob) + bomSize;
11051107
blob_zero(&temp);
11061108
blob_append(&temp, zUtf8, -1);
11071109
--- src/blob.c
+++ src/blob.c
@@ -1096,11 +1096,13 @@
1096 ** to be UTF-8 already, so no conversion is done.
1097 */
1098 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1099 char *zUtf8;
1100 int bomSize = 0;
 
1101 int bomReverse = 0;
 
1102 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1103 struct Blob temp;
1104 zUtf8 = blob_str(pBlob) + bomSize;
1105 blob_zero(&temp);
1106 blob_append(&temp, zUtf8, -1);
1107
--- src/blob.c
+++ src/blob.c
@@ -1096,11 +1096,13 @@
1096 ** to be UTF-8 already, so no conversion is done.
1097 */
1098 void blob_to_utf8_no_bom(Blob *pBlob, int useMbcs){
1099 char *zUtf8;
1100 int bomSize = 0;
1101 #if defined(_WIN32) || defined(__CYGWIN__)
1102 int bomReverse = 0;
1103 #endif
1104 if( starts_with_utf8_bom(pBlob, &bomSize) ){
1105 struct Blob temp;
1106 zUtf8 = blob_str(pBlob) + bomSize;
1107 blob_zero(&temp);
1108 blob_append(&temp, zUtf8, -1);
1109
+22
--- src/cgi.c
+++ src/cgi.c
@@ -1131,10 +1131,24 @@
11311131
va_end(ap);
11321132
cgi_reply();
11331133
fossil_exit(1);
11341134
}
11351135
}
1136
+
1137
+/* z[] is the value of an X-FORWARDED-FOR: line in an HTTP header.
1138
+** Return a pointer to a string containing the real IP address, or a
1139
+** NULL pointer to stick with the IP address previously computed and
1140
+** loaded into g.zIpAddr.
1141
+*/
1142
+static const char *cgi_accept_forwarded_for(const char *z){
1143
+ int i;
1144
+ if( fossil_strcmp(g.zIpAddr, "127.0.0.1")!=0 ) return 0;
1145
+
1146
+ i = strlen(z)-1;
1147
+ while( i>=0 && z[i]!=',' && !fossil_isspace(z[i]) ) i--;
1148
+ return &z[++i];
1149
+}
11361150
11371151
/*
11381152
** Remove the first space-delimited token from a string and return
11391153
** a pointer to it. Add a NULL to the string to terminate the token.
11401154
** Make *zLeftOver point to the start of the next token.
@@ -1175,10 +1189,11 @@
11751189
char zLine[2000]; /* A single line of input. */
11761190
g.fullHttpReply = 1;
11771191
if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
11781192
malformed_request();
11791193
}
1194
+ blob_append(&g.httpHeader, zLine, -1);
11801195
cgi_trace(zLine);
11811196
zToken = extract_token(zLine, &z);
11821197
if( zToken==0 ){
11831198
malformed_request();
11841199
}
@@ -1213,10 +1228,11 @@
12131228
while( fgets(zLine,sizeof(zLine),g.httpIn) ){
12141229
char *zFieldName;
12151230
char *zVal;
12161231
12171232
cgi_trace(zLine);
1233
+ blob_append(&g.httpHeader, zLine, -1);
12181234
zFieldName = extract_token(zLine,&zVal);
12191235
if( zFieldName==0 || *zFieldName==0 ) break;
12201236
while( fossil_isspace(*zVal) ){ zVal++; }
12211237
i = strlen(zVal);
12221238
while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
@@ -1242,10 +1258,16 @@
12421258
}else if( fossil_strcmp(zFieldName,"referer:")==0 ){
12431259
cgi_setenv("HTTP_REFERER", zVal);
12441260
#endif
12451261
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
12461262
cgi_setenv("HTTP_USER_AGENT", zVal);
1263
+ }else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
1264
+ const char *zIpAddr = cgi_accept_forwarded_for(zVal);
1265
+ if( zIpAddr!=0 ){
1266
+ g.zIpAddr = mprintf("%s", zIpAddr);
1267
+ cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
1268
+ }
12471269
}
12481270
}
12491271
cgi_init();
12501272
cgi_trace(0);
12511273
}
12521274
--- src/cgi.c
+++ src/cgi.c
@@ -1131,10 +1131,24 @@
1131 va_end(ap);
1132 cgi_reply();
1133 fossil_exit(1);
1134 }
1135 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1136
1137 /*
1138 ** Remove the first space-delimited token from a string and return
1139 ** a pointer to it. Add a NULL to the string to terminate the token.
1140 ** Make *zLeftOver point to the start of the next token.
@@ -1175,10 +1189,11 @@
1175 char zLine[2000]; /* A single line of input. */
1176 g.fullHttpReply = 1;
1177 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
1178 malformed_request();
1179 }
 
1180 cgi_trace(zLine);
1181 zToken = extract_token(zLine, &z);
1182 if( zToken==0 ){
1183 malformed_request();
1184 }
@@ -1213,10 +1228,11 @@
1213 while( fgets(zLine,sizeof(zLine),g.httpIn) ){
1214 char *zFieldName;
1215 char *zVal;
1216
1217 cgi_trace(zLine);
 
1218 zFieldName = extract_token(zLine,&zVal);
1219 if( zFieldName==0 || *zFieldName==0 ) break;
1220 while( fossil_isspace(*zVal) ){ zVal++; }
1221 i = strlen(zVal);
1222 while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
@@ -1242,10 +1258,16 @@
1242 }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1243 cgi_setenv("HTTP_REFERER", zVal);
1244 #endif
1245 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
1246 cgi_setenv("HTTP_USER_AGENT", zVal);
 
 
 
 
 
 
1247 }
1248 }
1249 cgi_init();
1250 cgi_trace(0);
1251 }
1252
--- src/cgi.c
+++ src/cgi.c
@@ -1131,10 +1131,24 @@
1131 va_end(ap);
1132 cgi_reply();
1133 fossil_exit(1);
1134 }
1135 }
1136
1137 /* z[] is the value of an X-FORWARDED-FOR: line in an HTTP header.
1138 ** Return a pointer to a string containing the real IP address, or a
1139 ** NULL pointer to stick with the IP address previously computed and
1140 ** loaded into g.zIpAddr.
1141 */
1142 static const char *cgi_accept_forwarded_for(const char *z){
1143 int i;
1144 if( fossil_strcmp(g.zIpAddr, "127.0.0.1")!=0 ) return 0;
1145
1146 i = strlen(z)-1;
1147 while( i>=0 && z[i]!=',' && !fossil_isspace(z[i]) ) i--;
1148 return &z[++i];
1149 }
1150
1151 /*
1152 ** Remove the first space-delimited token from a string and return
1153 ** a pointer to it. Add a NULL to the string to terminate the token.
1154 ** Make *zLeftOver point to the start of the next token.
@@ -1175,10 +1189,11 @@
1189 char zLine[2000]; /* A single line of input. */
1190 g.fullHttpReply = 1;
1191 if( fgets(zLine, sizeof(zLine),g.httpIn)==0 ){
1192 malformed_request();
1193 }
1194 blob_append(&g.httpHeader, zLine, -1);
1195 cgi_trace(zLine);
1196 zToken = extract_token(zLine, &z);
1197 if( zToken==0 ){
1198 malformed_request();
1199 }
@@ -1213,10 +1228,11 @@
1228 while( fgets(zLine,sizeof(zLine),g.httpIn) ){
1229 char *zFieldName;
1230 char *zVal;
1231
1232 cgi_trace(zLine);
1233 blob_append(&g.httpHeader, zLine, -1);
1234 zFieldName = extract_token(zLine,&zVal);
1235 if( zFieldName==0 || *zFieldName==0 ) break;
1236 while( fossil_isspace(*zVal) ){ zVal++; }
1237 i = strlen(zVal);
1238 while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
@@ -1242,10 +1258,16 @@
1258 }else if( fossil_strcmp(zFieldName,"referer:")==0 ){
1259 cgi_setenv("HTTP_REFERER", zVal);
1260 #endif
1261 }else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
1262 cgi_setenv("HTTP_USER_AGENT", zVal);
1263 }else if( fossil_strcmp(zFieldName,"x-forwarded-for:")==0 ){
1264 const char *zIpAddr = cgi_accept_forwarded_for(zVal);
1265 if( zIpAddr!=0 ){
1266 g.zIpAddr = mprintf("%s", zIpAddr);
1267 cgi_replace_parameter("REMOTE_ADDR", g.zIpAddr);
1268 }
1269 }
1270 }
1271 cgi_init();
1272 cgi_trace(0);
1273 }
1274
+61 -10
--- src/checkin.c
+++ src/checkin.c
@@ -103,16 +103,20 @@
103103
}
104104
}else if( isNew ){
105105
blob_appendf(report, "ADDED %s\n", zDisplayName);
106106
}else if( isDeleted ){
107107
blob_appendf(report, "DELETED %s\n", zDisplayName);
108
- }else if( isChnged==2 ){
109
- blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
110
- }else if( isChnged==3 ){
111
- blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
112
- }else if( isChnged==1 ){
113
- if( file_contains_merge_marker(zFullName) ){
108
+ }else if( isChnged ){
109
+ if( isChnged==2 ){
110
+ blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
111
+ }else if( isChnged==3 ){
112
+ blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
113
+ }else if( isChnged==4 ){
114
+ blob_appendf(report, "UPDATED_BY_INTEGRATE %s\n", zDisplayName);
115
+ }else if( isChnged==5 ){
116
+ blob_appendf(report, "ADDED_BY_INTEGRATE %s\n", zDisplayName);
117
+ }else if( file_contains_merge_marker(zFullName) ){
114118
blob_appendf(report, "CONFLICT %s\n", zDisplayName);
115119
}else{
116120
blob_appendf(report, "EDITED %s\n", zDisplayName);
117121
}
118122
}else if( isRenamed ){
@@ -127,12 +131,13 @@
127131
db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
128132
" WHERE id<=0");
129133
while( db_step(&q)==SQLITE_ROW ){
130134
const char *zLabel = "MERGED_WITH";
131135
switch( db_column_int(&q, 1) ){
132
- case -1: zLabel = "CHERRYPICK"; break;
133
- case -2: zLabel = "BACKOUT "; break;
136
+ case -1: zLabel = "CHERRYPICK "; break;
137
+ case -2: zLabel = "BACKOUT "; break;
138
+ case -4: zLabel = "INTEGRATE "; break;
134139
}
135140
blob_append(report, zPrefix, nPrefix);
136141
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
137142
}
138143
db_finalize(&q);
@@ -328,11 +333,23 @@
328333
type = "NOT_A_FILE ";
329334
}else{
330335
type = "MISSING ";
331336
}
332337
}else if( chnged ){
333
- type = "EDITED ";
338
+ if( chnged==2 ){
339
+ type = "UPDATED_BY_MERGE ";
340
+ }else if( chnged==3 ){
341
+ type = "ADDED_BY_MERGE ";
342
+ }else if( chnged==4 ){
343
+ type = "UPDATED_BY_INTEGRATE ";
344
+ }else if( chnged==5 ){
345
+ type = "ADDED_BY_INTEGRATE ";
346
+ }else if( file_contains_merge_marker(zFullName) ){
347
+ type = "CONFLICT ";
348
+ }else{
349
+ type = "EDITED ";
350
+ }
334351
}else if( renamed ){
335352
type = "RENAMED ";
336353
}else{
337354
type = "UNCHANGED ";
338355
}
@@ -1670,24 +1687,58 @@
16701687
** and rollback the transaction.
16711688
*/
16721689
if( dryRunFlag ){
16731690
blob_write_to_file(&manifest, "");
16741691
}
1675
-
16761692
if( outputManifest ){
16771693
zManifestFile = mprintf("%smanifest", g.zLocalRoot);
16781694
blob_write_to_file(&manifest, zManifestFile);
16791695
blob_reset(&manifest);
16801696
blob_read_from_file(&manifest, zManifestFile);
16811697
free(zManifestFile);
16821698
}
1699
+
16831700
nvid = content_put(&manifest);
16841701
if( nvid==0 ){
16851702
fossil_panic("trouble committing manifest: %s", g.zErrMsg);
16861703
}
16871704
db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
16881705
manifest_crosslink(nvid, &manifest);
1706
+
1707
+ db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid"
1708
+ " WHERE id=-4");
1709
+ while( db_step(&q)==SQLITE_ROW ){
1710
+ const char *zIntegrateUuid = db_column_text(&q, 0);
1711
+ int rid = db_column_int(&q, 1);
1712
+ if( !is_a_leaf(rid) ){
1713
+ fossil_print("Not_Closed: %s (not a leaf any more)\n", zIntegrateUuid);
1714
+ }else{
1715
+ if (!db_exists("SELECT 1 FROM tagxref "
1716
+ " WHERE tagid=%d AND rid=%d AND tagtype>0",
1717
+ TAG_CLOSED, rid)
1718
+ ){
1719
+ Blob ctrl;
1720
+ Blob cksum;
1721
+ char *zDate;
1722
+ int nrid;
1723
+
1724
+ blob_zero(&ctrl);
1725
+ zDate = date_in_standard_format(sCiInfo.zDateOvrd ? sCiInfo.zDateOvrd : "now");
1726
+ blob_appendf(&ctrl, "D %s\n", zDate);
1727
+ blob_appendf(&ctrl, "T +closed %s\n", zIntegrateUuid);
1728
+ blob_appendf(&ctrl, "U %F\n", sCiInfo.zUserOvrd ? sCiInfo.zUserOvrd : g.zLogin);
1729
+ md5sum_blob(&ctrl, &cksum);
1730
+ blob_appendf(&ctrl, "Z %b\n", &cksum);
1731
+ nrid = content_put(&ctrl);
1732
+ manifest_crosslink(nrid, &ctrl);
1733
+ assert( blob_is_reset(&ctrl) );
1734
+ }
1735
+ fossil_print("Closed: %s\n", zIntegrateUuid);
1736
+ }
1737
+ }
1738
+ db_finalize(&q);
1739
+
16891740
assert( blob_is_reset(&manifest) );
16901741
content_deltify(vid, nvid, 0);
16911742
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
16921743
fossil_print("New_Version: %s\n", zUuid);
16931744
if( outputManifest ){
16941745
--- src/checkin.c
+++ src/checkin.c
@@ -103,16 +103,20 @@
103 }
104 }else if( isNew ){
105 blob_appendf(report, "ADDED %s\n", zDisplayName);
106 }else if( isDeleted ){
107 blob_appendf(report, "DELETED %s\n", zDisplayName);
108 }else if( isChnged==2 ){
109 blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
110 }else if( isChnged==3 ){
111 blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
112 }else if( isChnged==1 ){
113 if( file_contains_merge_marker(zFullName) ){
 
 
 
 
114 blob_appendf(report, "CONFLICT %s\n", zDisplayName);
115 }else{
116 blob_appendf(report, "EDITED %s\n", zDisplayName);
117 }
118 }else if( isRenamed ){
@@ -127,12 +131,13 @@
127 db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
128 " WHERE id<=0");
129 while( db_step(&q)==SQLITE_ROW ){
130 const char *zLabel = "MERGED_WITH";
131 switch( db_column_int(&q, 1) ){
132 case -1: zLabel = "CHERRYPICK"; break;
133 case -2: zLabel = "BACKOUT "; break;
 
134 }
135 blob_append(report, zPrefix, nPrefix);
136 blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
137 }
138 db_finalize(&q);
@@ -328,11 +333,23 @@
328 type = "NOT_A_FILE ";
329 }else{
330 type = "MISSING ";
331 }
332 }else if( chnged ){
333 type = "EDITED ";
 
 
 
 
 
 
 
 
 
 
 
 
334 }else if( renamed ){
335 type = "RENAMED ";
336 }else{
337 type = "UNCHANGED ";
338 }
@@ -1670,24 +1687,58 @@
1670 ** and rollback the transaction.
1671 */
1672 if( dryRunFlag ){
1673 blob_write_to_file(&manifest, "");
1674 }
1675
1676 if( outputManifest ){
1677 zManifestFile = mprintf("%smanifest", g.zLocalRoot);
1678 blob_write_to_file(&manifest, zManifestFile);
1679 blob_reset(&manifest);
1680 blob_read_from_file(&manifest, zManifestFile);
1681 free(zManifestFile);
1682 }
 
1683 nvid = content_put(&manifest);
1684 if( nvid==0 ){
1685 fossil_panic("trouble committing manifest: %s", g.zErrMsg);
1686 }
1687 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
1688 manifest_crosslink(nvid, &manifest);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1689 assert( blob_is_reset(&manifest) );
1690 content_deltify(vid, nvid, 0);
1691 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
1692 fossil_print("New_Version: %s\n", zUuid);
1693 if( outputManifest ){
1694
--- src/checkin.c
+++ src/checkin.c
@@ -103,16 +103,20 @@
103 }
104 }else if( isNew ){
105 blob_appendf(report, "ADDED %s\n", zDisplayName);
106 }else if( isDeleted ){
107 blob_appendf(report, "DELETED %s\n", zDisplayName);
108 }else if( isChnged ){
109 if( isChnged==2 ){
110 blob_appendf(report, "UPDATED_BY_MERGE %s\n", zDisplayName);
111 }else if( isChnged==3 ){
112 blob_appendf(report, "ADDED_BY_MERGE %s\n", zDisplayName);
113 }else if( isChnged==4 ){
114 blob_appendf(report, "UPDATED_BY_INTEGRATE %s\n", zDisplayName);
115 }else if( isChnged==5 ){
116 blob_appendf(report, "ADDED_BY_INTEGRATE %s\n", zDisplayName);
117 }else if( file_contains_merge_marker(zFullName) ){
118 blob_appendf(report, "CONFLICT %s\n", zDisplayName);
119 }else{
120 blob_appendf(report, "EDITED %s\n", zDisplayName);
121 }
122 }else if( isRenamed ){
@@ -127,12 +131,13 @@
131 db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
132 " WHERE id<=0");
133 while( db_step(&q)==SQLITE_ROW ){
134 const char *zLabel = "MERGED_WITH";
135 switch( db_column_int(&q, 1) ){
136 case -1: zLabel = "CHERRYPICK "; break;
137 case -2: zLabel = "BACKOUT "; break;
138 case -4: zLabel = "INTEGRATE "; break;
139 }
140 blob_append(report, zPrefix, nPrefix);
141 blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
142 }
143 db_finalize(&q);
@@ -328,11 +333,23 @@
333 type = "NOT_A_FILE ";
334 }else{
335 type = "MISSING ";
336 }
337 }else if( chnged ){
338 if( chnged==2 ){
339 type = "UPDATED_BY_MERGE ";
340 }else if( chnged==3 ){
341 type = "ADDED_BY_MERGE ";
342 }else if( chnged==4 ){
343 type = "UPDATED_BY_INTEGRATE ";
344 }else if( chnged==5 ){
345 type = "ADDED_BY_INTEGRATE ";
346 }else if( file_contains_merge_marker(zFullName) ){
347 type = "CONFLICT ";
348 }else{
349 type = "EDITED ";
350 }
351 }else if( renamed ){
352 type = "RENAMED ";
353 }else{
354 type = "UNCHANGED ";
355 }
@@ -1670,24 +1687,58 @@
1687 ** and rollback the transaction.
1688 */
1689 if( dryRunFlag ){
1690 blob_write_to_file(&manifest, "");
1691 }
 
1692 if( outputManifest ){
1693 zManifestFile = mprintf("%smanifest", g.zLocalRoot);
1694 blob_write_to_file(&manifest, zManifestFile);
1695 blob_reset(&manifest);
1696 blob_read_from_file(&manifest, zManifestFile);
1697 free(zManifestFile);
1698 }
1699
1700 nvid = content_put(&manifest);
1701 if( nvid==0 ){
1702 fossil_panic("trouble committing manifest: %s", g.zErrMsg);
1703 }
1704 db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nvid);
1705 manifest_crosslink(nvid, &manifest);
1706
1707 db_prepare(&q, "SELECT uuid,merge FROM vmerge JOIN blob ON merge=rid"
1708 " WHERE id=-4");
1709 while( db_step(&q)==SQLITE_ROW ){
1710 const char *zIntegrateUuid = db_column_text(&q, 0);
1711 int rid = db_column_int(&q, 1);
1712 if( !is_a_leaf(rid) ){
1713 fossil_print("Not_Closed: %s (not a leaf any more)\n", zIntegrateUuid);
1714 }else{
1715 if (!db_exists("SELECT 1 FROM tagxref "
1716 " WHERE tagid=%d AND rid=%d AND tagtype>0",
1717 TAG_CLOSED, rid)
1718 ){
1719 Blob ctrl;
1720 Blob cksum;
1721 char *zDate;
1722 int nrid;
1723
1724 blob_zero(&ctrl);
1725 zDate = date_in_standard_format(sCiInfo.zDateOvrd ? sCiInfo.zDateOvrd : "now");
1726 blob_appendf(&ctrl, "D %s\n", zDate);
1727 blob_appendf(&ctrl, "T +closed %s\n", zIntegrateUuid);
1728 blob_appendf(&ctrl, "U %F\n", sCiInfo.zUserOvrd ? sCiInfo.zUserOvrd : g.zLogin);
1729 md5sum_blob(&ctrl, &cksum);
1730 blob_appendf(&ctrl, "Z %b\n", &cksum);
1731 nrid = content_put(&ctrl);
1732 manifest_crosslink(nrid, &ctrl);
1733 assert( blob_is_reset(&ctrl) );
1734 }
1735 fossil_print("Closed: %s\n", zIntegrateUuid);
1736 }
1737 }
1738 db_finalize(&q);
1739
1740 assert( blob_is_reset(&manifest) );
1741 content_deltify(vid, nvid, 0);
1742 zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", nvid);
1743 fossil_print("New_Version: %s\n", zUuid);
1744 if( outputManifest ){
1745
+9 -2
--- src/db.c
+++ src/db.c
@@ -712,10 +712,13 @@
712712
LOCAL sqlite3 *db_open(const char *zDbName){
713713
int rc;
714714
const char *zVfs;
715715
sqlite3 *db;
716716
717
+#if defined(__CYGWIN__)
718
+ zDbName = fossil_utf8_to_filename(zDbName);
719
+#endif
717720
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
718721
zVfs = fossil_getenv("FOSSIL_VFS");
719722
rc = sqlite3_open_v2(
720723
zDbName, &db,
721724
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
@@ -1020,13 +1023,17 @@
10201023
g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
10211024
#endif
10221025
fossil_panic("not a valid repository: %s", zDbName);
10231026
}
10241027
}
1025
- db_open_or_attach(zDbName, "repository", 0);
1026
- g.repositoryOpen = 1;
1028
+#if defined(__CYGWIN__)
1029
+ g.zRepositoryName = fossil_utf8_to_filename(zDbName);
1030
+#else
10271031
g.zRepositoryName = mprintf("%s", zDbName);
1032
+#endif
1033
+ db_open_or_attach(g.zRepositoryName, "repository", 0);
1034
+ g.repositoryOpen = 1;
10281035
/* Cache "allow-symlinks" option, because we'll need it on every stat call */
10291036
g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
10301037
}
10311038
10321039
/*
10331040
--- src/db.c
+++ src/db.c
@@ -712,10 +712,13 @@
712 LOCAL sqlite3 *db_open(const char *zDbName){
713 int rc;
714 const char *zVfs;
715 sqlite3 *db;
716
 
 
 
717 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
718 zVfs = fossil_getenv("FOSSIL_VFS");
719 rc = sqlite3_open_v2(
720 zDbName, &db,
721 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
@@ -1020,13 +1023,17 @@
1020 g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
1021 #endif
1022 fossil_panic("not a valid repository: %s", zDbName);
1023 }
1024 }
1025 db_open_or_attach(zDbName, "repository", 0);
1026 g.repositoryOpen = 1;
 
1027 g.zRepositoryName = mprintf("%s", zDbName);
 
 
 
1028 /* Cache "allow-symlinks" option, because we'll need it on every stat call */
1029 g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
1030 }
1031
1032 /*
1033
--- src/db.c
+++ src/db.c
@@ -712,10 +712,13 @@
712 LOCAL sqlite3 *db_open(const char *zDbName){
713 int rc;
714 const char *zVfs;
715 sqlite3 *db;
716
717 #if defined(__CYGWIN__)
718 zDbName = fossil_utf8_to_filename(zDbName);
719 #endif
720 if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
721 zVfs = fossil_getenv("FOSSIL_VFS");
722 rc = sqlite3_open_v2(
723 zDbName, &db,
724 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
@@ -1020,13 +1023,17 @@
1023 g.json.resultCode = FSL_JSON_E_DB_NOT_VALID;
1024 #endif
1025 fossil_panic("not a valid repository: %s", zDbName);
1026 }
1027 }
1028 #if defined(__CYGWIN__)
1029 g.zRepositoryName = fossil_utf8_to_filename(zDbName);
1030 #else
1031 g.zRepositoryName = mprintf("%s", zDbName);
1032 #endif
1033 db_open_or_attach(g.zRepositoryName, "repository", 0);
1034 g.repositoryOpen = 1;
1035 /* Cache "allow-symlinks" option, because we'll need it on every stat call */
1036 g.allowSymlinks = db_get_boolean("allow-symlinks", 0);
1037 }
1038
1039 /*
1040
+202 -516
--- src/diff.c
+++ src/diff.c
@@ -51,47 +51,20 @@
5151
"cannot compute difference between binary files\n"
5252
5353
#define DIFF_CANNOT_COMPUTE_SYMLINK \
5454
"cannot compute difference between symlink and regular file\n"
5555
56
-#define DIFF_TOO_MANY_CHANGES_TXT \
56
+#define DIFF_TOO_MANY_CHANGES \
5757
"more than 10,000 changes\n"
5858
59
-#define DIFF_TOO_MANY_CHANGES_HTML \
60
- "<p class='generalError'>More than 10,000 changes</p>\n"
61
-
62
-/*
63
-** This macro is designed to return non-zero if the specified blob contains
64
-** data that MAY be binary in nature; otherwise, zero will be returned.
65
-*/
66
-#define looks_like_binary(blob) \
67
- ((looks_like_utf8((blob), LOOK_BINARY) & LOOK_BINARY) != LOOK_NONE)
68
-
69
-/*
70
-** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
71
-** to convey status information about the blob content.
72
-*/
73
-#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
74
-#define LOOK_NUL ((int)0x00000001) /* One or more NUL chars were found. */
75
-#define LOOK_CR ((int)0x00000002) /* One or more CR chars were found. */
76
-#define LOOK_LONE_CR ((int)0x00000004) /* An unpaired CR char was found. */
77
-#define LOOK_LF ((int)0x00000008) /* One or more LF chars were found. */
78
-#define LOOK_LONE_LF ((int)0x00000010) /* An unpaired LF char was found. */
79
-#define LOOK_CRLF ((int)0x00000020) /* One or more CR/LF pairs were found. */
80
-#define LOOK_LONG ((int)0x00000040) /* An over length line was found. */
81
-#define LOOK_ODD ((int)0x00000080) /* An odd number of bytes was found. */
82
-#define LOOK_SHORT ((int)0x00000100) /* Unable to perform full check. */
83
-#define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
84
-#define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
85
-#define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
86
-#endif /* INTERFACE */
87
-
8859
/*
8960
** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
9061
*/
9162
#define LENGTH_MASK_SZ 13
9263
#define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
64
+
65
+#endif /* INTERFACE */
9366
9467
/*
9568
** Information about each line of a file being diffed.
9669
**
9770
** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -204,282 +177,10 @@
204177
/* Return results */
205178
*pnLine = nLine;
206179
return a;
207180
}
208181
209
-/*
210
-** This function attempts to scan each logical line within the blob to
211
-** determine the type of content it appears to contain. The return value
212
-** is a combination of one or more of the LOOK_XXX flags (see above):
213
-**
214
-** !LOOK_BINARY -- The content appears to consist entirely of text; however,
215
-** the encoding may not be UTF-8.
216
-**
217
-** LOOK_BINARY -- The content appears to be binary because it contains one
218
-** or more embedded NUL characters or an extremely long line.
219
-** Since this function does not understand UTF-16, it may
220
-** falsely consider UTF-16 text to be binary.
221
-**
222
-** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
223
-** may be present in the result as well; however, they should not impact the
224
-** determination of text versus binary content.
225
-**
226
-************************************ WARNING **********************************
227
-**
228
-** This function does not validate that the blob content is properly formed
229
-** UTF-8. It assumes that all code points are the same size. It does not
230
-** validate any code points. It makes no attempt to detect if any [invalid]
231
-** switches between UTF-8 and other encodings occur.
232
-**
233
-** The only code points that this function cares about are the NUL character,
234
-** carriage-return, and line-feed.
235
-**
236
-** This function examines the contents of the blob until one of the flags
237
-** specified in "stopFlags" is set.
238
-**
239
-************************************ WARNING **********************************
240
-*/
241
-int looks_like_utf8(const Blob *pContent, int stopFlags){
242
- const char *z = blob_buffer(pContent);
243
- unsigned int n = blob_size(pContent);
244
- int j, c, flags = LOOK_NONE; /* Assume UTF-8 text, prove otherwise */
245
-
246
- if( n==0 ) return flags; /* Empty file -> text */
247
- c = *z;
248
- if( c==0 ){
249
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
250
- }else if( c=='\r' ){
251
- flags |= LOOK_CR;
252
- if( n<=1 || z[1]!='\n' ){
253
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
254
- }
255
- }
256
- j = (c!='\n');
257
- if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
258
- while( !(flags&stopFlags) && --n>0 ){
259
- int c2 = c;
260
- c = *++z; ++j;
261
- if( c==0 ){
262
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
263
- }else if( c=='\n' ){
264
- flags |= LOOK_LF;
265
- if( c2=='\r' ){
266
- flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
267
- }else{
268
- flags |= LOOK_LONE_LF;
269
- }
270
- if( j>LENGTH_MASK ){
271
- flags |= LOOK_LONG; /* Very long line -> binary */
272
- }
273
- j = 0;
274
- }else if( c=='\r' ){
275
- flags |= LOOK_CR;
276
- if( n<=1 || z[1]!='\n' ){
277
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
278
- }
279
- }
280
- }
281
- if( n ){
282
- flags |= LOOK_SHORT; /* The whole blob was not examined */
283
- }
284
- if( j>LENGTH_MASK ){
285
- flags |= LOOK_LONG; /* Very long line -> binary */
286
- }
287
- return flags;
288
-}
289
-
290
-/*
291
-** Define the type needed to represent a Unicode (UTF-16) character.
292
-*/
293
-#ifndef WCHAR_T
294
-# ifdef _WIN32
295
-# define WCHAR_T wchar_t
296
-# else
297
-# define WCHAR_T unsigned short
298
-# endif
299
-#endif
300
-
301
-/*
302
-** Maximum length of a line in a text file, in UTF-16 characters. (4096)
303
-** The number of bytes represented by this value cannot exceed LENGTH_MASK
304
-** bytes, because that is the line buffer size used by the diff engine.
305
-*/
306
-#define UTF16_LENGTH_MASK_SZ (LENGTH_MASK_SZ-(sizeof(WCHAR_T)-sizeof(char)))
307
-#define UTF16_LENGTH_MASK ((1<<UTF16_LENGTH_MASK_SZ)-1)
308
-
309
-/*
310
-** This macro is used to swap the byte order of a UTF-16 character in the
311
-** looks_like_utf16() function.
312
-*/
313
-#define UTF16_SWAP(ch) ((((ch) << 8) & 0xFF00) | (((ch) >> 8) & 0xFF))
314
-#define UTF16_SWAP_IF(expr,ch) ((expr) ? UTF16_SWAP((ch)) : (ch))
315
-
316
-/*
317
-** This function attempts to scan each logical line within the blob to
318
-** determine the type of content it appears to contain. The return value
319
-** is a combination of one or more of the LOOK_XXX flags (see above):
320
-**
321
-** !LOOK_BINARY -- The content appears to consist entirely of text; however,
322
-** the encoding may not be UTF-16.
323
-**
324
-** LOOK_BINARY -- The content appears to be binary because it contains one
325
-** or more embedded NUL characters or an extremely long line.
326
-** Since this function does not understand UTF-8, it may
327
-** falsely consider UTF-8 text to be binary.
328
-**
329
-** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
330
-** may be present in the result as well; however, they should not impact the
331
-** determination of text versus binary content.
332
-**
333
-************************************ WARNING **********************************
334
-**
335
-** This function does not validate that the blob content is properly formed
336
-** UTF-16. It assumes that all code points are the same size. It does not
337
-** validate any code points. It makes no attempt to detect if any [invalid]
338
-** switches between the UTF-16be and UTF-16le encodings occur.
339
-**
340
-** The only code points that this function cares about are the NUL character,
341
-** carriage-return, and line-feed.
342
-**
343
-** This function examines the contents of the blob until one of the flags
344
-** specified in "stopFlags" is set.
345
-**
346
-************************************ WARNING **********************************
347
-*/
348
-int looks_like_utf16(const Blob *pContent, int bReverse, int stopFlags){
349
- const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
350
- unsigned int n = blob_size(pContent);
351
- int j, c, flags = LOOK_NONE; /* Assume UTF-16 text, prove otherwise */
352
-
353
- if( n==0 ) return flags; /* Empty file -> text */
354
- if( n%sizeof(WCHAR_T) ){
355
- flags |= LOOK_ODD; /* Odd number of bytes -> binary (UTF-8?) */
356
- if( n<sizeof(WCHAR_T) ) return flags; /* One byte -> binary (UTF-8?) */
357
- }
358
- c = *z;
359
- if( bReverse ){
360
- c = UTF16_SWAP(c);
361
- }
362
- if( c==0 ){
363
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
364
- }else if( c=='\r' ){
365
- flags |= LOOK_CR;
366
- if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
367
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
368
- }
369
- }
370
- j = (c!='\n');
371
- if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
372
- while( 1 ){
373
- int c2 = c;
374
- if( flags&stopFlags ) break;
375
- n -= sizeof(WCHAR_T);
376
- if( n<sizeof(WCHAR_T) ) break;
377
- c = *++z;
378
- if( bReverse ){
379
- c = UTF16_SWAP(c);
380
- }
381
- ++j;
382
- if( c==0 ){
383
- flags |= LOOK_NUL; /* NUL character in a file -> binary */
384
- }else if( c=='\n' ){
385
- flags |= LOOK_LF;
386
- if( c2=='\r' ){
387
- flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
388
- }else{
389
- flags |= LOOK_LONE_LF;
390
- }
391
- if( j>UTF16_LENGTH_MASK ){
392
- flags |= LOOK_LONG; /* Very long line -> binary */
393
- }
394
- j = 0;
395
- }else if( c=='\r' ){
396
- flags |= LOOK_CR;
397
- if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
398
- flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
399
- }
400
- }
401
- }
402
- if( n ){
403
- flags |= LOOK_SHORT; /* The whole blob was not examined */
404
- }
405
- if( j>UTF16_LENGTH_MASK ){
406
- flags |= LOOK_LONG; /* Very long line -> binary */
407
- }
408
- return flags;
409
-}
410
-
411
-/*
412
-** This function returns an array of bytes representing the byte-order-mark
413
-** for UTF-8.
414
-*/
415
-const unsigned char *get_utf8_bom(int *pnByte){
416
- static const unsigned char bom[] = {
417
- 0xEF, 0xBB, 0xBF, 0x00, 0x00, 0x00
418
- };
419
- if( pnByte ) *pnByte = 3;
420
- return bom;
421
-}
422
-
423
-/*
424
-** This function returns non-zero if the blob starts with a UTF-8
425
-** byte-order-mark (BOM).
426
-*/
427
-int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
428
- const char *z = blob_buffer(pContent);
429
- int bomSize = 0;
430
- const unsigned char *bom = get_utf8_bom(&bomSize);
431
-
432
- if( pnByte ) *pnByte = bomSize;
433
- if( blob_size(pContent)<bomSize ) return 0;
434
- return memcmp(z, bom, bomSize)==0;
435
-}
436
-
437
-/*
438
-** This function returns non-zero if the blob starts with a UTF-16
439
-** byte-order-mark (BOM), either in the endianness of the machine
440
-** or in reversed byte order. The UTF-32 BOM is ruled out by checking
441
-** if the UTF-16 BOM is not immediately followed by (utf16) 0.
442
-** pnByte is only set when the function returns 1.
443
-**
444
-** pbReverse is always set, even when no BOM is found. Without a BOM,
445
-** it is set to 1 on little-endian and 0 on big-endian platforms. See
446
-** clause D98 of conformance (section 3.10) of the Unicode standard.
447
-*/
448
-int starts_with_utf16_bom(
449
- const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
450
- int *pnByte, /* OUT: The number of bytes used for the BOM. */
451
- int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
452
-){
453
- const unsigned short *z = (unsigned short *)blob_buffer(pContent);
454
- int bomSize = sizeof(unsigned short);
455
- int size = blob_size(pContent);
456
-
457
- if( size<bomSize ) goto noBom; /* No: cannot read BOM. */
458
- if( size>=(2*bomSize) && z[1]==0 ) goto noBom; /* No: possible UTF-32. */
459
- if( z[0]==0xfeff ){
460
- if( pbReverse ) *pbReverse = 0;
461
- }else if( z[0]==0xfffe ){
462
- if( pbReverse ) *pbReverse = 1;
463
- }else{
464
- static const int one = 1;
465
- noBom:
466
- if( pbReverse ) *pbReverse = *(char *) &one;
467
- return 0; /* No: UTF-16 byte-order-mark not found. */
468
- }
469
- if( pnByte ) *pnByte = bomSize;
470
- return 1; /* Yes. */
471
-}
472
-
473
-/*
474
-** Returns non-zero if the specified content could be valid UTF-16.
475
-*/
476
-int could_be_utf16(const Blob *pContent, int *pbReverse){
477
- return (blob_size(pContent) % sizeof(WCHAR_T) == 0) ?
478
- starts_with_utf16_bom(pContent, 0, pbReverse) : 0;
479
-}
480
-
481182
/*
482183
** Return true if two DLine elements are identical.
483184
*/
484185
static int same_dline(DLine *pA, DLine *pB){
485186
return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
@@ -576,11 +277,11 @@
576277
int mxr; /* Maximum value for r */
577278
int na, nb; /* Number of lines shown from A and B */
578279
int i, j; /* Loop counters */
579280
int m; /* Number of lines to output */
580281
int skip; /* Number of lines to skip */
581
- int nChunk = 0; /* Number of diff chunks seen so far */
282
+ static int nChunk = 0; /* Number of diff chunks seen so far */
582283
int nContext; /* Number of lines of context */
583284
int showLn; /* Show line numbers */
584285
int html; /* Render as HTML */
585286
int showDivider = 0; /* True to show the divider between diff blocks */
586287
@@ -657,14 +358,14 @@
657358
if( !showDivider ){
658359
/* Do not show a top divider */
659360
showDivider = 1;
660361
}else if( html ){
661362
blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
662
- blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
663363
}else{
664364
blob_appendf(pOut, "%.80c\n", '.');
665365
}
366
+ if( html ) blob_appendf(pOut, "<span id=\"chunk%d\"></span>", nChunk);
666367
}else{
667368
if( html ) blob_appendf(pOut, "<span class=\"diffln\">");
668369
/*
669370
* If the patch changes an empty file or results in an empty file,
670371
* the block header must use 0,0 as position indicator and not 1,0.
@@ -727,12 +428,11 @@
727428
/*
728429
** Status of a single output line
729430
*/
730431
typedef struct SbsLine SbsLine;
731432
struct SbsLine {
732
- char *zLine; /* The output line under construction */
733
- int n; /* Index of next unused slot in the zLine[] */
433
+ Blob *apCols[5]; /* Array of pointers to output columns */
734434
int width; /* Maximum width of a column in the output */
735435
unsigned char escHtml; /* True to escape html characters */
736436
int iStart; /* Write zStart prior to character iStart */
737437
const char *zStart; /* A <span> tag */
738438
int iEnd; /* Write </span> prior to character iEnd */
@@ -741,125 +441,155 @@
741441
int iEnd2; /* Write </span> prior to character iEnd2 */
742442
ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
743443
};
744444
745445
/*
746
-** Flags for sbsWriteText()
446
+** Column indices for SbsLine.apCols[]
447
+*/
448
+#define SBS_LNA 0 /* Left line number */
449
+#define SBS_TXTA 1 /* Left text */
450
+#define SBS_MKR 2 /* Middle separator column */
451
+#define SBS_LNB 3 /* Right line number */
452
+#define SBS_TXTB 4 /* Right text */
453
+
454
+/*
455
+** Append newlines to all columns.
456
+*/
457
+static void sbsWriteNewlines(SbsLine *p){
458
+ int i;
459
+ for( i=p->escHtml ? SBS_LNA : SBS_TXTB; i<=SBS_TXTB; i++ ){
460
+ blob_append(p->apCols[i], "\n", 1);
461
+ }
462
+}
463
+
464
+/*
465
+** Append n spaces to the column.
747466
*/
748
-#define SBS_NEWLINE 0x0001 /* End with \n\000 */
749
-#define SBS_PAD 0x0002 /* Pad output to width spaces */
467
+static void sbsWriteSpace(SbsLine *p, int n, int col){
468
+ blob_appendf(p->apCols[col], "%*s", n, "");
469
+}
750470
751471
/*
752
-** Write up to width characters of pLine into p->zLine[]. Translate tabs into
753
-** spaces. Add a newline if SBS_NEWLINE is set. Translate HTML characters
754
-** if SBS_HTML is set. Pad the rendering out width bytes if SBS_PAD is set.
472
+** Write the text of pLine into column iCol of p.
473
+**
474
+** If outputting HTML, write the full line. Otherwise, only write the
475
+** width characters. Translate tabs into spaces. Add newlines if col
476
+** is SBS_TXTB. Translate HTML characters if escHtml is true. Pad the
477
+** rendering to width bytes if col is SBS_TXTA and escHtml is false.
755478
**
756479
** This comment contains multibyte unicode characters (ü, Æ, ð) in order
757480
** to test the ability of the diff code to handle such characters.
758481
*/
759
-static void sbsWriteText(SbsLine *p, DLine *pLine, unsigned flags){
482
+static void sbsWriteText(SbsLine *p, DLine *pLine, int col){
483
+ Blob *pCol = p->apCols[col];
760484
int n = pLine->h & LENGTH_MASK;
761485
int i; /* Number of input characters consumed */
762
- int j; /* Number of output characters generated */
763486
int k; /* Cursor position */
764487
int needEndSpan = 0;
765488
const char *zIn = pLine->z;
766
- char *z = &p->zLine[p->n];
767489
int w = p->width;
768490
int colorize = p->escHtml;
769491
if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
770492
colorize = 0;
771493
}
772
- for(i=j=k=0; k<w && i<n; i++, k++){
494
+ for(i=k=0; (p->escHtml || k<w) && i<n; i++, k++){
773495
char c = zIn[i];
774496
if( colorize ){
775497
if( i==p->iStart ){
776498
int x = strlen(p->zStart);
777
- memcpy(z+j, p->zStart, x);
778
- j += x;
499
+ blob_append(pCol, p->zStart, x);
779500
needEndSpan = 1;
780501
if( p->iStart2 ){
781502
p->iStart = p->iStart2;
782503
p->zStart = p->zStart2;
783504
p->iStart2 = 0;
784505
}
785506
}else if( i==p->iEnd ){
786
- memcpy(z+j, "</span>", 7);
787
- j += 7;
507
+ blob_append(pCol, "</span>", 7);
788508
needEndSpan = 0;
789509
if( p->iEnd2 ){
790510
p->iEnd = p->iEnd2;
791511
p->iEnd2 = 0;
792512
}
793513
}
794514
}
795
- if( c=='\t' ){
796
- z[j++] = ' ';
797
- while( (k&7)!=7 && k<w ){ z[j++] = ' '; k++; }
515
+ if( c=='\t' && !p->escHtml ){
516
+ blob_append(pCol, " ", 1);
517
+ while( (k&7)!=7 && (p->escHtml || k<w) ){
518
+ blob_append(pCol, " ", 1);
519
+ k++;
520
+ }
798521
}else if( c=='\r' || c=='\f' ){
799
- z[j++] = ' ';
522
+ blob_append(pCol, " ", 1);
800523
}else if( c=='<' && p->escHtml ){
801
- memcpy(&z[j], "&lt;", 4);
802
- j += 4;
524
+ blob_append(pCol, "&lt;", 4);
803525
}else if( c=='&' && p->escHtml ){
804
- memcpy(&z[j], "&amp;", 5);
805
- j += 5;
526
+ blob_append(pCol, "&amp;", 5);
806527
}else if( c=='>' && p->escHtml ){
807
- memcpy(&z[j], "&gt;", 4);
808
- j += 4;
528
+ blob_append(pCol, "&gt;", 4);
809529
}else if( c=='"' && p->escHtml ){
810
- memcpy(&z[j], "&quot;", 6);
811
- j += 6;
530
+ blob_append(pCol, "&quot;", 6);
812531
}else{
813
- z[j++] = c;
532
+ blob_append(pCol, &zIn[i], 1);
814533
if( (c&0xc0)==0x80 ) k--;
815534
}
816535
}
817536
if( needEndSpan ){
818
- memcpy(&z[j], "</span>", 7);
819
- j += 7;
820
- }
821
- if( (flags & SBS_PAD)!=0 ){
822
- while( k<w ){ k++; z[j++] = ' '; }
823
- }
824
- if( flags & SBS_NEWLINE ){
825
- z[j++] = '\n';
826
- }
827
- p->n += j;
828
-}
829
-
830
-/*
831
-** Append a string to an SbSLine without coding, interpretation, or padding.
832
-*/
833
-static void sbsWrite(SbsLine *p, const char *zIn, int nIn){
834
- memcpy(p->zLine+p->n, zIn, nIn);
835
- p->n += nIn;
836
-}
837
-
838
-/*
839
-** Append n spaces to the string.
840
-*/
841
-static void sbsWriteSpace(SbsLine *p, int n){
842
- while( n-- ) p->zLine[p->n++] = ' ';
843
-}
844
-
845
-/*
846
-** Append a string to the output only if we are rendering HTML.
847
-*/
848
-static void sbsWriteHtml(SbsLine *p, const char *zIn){
849
- if( p->escHtml ) sbsWrite(p, zIn, strlen(zIn));
850
-}
851
-
852
-/*
853
-** Write a 6-digit line number followed by a single space onto the line.
854
-*/
855
-static void sbsWriteLineno(SbsLine *p, int ln){
856
- sbsWriteHtml(p, "<span class=\"diffln\">");
857
- sqlite3_snprintf(7, &p->zLine[p->n], "%5d ", ln+1);
858
- p->n += 6;
859
- sbsWriteHtml(p, "</span>");
860
- p->zLine[p->n++] = ' ';
537
+ blob_append(pCol, "</span>", 7);
538
+ }
539
+ if( col==SBS_TXTB ){
540
+ sbsWriteNewlines(p);
541
+ }else if( !p->escHtml ){
542
+ sbsWriteSpace(p, w-k, SBS_TXTA);
543
+ }
544
+}
545
+
546
+/*
547
+** Append a column to the final output blob.
548
+*/
549
+static void sbsWriteColumn(Blob *pOut, Blob *pCol, int col){
550
+ blob_appendf(pOut,
551
+ "<td><div class=\"diff%scol\">\n"
552
+ "<pre>\n"
553
+ "%s"
554
+ "</pre>\n"
555
+ "</div></td>\n",
556
+ col % 3 ? (col == SBS_MKR ? "mkr" : "txt") : "ln",
557
+ blob_str(pCol)
558
+ );
559
+}
560
+
561
+/*
562
+** Append a separator line to column iCol
563
+*/
564
+static void sbsWriteSep(SbsLine *p, int len, int col){
565
+ char ch = '.';
566
+ if( len<1 ){
567
+ len = 1;
568
+ ch = ' ';
569
+ }
570
+ blob_appendf(p->apCols[col], "<span class=\"diffhr\">%.*c</span>\n", len, ch);
571
+}
572
+
573
+/*
574
+** Append the appropriate marker into the center column of the diff.
575
+*/
576
+static void sbsWriteMarker(SbsLine *p, const char *zTxt, const char *zHtml){
577
+ blob_append(p->apCols[SBS_MKR], p->escHtml ? zHtml : zTxt, -1);
578
+}
579
+
580
+/*
581
+** Append a line number to the column.
582
+*/
583
+static void sbsWriteLineno(SbsLine *p, int ln, int col){
584
+ if( p->escHtml ){
585
+ blob_appendf(p->apCols[col], "%d", ln+1);
586
+ }else{
587
+ char zLn[7];
588
+ sqlite3_snprintf(7, zLn, "%5d ", ln+1);
589
+ blob_appendf(p->apCols[col], "%s ", zLn);
590
+ }
861591
}
862592
863593
/*
864594
** The two text segments zLeft and zRight are known to be different on
865595
** both ends, but they might have a common segment in the middle. If
@@ -1018,43 +748,42 @@
1018748
}
1019749
if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
1020750
}
1021751
if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
1022752
1023
-
1024753
/* A single chunk of text inserted on the right */
1025754
if( nPrefix+nSuffix==nLeft ){
1026
- sbsWriteLineno(p, lnLeft);
755
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1027756
p->iStart2 = p->iEnd2 = 0;
1028757
p->iStart = p->iEnd = -1;
1029
- sbsWriteText(p, pLeft, SBS_PAD);
758
+ sbsWriteText(p, pLeft, SBS_TXTA);
1030759
if( nLeft==nRight && zLeft[nLeft]==zRight[nRight] ){
1031
- sbsWrite(p, " ", 3);
760
+ sbsWriteMarker(p, " ", "");
1032761
}else{
1033
- sbsWrite(p, " | ", 3);
762
+ sbsWriteMarker(p, " | ", "|");
1034763
}
1035
- sbsWriteLineno(p, lnRight);
764
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1036765
p->iStart = nPrefix;
1037766
p->iEnd = nRight - nSuffix;
1038767
p->zStart = zClassAdd;
1039
- sbsWriteText(p, pRight, SBS_NEWLINE);
768
+ sbsWriteText(p, pRight, SBS_TXTB);
1040769
return;
1041770
}
1042771
1043772
/* A single chunk of text deleted from the left */
1044773
if( nPrefix+nSuffix==nRight ){
1045774
/* Text deleted from the left */
1046
- sbsWriteLineno(p, lnLeft);
775
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1047776
p->iStart2 = p->iEnd2 = 0;
1048777
p->iStart = nPrefix;
1049778
p->iEnd = nLeft - nSuffix;
1050779
p->zStart = zClassRm;
1051
- sbsWriteText(p, pLeft, SBS_PAD);
1052
- sbsWrite(p, " | ", 3);
1053
- sbsWriteLineno(p, lnRight);
780
+ sbsWriteText(p, pLeft, SBS_TXTA);
781
+ sbsWriteMarker(p, " | ", "|");
782
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1054783
p->iStart = p->iEnd = -1;
1055
- sbsWriteText(p, pRight, SBS_NEWLINE);
784
+ sbsWriteText(p, pRight, SBS_TXTB);
1056785
return;
1057786
}
1058787
1059788
/* At this point we know that there is a chunk of text that has
1060789
** changed between the left and the right. Check to see if there
@@ -1065,11 +794,11 @@
1065794
if( p->escHtml
1066795
&& nLeftDiff >= 6
1067796
&& nRightDiff >= 6
1068797
&& textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
1069798
){
1070
- sbsWriteLineno(p, lnLeft);
799
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1071800
p->iStart = nPrefix;
1072801
p->iEnd = nPrefix + aLCS[0];
1073802
if( aLCS[2]==0 ){
1074803
sbsShiftLeft(p, pLeft->z);
1075804
p->zStart = zClassRm;
@@ -1078,13 +807,13 @@
1078807
}
1079808
p->iStart2 = nPrefix + aLCS[1];
1080809
p->iEnd2 = nLeft - nSuffix;
1081810
p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
1082811
sbsSimplifyLine(p, zLeft+nPrefix);
1083
- sbsWriteText(p, pLeft, SBS_PAD);
1084
- sbsWrite(p, " | ", 3);
1085
- sbsWriteLineno(p, lnRight);
812
+ sbsWriteText(p, pLeft, SBS_TXTA);
813
+ sbsWriteMarker(p, " | ", "|");
814
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1086815
p->iStart = nPrefix;
1087816
p->iEnd = nPrefix + aLCS[2];
1088817
if( aLCS[0]==0 ){
1089818
sbsShiftLeft(p, pRight->z);
1090819
p->zStart = zClassAdd;
@@ -1093,25 +822,25 @@
1093822
}
1094823
p->iStart2 = nPrefix + aLCS[3];
1095824
p->iEnd2 = nRight - nSuffix;
1096825
p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
1097826
sbsSimplifyLine(p, zRight+nPrefix);
1098
- sbsWriteText(p, pRight, SBS_NEWLINE);
827
+ sbsWriteText(p, pRight, SBS_TXTB);
1099828
return;
1100829
}
1101830
1102831
/* If all else fails, show a single big change between left and right */
1103
- sbsWriteLineno(p, lnLeft);
832
+ sbsWriteLineno(p, lnLeft, SBS_LNA);
1104833
p->iStart2 = p->iEnd2 = 0;
1105834
p->iStart = nPrefix;
1106835
p->iEnd = nLeft - nSuffix;
1107836
p->zStart = zClassChng;
1108
- sbsWriteText(p, pLeft, SBS_PAD);
1109
- sbsWrite(p, " | ", 3);
1110
- sbsWriteLineno(p, lnRight);
837
+ sbsWriteText(p, pLeft, SBS_TXTA);
838
+ sbsWriteMarker(p, " | ", "|");
839
+ sbsWriteLineno(p, lnRight, SBS_LNB);
1111840
p->iEnd = nRight - nSuffix;
1112
- sbsWriteText(p, pRight, SBS_NEWLINE);
841
+ sbsWriteText(p, pRight, SBS_TXTB);
1113842
}
1114843
1115844
/*
1116845
** Minimum of two values
1117846
*/
@@ -1357,30 +1086,40 @@
13571086
int mxr; /* Maximum value for r */
13581087
int na, nb; /* Number of lines shown from A and B */
13591088
int i, j; /* Loop counters */
13601089
int m, ma, mb;/* Number of lines to output */
13611090
int skip; /* Number of lines to skip */
1362
- int nChunk = 0; /* Number of chunks of diff output seen so far */
1091
+ static int nChunk = 0; /* Number of chunks of diff output seen so far */
13631092
SbsLine s; /* Output line buffer */
13641093
int nContext; /* Lines of context above and below each change */
13651094
int showDivider = 0; /* True to show the divider */
1095
+ Blob aCols[5]; /* Array of column blobs */
13661096
13671097
memset(&s, 0, sizeof(s));
13681098
s.width = diff_width(diffFlags);
1369
- s.zLine = fossil_malloc( 15*s.width + 200 );
1370
- if( s.zLine==0 ) return;
13711099
nContext = diff_context_lines(diffFlags);
13721100
s.escHtml = (diffFlags & DIFF_HTML)!=0;
1101
+ if( s.escHtml ){
1102
+ for(i=SBS_LNA; i<=SBS_TXTB; i++){
1103
+ blob_zero(&aCols[i]);
1104
+ s.apCols[i] = &aCols[i];
1105
+ }
1106
+ }else{
1107
+ for(i=SBS_LNA; i<=SBS_TXTB; i++){
1108
+ s.apCols[i] = pOut;
1109
+ }
1110
+ }
13731111
s.pRe = pRe;
13741112
s.iStart = -1;
13751113
s.iStart2 = 0;
13761114
s.iEnd = -1;
13771115
A = p->aFrom;
13781116
B = p->aTo;
13791117
R = p->aEdit;
13801118
mxr = p->nEdit;
13811119
while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
1120
+
13821121
for(r=0; r<mxr; r += 3*nr){
13831122
/* Figure out how many triples to show in a single block */
13841123
for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
13851124
/* printf("r=%d nr=%d\n", r, nr); */
13861125
@@ -1436,35 +1175,39 @@
14361175
}
14371176
14381177
/* Draw the separator between blocks */
14391178
if( showDivider ){
14401179
if( s.escHtml ){
1441
- blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1442
- s.width*2+16, '.');
1180
+ char zLn[10];
1181
+ sqlite3_snprintf(sizeof(zLn), zLn, "%d", a+skip+1);
1182
+ sbsWriteSep(&s, strlen(zLn), SBS_LNA);
1183
+ sbsWriteSep(&s, s.width, SBS_TXTA);
1184
+ sbsWriteSep(&s, 0, SBS_MKR);
1185
+ sqlite3_snprintf(sizeof(zLn), zLn, "%d", b+skip+1);
1186
+ sbsWriteSep(&s, strlen(zLn), SBS_LNB);
1187
+ sbsWriteSep(&s, s.width, SBS_TXTB);
14431188
}else{
14441189
blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
14451190
}
14461191
}
14471192
showDivider = 1;
14481193
nChunk++;
14491194
if( s.escHtml ){
1450
- blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
1195
+ blob_appendf(s.apCols[SBS_LNA], "<span id=\"chunk%d\"></span>", nChunk);
14511196
}
14521197
14531198
/* Show the initial common area */
14541199
a += skip;
14551200
b += skip;
14561201
m = R[r] - skip;
14571202
for(j=0; j<m; j++){
1458
- s.n = 0;
1459
- sbsWriteLineno(&s, a+j);
1203
+ sbsWriteLineno(&s, a+j, SBS_LNA);
14601204
s.iStart = s.iEnd = -1;
1461
- sbsWriteText(&s, &A[a+j], SBS_PAD);
1462
- sbsWrite(&s, " ", 3);
1463
- sbsWriteLineno(&s, b+j);
1464
- sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1465
- blob_append(pOut, s.zLine, s.n);
1205
+ sbsWriteText(&s, &A[a+j], SBS_TXTA);
1206
+ sbsWriteMarker(&s, " ", "");
1207
+ sbsWriteLineno(&s, b+j, SBS_LNB);
1208
+ sbsWriteText(&s, &B[b+j], SBS_TXTB);
14661209
}
14671210
a += m;
14681211
b += m;
14691212
14701213
/* Show the differences */
@@ -1485,87 +1228,71 @@
14851228
14861229
alignment = sbsAlignment(&A[a], ma, &B[b], mb);
14871230
for(j=0; ma+mb>0; j++){
14881231
if( alignment[j]==1 ){
14891232
/* Delete one line from the left */
1490
- s.n = 0;
1491
- sbsWriteLineno(&s, a);
1233
+ sbsWriteLineno(&s, a, SBS_LNA);
14921234
s.iStart = 0;
14931235
s.zStart = "<span class=\"diffrm\">";
14941236
s.iEnd = LENGTH(&A[a]);
1495
- sbsWriteText(&s, &A[a], SBS_PAD);
1496
- if( s.escHtml ){
1497
- sbsWrite(&s, " &lt;\n", 6);
1498
- }else{
1499
- sbsWrite(&s, " <\n", 3);
1500
- }
1501
- blob_append(pOut, s.zLine, s.n);
1237
+ sbsWriteText(&s, &A[a], SBS_TXTA);
1238
+ sbsWriteMarker(&s, " <", "&lt;");
1239
+ sbsWriteNewlines(&s);
15021240
assert( ma>0 );
15031241
ma--;
15041242
a++;
15051243
}else if( alignment[j]==3 ){
15061244
/* The left line is changed into the right line */
1507
- s.n = 0;
15081245
sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1509
- blob_append(pOut, s.zLine, s.n);
15101246
assert( ma>0 && mb>0 );
15111247
ma--;
15121248
mb--;
15131249
a++;
15141250
b++;
15151251
}else if( alignment[j]==2 ){
15161252
/* Insert one line on the right */
1517
- s.n = 0;
1518
- sbsWriteSpace(&s, s.width + 7);
1519
- if( s.escHtml ){
1520
- sbsWrite(&s, " &gt; ", 6);
1521
- }else{
1522
- sbsWrite(&s, " > ", 3);
1523
- }
1524
- sbsWriteLineno(&s, b);
1253
+ if( !s.escHtml ){
1254
+ sbsWriteSpace(&s, s.width + 7, SBS_TXTA);
1255
+ }
1256
+ sbsWriteMarker(&s, " > ", "&gt;");
1257
+ sbsWriteLineno(&s, b, SBS_LNB);
15251258
s.iStart = 0;
15261259
s.zStart = "<span class=\"diffadd\">";
15271260
s.iEnd = LENGTH(&B[b]);
1528
- sbsWriteText(&s, &B[b], SBS_NEWLINE);
1529
- blob_append(pOut, s.zLine, s.n);
1261
+ sbsWriteText(&s, &B[b], SBS_TXTB);
15301262
assert( mb>0 );
15311263
mb--;
15321264
b++;
15331265
}else{
15341266
/* Delete from the left and insert on the right */
1535
- s.n = 0;
1536
- sbsWriteLineno(&s, a);
1267
+ sbsWriteLineno(&s, a, SBS_LNA);
15371268
s.iStart = 0;
15381269
s.zStart = "<span class=\"diffrm\">";
15391270
s.iEnd = LENGTH(&A[a]);
1540
- sbsWriteText(&s, &A[a], SBS_PAD);
1541
- sbsWrite(&s, " | ", 3);
1542
- sbsWriteLineno(&s, b);
1271
+ sbsWriteText(&s, &A[a], SBS_TXTA);
1272
+ sbsWriteMarker(&s, " | ", "|");
1273
+ sbsWriteLineno(&s, b, SBS_LNB);
15431274
s.iStart = 0;
15441275
s.zStart = "<span class=\"diffadd\">";
15451276
s.iEnd = LENGTH(&B[b]);
1546
- sbsWriteText(&s, &B[b], SBS_NEWLINE);
1547
- blob_append(pOut, s.zLine, s.n);
1277
+ sbsWriteText(&s, &B[b], SBS_TXTB);
15481278
ma--;
15491279
mb--;
15501280
a++;
15511281
b++;
15521282
}
1553
-
15541283
}
15551284
fossil_free(alignment);
15561285
if( i<nr-1 ){
15571286
m = R[r+i*3+3];
15581287
for(j=0; j<m; j++){
1559
- s.n = 0;
1560
- sbsWriteLineno(&s, a+j);
1288
+ sbsWriteLineno(&s, a+j, SBS_LNA);
15611289
s.iStart = s.iEnd = -1;
1562
- sbsWriteText(&s, &A[a+j], SBS_PAD);
1563
- sbsWrite(&s, " ", 3);
1564
- sbsWriteLineno(&s, b+j);
1565
- sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1566
- blob_append(pOut, s.zLine, s.n);
1290
+ sbsWriteText(&s, &A[a+j], SBS_TXTA);
1291
+ sbsWriteMarker(&s, " ", "");
1292
+ sbsWriteLineno(&s, b+j, SBS_LNB);
1293
+ sbsWriteText(&s, &B[b+j], SBS_TXTB);
15671294
}
15681295
b += m;
15691296
a += m;
15701297
}
15711298
}
@@ -1573,21 +1300,27 @@
15731300
/* Show the final common area */
15741301
assert( nr==i );
15751302
m = R[r+nr*3];
15761303
if( m>nContext ) m = nContext;
15771304
for(j=0; j<m; j++){
1578
- s.n = 0;
1579
- sbsWriteLineno(&s, a+j);
1305
+ sbsWriteLineno(&s, a+j, SBS_LNA);
15801306
s.iStart = s.iEnd = -1;
1581
- sbsWriteText(&s, &A[a+j], SBS_PAD);
1582
- sbsWrite(&s, " ", 3);
1583
- sbsWriteLineno(&s, b+j);
1584
- sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1585
- blob_append(pOut, s.zLine, s.n);
1307
+ sbsWriteText(&s, &A[a+j], SBS_TXTA);
1308
+ sbsWriteMarker(&s, " ", "");
1309
+ sbsWriteLineno(&s, b+j, SBS_LNB);
1310
+ sbsWriteText(&s, &B[b+j], SBS_TXTB);
15861311
}
15871312
}
1588
- free(s.zLine);
1313
+
1314
+ if( s.escHtml && blob_size(s.apCols[SBS_LNA])>0 ){
1315
+ blob_append(pOut, "<table class=\"sbsdiffcols\" width=\"90%\"><tr>\n", -1);
1316
+ for(i=SBS_LNA; i<=SBS_TXTB; i++){
1317
+ sbsWriteColumn(pOut, s.apCols[i], i);
1318
+ blob_reset(s.apCols[i]);
1319
+ }
1320
+ blob_append(pOut, "</tr></table>\n", -1);
1321
+ }
15891322
}
15901323
15911324
/*
15921325
** Compute the optimal longest common subsequence (LCS) using an
15931326
** exhaustive search. This version of the LCS is only used for
@@ -1990,10 +1723,21 @@
19901723
int diff_width(u64 diffFlags){
19911724
int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
19921725
if( w==0 ) w = 80;
19931726
return w;
19941727
}
1728
+
1729
+/*
1730
+** Append the error message to pOut.
1731
+*/
1732
+void diff_errmsg(Blob *pOut, const char *msg, int diffFlags){
1733
+ if( diffFlags & DIFF_HTML ){
1734
+ blob_appendf(pOut, "<p class=\"generalError\">%s</p>", msg);
1735
+ }else{
1736
+ blob_append(pOut, msg, -1);
1737
+ }
1738
+}
19951739
19961740
/*
19971741
** Generate a report of the differences between files pA and pB.
19981742
** If pOut is not NULL then a unified diff is appended there. It
19991743
** is assumed that pOut has already been initialized. If pOut is
@@ -2032,11 +1776,11 @@
20321776
&c.nTo, ignoreEolWs);
20331777
if( c.aFrom==0 || c.aTo==0 ){
20341778
fossil_free(c.aFrom);
20351779
fossil_free(c.aTo);
20361780
if( pOut ){
2037
- blob_appendf(pOut, DIFF_CANNOT_COMPUTE_BINARY);
1781
+ diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, diffFlags);
20381782
}
20391783
return 0;
20401784
}
20411785
20421786
/* Compute the difference */
@@ -2048,15 +1792,11 @@
20481792
for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
20491793
if( n>10000 ){
20501794
fossil_free(c.aFrom);
20511795
fossil_free(c.aTo);
20521796
fossil_free(c.aEdit);
2053
- if( diffFlags & DIFF_HTML ){
2054
- blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
2055
- }else{
2056
- blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
2057
- }
1797
+ diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, diffFlags);
20581798
return 0;
20591799
}
20601800
}
20611801
if( (diffFlags & DIFF_NOOPT)==0 ){
20621802
diff_optimize(&c);
@@ -2159,10 +1899,11 @@
21591899
if( find_option("tk",0,0)!=0 ){
21601900
diff_tk("test-diff", 2);
21611901
return;
21621902
}
21631903
find_option("i",0,0);
1904
+ find_option("v",0,0);
21641905
zRe = find_option("regexp","e",1);
21651906
if( zRe ){
21661907
const char *zErr = re_compile(&pRe, zRe, 0);
21671908
if( zErr ) fossil_fatal("regex error: %s", zErr);
21681909
}
@@ -2616,60 +2357,5 @@
26162357
zPrefix[0] = 0;
26172358
}
26182359
fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z);
26192360
}
26202361
}
2621
-
2622
-/*
2623
-** COMMAND: test-looks-like-utf
2624
-**
2625
-** Usage: %fossil test-looks-like-utf FILENAME
2626
-**
2627
-** Options:
2628
-** --utf8 Ignoring BOM and file size, force UTF-8 checking
2629
-** --utf16 Ignoring BOM and file size, force UTF-16 checking
2630
-**
2631
-** FILENAME is the name of a file to check for textual content in the UTF-8
2632
-** and/or UTF-16 encodings.
2633
-*/
2634
-void looks_like_utf_test_cmd(void){
2635
- Blob blob; /* the contents of the specified file */
2636
- int fUtf8; /* return value of starts_with_utf8_bom() */
2637
- int fUtf16; /* return value of starts_with_utf16_bom() */
2638
- int fUnicode; /* return value of could_be_utf16() */
2639
- int lookFlags; /* output flags from looks_like_utf8/utf16() */
2640
- int bRevUtf16 = 0; /* non-zero -> UTF-16 byte order reversed */
2641
- int bRevUnicode = 0; /* non-zero -> UTF-16 byte order reversed */
2642
- int fForceUtf8 = find_option("utf8",0,0)!=0;
2643
- int fForceUtf16 = find_option("utf16",0,0)!=0;
2644
- if( g.argc!=3 ) usage("FILENAME");
2645
- blob_read_from_file(&blob, g.argv[2]);
2646
- fUtf8 = starts_with_utf8_bom(&blob, 0);
2647
- fUtf16 = starts_with_utf16_bom(&blob, 0, &bRevUtf16);
2648
- if( fForceUtf8 ){
2649
- fUnicode = 0;
2650
- }else{
2651
- fUnicode = could_be_utf16(&blob, &bRevUnicode) || fForceUtf16;
2652
- }
2653
- lookFlags = fUnicode ? looks_like_utf16(&blob, bRevUnicode, 0) :
2654
- looks_like_utf8(&blob, 0);
2655
- fossil_print("File \"%s\" has %d bytes.\n",g.argv[2],blob_size(&blob));
2656
- fossil_print("Starts with UTF-8 BOM: %s\n",fUtf8?"yes":"no");
2657
- fossil_print("Starts with UTF-16 BOM: %s\n",
2658
- fUtf16?(bRevUtf16?"reversed":"yes"):"no");
2659
- fossil_print("Looks like UTF-%s: %s\n",fUnicode?"16":"8",
2660
- (lookFlags&LOOK_BINARY)?"no":"yes");
2661
- fossil_print("Has flag LOOK_NUL: %s\n",(lookFlags&LOOK_NUL)?"yes":"no");
2662
- fossil_print("Has flag LOOK_CR: %s\n",(lookFlags&LOOK_CR)?"yes":"no");
2663
- fossil_print("Has flag LOOK_LONE_CR: %s\n",
2664
- (lookFlags&LOOK_LONE_CR)?"yes":"no");
2665
- fossil_print("Has flag LOOK_LF: %s\n",(lookFlags&LOOK_LF)?"yes":"no");
2666
- fossil_print("Has flag LOOK_LONE_LF: %s\n",
2667
- (lookFlags&LOOK_LONE_LF)?"yes":"no");
2668
- fossil_print("Has flag LOOK_CRLF: %s\n",(lookFlags&LOOK_CRLF)?"yes":"no");
2669
- fossil_print("Has flag LOOK_LONG: %s\n",(lookFlags&LOOK_LONG)?"yes":"no");
2670
- fossil_print("Has flag LOOK_INVALID: %s\n",
2671
- (lookFlags&LOOK_INVALID)?"yes":"no");
2672
- fossil_print("Has flag LOOK_ODD: %s\n",(lookFlags&LOOK_ODD)?"yes":"no");
2673
- fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
2674
- blob_reset(&blob);
2675
-}
26762362
--- src/diff.c
+++ src/diff.c
@@ -51,47 +51,20 @@
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 /*
63 ** This macro is designed to return non-zero if the specified blob contains
64 ** data that MAY be binary in nature; otherwise, zero will be returned.
65 */
66 #define looks_like_binary(blob) \
67 ((looks_like_utf8((blob), LOOK_BINARY) & LOOK_BINARY) != LOOK_NONE)
68
69 /*
70 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
71 ** to convey status information about the blob content.
72 */
73 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
74 #define LOOK_NUL ((int)0x00000001) /* One or more NUL chars were found. */
75 #define LOOK_CR ((int)0x00000002) /* One or more CR chars were found. */
76 #define LOOK_LONE_CR ((int)0x00000004) /* An unpaired CR char was found. */
77 #define LOOK_LF ((int)0x00000008) /* One or more LF chars were found. */
78 #define LOOK_LONE_LF ((int)0x00000010) /* An unpaired LF char was found. */
79 #define LOOK_CRLF ((int)0x00000020) /* One or more CR/LF pairs were found. */
80 #define LOOK_LONG ((int)0x00000040) /* An over length line was found. */
81 #define LOOK_ODD ((int)0x00000080) /* An odd number of bytes was found. */
82 #define LOOK_SHORT ((int)0x00000100) /* Unable to perform full check. */
83 #define LOOK_INVALID ((int)0x00000200) /* Invalid sequence was found. */
84 #define LOOK_BINARY (LOOK_NUL | LOOK_LONG | LOOK_SHORT) /* May be binary. */
85 #define LOOK_EOL (LOOK_LONE_CR | LOOK_LONE_LF | LOOK_CRLF) /* Line seps. */
86 #endif /* INTERFACE */
87
88 /*
89 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
90 */
91 #define LENGTH_MASK_SZ 13
92 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
 
 
93
94 /*
95 ** Information about each line of a file being diffed.
96 **
97 ** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -204,282 +177,10 @@
204 /* Return results */
205 *pnLine = nLine;
206 return a;
207 }
208
209 /*
210 ** This function attempts to scan each logical line within the blob to
211 ** determine the type of content it appears to contain. The return value
212 ** is a combination of one or more of the LOOK_XXX flags (see above):
213 **
214 ** !LOOK_BINARY -- The content appears to consist entirely of text; however,
215 ** the encoding may not be UTF-8.
216 **
217 ** LOOK_BINARY -- The content appears to be binary because it contains one
218 ** or more embedded NUL characters or an extremely long line.
219 ** Since this function does not understand UTF-16, it may
220 ** falsely consider UTF-16 text to be binary.
221 **
222 ** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
223 ** may be present in the result as well; however, they should not impact the
224 ** determination of text versus binary content.
225 **
226 ************************************ WARNING **********************************
227 **
228 ** This function does not validate that the blob content is properly formed
229 ** UTF-8. It assumes that all code points are the same size. It does not
230 ** validate any code points. It makes no attempt to detect if any [invalid]
231 ** switches between UTF-8 and other encodings occur.
232 **
233 ** The only code points that this function cares about are the NUL character,
234 ** carriage-return, and line-feed.
235 **
236 ** This function examines the contents of the blob until one of the flags
237 ** specified in "stopFlags" is set.
238 **
239 ************************************ WARNING **********************************
240 */
241 int looks_like_utf8(const Blob *pContent, int stopFlags){
242 const char *z = blob_buffer(pContent);
243 unsigned int n = blob_size(pContent);
244 int j, c, flags = LOOK_NONE; /* Assume UTF-8 text, prove otherwise */
245
246 if( n==0 ) return flags; /* Empty file -> text */
247 c = *z;
248 if( c==0 ){
249 flags |= LOOK_NUL; /* NUL character in a file -> binary */
250 }else if( c=='\r' ){
251 flags |= LOOK_CR;
252 if( n<=1 || z[1]!='\n' ){
253 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
254 }
255 }
256 j = (c!='\n');
257 if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
258 while( !(flags&stopFlags) && --n>0 ){
259 int c2 = c;
260 c = *++z; ++j;
261 if( c==0 ){
262 flags |= LOOK_NUL; /* NUL character in a file -> binary */
263 }else if( c=='\n' ){
264 flags |= LOOK_LF;
265 if( c2=='\r' ){
266 flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
267 }else{
268 flags |= LOOK_LONE_LF;
269 }
270 if( j>LENGTH_MASK ){
271 flags |= LOOK_LONG; /* Very long line -> binary */
272 }
273 j = 0;
274 }else if( c=='\r' ){
275 flags |= LOOK_CR;
276 if( n<=1 || z[1]!='\n' ){
277 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
278 }
279 }
280 }
281 if( n ){
282 flags |= LOOK_SHORT; /* The whole blob was not examined */
283 }
284 if( j>LENGTH_MASK ){
285 flags |= LOOK_LONG; /* Very long line -> binary */
286 }
287 return flags;
288 }
289
290 /*
291 ** Define the type needed to represent a Unicode (UTF-16) character.
292 */
293 #ifndef WCHAR_T
294 # ifdef _WIN32
295 # define WCHAR_T wchar_t
296 # else
297 # define WCHAR_T unsigned short
298 # endif
299 #endif
300
301 /*
302 ** Maximum length of a line in a text file, in UTF-16 characters. (4096)
303 ** The number of bytes represented by this value cannot exceed LENGTH_MASK
304 ** bytes, because that is the line buffer size used by the diff engine.
305 */
306 #define UTF16_LENGTH_MASK_SZ (LENGTH_MASK_SZ-(sizeof(WCHAR_T)-sizeof(char)))
307 #define UTF16_LENGTH_MASK ((1<<UTF16_LENGTH_MASK_SZ)-1)
308
309 /*
310 ** This macro is used to swap the byte order of a UTF-16 character in the
311 ** looks_like_utf16() function.
312 */
313 #define UTF16_SWAP(ch) ((((ch) << 8) & 0xFF00) | (((ch) >> 8) & 0xFF))
314 #define UTF16_SWAP_IF(expr,ch) ((expr) ? UTF16_SWAP((ch)) : (ch))
315
316 /*
317 ** This function attempts to scan each logical line within the blob to
318 ** determine the type of content it appears to contain. The return value
319 ** is a combination of one or more of the LOOK_XXX flags (see above):
320 **
321 ** !LOOK_BINARY -- The content appears to consist entirely of text; however,
322 ** the encoding may not be UTF-16.
323 **
324 ** LOOK_BINARY -- The content appears to be binary because it contains one
325 ** or more embedded NUL characters or an extremely long line.
326 ** Since this function does not understand UTF-8, it may
327 ** falsely consider UTF-8 text to be binary.
328 **
329 ** Additional flags (i.e. those other than the ones included in LOOK_BINARY)
330 ** may be present in the result as well; however, they should not impact the
331 ** determination of text versus binary content.
332 **
333 ************************************ WARNING **********************************
334 **
335 ** This function does not validate that the blob content is properly formed
336 ** UTF-16. It assumes that all code points are the same size. It does not
337 ** validate any code points. It makes no attempt to detect if any [invalid]
338 ** switches between the UTF-16be and UTF-16le encodings occur.
339 **
340 ** The only code points that this function cares about are the NUL character,
341 ** carriage-return, and line-feed.
342 **
343 ** This function examines the contents of the blob until one of the flags
344 ** specified in "stopFlags" is set.
345 **
346 ************************************ WARNING **********************************
347 */
348 int looks_like_utf16(const Blob *pContent, int bReverse, int stopFlags){
349 const WCHAR_T *z = (WCHAR_T *)blob_buffer(pContent);
350 unsigned int n = blob_size(pContent);
351 int j, c, flags = LOOK_NONE; /* Assume UTF-16 text, prove otherwise */
352
353 if( n==0 ) return flags; /* Empty file -> text */
354 if( n%sizeof(WCHAR_T) ){
355 flags |= LOOK_ODD; /* Odd number of bytes -> binary (UTF-8?) */
356 if( n<sizeof(WCHAR_T) ) return flags; /* One byte -> binary (UTF-8?) */
357 }
358 c = *z;
359 if( bReverse ){
360 c = UTF16_SWAP(c);
361 }
362 if( c==0 ){
363 flags |= LOOK_NUL; /* NUL character in a file -> binary */
364 }else if( c=='\r' ){
365 flags |= LOOK_CR;
366 if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
367 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
368 }
369 }
370 j = (c!='\n');
371 if( !j ) flags |= (LOOK_LF | LOOK_LONE_LF); /* Found LF as first char */
372 while( 1 ){
373 int c2 = c;
374 if( flags&stopFlags ) break;
375 n -= sizeof(WCHAR_T);
376 if( n<sizeof(WCHAR_T) ) break;
377 c = *++z;
378 if( bReverse ){
379 c = UTF16_SWAP(c);
380 }
381 ++j;
382 if( c==0 ){
383 flags |= LOOK_NUL; /* NUL character in a file -> binary */
384 }else if( c=='\n' ){
385 flags |= LOOK_LF;
386 if( c2=='\r' ){
387 flags |= (LOOK_CR | LOOK_CRLF); /* Found LF preceded by CR */
388 }else{
389 flags |= LOOK_LONE_LF;
390 }
391 if( j>UTF16_LENGTH_MASK ){
392 flags |= LOOK_LONG; /* Very long line -> binary */
393 }
394 j = 0;
395 }else if( c=='\r' ){
396 flags |= LOOK_CR;
397 if( n<(2*sizeof(WCHAR_T)) || UTF16_SWAP_IF(bReverse, z[1])!='\n' ){
398 flags |= LOOK_LONE_CR; /* More chars, next char is not LF */
399 }
400 }
401 }
402 if( n ){
403 flags |= LOOK_SHORT; /* The whole blob was not examined */
404 }
405 if( j>UTF16_LENGTH_MASK ){
406 flags |= LOOK_LONG; /* Very long line -> binary */
407 }
408 return flags;
409 }
410
411 /*
412 ** This function returns an array of bytes representing the byte-order-mark
413 ** for UTF-8.
414 */
415 const unsigned char *get_utf8_bom(int *pnByte){
416 static const unsigned char bom[] = {
417 0xEF, 0xBB, 0xBF, 0x00, 0x00, 0x00
418 };
419 if( pnByte ) *pnByte = 3;
420 return bom;
421 }
422
423 /*
424 ** This function returns non-zero if the blob starts with a UTF-8
425 ** byte-order-mark (BOM).
426 */
427 int starts_with_utf8_bom(const Blob *pContent, int *pnByte){
428 const char *z = blob_buffer(pContent);
429 int bomSize = 0;
430 const unsigned char *bom = get_utf8_bom(&bomSize);
431
432 if( pnByte ) *pnByte = bomSize;
433 if( blob_size(pContent)<bomSize ) return 0;
434 return memcmp(z, bom, bomSize)==0;
435 }
436
437 /*
438 ** This function returns non-zero if the blob starts with a UTF-16
439 ** byte-order-mark (BOM), either in the endianness of the machine
440 ** or in reversed byte order. The UTF-32 BOM is ruled out by checking
441 ** if the UTF-16 BOM is not immediately followed by (utf16) 0.
442 ** pnByte is only set when the function returns 1.
443 **
444 ** pbReverse is always set, even when no BOM is found. Without a BOM,
445 ** it is set to 1 on little-endian and 0 on big-endian platforms. See
446 ** clause D98 of conformance (section 3.10) of the Unicode standard.
447 */
448 int starts_with_utf16_bom(
449 const Blob *pContent, /* IN: Blob content to perform BOM detection on. */
450 int *pnByte, /* OUT: The number of bytes used for the BOM. */
451 int *pbReverse /* OUT: Non-zero for BOM in reverse byte-order. */
452 ){
453 const unsigned short *z = (unsigned short *)blob_buffer(pContent);
454 int bomSize = sizeof(unsigned short);
455 int size = blob_size(pContent);
456
457 if( size<bomSize ) goto noBom; /* No: cannot read BOM. */
458 if( size>=(2*bomSize) && z[1]==0 ) goto noBom; /* No: possible UTF-32. */
459 if( z[0]==0xfeff ){
460 if( pbReverse ) *pbReverse = 0;
461 }else if( z[0]==0xfffe ){
462 if( pbReverse ) *pbReverse = 1;
463 }else{
464 static const int one = 1;
465 noBom:
466 if( pbReverse ) *pbReverse = *(char *) &one;
467 return 0; /* No: UTF-16 byte-order-mark not found. */
468 }
469 if( pnByte ) *pnByte = bomSize;
470 return 1; /* Yes. */
471 }
472
473 /*
474 ** Returns non-zero if the specified content could be valid UTF-16.
475 */
476 int could_be_utf16(const Blob *pContent, int *pbReverse){
477 return (blob_size(pContent) % sizeof(WCHAR_T) == 0) ?
478 starts_with_utf16_bom(pContent, 0, pbReverse) : 0;
479 }
480
481 /*
482 ** Return true if two DLine elements are identical.
483 */
484 static int same_dline(DLine *pA, DLine *pB){
485 return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
@@ -576,11 +277,11 @@
576 int mxr; /* Maximum value for r */
577 int na, nb; /* Number of lines shown from A and B */
578 int i, j; /* Loop counters */
579 int m; /* Number of lines to output */
580 int skip; /* Number of lines to skip */
581 int nChunk = 0; /* Number of diff chunks seen so far */
582 int nContext; /* Number of lines of context */
583 int showLn; /* Show line numbers */
584 int html; /* Render as HTML */
585 int showDivider = 0; /* True to show the divider between diff blocks */
586
@@ -657,14 +358,14 @@
657 if( !showDivider ){
658 /* Do not show a top divider */
659 showDivider = 1;
660 }else if( html ){
661 blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
662 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
663 }else{
664 blob_appendf(pOut, "%.80c\n", '.');
665 }
 
666 }else{
667 if( html ) blob_appendf(pOut, "<span class=\"diffln\">");
668 /*
669 * If the patch changes an empty file or results in an empty file,
670 * the block header must use 0,0 as position indicator and not 1,0.
@@ -727,12 +428,11 @@
727 /*
728 ** Status of a single output line
729 */
730 typedef struct SbsLine SbsLine;
731 struct SbsLine {
732 char *zLine; /* The output line under construction */
733 int n; /* Index of next unused slot in the zLine[] */
734 int width; /* Maximum width of a column in the output */
735 unsigned char escHtml; /* True to escape html characters */
736 int iStart; /* Write zStart prior to character iStart */
737 const char *zStart; /* A <span> tag */
738 int iEnd; /* Write </span> prior to character iEnd */
@@ -741,125 +441,155 @@
741 int iEnd2; /* Write </span> prior to character iEnd2 */
742 ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
743 };
744
745 /*
746 ** Flags for sbsWriteText()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747 */
748 #define SBS_NEWLINE 0x0001 /* End with \n\000 */
749 #define SBS_PAD 0x0002 /* Pad output to width spaces */
 
750
751 /*
752 ** Write up to width characters of pLine into p->zLine[]. Translate tabs into
753 ** spaces. Add a newline if SBS_NEWLINE is set. Translate HTML characters
754 ** if SBS_HTML is set. Pad the rendering out width bytes if SBS_PAD is set.
 
 
 
755 **
756 ** This comment contains multibyte unicode characters (ü, Æ, ð) in order
757 ** to test the ability of the diff code to handle such characters.
758 */
759 static void sbsWriteText(SbsLine *p, DLine *pLine, unsigned flags){
 
760 int n = pLine->h & LENGTH_MASK;
761 int i; /* Number of input characters consumed */
762 int j; /* Number of output characters generated */
763 int k; /* Cursor position */
764 int needEndSpan = 0;
765 const char *zIn = pLine->z;
766 char *z = &p->zLine[p->n];
767 int w = p->width;
768 int colorize = p->escHtml;
769 if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
770 colorize = 0;
771 }
772 for(i=j=k=0; k<w && i<n; i++, k++){
773 char c = zIn[i];
774 if( colorize ){
775 if( i==p->iStart ){
776 int x = strlen(p->zStart);
777 memcpy(z+j, p->zStart, x);
778 j += x;
779 needEndSpan = 1;
780 if( p->iStart2 ){
781 p->iStart = p->iStart2;
782 p->zStart = p->zStart2;
783 p->iStart2 = 0;
784 }
785 }else if( i==p->iEnd ){
786 memcpy(z+j, "</span>", 7);
787 j += 7;
788 needEndSpan = 0;
789 if( p->iEnd2 ){
790 p->iEnd = p->iEnd2;
791 p->iEnd2 = 0;
792 }
793 }
794 }
795 if( c=='\t' ){
796 z[j++] = ' ';
797 while( (k&7)!=7 && k<w ){ z[j++] = ' '; k++; }
 
 
 
798 }else if( c=='\r' || c=='\f' ){
799 z[j++] = ' ';
800 }else if( c=='<' && p->escHtml ){
801 memcpy(&z[j], "&lt;", 4);
802 j += 4;
803 }else if( c=='&' && p->escHtml ){
804 memcpy(&z[j], "&amp;", 5);
805 j += 5;
806 }else if( c=='>' && p->escHtml ){
807 memcpy(&z[j], "&gt;", 4);
808 j += 4;
809 }else if( c=='"' && p->escHtml ){
810 memcpy(&z[j], "&quot;", 6);
811 j += 6;
812 }else{
813 z[j++] = c;
814 if( (c&0xc0)==0x80 ) k--;
815 }
816 }
817 if( needEndSpan ){
818 memcpy(&z[j], "</span>", 7);
819 j += 7;
820 }
821 if( (flags & SBS_PAD)!=0 ){
822 while( k<w ){ k++; z[j++] = ' '; }
823 }
824 if( flags & SBS_NEWLINE ){
825 z[j++] = '\n';
826 }
827 p->n += j;
828 }
829
830 /*
831 ** Append a string to an SbSLine without coding, interpretation, or padding.
832 */
833 static void sbsWrite(SbsLine *p, const char *zIn, int nIn){
834 memcpy(p->zLine+p->n, zIn, nIn);
835 p->n += nIn;
836 }
837
838 /*
839 ** Append n spaces to the string.
840 */
841 static void sbsWriteSpace(SbsLine *p, int n){
842 while( n-- ) p->zLine[p->n++] = ' ';
843 }
844
845 /*
846 ** Append a string to the output only if we are rendering HTML.
847 */
848 static void sbsWriteHtml(SbsLine *p, const char *zIn){
849 if( p->escHtml ) sbsWrite(p, zIn, strlen(zIn));
850 }
851
852 /*
853 ** Write a 6-digit line number followed by a single space onto the line.
854 */
855 static void sbsWriteLineno(SbsLine *p, int ln){
856 sbsWriteHtml(p, "<span class=\"diffln\">");
857 sqlite3_snprintf(7, &p->zLine[p->n], "%5d ", ln+1);
858 p->n += 6;
859 sbsWriteHtml(p, "</span>");
860 p->zLine[p->n++] = ' ';
 
 
 
 
 
 
 
 
 
 
 
861 }
862
863 /*
864 ** The two text segments zLeft and zRight are known to be different on
865 ** both ends, but they might have a common segment in the middle. If
@@ -1018,43 +748,42 @@
1018 }
1019 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
1020 }
1021 if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
1022
1023
1024 /* A single chunk of text inserted on the right */
1025 if( nPrefix+nSuffix==nLeft ){
1026 sbsWriteLineno(p, lnLeft);
1027 p->iStart2 = p->iEnd2 = 0;
1028 p->iStart = p->iEnd = -1;
1029 sbsWriteText(p, pLeft, SBS_PAD);
1030 if( nLeft==nRight && zLeft[nLeft]==zRight[nRight] ){
1031 sbsWrite(p, " ", 3);
1032 }else{
1033 sbsWrite(p, " | ", 3);
1034 }
1035 sbsWriteLineno(p, lnRight);
1036 p->iStart = nPrefix;
1037 p->iEnd = nRight - nSuffix;
1038 p->zStart = zClassAdd;
1039 sbsWriteText(p, pRight, SBS_NEWLINE);
1040 return;
1041 }
1042
1043 /* A single chunk of text deleted from the left */
1044 if( nPrefix+nSuffix==nRight ){
1045 /* Text deleted from the left */
1046 sbsWriteLineno(p, lnLeft);
1047 p->iStart2 = p->iEnd2 = 0;
1048 p->iStart = nPrefix;
1049 p->iEnd = nLeft - nSuffix;
1050 p->zStart = zClassRm;
1051 sbsWriteText(p, pLeft, SBS_PAD);
1052 sbsWrite(p, " | ", 3);
1053 sbsWriteLineno(p, lnRight);
1054 p->iStart = p->iEnd = -1;
1055 sbsWriteText(p, pRight, SBS_NEWLINE);
1056 return;
1057 }
1058
1059 /* At this point we know that there is a chunk of text that has
1060 ** changed between the left and the right. Check to see if there
@@ -1065,11 +794,11 @@
1065 if( p->escHtml
1066 && nLeftDiff >= 6
1067 && nRightDiff >= 6
1068 && textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
1069 ){
1070 sbsWriteLineno(p, lnLeft);
1071 p->iStart = nPrefix;
1072 p->iEnd = nPrefix + aLCS[0];
1073 if( aLCS[2]==0 ){
1074 sbsShiftLeft(p, pLeft->z);
1075 p->zStart = zClassRm;
@@ -1078,13 +807,13 @@
1078 }
1079 p->iStart2 = nPrefix + aLCS[1];
1080 p->iEnd2 = nLeft - nSuffix;
1081 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
1082 sbsSimplifyLine(p, zLeft+nPrefix);
1083 sbsWriteText(p, pLeft, SBS_PAD);
1084 sbsWrite(p, " | ", 3);
1085 sbsWriteLineno(p, lnRight);
1086 p->iStart = nPrefix;
1087 p->iEnd = nPrefix + aLCS[2];
1088 if( aLCS[0]==0 ){
1089 sbsShiftLeft(p, pRight->z);
1090 p->zStart = zClassAdd;
@@ -1093,25 +822,25 @@
1093 }
1094 p->iStart2 = nPrefix + aLCS[3];
1095 p->iEnd2 = nRight - nSuffix;
1096 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
1097 sbsSimplifyLine(p, zRight+nPrefix);
1098 sbsWriteText(p, pRight, SBS_NEWLINE);
1099 return;
1100 }
1101
1102 /* If all else fails, show a single big change between left and right */
1103 sbsWriteLineno(p, lnLeft);
1104 p->iStart2 = p->iEnd2 = 0;
1105 p->iStart = nPrefix;
1106 p->iEnd = nLeft - nSuffix;
1107 p->zStart = zClassChng;
1108 sbsWriteText(p, pLeft, SBS_PAD);
1109 sbsWrite(p, " | ", 3);
1110 sbsWriteLineno(p, lnRight);
1111 p->iEnd = nRight - nSuffix;
1112 sbsWriteText(p, pRight, SBS_NEWLINE);
1113 }
1114
1115 /*
1116 ** Minimum of two values
1117 */
@@ -1357,30 +1086,40 @@
1357 int mxr; /* Maximum value for r */
1358 int na, nb; /* Number of lines shown from A and B */
1359 int i, j; /* Loop counters */
1360 int m, ma, mb;/* Number of lines to output */
1361 int skip; /* Number of lines to skip */
1362 int nChunk = 0; /* Number of chunks of diff output seen so far */
1363 SbsLine s; /* Output line buffer */
1364 int nContext; /* Lines of context above and below each change */
1365 int showDivider = 0; /* True to show the divider */
 
1366
1367 memset(&s, 0, sizeof(s));
1368 s.width = diff_width(diffFlags);
1369 s.zLine = fossil_malloc( 15*s.width + 200 );
1370 if( s.zLine==0 ) return;
1371 nContext = diff_context_lines(diffFlags);
1372 s.escHtml = (diffFlags & DIFF_HTML)!=0;
 
 
 
 
 
 
 
 
 
 
1373 s.pRe = pRe;
1374 s.iStart = -1;
1375 s.iStart2 = 0;
1376 s.iEnd = -1;
1377 A = p->aFrom;
1378 B = p->aTo;
1379 R = p->aEdit;
1380 mxr = p->nEdit;
1381 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
 
1382 for(r=0; r<mxr; r += 3*nr){
1383 /* Figure out how many triples to show in a single block */
1384 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
1385 /* printf("r=%d nr=%d\n", r, nr); */
1386
@@ -1436,35 +1175,39 @@
1436 }
1437
1438 /* Draw the separator between blocks */
1439 if( showDivider ){
1440 if( s.escHtml ){
1441 blob_appendf(pOut, "<span class=\"diffhr\">%.*c</span>\n",
1442 s.width*2+16, '.');
 
 
 
 
 
 
1443 }else{
1444 blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
1445 }
1446 }
1447 showDivider = 1;
1448 nChunk++;
1449 if( s.escHtml ){
1450 blob_appendf(pOut, "<a name=\"chunk%d\"></a>\n", nChunk);
1451 }
1452
1453 /* Show the initial common area */
1454 a += skip;
1455 b += skip;
1456 m = R[r] - skip;
1457 for(j=0; j<m; j++){
1458 s.n = 0;
1459 sbsWriteLineno(&s, a+j);
1460 s.iStart = s.iEnd = -1;
1461 sbsWriteText(&s, &A[a+j], SBS_PAD);
1462 sbsWrite(&s, " ", 3);
1463 sbsWriteLineno(&s, b+j);
1464 sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1465 blob_append(pOut, s.zLine, s.n);
1466 }
1467 a += m;
1468 b += m;
1469
1470 /* Show the differences */
@@ -1485,87 +1228,71 @@
1485
1486 alignment = sbsAlignment(&A[a], ma, &B[b], mb);
1487 for(j=0; ma+mb>0; j++){
1488 if( alignment[j]==1 ){
1489 /* Delete one line from the left */
1490 s.n = 0;
1491 sbsWriteLineno(&s, a);
1492 s.iStart = 0;
1493 s.zStart = "<span class=\"diffrm\">";
1494 s.iEnd = LENGTH(&A[a]);
1495 sbsWriteText(&s, &A[a], SBS_PAD);
1496 if( s.escHtml ){
1497 sbsWrite(&s, " &lt;\n", 6);
1498 }else{
1499 sbsWrite(&s, " <\n", 3);
1500 }
1501 blob_append(pOut, s.zLine, s.n);
1502 assert( ma>0 );
1503 ma--;
1504 a++;
1505 }else if( alignment[j]==3 ){
1506 /* The left line is changed into the right line */
1507 s.n = 0;
1508 sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1509 blob_append(pOut, s.zLine, s.n);
1510 assert( ma>0 && mb>0 );
1511 ma--;
1512 mb--;
1513 a++;
1514 b++;
1515 }else if( alignment[j]==2 ){
1516 /* Insert one line on the right */
1517 s.n = 0;
1518 sbsWriteSpace(&s, s.width + 7);
1519 if( s.escHtml ){
1520 sbsWrite(&s, " &gt; ", 6);
1521 }else{
1522 sbsWrite(&s, " > ", 3);
1523 }
1524 sbsWriteLineno(&s, b);
1525 s.iStart = 0;
1526 s.zStart = "<span class=\"diffadd\">";
1527 s.iEnd = LENGTH(&B[b]);
1528 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1529 blob_append(pOut, s.zLine, s.n);
1530 assert( mb>0 );
1531 mb--;
1532 b++;
1533 }else{
1534 /* Delete from the left and insert on the right */
1535 s.n = 0;
1536 sbsWriteLineno(&s, a);
1537 s.iStart = 0;
1538 s.zStart = "<span class=\"diffrm\">";
1539 s.iEnd = LENGTH(&A[a]);
1540 sbsWriteText(&s, &A[a], SBS_PAD);
1541 sbsWrite(&s, " | ", 3);
1542 sbsWriteLineno(&s, b);
1543 s.iStart = 0;
1544 s.zStart = "<span class=\"diffadd\">";
1545 s.iEnd = LENGTH(&B[b]);
1546 sbsWriteText(&s, &B[b], SBS_NEWLINE);
1547 blob_append(pOut, s.zLine, s.n);
1548 ma--;
1549 mb--;
1550 a++;
1551 b++;
1552 }
1553
1554 }
1555 fossil_free(alignment);
1556 if( i<nr-1 ){
1557 m = R[r+i*3+3];
1558 for(j=0; j<m; j++){
1559 s.n = 0;
1560 sbsWriteLineno(&s, a+j);
1561 s.iStart = s.iEnd = -1;
1562 sbsWriteText(&s, &A[a+j], SBS_PAD);
1563 sbsWrite(&s, " ", 3);
1564 sbsWriteLineno(&s, b+j);
1565 sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1566 blob_append(pOut, s.zLine, s.n);
1567 }
1568 b += m;
1569 a += m;
1570 }
1571 }
@@ -1573,21 +1300,27 @@
1573 /* Show the final common area */
1574 assert( nr==i );
1575 m = R[r+nr*3];
1576 if( m>nContext ) m = nContext;
1577 for(j=0; j<m; j++){
1578 s.n = 0;
1579 sbsWriteLineno(&s, a+j);
1580 s.iStart = s.iEnd = -1;
1581 sbsWriteText(&s, &A[a+j], SBS_PAD);
1582 sbsWrite(&s, " ", 3);
1583 sbsWriteLineno(&s, b+j);
1584 sbsWriteText(&s, &B[b+j], SBS_NEWLINE);
1585 blob_append(pOut, s.zLine, s.n);
1586 }
1587 }
1588 free(s.zLine);
 
 
 
 
 
 
 
 
1589 }
1590
1591 /*
1592 ** Compute the optimal longest common subsequence (LCS) using an
1593 ** exhaustive search. This version of the LCS is only used for
@@ -1990,10 +1723,21 @@
1990 int diff_width(u64 diffFlags){
1991 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1992 if( w==0 ) w = 80;
1993 return w;
1994 }
 
 
 
 
 
 
 
 
 
 
 
1995
1996 /*
1997 ** Generate a report of the differences between files pA and pB.
1998 ** If pOut is not NULL then a unified diff is appended there. It
1999 ** is assumed that pOut has already been initialized. If pOut is
@@ -2032,11 +1776,11 @@
2032 &c.nTo, ignoreEolWs);
2033 if( c.aFrom==0 || c.aTo==0 ){
2034 fossil_free(c.aFrom);
2035 fossil_free(c.aTo);
2036 if( pOut ){
2037 blob_appendf(pOut, DIFF_CANNOT_COMPUTE_BINARY);
2038 }
2039 return 0;
2040 }
2041
2042 /* Compute the difference */
@@ -2048,15 +1792,11 @@
2048 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
2049 if( n>10000 ){
2050 fossil_free(c.aFrom);
2051 fossil_free(c.aTo);
2052 fossil_free(c.aEdit);
2053 if( diffFlags & DIFF_HTML ){
2054 blob_append(pOut, DIFF_TOO_MANY_CHANGES_HTML, -1);
2055 }else{
2056 blob_append(pOut, DIFF_TOO_MANY_CHANGES_TXT, -1);
2057 }
2058 return 0;
2059 }
2060 }
2061 if( (diffFlags & DIFF_NOOPT)==0 ){
2062 diff_optimize(&c);
@@ -2159,10 +1899,11 @@
2159 if( find_option("tk",0,0)!=0 ){
2160 diff_tk("test-diff", 2);
2161 return;
2162 }
2163 find_option("i",0,0);
 
2164 zRe = find_option("regexp","e",1);
2165 if( zRe ){
2166 const char *zErr = re_compile(&pRe, zRe, 0);
2167 if( zErr ) fossil_fatal("regex error: %s", zErr);
2168 }
@@ -2616,60 +2357,5 @@
2616 zPrefix[0] = 0;
2617 }
2618 fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z);
2619 }
2620 }
2621
2622 /*
2623 ** COMMAND: test-looks-like-utf
2624 **
2625 ** Usage: %fossil test-looks-like-utf FILENAME
2626 **
2627 ** Options:
2628 ** --utf8 Ignoring BOM and file size, force UTF-8 checking
2629 ** --utf16 Ignoring BOM and file size, force UTF-16 checking
2630 **
2631 ** FILENAME is the name of a file to check for textual content in the UTF-8
2632 ** and/or UTF-16 encodings.
2633 */
2634 void looks_like_utf_test_cmd(void){
2635 Blob blob; /* the contents of the specified file */
2636 int fUtf8; /* return value of starts_with_utf8_bom() */
2637 int fUtf16; /* return value of starts_with_utf16_bom() */
2638 int fUnicode; /* return value of could_be_utf16() */
2639 int lookFlags; /* output flags from looks_like_utf8/utf16() */
2640 int bRevUtf16 = 0; /* non-zero -> UTF-16 byte order reversed */
2641 int bRevUnicode = 0; /* non-zero -> UTF-16 byte order reversed */
2642 int fForceUtf8 = find_option("utf8",0,0)!=0;
2643 int fForceUtf16 = find_option("utf16",0,0)!=0;
2644 if( g.argc!=3 ) usage("FILENAME");
2645 blob_read_from_file(&blob, g.argv[2]);
2646 fUtf8 = starts_with_utf8_bom(&blob, 0);
2647 fUtf16 = starts_with_utf16_bom(&blob, 0, &bRevUtf16);
2648 if( fForceUtf8 ){
2649 fUnicode = 0;
2650 }else{
2651 fUnicode = could_be_utf16(&blob, &bRevUnicode) || fForceUtf16;
2652 }
2653 lookFlags = fUnicode ? looks_like_utf16(&blob, bRevUnicode, 0) :
2654 looks_like_utf8(&blob, 0);
2655 fossil_print("File \"%s\" has %d bytes.\n",g.argv[2],blob_size(&blob));
2656 fossil_print("Starts with UTF-8 BOM: %s\n",fUtf8?"yes":"no");
2657 fossil_print("Starts with UTF-16 BOM: %s\n",
2658 fUtf16?(bRevUtf16?"reversed":"yes"):"no");
2659 fossil_print("Looks like UTF-%s: %s\n",fUnicode?"16":"8",
2660 (lookFlags&LOOK_BINARY)?"no":"yes");
2661 fossil_print("Has flag LOOK_NUL: %s\n",(lookFlags&LOOK_NUL)?"yes":"no");
2662 fossil_print("Has flag LOOK_CR: %s\n",(lookFlags&LOOK_CR)?"yes":"no");
2663 fossil_print("Has flag LOOK_LONE_CR: %s\n",
2664 (lookFlags&LOOK_LONE_CR)?"yes":"no");
2665 fossil_print("Has flag LOOK_LF: %s\n",(lookFlags&LOOK_LF)?"yes":"no");
2666 fossil_print("Has flag LOOK_LONE_LF: %s\n",
2667 (lookFlags&LOOK_LONE_LF)?"yes":"no");
2668 fossil_print("Has flag LOOK_CRLF: %s\n",(lookFlags&LOOK_CRLF)?"yes":"no");
2669 fossil_print("Has flag LOOK_LONG: %s\n",(lookFlags&LOOK_LONG)?"yes":"no");
2670 fossil_print("Has flag LOOK_INVALID: %s\n",
2671 (lookFlags&LOOK_INVALID)?"yes":"no");
2672 fossil_print("Has flag LOOK_ODD: %s\n",(lookFlags&LOOK_ODD)?"yes":"no");
2673 fossil_print("Has flag LOOK_SHORT: %s\n",(lookFlags&LOOK_SHORT)?"yes":"no");
2674 blob_reset(&blob);
2675 }
2676
--- src/diff.c
+++ src/diff.c
@@ -51,47 +51,20 @@
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 \
57 "more than 10,000 changes\n"
58
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59 /*
60 ** Maximum length of a line in a text file, in bytes. (2**13 = 8192 bytes)
61 */
62 #define LENGTH_MASK_SZ 13
63 #define LENGTH_MASK ((1<<LENGTH_MASK_SZ)-1)
64
65 #endif /* INTERFACE */
66
67 /*
68 ** Information about each line of a file being diffed.
69 **
70 ** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
@@ -204,282 +177,10 @@
177 /* Return results */
178 *pnLine = nLine;
179 return a;
180 }
181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
182 /*
183 ** Return true if two DLine elements are identical.
184 */
185 static int same_dline(DLine *pA, DLine *pB){
186 return pA->h==pB->h && memcmp(pA->z,pB->z,pA->h & LENGTH_MASK)==0;
@@ -576,11 +277,11 @@
277 int mxr; /* Maximum value for r */
278 int na, nb; /* Number of lines shown from A and B */
279 int i, j; /* Loop counters */
280 int m; /* Number of lines to output */
281 int skip; /* Number of lines to skip */
282 static int nChunk = 0; /* Number of diff chunks seen so far */
283 int nContext; /* Number of lines of context */
284 int showLn; /* Show line numbers */
285 int html; /* Render as HTML */
286 int showDivider = 0; /* True to show the divider between diff blocks */
287
@@ -657,14 +358,14 @@
358 if( !showDivider ){
359 /* Do not show a top divider */
360 showDivider = 1;
361 }else if( html ){
362 blob_appendf(pOut, "<span class=\"diffhr\">%.80c</span>\n", '.');
 
363 }else{
364 blob_appendf(pOut, "%.80c\n", '.');
365 }
366 if( html ) blob_appendf(pOut, "<span id=\"chunk%d\"></span>", nChunk);
367 }else{
368 if( html ) blob_appendf(pOut, "<span class=\"diffln\">");
369 /*
370 * If the patch changes an empty file or results in an empty file,
371 * the block header must use 0,0 as position indicator and not 1,0.
@@ -727,12 +428,11 @@
428 /*
429 ** Status of a single output line
430 */
431 typedef struct SbsLine SbsLine;
432 struct SbsLine {
433 Blob *apCols[5]; /* Array of pointers to output columns */
 
434 int width; /* Maximum width of a column in the output */
435 unsigned char escHtml; /* True to escape html characters */
436 int iStart; /* Write zStart prior to character iStart */
437 const char *zStart; /* A <span> tag */
438 int iEnd; /* Write </span> prior to character iEnd */
@@ -741,125 +441,155 @@
441 int iEnd2; /* Write </span> prior to character iEnd2 */
442 ReCompiled *pRe; /* Only colorize matching lines, if not NULL */
443 };
444
445 /*
446 ** Column indices for SbsLine.apCols[]
447 */
448 #define SBS_LNA 0 /* Left line number */
449 #define SBS_TXTA 1 /* Left text */
450 #define SBS_MKR 2 /* Middle separator column */
451 #define SBS_LNB 3 /* Right line number */
452 #define SBS_TXTB 4 /* Right text */
453
454 /*
455 ** Append newlines to all columns.
456 */
457 static void sbsWriteNewlines(SbsLine *p){
458 int i;
459 for( i=p->escHtml ? SBS_LNA : SBS_TXTB; i<=SBS_TXTB; i++ ){
460 blob_append(p->apCols[i], "\n", 1);
461 }
462 }
463
464 /*
465 ** Append n spaces to the column.
466 */
467 static void sbsWriteSpace(SbsLine *p, int n, int col){
468 blob_appendf(p->apCols[col], "%*s", n, "");
469 }
470
471 /*
472 ** Write the text of pLine into column iCol of p.
473 **
474 ** If outputting HTML, write the full line. Otherwise, only write the
475 ** width characters. Translate tabs into spaces. Add newlines if col
476 ** is SBS_TXTB. Translate HTML characters if escHtml is true. Pad the
477 ** rendering to width bytes if col is SBS_TXTA and escHtml is false.
478 **
479 ** This comment contains multibyte unicode characters (ü, Æ, ð) in order
480 ** to test the ability of the diff code to handle such characters.
481 */
482 static void sbsWriteText(SbsLine *p, DLine *pLine, int col){
483 Blob *pCol = p->apCols[col];
484 int n = pLine->h & LENGTH_MASK;
485 int i; /* Number of input characters consumed */
 
486 int k; /* Cursor position */
487 int needEndSpan = 0;
488 const char *zIn = pLine->z;
 
489 int w = p->width;
490 int colorize = p->escHtml;
491 if( colorize && p->pRe && re_dline_match(p->pRe, pLine, 1)==0 ){
492 colorize = 0;
493 }
494 for(i=k=0; (p->escHtml || k<w) && i<n; i++, k++){
495 char c = zIn[i];
496 if( colorize ){
497 if( i==p->iStart ){
498 int x = strlen(p->zStart);
499 blob_append(pCol, p->zStart, x);
 
500 needEndSpan = 1;
501 if( p->iStart2 ){
502 p->iStart = p->iStart2;
503 p->zStart = p->zStart2;
504 p->iStart2 = 0;
505 }
506 }else if( i==p->iEnd ){
507 blob_append(pCol, "</span>", 7);
 
508 needEndSpan = 0;
509 if( p->iEnd2 ){
510 p->iEnd = p->iEnd2;
511 p->iEnd2 = 0;
512 }
513 }
514 }
515 if( c=='\t' && !p->escHtml ){
516 blob_append(pCol, " ", 1);
517 while( (k&7)!=7 && (p->escHtml || k<w) ){
518 blob_append(pCol, " ", 1);
519 k++;
520 }
521 }else if( c=='\r' || c=='\f' ){
522 blob_append(pCol, " ", 1);
523 }else if( c=='<' && p->escHtml ){
524 blob_append(pCol, "&lt;", 4);
 
525 }else if( c=='&' && p->escHtml ){
526 blob_append(pCol, "&amp;", 5);
 
527 }else if( c=='>' && p->escHtml ){
528 blob_append(pCol, "&gt;", 4);
 
529 }else if( c=='"' && p->escHtml ){
530 blob_append(pCol, "&quot;", 6);
 
531 }else{
532 blob_append(pCol, &zIn[i], 1);
533 if( (c&0xc0)==0x80 ) k--;
534 }
535 }
536 if( needEndSpan ){
537 blob_append(pCol, "</span>", 7);
538 }
539 if( col==SBS_TXTB ){
540 sbsWriteNewlines(p);
541 }else if( !p->escHtml ){
542 sbsWriteSpace(p, w-k, SBS_TXTA);
543 }
544 }
545
546 /*
547 ** Append a column to the final output blob.
548 */
549 static void sbsWriteColumn(Blob *pOut, Blob *pCol, int col){
550 blob_appendf(pOut,
551 "<td><div class=\"diff%scol\">\n"
552 "<pre>\n"
553 "%s"
554 "</pre>\n"
555 "</div></td>\n",
556 col % 3 ? (col == SBS_MKR ? "mkr" : "txt") : "ln",
557 blob_str(pCol)
558 );
559 }
560
561 /*
562 ** Append a separator line to column iCol
563 */
564 static void sbsWriteSep(SbsLine *p, int len, int col){
565 char ch = '.';
566 if( len<1 ){
567 len = 1;
568 ch = ' ';
569 }
570 blob_appendf(p->apCols[col], "<span class=\"diffhr\">%.*c</span>\n", len, ch);
571 }
572
573 /*
574 ** Append the appropriate marker into the center column of the diff.
575 */
576 static void sbsWriteMarker(SbsLine *p, const char *zTxt, const char *zHtml){
577 blob_append(p->apCols[SBS_MKR], p->escHtml ? zHtml : zTxt, -1);
578 }
579
580 /*
581 ** Append a line number to the column.
582 */
583 static void sbsWriteLineno(SbsLine *p, int ln, int col){
584 if( p->escHtml ){
585 blob_appendf(p->apCols[col], "%d", ln+1);
586 }else{
587 char zLn[7];
588 sqlite3_snprintf(7, zLn, "%5d ", ln+1);
589 blob_appendf(p->apCols[col], "%s ", zLn);
590 }
591 }
592
593 /*
594 ** The two text segments zLeft and zRight are known to be different on
595 ** both ends, but they might have a common segment in the middle. If
@@ -1018,43 +748,42 @@
748 }
749 if( nSuffix==nLeft || nSuffix==nRight ) nPrefix = 0;
750 }
751 if( nPrefix+nSuffix > nShort ) nPrefix = nShort - nSuffix;
752
 
753 /* A single chunk of text inserted on the right */
754 if( nPrefix+nSuffix==nLeft ){
755 sbsWriteLineno(p, lnLeft, SBS_LNA);
756 p->iStart2 = p->iEnd2 = 0;
757 p->iStart = p->iEnd = -1;
758 sbsWriteText(p, pLeft, SBS_TXTA);
759 if( nLeft==nRight && zLeft[nLeft]==zRight[nRight] ){
760 sbsWriteMarker(p, " ", "");
761 }else{
762 sbsWriteMarker(p, " | ", "|");
763 }
764 sbsWriteLineno(p, lnRight, SBS_LNB);
765 p->iStart = nPrefix;
766 p->iEnd = nRight - nSuffix;
767 p->zStart = zClassAdd;
768 sbsWriteText(p, pRight, SBS_TXTB);
769 return;
770 }
771
772 /* A single chunk of text deleted from the left */
773 if( nPrefix+nSuffix==nRight ){
774 /* Text deleted from the left */
775 sbsWriteLineno(p, lnLeft, SBS_LNA);
776 p->iStart2 = p->iEnd2 = 0;
777 p->iStart = nPrefix;
778 p->iEnd = nLeft - nSuffix;
779 p->zStart = zClassRm;
780 sbsWriteText(p, pLeft, SBS_TXTA);
781 sbsWriteMarker(p, " | ", "|");
782 sbsWriteLineno(p, lnRight, SBS_LNB);
783 p->iStart = p->iEnd = -1;
784 sbsWriteText(p, pRight, SBS_TXTB);
785 return;
786 }
787
788 /* At this point we know that there is a chunk of text that has
789 ** changed between the left and the right. Check to see if there
@@ -1065,11 +794,11 @@
794 if( p->escHtml
795 && nLeftDiff >= 6
796 && nRightDiff >= 6
797 && textLCS(&zLeft[nPrefix], nLeftDiff, &zRight[nPrefix], nRightDiff, aLCS)
798 ){
799 sbsWriteLineno(p, lnLeft, SBS_LNA);
800 p->iStart = nPrefix;
801 p->iEnd = nPrefix + aLCS[0];
802 if( aLCS[2]==0 ){
803 sbsShiftLeft(p, pLeft->z);
804 p->zStart = zClassRm;
@@ -1078,13 +807,13 @@
807 }
808 p->iStart2 = nPrefix + aLCS[1];
809 p->iEnd2 = nLeft - nSuffix;
810 p->zStart2 = aLCS[3]==nRightDiff ? zClassRm : zClassChng;
811 sbsSimplifyLine(p, zLeft+nPrefix);
812 sbsWriteText(p, pLeft, SBS_TXTA);
813 sbsWriteMarker(p, " | ", "|");
814 sbsWriteLineno(p, lnRight, SBS_LNB);
815 p->iStart = nPrefix;
816 p->iEnd = nPrefix + aLCS[2];
817 if( aLCS[0]==0 ){
818 sbsShiftLeft(p, pRight->z);
819 p->zStart = zClassAdd;
@@ -1093,25 +822,25 @@
822 }
823 p->iStart2 = nPrefix + aLCS[3];
824 p->iEnd2 = nRight - nSuffix;
825 p->zStart2 = aLCS[1]==nLeftDiff ? zClassAdd : zClassChng;
826 sbsSimplifyLine(p, zRight+nPrefix);
827 sbsWriteText(p, pRight, SBS_TXTB);
828 return;
829 }
830
831 /* If all else fails, show a single big change between left and right */
832 sbsWriteLineno(p, lnLeft, SBS_LNA);
833 p->iStart2 = p->iEnd2 = 0;
834 p->iStart = nPrefix;
835 p->iEnd = nLeft - nSuffix;
836 p->zStart = zClassChng;
837 sbsWriteText(p, pLeft, SBS_TXTA);
838 sbsWriteMarker(p, " | ", "|");
839 sbsWriteLineno(p, lnRight, SBS_LNB);
840 p->iEnd = nRight - nSuffix;
841 sbsWriteText(p, pRight, SBS_TXTB);
842 }
843
844 /*
845 ** Minimum of two values
846 */
@@ -1357,30 +1086,40 @@
1086 int mxr; /* Maximum value for r */
1087 int na, nb; /* Number of lines shown from A and B */
1088 int i, j; /* Loop counters */
1089 int m, ma, mb;/* Number of lines to output */
1090 int skip; /* Number of lines to skip */
1091 static int nChunk = 0; /* Number of chunks of diff output seen so far */
1092 SbsLine s; /* Output line buffer */
1093 int nContext; /* Lines of context above and below each change */
1094 int showDivider = 0; /* True to show the divider */
1095 Blob aCols[5]; /* Array of column blobs */
1096
1097 memset(&s, 0, sizeof(s));
1098 s.width = diff_width(diffFlags);
 
 
1099 nContext = diff_context_lines(diffFlags);
1100 s.escHtml = (diffFlags & DIFF_HTML)!=0;
1101 if( s.escHtml ){
1102 for(i=SBS_LNA; i<=SBS_TXTB; i++){
1103 blob_zero(&aCols[i]);
1104 s.apCols[i] = &aCols[i];
1105 }
1106 }else{
1107 for(i=SBS_LNA; i<=SBS_TXTB; i++){
1108 s.apCols[i] = pOut;
1109 }
1110 }
1111 s.pRe = pRe;
1112 s.iStart = -1;
1113 s.iStart2 = 0;
1114 s.iEnd = -1;
1115 A = p->aFrom;
1116 B = p->aTo;
1117 R = p->aEdit;
1118 mxr = p->nEdit;
1119 while( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
1120
1121 for(r=0; r<mxr; r += 3*nr){
1122 /* Figure out how many triples to show in a single block */
1123 for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
1124 /* printf("r=%d nr=%d\n", r, nr); */
1125
@@ -1436,35 +1175,39 @@
1175 }
1176
1177 /* Draw the separator between blocks */
1178 if( showDivider ){
1179 if( s.escHtml ){
1180 char zLn[10];
1181 sqlite3_snprintf(sizeof(zLn), zLn, "%d", a+skip+1);
1182 sbsWriteSep(&s, strlen(zLn), SBS_LNA);
1183 sbsWriteSep(&s, s.width, SBS_TXTA);
1184 sbsWriteSep(&s, 0, SBS_MKR);
1185 sqlite3_snprintf(sizeof(zLn), zLn, "%d", b+skip+1);
1186 sbsWriteSep(&s, strlen(zLn), SBS_LNB);
1187 sbsWriteSep(&s, s.width, SBS_TXTB);
1188 }else{
1189 blob_appendf(pOut, "%.*c\n", s.width*2+16, '.');
1190 }
1191 }
1192 showDivider = 1;
1193 nChunk++;
1194 if( s.escHtml ){
1195 blob_appendf(s.apCols[SBS_LNA], "<span id=\"chunk%d\"></span>", nChunk);
1196 }
1197
1198 /* Show the initial common area */
1199 a += skip;
1200 b += skip;
1201 m = R[r] - skip;
1202 for(j=0; j<m; j++){
1203 sbsWriteLineno(&s, a+j, SBS_LNA);
 
1204 s.iStart = s.iEnd = -1;
1205 sbsWriteText(&s, &A[a+j], SBS_TXTA);
1206 sbsWriteMarker(&s, " ", "");
1207 sbsWriteLineno(&s, b+j, SBS_LNB);
1208 sbsWriteText(&s, &B[b+j], SBS_TXTB);
 
1209 }
1210 a += m;
1211 b += m;
1212
1213 /* Show the differences */
@@ -1485,87 +1228,71 @@
1228
1229 alignment = sbsAlignment(&A[a], ma, &B[b], mb);
1230 for(j=0; ma+mb>0; j++){
1231 if( alignment[j]==1 ){
1232 /* Delete one line from the left */
1233 sbsWriteLineno(&s, a, SBS_LNA);
 
1234 s.iStart = 0;
1235 s.zStart = "<span class=\"diffrm\">";
1236 s.iEnd = LENGTH(&A[a]);
1237 sbsWriteText(&s, &A[a], SBS_TXTA);
1238 sbsWriteMarker(&s, " <", "&lt;");
1239 sbsWriteNewlines(&s);
 
 
 
 
1240 assert( ma>0 );
1241 ma--;
1242 a++;
1243 }else if( alignment[j]==3 ){
1244 /* The left line is changed into the right line */
 
1245 sbsWriteLineChange(&s, &A[a], a, &B[b], b);
 
1246 assert( ma>0 && mb>0 );
1247 ma--;
1248 mb--;
1249 a++;
1250 b++;
1251 }else if( alignment[j]==2 ){
1252 /* Insert one line on the right */
1253 if( !s.escHtml ){
1254 sbsWriteSpace(&s, s.width + 7, SBS_TXTA);
1255 }
1256 sbsWriteMarker(&s, " > ", "&gt;");
1257 sbsWriteLineno(&s, b, SBS_LNB);
 
 
 
1258 s.iStart = 0;
1259 s.zStart = "<span class=\"diffadd\">";
1260 s.iEnd = LENGTH(&B[b]);
1261 sbsWriteText(&s, &B[b], SBS_TXTB);
 
1262 assert( mb>0 );
1263 mb--;
1264 b++;
1265 }else{
1266 /* Delete from the left and insert on the right */
1267 sbsWriteLineno(&s, a, SBS_LNA);
 
1268 s.iStart = 0;
1269 s.zStart = "<span class=\"diffrm\">";
1270 s.iEnd = LENGTH(&A[a]);
1271 sbsWriteText(&s, &A[a], SBS_TXTA);
1272 sbsWriteMarker(&s, " | ", "|");
1273 sbsWriteLineno(&s, b, SBS_LNB);
1274 s.iStart = 0;
1275 s.zStart = "<span class=\"diffadd\">";
1276 s.iEnd = LENGTH(&B[b]);
1277 sbsWriteText(&s, &B[b], SBS_TXTB);
 
1278 ma--;
1279 mb--;
1280 a++;
1281 b++;
1282 }
 
1283 }
1284 fossil_free(alignment);
1285 if( i<nr-1 ){
1286 m = R[r+i*3+3];
1287 for(j=0; j<m; j++){
1288 sbsWriteLineno(&s, a+j, SBS_LNA);
 
1289 s.iStart = s.iEnd = -1;
1290 sbsWriteText(&s, &A[a+j], SBS_TXTA);
1291 sbsWriteMarker(&s, " ", "");
1292 sbsWriteLineno(&s, b+j, SBS_LNB);
1293 sbsWriteText(&s, &B[b+j], SBS_TXTB);
 
1294 }
1295 b += m;
1296 a += m;
1297 }
1298 }
@@ -1573,21 +1300,27 @@
1300 /* Show the final common area */
1301 assert( nr==i );
1302 m = R[r+nr*3];
1303 if( m>nContext ) m = nContext;
1304 for(j=0; j<m; j++){
1305 sbsWriteLineno(&s, a+j, SBS_LNA);
 
1306 s.iStart = s.iEnd = -1;
1307 sbsWriteText(&s, &A[a+j], SBS_TXTA);
1308 sbsWriteMarker(&s, " ", "");
1309 sbsWriteLineno(&s, b+j, SBS_LNB);
1310 sbsWriteText(&s, &B[b+j], SBS_TXTB);
 
1311 }
1312 }
1313
1314 if( s.escHtml && blob_size(s.apCols[SBS_LNA])>0 ){
1315 blob_append(pOut, "<table class=\"sbsdiffcols\" width=\"90%\"><tr>\n", -1);
1316 for(i=SBS_LNA; i<=SBS_TXTB; i++){
1317 sbsWriteColumn(pOut, s.apCols[i], i);
1318 blob_reset(s.apCols[i]);
1319 }
1320 blob_append(pOut, "</tr></table>\n", -1);
1321 }
1322 }
1323
1324 /*
1325 ** Compute the optimal longest common subsequence (LCS) using an
1326 ** exhaustive search. This version of the LCS is only used for
@@ -1990,10 +1723,21 @@
1723 int diff_width(u64 diffFlags){
1724 int w = (diffFlags & DIFF_WIDTH_MASK)/(DIFF_CONTEXT_MASK+1);
1725 if( w==0 ) w = 80;
1726 return w;
1727 }
1728
1729 /*
1730 ** Append the error message to pOut.
1731 */
1732 void diff_errmsg(Blob *pOut, const char *msg, int diffFlags){
1733 if( diffFlags & DIFF_HTML ){
1734 blob_appendf(pOut, "<p class=\"generalError\">%s</p>", msg);
1735 }else{
1736 blob_append(pOut, msg, -1);
1737 }
1738 }
1739
1740 /*
1741 ** Generate a report of the differences between files pA and pB.
1742 ** If pOut is not NULL then a unified diff is appended there. It
1743 ** is assumed that pOut has already been initialized. If pOut is
@@ -2032,11 +1776,11 @@
1776 &c.nTo, ignoreEolWs);
1777 if( c.aFrom==0 || c.aTo==0 ){
1778 fossil_free(c.aFrom);
1779 fossil_free(c.aTo);
1780 if( pOut ){
1781 diff_errmsg(pOut, DIFF_CANNOT_COMPUTE_BINARY, diffFlags);
1782 }
1783 return 0;
1784 }
1785
1786 /* Compute the difference */
@@ -2048,15 +1792,11 @@
1792 for(i=m=n=0; i<mx; i+=3){ m += a[i]; n += a[i+1]+a[i+2]; }
1793 if( n>10000 ){
1794 fossil_free(c.aFrom);
1795 fossil_free(c.aTo);
1796 fossil_free(c.aEdit);
1797 diff_errmsg(pOut, DIFF_TOO_MANY_CHANGES, diffFlags);
 
 
 
 
1798 return 0;
1799 }
1800 }
1801 if( (diffFlags & DIFF_NOOPT)==0 ){
1802 diff_optimize(&c);
@@ -2159,10 +1899,11 @@
1899 if( find_option("tk",0,0)!=0 ){
1900 diff_tk("test-diff", 2);
1901 return;
1902 }
1903 find_option("i",0,0);
1904 find_option("v",0,0);
1905 zRe = find_option("regexp","e",1);
1906 if( zRe ){
1907 const char *zErr = re_compile(&pRe, zRe, 0);
1908 if( zErr ) fossil_fatal("regex error: %s", zErr);
1909 }
@@ -2616,60 +2357,5 @@
2357 zPrefix[0] = 0;
2358 }
2359 fossil_print("%21s %4d: %.*s\n", zPrefix, i+1, n, z);
2360 }
2361 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2362
+307 -38
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -597,52 +597,321 @@
597597
return db_get(zName, zDefault);
598598
}
599599
600600
/* A Tcl/Tk script used to render diff output.
601601
*/
602
-static const char zDiffScript[] =
602
+static const char zDiffScript[] =
603603
@ package require Tk
604
-@ wm withdraw .
605
-@ wm title . {Fossil Diff}
606
-@ wm iconname . {Fossil Diff}
607
-@ bind . <q> exit
608
-@ set body {}
609
-@ set mx 80 ;# Length of the longest line of text
610
-@ set nLine 0 ;# Number of lines of text
611
-@ text .t -width 180 -yscroll {.sb set}
612
-@ if {$tcl_platform(platform)=="windows"} {.t config -font {courier 9}}
613
-@ .t tag config ln -foreground gray
614
-@ .t tag config chng -background {#d0d0ff}
615
-@ .t tag config add -background {#c0ffc0}
616
-@ .t tag config rm -background {#ffc0c0}
604
+@
605
+@ array set CFG {
606
+@ TITLE {Fossil Diff}
607
+@ LN_COL_BG #dddddd
608
+@ LN_COL_FG #444444
609
+@ TXT_COL_BG #ffffff
610
+@ TXT_COL_FG #000000
611
+@ MKR_COL_BG #444444
612
+@ MKR_COL_FG #dddddd
613
+@ CHNG_BG #d0d0ff
614
+@ ADD_BG #c0ffc0
615
+@ RM_BG #ffc0c0
616
+@ HR_FG #888888
617
+@ HR_PAD_TOP 4
618
+@ HR_PAD_BTM 8
619
+@ FN_BG #444444
620
+@ FN_FG #ffffff
621
+@ FN_PAD 5
622
+@ FONTS {{DejaVu Sans Mono} Consolas Monaco}
623
+@ FONT_SIZE 9
624
+@ PADX 5
625
+@ WIDTH 80
626
+@ HEIGHT 45
627
+@ LB_HEIGHT 25
628
+@ }
629
+@
630
+@ if {![namespace exists ttk]} {
631
+@ interp alias {} ::ttk::scrollbar {} ::scrollbar
632
+@ interp alias {} ::ttk::menubutton {} ::menubutton
633
+@ }
634
+@
617635
@ proc dehtml {x} {
636
+@ set x [regsub -all {<[^>]*>} $x {}]
618637
@ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
619638
@ }
620
-@ # puts $cmd
621
-@ set in [open $cmd r]
622
-@ while {![eof $in]} {
623
-@ set line [gets $in]
624
-@ if {[regexp {^<a name="chunk.*"></a>} $line]} continue
625
-@ if {[regexp {^===} $line]} {
626
-@ set n [string length $line]
627
-@ if {$n>$mx} {set mx $n}
628
-@ }
629
-@ incr nLine
630
-@ while {[regexp {^(.*?)<span class="diff([a-z]+)">(.*?)</span>(.*)$} $line \
631
-@ all pre class mid tail]} {
632
-@ .t insert end [dehtml $pre] {} [dehtml $mid] $class
633
-@ set line $tail
634
-@ }
635
-@ .t insert end [dehtml $line]\n {}
639
+@
640
+@ proc cols {} {
641
+@ return [list .lnA .txtA .mkr .lnB .txtB]
642
+@ }
643
+@
644
+@ proc colType {c} {
645
+@ regexp {[a-z]+} $c type
646
+@ return $type
647
+@ }
648
+@
649
+@ proc readDiffs {cmd} {
650
+@ set in [open $cmd r]
651
+@ fconfigure $in -encoding utf-8
652
+@ set nDiffs 0
653
+@ array set widths {txt 0 ln 0 mkr 0}
654
+@ while {[gets $in line] != -1} {
655
+@ if {![regexp {^=+\s+(.*?)\s+=+$} $line all fn]} {
656
+@ continue
657
+@ }
658
+@ if {[string compare -length 6 [gets $in] "<table"]} {
659
+@ continue
660
+@ }
661
+@ incr nDiffs
662
+@ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
663
+@ .wfiles.lb insert end $fn
664
+@
665
+@ foreach c [cols] {
666
+@ while {[gets $in] ne "<pre>"} continue
667
+@
668
+@ if {$nDiffs > 1} {
669
+@ $c insert end \n -
670
+@ }
671
+@ if {[colType $c] eq "txt"} {
672
+@ $c insert end $fn\n fn
673
+@ } else {
674
+@ $c insert end \n fn
675
+@ }
676
+@ $c insert end \n -
677
+@
678
+@ set type [colType $c]
679
+@ set str {}
680
+@ while {[set line [gets $in]] ne "</pre>"} {
681
+@ set len [string length [dehtml $line]]
682
+@ if {$len > $widths($type)} {
683
+@ set widths($type) $len
684
+@ }
685
+@ append str $line\n
686
+@ }
687
+@
688
+@ set re {<span class="diff([a-z]+)">([^<]*)</span>}
689
+@ # Use \r as separator since it can't appear in the diff output (it gets
690
+@ # converted to a space).
691
+@ set str [regsub -all $re $str "\r\\1\r\\2\r"]
692
+@ foreach {pre class mid} [split $str \r] {
693
+@ if {$class ne ""} {
694
+@ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
695
+@ } else {
696
+@ $c insert end [dehtml $pre] -
697
+@ }
698
+@ }
699
+@ }
700
+@ }
701
+@ close $in
702
+@
703
+@ foreach c [cols] {
704
+@ set type [colType $c]
705
+@ if {$type ne "txt"} {
706
+@ $c config -width $widths($type)
707
+@ }
708
+@ $c config -state disabled
709
+@ }
710
+@ if {$nDiffs <= [.wfiles.lb cget -height]} {
711
+@ .wfiles.lb config -height $nDiffs
712
+@ grid remove .wfiles.sb
713
+@ }
714
+@
715
+@ return $nDiffs
716
+@ }
717
+@
718
+@ proc viewDiff {idx} {
719
+@ .txtA yview $idx
720
+@ .txtA xview moveto 0
721
+@ }
722
+@
723
+@ proc cycleDiffs {{reverse 0}} {
724
+@ if {$reverse} {
725
+@ set range [.txtA tag prevrange fn @0,0 1.0]
726
+@ if {$range eq ""} {
727
+@ viewDiff {fn.last -1c}
728
+@ } else {
729
+@ viewDiff [lindex $range 0]
730
+@ }
731
+@ } else {
732
+@ set range [.txtA tag nextrange fn {@0,0 +1c} end]
733
+@ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
734
+@ viewDiff fn.first
735
+@ } else {
736
+@ viewDiff [lindex $range 0]
737
+@ }
738
+@ }
739
+@ }
740
+@
741
+@ proc xvis {col} {
742
+@ set view [$col xview]
743
+@ return [expr {[lindex $view 1]-[lindex $view 0]}]
744
+@ }
745
+@
746
+@ proc scroll-x {args} {
747
+@ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
748
+@ eval $c xview $args
749
+@ }
750
+@
751
+@ interp alias {} scroll-y {} .txtA yview
752
+@
753
+@ proc noop {args} {}
754
+@
755
+@ proc enableSync {axis} {
756
+@ update idletasks
757
+@ interp alias {} sync-$axis {}
758
+@ rename _sync-$axis sync-$axis
759
+@ }
760
+@
761
+@ proc disableSync {axis} {
762
+@ rename sync-$axis _sync-$axis
763
+@ interp alias {} sync-$axis {} noop
764
+@ }
765
+@
766
+@ proc sync-x {col first last} {
767
+@ disableSync x
768
+@ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
769
+@ foreach side {A B} {
770
+@ set sb .sbx$side
771
+@ set xview [.txt$side xview]
772
+@ if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} {
773
+@ grid $sb
774
+@ eval $sb set $xview
775
+@ } else {
776
+@ grid remove $sb
777
+@ }
778
+@ }
779
+@ enableSync x
780
+@ }
781
+@
782
+@ proc sync-y {first last} {
783
+@ disableSync y
784
+@ foreach c [cols] {
785
+@ $c yview moveto $first
786
+@ }
787
+@ if {$first > 0 || $last < 1} {
788
+@ grid .sby
789
+@ .sby set $first $last
790
+@ } else {
791
+@ grid remove .sby
792
+@ }
793
+@ enableSync y
794
+@ }
795
+@
796
+@ wm withdraw .
797
+@ wm title . $CFG(TITLE)
798
+@ wm iconname . $CFG(TITLE)
799
+@ bind . <q> exit
800
+@ bind . <Tab> {cycleDiffs; break}
801
+@ bind . <<PrevWindow>> {cycleDiffs 1; break}
802
+@ bind . <Return> {
803
+@ event generate .files <1>
804
+@ event generate .files <ButtonRelease-1>
805
+@ break
806
+@ }
807
+@ foreach {key axis args} {
808
+@ Up y {scroll -5 units}
809
+@ Down y {scroll 5 units}
810
+@ Left x {scroll -5 units}
811
+@ Right x {scroll 5 units}
812
+@ Prior y {scroll -1 page}
813
+@ Next y {scroll 1 page}
814
+@ Home y {moveto 0}
815
+@ End y {moveto 1}
816
+@ } {
817
+@ bind . <$key> "scroll-$axis $args; break"
818
+@ bind . <Shift-$key> continue
819
+@ }
820
+@
821
+@ ::ttk::menubutton .files -text "Files"
822
+@ toplevel .wfiles
823
+@ wm withdraw .wfiles
824
+@ update idletasks
825
+@ wm transient .wfiles .
826
+@ wm overrideredirect .wfiles 1
827
+@ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
828
+@ -yscroll {.wfiles.sb set}
829
+@ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
830
+@ grid .wfiles.lb .wfiles.sb -sticky ns
831
+@ bind .files <1> {
832
+@ set x [winfo rootx %W]
833
+@ set y [expr {[winfo rooty %W]+[winfo height %W]}]
834
+@ wm geometry .wfiles +$x+$y
835
+@ wm deiconify .wfiles
836
+@ focus .wfiles.lb
837
+@ }
838
+@ bind .wfiles <FocusOut> {wm withdraw .wfiles}
839
+@ bind .wfiles <Escape> {focus .}
840
+@ foreach evt {1 Return} {
841
+@ bind .wfiles.lb <$evt> {
842
+@ catch {
843
+@ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
844
+@ viewDiff $idx
845
+@ }
846
+@ focus .
847
+@ break
848
+@ }
849
+@ }
850
+@ bind .wfiles.lb <Motion> {
851
+@ %W selection clear 0 end
852
+@ %W selection set @%x,%y
853
+@ }
854
+@
855
+@ foreach {side syncCol} {A .txtB B .txtA} {
856
+@ set ln .ln$side
857
+@ text $ln
858
+@ $ln tag config - -justify right
859
+@
860
+@ set txt .txt$side
861
+@ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
862
+@ -xscroll "sync-x $syncCol"
863
+@ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
864
+@ foreach tag {add rm chng} {
865
+@ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
866
+@ $txt tag lower $tag
867
+@ }
868
+@ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
869
+@ -justify center
870
+@ }
871
+@ text .mkr
872
+@
873
+@ font create mono -family courier -size $CFG(FONT_SIZE)
874
+@ foreach font $CFG(FONTS) {
875
+@ if {[lsearch -exact [font families] $font] != -1} {
876
+@ font config mono -family $font
877
+@ break
878
+@ }
879
+@ }
880
+@ foreach c [cols] {
881
+@ set keyPrefix [string toupper [colType $c]]_COL_
882
+@ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
883
+@ -font mono -padx $CFG(PADX) -yscroll sync-y
884
+@ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
885
+@ -foreground $CFG(HR_FG)
886
+@ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
887
+@ bindtags $c ". $c Text all"
888
+@ bind $c <1> {focus %W}
889
+@ }
890
+@
891
+@ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
892
+@ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
893
+@ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
894
+@ frame .spacer
895
+@
896
+@ if {[readDiffs $cmd] == 0} {
897
+@ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
898
+@ exit
636899
@ }
637
-@ close $in
638
-@ if {$mx>250} {set mx 250} ;# Limit window width to 200 characters
639
-@ if {$nLine>55} {set nLine 55} ;# Limit window height to 55 lines
640
-@ .t config -height $nLine -width $mx
641
-@ pack .t -side left -fill both -expand 1
642
-@ scrollbar .sb -command {.t yview} -orient vertical
643
-@ pack .sb -side left -fill y
900
+@ update idletasks
901
+@
902
+@ grid rowconfigure . 1 -weight 1
903
+@ grid columnconfigure . 1 -weight 1
904
+@ grid columnconfigure . 4 -weight 1
905
+@ grid .files -row 0 -columnspan 6
906
+@ eval grid [cols] -row 1 -sticky nsew
907
+@ grid .sby -row 1 -column 5 -sticky ns
908
+@ grid .sbxA -row 2 -columnspan 2 -sticky ew
909
+@ grid .spacer -row 2 -column 2
910
+@ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
911
+@
912
+@ .spacer config -height [winfo height .sbxA]
644913
@ wm deiconify .
645914
;
646915
647916
/*
648917
** Show diff output in a Tcl/Tk window, in response to the --tk option
@@ -657,11 +926,11 @@
657926
int i;
658927
Blob script;
659928
char *zTempFile;
660929
char *zCmd;
661930
blob_zero(&script);
662
- blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
931
+ blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i -v",
663932
g.nameOfExe, zSubCmd);
664933
for(i=firstArg; i<g.argc; i++){
665934
const char *z = g.argv[i];
666935
if( z[0]=='-' ){
667936
if( strglob("*-html",z) ) continue;
668937
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -597,52 +597,321 @@
597 return db_get(zName, zDefault);
598 }
599
600 /* A Tcl/Tk script used to render diff output.
601 */
602 static const char zDiffScript[] =
603 @ package require Tk
604 @ wm withdraw .
605 @ wm title . {Fossil Diff}
606 @ wm iconname . {Fossil Diff}
607 @ bind . <q> exit
608 @ set body {}
609 @ set mx 80 ;# Length of the longest line of text
610 @ set nLine 0 ;# Number of lines of text
611 @ text .t -width 180 -yscroll {.sb set}
612 @ if {$tcl_platform(platform)=="windows"} {.t config -font {courier 9}}
613 @ .t tag config ln -foreground gray
614 @ .t tag config chng -background {#d0d0ff}
615 @ .t tag config add -background {#c0ffc0}
616 @ .t tag config rm -background {#ffc0c0}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
617 @ proc dehtml {x} {
 
618 @ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
619 @ }
620 @ # puts $cmd
621 @ set in [open $cmd r]
622 @ while {![eof $in]} {
623 @ set line [gets $in]
624 @ if {[regexp {^<a name="chunk.*"></a>} $line]} continue
625 @ if {[regexp {^===} $line]} {
626 @ set n [string length $line]
627 @ if {$n>$mx} {set mx $n}
628 @ }
629 @ incr nLine
630 @ while {[regexp {^(.*?)<span class="diff([a-z]+)">(.*?)</span>(.*)$} $line \
631 @ all pre class mid tail]} {
632 @ .t insert end [dehtml $pre] {} [dehtml $mid] $class
633 @ set line $tail
634 @ }
635 @ .t insert end [dehtml $line]\n {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636 @ }
637 @ close $in
638 @ if {$mx>250} {set mx 250} ;# Limit window width to 200 characters
639 @ if {$nLine>55} {set nLine 55} ;# Limit window height to 55 lines
640 @ .t config -height $nLine -width $mx
641 @ pack .t -side left -fill both -expand 1
642 @ scrollbar .sb -command {.t yview} -orient vertical
643 @ pack .sb -side left -fill y
 
 
 
 
 
 
644 @ wm deiconify .
645 ;
646
647 /*
648 ** Show diff output in a Tcl/Tk window, in response to the --tk option
@@ -657,11 +926,11 @@
657 int i;
658 Blob script;
659 char *zTempFile;
660 char *zCmd;
661 blob_zero(&script);
662 blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i",
663 g.nameOfExe, zSubCmd);
664 for(i=firstArg; i<g.argc; i++){
665 const char *z = g.argv[i];
666 if( z[0]=='-' ){
667 if( strglob("*-html",z) ) continue;
668
--- src/diffcmd.c
+++ src/diffcmd.c
@@ -597,52 +597,321 @@
597 return db_get(zName, zDefault);
598 }
599
600 /* A Tcl/Tk script used to render diff output.
601 */
602 static const char zDiffScript[] =
603 @ package require Tk
604 @
605 @ array set CFG {
606 @ TITLE {Fossil Diff}
607 @ LN_COL_BG #dddddd
608 @ LN_COL_FG #444444
609 @ TXT_COL_BG #ffffff
610 @ TXT_COL_FG #000000
611 @ MKR_COL_BG #444444
612 @ MKR_COL_FG #dddddd
613 @ CHNG_BG #d0d0ff
614 @ ADD_BG #c0ffc0
615 @ RM_BG #ffc0c0
616 @ HR_FG #888888
617 @ HR_PAD_TOP 4
618 @ HR_PAD_BTM 8
619 @ FN_BG #444444
620 @ FN_FG #ffffff
621 @ FN_PAD 5
622 @ FONTS {{DejaVu Sans Mono} Consolas Monaco}
623 @ FONT_SIZE 9
624 @ PADX 5
625 @ WIDTH 80
626 @ HEIGHT 45
627 @ LB_HEIGHT 25
628 @ }
629 @
630 @ if {![namespace exists ttk]} {
631 @ interp alias {} ::ttk::scrollbar {} ::scrollbar
632 @ interp alias {} ::ttk::menubutton {} ::menubutton
633 @ }
634 @
635 @ proc dehtml {x} {
636 @ set x [regsub -all {<[^>]*>} $x {}]
637 @ return [string map {&amp; & &lt; < &gt; > &#39; ' &quot; \"} $x]
638 @ }
639 @
640 @ proc cols {} {
641 @ return [list .lnA .txtA .mkr .lnB .txtB]
642 @ }
643 @
644 @ proc colType {c} {
645 @ regexp {[a-z]+} $c type
646 @ return $type
647 @ }
648 @
649 @ proc readDiffs {cmd} {
650 @ set in [open $cmd r]
651 @ fconfigure $in -encoding utf-8
652 @ set nDiffs 0
653 @ array set widths {txt 0 ln 0 mkr 0}
654 @ while {[gets $in line] != -1} {
655 @ if {![regexp {^=+\s+(.*?)\s+=+$} $line all fn]} {
656 @ continue
657 @ }
658 @ if {[string compare -length 6 [gets $in] "<table"]} {
659 @ continue
660 @ }
661 @ incr nDiffs
662 @ set idx [expr {$nDiffs > 1 ? [.txtA index end] : "1.0"}]
663 @ .wfiles.lb insert end $fn
664 @
665 @ foreach c [cols] {
666 @ while {[gets $in] ne "<pre>"} continue
667 @
668 @ if {$nDiffs > 1} {
669 @ $c insert end \n -
670 @ }
671 @ if {[colType $c] eq "txt"} {
672 @ $c insert end $fn\n fn
673 @ } else {
674 @ $c insert end \n fn
675 @ }
676 @ $c insert end \n -
677 @
678 @ set type [colType $c]
679 @ set str {}
680 @ while {[set line [gets $in]] ne "</pre>"} {
681 @ set len [string length [dehtml $line]]
682 @ if {$len > $widths($type)} {
683 @ set widths($type) $len
684 @ }
685 @ append str $line\n
686 @ }
687 @
688 @ set re {<span class="diff([a-z]+)">([^<]*)</span>}
689 @ # Use \r as separator since it can't appear in the diff output (it gets
690 @ # converted to a space).
691 @ set str [regsub -all $re $str "\r\\1\r\\2\r"]
692 @ foreach {pre class mid} [split $str \r] {
693 @ if {$class ne ""} {
694 @ $c insert end [dehtml $pre] - [dehtml $mid] [list $class -]
695 @ } else {
696 @ $c insert end [dehtml $pre] -
697 @ }
698 @ }
699 @ }
700 @ }
701 @ close $in
702 @
703 @ foreach c [cols] {
704 @ set type [colType $c]
705 @ if {$type ne "txt"} {
706 @ $c config -width $widths($type)
707 @ }
708 @ $c config -state disabled
709 @ }
710 @ if {$nDiffs <= [.wfiles.lb cget -height]} {
711 @ .wfiles.lb config -height $nDiffs
712 @ grid remove .wfiles.sb
713 @ }
714 @
715 @ return $nDiffs
716 @ }
717 @
718 @ proc viewDiff {idx} {
719 @ .txtA yview $idx
720 @ .txtA xview moveto 0
721 @ }
722 @
723 @ proc cycleDiffs {{reverse 0}} {
724 @ if {$reverse} {
725 @ set range [.txtA tag prevrange fn @0,0 1.0]
726 @ if {$range eq ""} {
727 @ viewDiff {fn.last -1c}
728 @ } else {
729 @ viewDiff [lindex $range 0]
730 @ }
731 @ } else {
732 @ set range [.txtA tag nextrange fn {@0,0 +1c} end]
733 @ if {$range eq "" || [lindex [.txtA yview] 1] == 1} {
734 @ viewDiff fn.first
735 @ } else {
736 @ viewDiff [lindex $range 0]
737 @ }
738 @ }
739 @ }
740 @
741 @ proc xvis {col} {
742 @ set view [$col xview]
743 @ return [expr {[lindex $view 1]-[lindex $view 0]}]
744 @ }
745 @
746 @ proc scroll-x {args} {
747 @ set c .txt[expr {[xvis .txtA] < [xvis .txtB] ? "A" : "B"}]
748 @ eval $c xview $args
749 @ }
750 @
751 @ interp alias {} scroll-y {} .txtA yview
752 @
753 @ proc noop {args} {}
754 @
755 @ proc enableSync {axis} {
756 @ update idletasks
757 @ interp alias {} sync-$axis {}
758 @ rename _sync-$axis sync-$axis
759 @ }
760 @
761 @ proc disableSync {axis} {
762 @ rename sync-$axis _sync-$axis
763 @ interp alias {} sync-$axis {} noop
764 @ }
765 @
766 @ proc sync-x {col first last} {
767 @ disableSync x
768 @ $col xview moveto [expr {$first*[xvis $col]/($last-$first)}]
769 @ foreach side {A B} {
770 @ set sb .sbx$side
771 @ set xview [.txt$side xview]
772 @ if {[lindex $xview 0] > 0 || [lindex $xview 1] < 1} {
773 @ grid $sb
774 @ eval $sb set $xview
775 @ } else {
776 @ grid remove $sb
777 @ }
778 @ }
779 @ enableSync x
780 @ }
781 @
782 @ proc sync-y {first last} {
783 @ disableSync y
784 @ foreach c [cols] {
785 @ $c yview moveto $first
786 @ }
787 @ if {$first > 0 || $last < 1} {
788 @ grid .sby
789 @ .sby set $first $last
790 @ } else {
791 @ grid remove .sby
792 @ }
793 @ enableSync y
794 @ }
795 @
796 @ wm withdraw .
797 @ wm title . $CFG(TITLE)
798 @ wm iconname . $CFG(TITLE)
799 @ bind . <q> exit
800 @ bind . <Tab> {cycleDiffs; break}
801 @ bind . <<PrevWindow>> {cycleDiffs 1; break}
802 @ bind . <Return> {
803 @ event generate .files <1>
804 @ event generate .files <ButtonRelease-1>
805 @ break
806 @ }
807 @ foreach {key axis args} {
808 @ Up y {scroll -5 units}
809 @ Down y {scroll 5 units}
810 @ Left x {scroll -5 units}
811 @ Right x {scroll 5 units}
812 @ Prior y {scroll -1 page}
813 @ Next y {scroll 1 page}
814 @ Home y {moveto 0}
815 @ End y {moveto 1}
816 @ } {
817 @ bind . <$key> "scroll-$axis $args; break"
818 @ bind . <Shift-$key> continue
819 @ }
820 @
821 @ ::ttk::menubutton .files -text "Files"
822 @ toplevel .wfiles
823 @ wm withdraw .wfiles
824 @ update idletasks
825 @ wm transient .wfiles .
826 @ wm overrideredirect .wfiles 1
827 @ listbox .wfiles.lb -width 0 -height $CFG(LB_HEIGHT) -activestyle none \
828 @ -yscroll {.wfiles.sb set}
829 @ ::ttk::scrollbar .wfiles.sb -command {.wfiles.lb yview}
830 @ grid .wfiles.lb .wfiles.sb -sticky ns
831 @ bind .files <1> {
832 @ set x [winfo rootx %W]
833 @ set y [expr {[winfo rooty %W]+[winfo height %W]}]
834 @ wm geometry .wfiles +$x+$y
835 @ wm deiconify .wfiles
836 @ focus .wfiles.lb
837 @ }
838 @ bind .wfiles <FocusOut> {wm withdraw .wfiles}
839 @ bind .wfiles <Escape> {focus .}
840 @ foreach evt {1 Return} {
841 @ bind .wfiles.lb <$evt> {
842 @ catch {
843 @ set idx [lindex [.txtA tag ranges fn] [expr {[%W curselection]*2}]]
844 @ viewDiff $idx
845 @ }
846 @ focus .
847 @ break
848 @ }
849 @ }
850 @ bind .wfiles.lb <Motion> {
851 @ %W selection clear 0 end
852 @ %W selection set @%x,%y
853 @ }
854 @
855 @ foreach {side syncCol} {A .txtB B .txtA} {
856 @ set ln .ln$side
857 @ text $ln
858 @ $ln tag config - -justify right
859 @
860 @ set txt .txt$side
861 @ text $txt -width $CFG(WIDTH) -height $CFG(HEIGHT) -wrap none \
862 @ -xscroll "sync-x $syncCol"
863 @ catch {$txt config -tabstyle wordprocessor} ;# Required for Tk>=8.5
864 @ foreach tag {add rm chng} {
865 @ $txt tag config $tag -background $CFG([string toupper $tag]_BG)
866 @ $txt tag lower $tag
867 @ }
868 @ $txt tag config fn -background $CFG(FN_BG) -foreground $CFG(FN_FG) \
869 @ -justify center
870 @ }
871 @ text .mkr
872 @
873 @ font create mono -family courier -size $CFG(FONT_SIZE)
874 @ foreach font $CFG(FONTS) {
875 @ if {[lsearch -exact [font families] $font] != -1} {
876 @ font config mono -family $font
877 @ break
878 @ }
879 @ }
880 @ foreach c [cols] {
881 @ set keyPrefix [string toupper [colType $c]]_COL_
882 @ $c config -bg $CFG(${keyPrefix}BG) -fg $CFG(${keyPrefix}FG) -borderwidth 0 \
883 @ -font mono -padx $CFG(PADX) -yscroll sync-y
884 @ $c tag config hr -spacing1 $CFG(HR_PAD_TOP) -spacing3 $CFG(HR_PAD_BTM) \
885 @ -foreground $CFG(HR_FG)
886 @ $c tag config fn -spacing1 $CFG(FN_PAD) -spacing3 $CFG(FN_PAD)
887 @ bindtags $c ". $c Text all"
888 @ bind $c <1> {focus %W}
889 @ }
890 @
891 @ ::ttk::scrollbar .sby -command {.txtA yview} -orient vertical
892 @ ::ttk::scrollbar .sbxA -command {.txtA xview} -orient horizontal
893 @ ::ttk::scrollbar .sbxB -command {.txtB xview} -orient horizontal
894 @ frame .spacer
895 @
896 @ if {[readDiffs $cmd] == 0} {
897 @ tk_messageBox -type ok -title $CFG(TITLE) -message "No changes"
898 @ exit
899 @ }
900 @ update idletasks
901 @
902 @ grid rowconfigure . 1 -weight 1
903 @ grid columnconfigure . 1 -weight 1
904 @ grid columnconfigure . 4 -weight 1
905 @ grid .files -row 0 -columnspan 6
906 @ eval grid [cols] -row 1 -sticky nsew
907 @ grid .sby -row 1 -column 5 -sticky ns
908 @ grid .sbxA -row 2 -columnspan 2 -sticky ew
909 @ grid .spacer -row 2 -column 2
910 @ grid .sbxB -row 2 -column 3 -columnspan 2 -sticky ew
911 @
912 @ .spacer config -height [winfo height .sbxA]
913 @ wm deiconify .
914 ;
915
916 /*
917 ** Show diff output in a Tcl/Tk window, in response to the --tk option
@@ -657,11 +926,11 @@
926 int i;
927 Blob script;
928 char *zTempFile;
929 char *zCmd;
930 blob_zero(&script);
931 blob_appendf(&script, "set cmd {| \"%/\" %s --html -y -i -v",
932 g.nameOfExe, zSubCmd);
933 for(i=firstArg; i<g.argc; i++){
934 const char *z = g.argv[i];
935 if( z[0]=='-' ){
936 if( strglob("*-html",z) ) continue;
937
+5 -5
--- src/event.c
+++ src/event.c
@@ -399,32 +399,32 @@
399399
@ <form method="post" action="%s(g.zTop)/eventedit"><div>
400400
login_insert_csrf_secret();
401401
@ <input type="hidden" name="name" value="%h(zEventId)" />
402402
@ <table border="0" cellspacing="10">
403403
404
- @ <tr><td align="right" valign="top"><b>Event&nbsp;Time:</b></td>
404
+ @ <tr><th align="right" valign="top">Event&nbsp;Time:</th>
405405
@ <td valign="top">
406406
@ <input type="text" name="t" size="25" value="%h(zETime)" />
407407
@ </td></tr>
408408
409
- @ <tr><td align="right" valign="top"><b>Timeline&nbsp;Comment:</b></td>
409
+ @ <tr><th align="right" valign="top">Timeline&nbsp;Comment:</th>
410410
@ <td valign="top">
411411
@ <textarea name="c" class="eventedit" cols="80"
412412
@ rows="3" wrap="virtual">%h(zComment)</textarea>
413413
@ </td></tr>
414414
415
- @ <tr><td align="right" valign="top"><b>Background&nbsp;Color:</b></td>
415
+ @ <tr><th align="right" valign="top">Background&nbsp;Color:</th>
416416
@ <td valign="top">
417417
render_color_chooser(0, zClr, 0, "clr", "cclr");
418418
@ </td></tr>
419419
420
- @ <tr><td align="right" valign="top"><b>Tags:</b></td>
420
+ @ <tr><th align="right" valign="top">Tags:</th>
421421
@ <td valign="top">
422422
@ <input type="text" name="g" size="40" value="%h(zTags)" />
423423
@ </td></tr>
424424
425
- @ <tr><td align="right" valign="top"><b>Page&nbsp;Content:</b></td>
425
+ @ <tr><th align="right" valign="top">Page&nbsp;Content:</th>
426426
@ <td valign="top">
427427
@ <textarea name="w" class="eventedit" cols="80"
428428
@ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
429429
@ </td></tr>
430430
431431
--- src/event.c
+++ src/event.c
@@ -399,32 +399,32 @@
399 @ <form method="post" action="%s(g.zTop)/eventedit"><div>
400 login_insert_csrf_secret();
401 @ <input type="hidden" name="name" value="%h(zEventId)" />
402 @ <table border="0" cellspacing="10">
403
404 @ <tr><td align="right" valign="top"><b>Event&nbsp;Time:</b></td>
405 @ <td valign="top">
406 @ <input type="text" name="t" size="25" value="%h(zETime)" />
407 @ </td></tr>
408
409 @ <tr><td align="right" valign="top"><b>Timeline&nbsp;Comment:</b></td>
410 @ <td valign="top">
411 @ <textarea name="c" class="eventedit" cols="80"
412 @ rows="3" wrap="virtual">%h(zComment)</textarea>
413 @ </td></tr>
414
415 @ <tr><td align="right" valign="top"><b>Background&nbsp;Color:</b></td>
416 @ <td valign="top">
417 render_color_chooser(0, zClr, 0, "clr", "cclr");
418 @ </td></tr>
419
420 @ <tr><td align="right" valign="top"><b>Tags:</b></td>
421 @ <td valign="top">
422 @ <input type="text" name="g" size="40" value="%h(zTags)" />
423 @ </td></tr>
424
425 @ <tr><td align="right" valign="top"><b>Page&nbsp;Content:</b></td>
426 @ <td valign="top">
427 @ <textarea name="w" class="eventedit" cols="80"
428 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
429 @ </td></tr>
430
431
--- src/event.c
+++ src/event.c
@@ -399,32 +399,32 @@
399 @ <form method="post" action="%s(g.zTop)/eventedit"><div>
400 login_insert_csrf_secret();
401 @ <input type="hidden" name="name" value="%h(zEventId)" />
402 @ <table border="0" cellspacing="10">
403
404 @ <tr><th align="right" valign="top">Event&nbsp;Time:</th>
405 @ <td valign="top">
406 @ <input type="text" name="t" size="25" value="%h(zETime)" />
407 @ </td></tr>
408
409 @ <tr><th align="right" valign="top">Timeline&nbsp;Comment:</th>
410 @ <td valign="top">
411 @ <textarea name="c" class="eventedit" cols="80"
412 @ rows="3" wrap="virtual">%h(zComment)</textarea>
413 @ </td></tr>
414
415 @ <tr><th align="right" valign="top">Background&nbsp;Color:</th>
416 @ <td valign="top">
417 render_color_chooser(0, zClr, 0, "clr", "cclr");
418 @ </td></tr>
419
420 @ <tr><th align="right" valign="top">Tags:</th>
421 @ <td valign="top">
422 @ <input type="text" name="g" size="40" value="%h(zTags)" />
423 @ </td></tr>
424
425 @ <tr><th align="right" valign="top">Page&nbsp;Content:</th>
426 @ <td valign="top">
427 @ <textarea name="w" class="eventedit" cols="80"
428 @ rows="%d(n)" wrap="virtual">%h(zBody)</textarea>
429 @ </td></tr>
430
431
+97 -81
--- src/info.c
+++ src/info.c
@@ -316,25 +316,22 @@
316316
blob_zero(&to);
317317
}
318318
blob_zero(&out);
319319
if( diffFlags & DIFF_SIDEBYSIDE ){
320320
text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
321
- @ <div class="sbsdiff">
322321
@ %s(blob_str(&out))
323
- @ </div>
324322
}else{
325323
text_diff(&from, &to, &out, pRe,
326324
diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
327
- @ <div class="udiff">
325
+ @ <pre class="udiff">
328326
@ %s(blob_str(&out))
329
- @ </div>
327
+ @ </pre>
330328
}
331329
blob_reset(&from);
332330
blob_reset(&to);
333331
blob_reset(&out);
334332
}
335
-
336333
337334
/*
338335
** Write a line of web-page output that shows changes that have occurred
339336
** to a file between two check-ins.
340337
*/
@@ -359,13 +356,11 @@
359356
@ for %h(zName)</p>
360357
}else{
361358
@ <p>Changes to %h(zName)</p>
362359
}
363360
if( diffFlags ){
364
- @ <pre style="white-space:pre;">
365361
append_diff(zOld, zNew, diffFlags, pRe);
366
- @ </pre>
367362
}
368363
}else{
369364
if( zOld && zNew ){
370365
if( fossil_strcmp(zOld, zNew)!=0 ){
371366
@ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -385,20 +380,51 @@
385380
}else{
386381
@ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
387382
@ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
388383
}
389384
if( diffFlags ){
390
- @ <pre style="white-space:pre;">
391385
append_diff(zOld, zNew, diffFlags, pRe);
392
- @ </pre>
393386
}else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
394387
@ &nbsp;&nbsp;
395388
@ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a>
396389
}
397
- @ </p>
398390
}
399391
}
392
+
393
+/*
394
+** Generate javascript to enhance HTML diffs.
395
+*/
396
+void append_diff_javascript(int sideBySide){
397
+ if( !sideBySide ) return;
398
+ @ <script>(function(){
399
+ @ var SCROLL_LEN = 25;
400
+ @ function initSbsDiff(diff){
401
+ @ var txtCols = diff.querySelectorAll('.difftxtcol');
402
+ @ var txtPres = diff.querySelectorAll('.difftxtcol pre');
403
+ @ var width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
404
+ @ for(var i=0; i<2; i++){
405
+ @ txtPres[i].style.width = width + 'px';
406
+ @ txtCols[i].onscroll = function(e){
407
+ @ txtCols[0].scrollLeft = txtCols[1].scrollLeft = this.scrollLeft;
408
+ @ };
409
+ @ }
410
+ @ diff.tabIndex = 0;
411
+ @ diff.onkeydown = function(e){
412
+ @ e = e || event;
413
+ @ var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
414
+ @ if( !len ) return;
415
+ @ txtCols[0].scrollLeft += len;
416
+ @ return false;
417
+ @ };
418
+ @ }
419
+ @
420
+ @ var diffs = document.querySelectorAll('.sbsdiffcols');
421
+ @ for(var i=0; i<diffs.length; i++){
422
+ @ initSbsDiff(diffs[i]);
423
+ @ }
424
+ @ }())</script>
425
+}
400426
401427
/*
402428
** Construct an appropriate diffFlag for text_diff() based on query
403429
** parameters and the to boolean arguments.
404430
*/
@@ -675,10 +701,11 @@
675701
const char *zOldName = db_column_text(&q, 4);
676702
append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
677703
}
678704
db_finalize(&q);
679705
}
706
+ append_diff_javascript(sideBySide);
680707
style_footer();
681708
}
682709
683710
/*
684711
** WEBPAGE: winfo
@@ -988,11 +1015,11 @@
9881015
pFileTo = manifest_file_next(pTo, 0);
9891016
}
9901017
}
9911018
manifest_destroy(pFrom);
9921019
manifest_destroy(pTo);
993
-
1020
+ append_diff_javascript(sideBySide);
9941021
style_footer();
9951022
}
9961023
9971024
#if INTERFACE
9981025
/*
@@ -1244,85 +1271,74 @@
12441271
*/
12451272
void diff_page(void){
12461273
int v1, v2;
12471274
int isPatch;
12481275
int sideBySide;
1249
- Blob c1, c2, diff, *pOut;
12501276
char *zV1;
12511277
char *zV2;
12521278
const char *zRe;
12531279
ReCompiled *pRe = 0;
12541280
u64 diffFlags;
1255
- const char *zStyle = "sbsdiff";
12561281
12571282
login_check_credentials();
12581283
if( !g.perm.Read ){ login_needed(); return; }
12591284
v1 = name_to_rid_www("v1");
12601285
v2 = name_to_rid_www("v2");
12611286
if( v1==0 || v2==0 ) fossil_redirect_home();
1262
- sideBySide = !is_false(PD("sbs","1"));
1263
- zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1264
- zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1287
+ zRe = P("regex");
1288
+ if( zRe ) re_compile(&pRe, zRe, 0);
12651289
isPatch = P("patch")!=0;
12661290
if( isPatch ){
1291
+ Blob c1, c2, *pOut;
12671292
pOut = cgi_output_blob();
12681293
cgi_set_content_type("text/plain");
12691294
diffFlags = 4;
1270
- }else{
1271
- blob_zero(&diff);
1272
- pOut = &diff;
1273
- diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1274
- if( sideBySide ){
1275
- zStyle = "sbsdiff";
1276
- }else{
1277
- diffFlags |= DIFF_LINENO;
1278
- zStyle = "udiff";
1279
- }
1280
- }
1281
- zRe = P("regex");
1282
- if( zRe ) re_compile(&pRe, zRe, 0);
1283
- content_get(v1, &c1);
1284
- content_get(v2, &c2);
1285
- text_diff(&c1, &c2, pOut, pRe, diffFlags);
1286
- blob_reset(&c1);
1287
- blob_reset(&c2);
1288
- if( !isPatch ){
1289
- style_header("Diff");
1290
- style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1291
- g.zTop, P("v1"), P("v2"));
1292
- if( !sideBySide ){
1293
- style_submenu_element("Side-by-side Diff", "sbsdiff",
1294
- "%s/fdiff?v1=%T&v2=%T&sbs=1",
1295
- g.zTop, P("v1"), P("v2"));
1296
- }else{
1297
- style_submenu_element("Unified Diff", "udiff",
1298
- "%s/fdiff?v1=%T&v2=%T&sbs=0",
1299
- g.zTop, P("v1"), P("v2"));
1300
- }
1301
-
1302
- if( P("smhdr")!=0 ){
1303
- @ <h2>Differences From Artifact
1304
- @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1305
- @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1306
- }else{
1307
- @ <h2>Differences From
1308
- @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1309
- object_description(v1, 0, 0);
1310
- @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1311
- object_description(v2, 0, 0);
1312
- }
1313
- if( pRe ){
1314
- @ <b>Only differences that match regular expression "%h(zRe)"
1315
- @ are shown.</b>
1316
- }
1317
- @ <hr />
1318
- @ <div class="%s(zStyle)">
1319
- @ %s(blob_str(&diff))
1320
- @ </div>
1321
- blob_reset(&diff);
1322
- style_footer();
1323
- }
1295
+ content_get(v1, &c1);
1296
+ content_get(v2, &c2);
1297
+ text_diff(&c1, &c2, pOut, pRe, diffFlags);
1298
+ blob_reset(&c1);
1299
+ blob_reset(&c2);
1300
+ return;
1301
+ }
1302
+
1303
+ sideBySide = !is_false(PD("sbs","1"));
1304
+ zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1305
+ zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1306
+ diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1307
+
1308
+ style_header("Diff");
1309
+ style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1310
+ g.zTop, P("v1"), P("v2"));
1311
+ if( !sideBySide ){
1312
+ style_submenu_element("Side-by-side Diff", "sbsdiff",
1313
+ "%s/fdiff?v1=%T&v2=%T&sbs=1",
1314
+ g.zTop, P("v1"), P("v2"));
1315
+ }else{
1316
+ style_submenu_element("Unified Diff", "udiff",
1317
+ "%s/fdiff?v1=%T&v2=%T&sbs=0",
1318
+ g.zTop, P("v1"), P("v2"));
1319
+ }
1320
+
1321
+ if( P("smhdr")!=0 ){
1322
+ @ <h2>Differences From Artifact
1323
+ @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1324
+ @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1325
+ }else{
1326
+ @ <h2>Differences From
1327
+ @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1328
+ object_description(v1, 0, 0);
1329
+ @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1330
+ object_description(v2, 0, 0);
1331
+ }
1332
+ if( pRe ){
1333
+ @ <b>Only differences that match regular expression "%h(zRe)"
1334
+ @ are shown.</b>
1335
+ }
1336
+ @ <hr />
1337
+ append_diff(zV1, zV2, diffFlags, pRe);
1338
+ append_diff_javascript(sideBySide);
1339
+ style_footer();
13241340
}
13251341
13261342
/*
13271343
** WEBPAGE: raw
13281344
** URL: /raw?name=ARTIFACTID&m=TYPE
@@ -1427,11 +1443,11 @@
14271443
if( !g.perm.Read ){ login_needed(); return; }
14281444
if( rid==0 ) fossil_redirect_home();
14291445
if( g.perm.Admin ){
14301446
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
14311447
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1432
- style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
1448
+ style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
14331449
g.zTop, zUuid);
14341450
}else{
14351451
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
14361452
g.zTop, zUuid);
14371453
}
@@ -1577,11 +1593,11 @@
15771593
if( !g.perm.Read ){ login_needed(); return; }
15781594
if( rid==0 ) fossil_redirect_home();
15791595
if( g.perm.Admin ){
15801596
const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
15811597
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1582
- style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
1598
+ style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
15831599
g.zTop, zUuid);
15841600
}else{
15851601
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
15861602
g.zTop, zUuid);
15871603
}
@@ -1685,11 +1701,11 @@
16851701
rid = name_to_rid_www("name");
16861702
if( rid==0 ){ fossil_redirect_home(); }
16871703
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
16881704
if( g.perm.Admin ){
16891705
if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1690
- style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
1706
+ style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
16911707
g.zTop, zUuid);
16921708
}else{
16931709
style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
16941710
g.zTop, zUuid);
16951711
}
@@ -2205,38 +2221,38 @@
22052221
form_begin(0, "%R/ci_edit");
22062222
login_insert_csrf_secret();
22072223
@ <div><input type="hidden" name="r" value="%S(zUuid)" />
22082224
@ <table border="0" cellspacing="10">
22092225
2210
- @ <tr><td align="right" valign="top"><b>User:</b></td>
2226
+ @ <tr><th align="right" valign="top">User:</th>
22112227
@ <td valign="top">
22122228
@ <input type="text" name="u" size="20" value="%h(zNewUser)" />
22132229
@ </td></tr>
22142230
2215
- @ <tr><td align="right" valign="top"><b>Comment:</b></td>
2231
+ @ <tr><th align="right" valign="top">Comment:</th>
22162232
@ <td valign="top">
22172233
@ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
22182234
@ </td></tr>
22192235
2220
- @ <tr><td align="right" valign="top"><b>Check-in Time:</b></td>
2236
+ @ <tr><th align="right" valign="top">Check-in Time:</th>
22212237
@ <td valign="top">
22222238
@ <input type="text" name="dt" size="20" value="%h(zNewDate)" />
22232239
@ </td></tr>
22242240
22252241
if( zChngTime ){
2226
- @ <tr><td align="right" valign="top"><b>Timestamp of this change:</b></td>
2242
+ @ <tr><th align="right" valign="top">Timestamp of this change:</th>
22272243
@ <td valign="top">
22282244
@ <input type="text" name="chngtime" size="20" value="%h(zChngTime)" />
22292245
@ </td></tr>
22302246
}
22312247
2232
- @ <tr><td align="right" valign="top"><b>Background Color:</b></td>
2248
+ @ <tr><th align="right" valign="top">Background Color:</th>
22332249
@ <td valign="top">
22342250
render_color_chooser(fNewPropagateColor, zNewColor, "pclr", "clr", "clrcust");
22352251
@ </td></tr>
22362252
2237
- @ <tr><td align="right" valign="top"><b>Tags:</b></td>
2253
+ @ <tr><th align="right" valign="top">Tags:</th>
22382254
@ <td valign="top">
22392255
@ <label><input type="checkbox" id="newtag" name="newtag"%s(zNewTagFlag) />
22402256
@ Add the following new tag name to this check-in:</label>
22412257
@ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)"
22422258
@ onkeyup="gebi('newtag').checked=!!this.value" />
@@ -2265,11 +2281,11 @@
22652281
}
22662282
}
22672283
db_finalize(&q);
22682284
@ </td></tr>
22692285
2270
- @ <tr><td align="right" valign="top"><b>Branching:</b></td>
2286
+ @ <tr><th align="right" valign="top">Branching:</th>
22712287
@ <td valign="top">
22722288
@ <label><input id="newbr" type="checkbox" name="newbr"%s(zNewBrFlag) />
22732289
@ Make this check-in the start of a new branch named:</label>
22742290
@ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)"
22752291
@ onkeyup="gebi('newbr').checked=!!this.value" />
@@ -2278,11 +2294,11 @@
22782294
if( is_a_leaf(rid)
22792295
&& !db_exists("SELECT 1 FROM tagxref "
22802296
" WHERE tagid=%d AND rid=%d AND tagtype>0",
22812297
TAG_CLOSED, rid)
22822298
){
2283
- @ <tr><td align="right" valign="top"><b>Leaf Closure:</b></td>
2299
+ @ <tr><th align="right" valign="top">Leaf Closure:</th>
22842300
@ <td valign="top">
22852301
@ <label><input type="checkbox" name="close"%s(zCloseFlag) />
22862302
@ Mark this leaf as "closed" so that it no longer appears on the
22872303
@ "leaves" page and is no longer labeled as a "<b>Leaf</b>".</label>
22882304
@ </td></tr>
22892305
--- src/info.c
+++ src/info.c
@@ -316,25 +316,22 @@
316 blob_zero(&to);
317 }
318 blob_zero(&out);
319 if( diffFlags & DIFF_SIDEBYSIDE ){
320 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
321 @ <div class="sbsdiff">
322 @ %s(blob_str(&out))
323 @ </div>
324 }else{
325 text_diff(&from, &to, &out, pRe,
326 diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
327 @ <div class="udiff">
328 @ %s(blob_str(&out))
329 @ </div>
330 }
331 blob_reset(&from);
332 blob_reset(&to);
333 blob_reset(&out);
334 }
335
336
337 /*
338 ** Write a line of web-page output that shows changes that have occurred
339 ** to a file between two check-ins.
340 */
@@ -359,13 +356,11 @@
359 @ for %h(zName)</p>
360 }else{
361 @ <p>Changes to %h(zName)</p>
362 }
363 if( diffFlags ){
364 @ <pre style="white-space:pre;">
365 append_diff(zOld, zNew, diffFlags, pRe);
366 @ </pre>
367 }
368 }else{
369 if( zOld && zNew ){
370 if( fossil_strcmp(zOld, zNew)!=0 ){
371 @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -385,20 +380,51 @@
385 }else{
386 @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
387 @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
388 }
389 if( diffFlags ){
390 @ <pre style="white-space:pre;">
391 append_diff(zOld, zNew, diffFlags, pRe);
392 @ </pre>
393 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
394 @ &nbsp;&nbsp;
395 @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a>
396 }
397 @ </p>
398 }
399 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
400
401 /*
402 ** Construct an appropriate diffFlag for text_diff() based on query
403 ** parameters and the to boolean arguments.
404 */
@@ -675,10 +701,11 @@
675 const char *zOldName = db_column_text(&q, 4);
676 append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
677 }
678 db_finalize(&q);
679 }
 
680 style_footer();
681 }
682
683 /*
684 ** WEBPAGE: winfo
@@ -988,11 +1015,11 @@
988 pFileTo = manifest_file_next(pTo, 0);
989 }
990 }
991 manifest_destroy(pFrom);
992 manifest_destroy(pTo);
993
994 style_footer();
995 }
996
997 #if INTERFACE
998 /*
@@ -1244,85 +1271,74 @@
1244 */
1245 void diff_page(void){
1246 int v1, v2;
1247 int isPatch;
1248 int sideBySide;
1249 Blob c1, c2, diff, *pOut;
1250 char *zV1;
1251 char *zV2;
1252 const char *zRe;
1253 ReCompiled *pRe = 0;
1254 u64 diffFlags;
1255 const char *zStyle = "sbsdiff";
1256
1257 login_check_credentials();
1258 if( !g.perm.Read ){ login_needed(); return; }
1259 v1 = name_to_rid_www("v1");
1260 v2 = name_to_rid_www("v2");
1261 if( v1==0 || v2==0 ) fossil_redirect_home();
1262 sideBySide = !is_false(PD("sbs","1"));
1263 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1264 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1265 isPatch = P("patch")!=0;
1266 if( isPatch ){
 
1267 pOut = cgi_output_blob();
1268 cgi_set_content_type("text/plain");
1269 diffFlags = 4;
1270 }else{
1271 blob_zero(&diff);
1272 pOut = &diff;
1273 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1274 if( sideBySide ){
1275 zStyle = "sbsdiff";
1276 }else{
1277 diffFlags |= DIFF_LINENO;
1278 zStyle = "udiff";
1279 }
1280 }
1281 zRe = P("regex");
1282 if( zRe ) re_compile(&pRe, zRe, 0);
1283 content_get(v1, &c1);
1284 content_get(v2, &c2);
1285 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1286 blob_reset(&c1);
1287 blob_reset(&c2);
1288 if( !isPatch ){
1289 style_header("Diff");
1290 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1291 g.zTop, P("v1"), P("v2"));
1292 if( !sideBySide ){
1293 style_submenu_element("Side-by-side Diff", "sbsdiff",
1294 "%s/fdiff?v1=%T&v2=%T&sbs=1",
1295 g.zTop, P("v1"), P("v2"));
1296 }else{
1297 style_submenu_element("Unified Diff", "udiff",
1298 "%s/fdiff?v1=%T&v2=%T&sbs=0",
1299 g.zTop, P("v1"), P("v2"));
1300 }
1301
1302 if( P("smhdr")!=0 ){
1303 @ <h2>Differences From Artifact
1304 @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1305 @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1306 }else{
1307 @ <h2>Differences From
1308 @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1309 object_description(v1, 0, 0);
1310 @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1311 object_description(v2, 0, 0);
1312 }
1313 if( pRe ){
1314 @ <b>Only differences that match regular expression "%h(zRe)"
1315 @ are shown.</b>
1316 }
1317 @ <hr />
1318 @ <div class="%s(zStyle)">
1319 @ %s(blob_str(&diff))
1320 @ </div>
1321 blob_reset(&diff);
1322 style_footer();
1323 }
1324 }
1325
1326 /*
1327 ** WEBPAGE: raw
1328 ** URL: /raw?name=ARTIFACTID&m=TYPE
@@ -1427,11 +1443,11 @@
1427 if( !g.perm.Read ){ login_needed(); return; }
1428 if( rid==0 ) fossil_redirect_home();
1429 if( g.perm.Admin ){
1430 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1431 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1432 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
1433 g.zTop, zUuid);
1434 }else{
1435 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1436 g.zTop, zUuid);
1437 }
@@ -1577,11 +1593,11 @@
1577 if( !g.perm.Read ){ login_needed(); return; }
1578 if( rid==0 ) fossil_redirect_home();
1579 if( g.perm.Admin ){
1580 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1581 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1582 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
1583 g.zTop, zUuid);
1584 }else{
1585 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1586 g.zTop, zUuid);
1587 }
@@ -1685,11 +1701,11 @@
1685 rid = name_to_rid_www("name");
1686 if( rid==0 ){ fossil_redirect_home(); }
1687 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1688 if( g.perm.Admin ){
1689 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1690 style_submenu_element("Unshun","Unshun", "%s/shun?uuid=%s&sub=1",
1691 g.zTop, zUuid);
1692 }else{
1693 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1694 g.zTop, zUuid);
1695 }
@@ -2205,38 +2221,38 @@
2205 form_begin(0, "%R/ci_edit");
2206 login_insert_csrf_secret();
2207 @ <div><input type="hidden" name="r" value="%S(zUuid)" />
2208 @ <table border="0" cellspacing="10">
2209
2210 @ <tr><td align="right" valign="top"><b>User:</b></td>
2211 @ <td valign="top">
2212 @ <input type="text" name="u" size="20" value="%h(zNewUser)" />
2213 @ </td></tr>
2214
2215 @ <tr><td align="right" valign="top"><b>Comment:</b></td>
2216 @ <td valign="top">
2217 @ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
2218 @ </td></tr>
2219
2220 @ <tr><td align="right" valign="top"><b>Check-in Time:</b></td>
2221 @ <td valign="top">
2222 @ <input type="text" name="dt" size="20" value="%h(zNewDate)" />
2223 @ </td></tr>
2224
2225 if( zChngTime ){
2226 @ <tr><td align="right" valign="top"><b>Timestamp of this change:</b></td>
2227 @ <td valign="top">
2228 @ <input type="text" name="chngtime" size="20" value="%h(zChngTime)" />
2229 @ </td></tr>
2230 }
2231
2232 @ <tr><td align="right" valign="top"><b>Background Color:</b></td>
2233 @ <td valign="top">
2234 render_color_chooser(fNewPropagateColor, zNewColor, "pclr", "clr", "clrcust");
2235 @ </td></tr>
2236
2237 @ <tr><td align="right" valign="top"><b>Tags:</b></td>
2238 @ <td valign="top">
2239 @ <label><input type="checkbox" id="newtag" name="newtag"%s(zNewTagFlag) />
2240 @ Add the following new tag name to this check-in:</label>
2241 @ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)"
2242 @ onkeyup="gebi('newtag').checked=!!this.value" />
@@ -2265,11 +2281,11 @@
2265 }
2266 }
2267 db_finalize(&q);
2268 @ </td></tr>
2269
2270 @ <tr><td align="right" valign="top"><b>Branching:</b></td>
2271 @ <td valign="top">
2272 @ <label><input id="newbr" type="checkbox" name="newbr"%s(zNewBrFlag) />
2273 @ Make this check-in the start of a new branch named:</label>
2274 @ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)"
2275 @ onkeyup="gebi('newbr').checked=!!this.value" />
@@ -2278,11 +2294,11 @@
2278 if( is_a_leaf(rid)
2279 && !db_exists("SELECT 1 FROM tagxref "
2280 " WHERE tagid=%d AND rid=%d AND tagtype>0",
2281 TAG_CLOSED, rid)
2282 ){
2283 @ <tr><td align="right" valign="top"><b>Leaf Closure:</b></td>
2284 @ <td valign="top">
2285 @ <label><input type="checkbox" name="close"%s(zCloseFlag) />
2286 @ Mark this leaf as "closed" so that it no longer appears on the
2287 @ "leaves" page and is no longer labeled as a "<b>Leaf</b>".</label>
2288 @ </td></tr>
2289
--- src/info.c
+++ src/info.c
@@ -316,25 +316,22 @@
316 blob_zero(&to);
317 }
318 blob_zero(&out);
319 if( diffFlags & DIFF_SIDEBYSIDE ){
320 text_diff(&from, &to, &out, pRe, diffFlags | DIFF_HTML | DIFF_NOTTOOBIG);
 
321 @ %s(blob_str(&out))
 
322 }else{
323 text_diff(&from, &to, &out, pRe,
324 diffFlags | DIFF_LINENO | DIFF_HTML | DIFF_NOTTOOBIG);
325 @ <pre class="udiff">
326 @ %s(blob_str(&out))
327 @ </pre>
328 }
329 blob_reset(&from);
330 blob_reset(&to);
331 blob_reset(&out);
332 }
 
333
334 /*
335 ** Write a line of web-page output that shows changes that have occurred
336 ** to a file between two check-ins.
337 */
@@ -359,13 +356,11 @@
356 @ for %h(zName)</p>
357 }else{
358 @ <p>Changes to %h(zName)</p>
359 }
360 if( diffFlags ){
 
361 append_diff(zOld, zNew, diffFlags, pRe);
 
362 }
363 }else{
364 if( zOld && zNew ){
365 if( fossil_strcmp(zOld, zNew)!=0 ){
366 @ <p>Modified %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
@@ -385,20 +380,51 @@
380 }else{
381 @ <p>Added %z(href("%R/finfo?name=%T",zName))%h(zName)</a>
382 @ version %z(href("%R/artifact/%s",zNew))[%S(zNew)]</a>
383 }
384 if( diffFlags ){
 
385 append_diff(zOld, zNew, diffFlags, pRe);
 
386 }else if( zOld && zNew && fossil_strcmp(zOld,zNew)!=0 ){
387 @ &nbsp;&nbsp;
388 @ %z(href("%R/fdiff?v1=%S&v2=%S&sbs=1",zOld,zNew))[diff]</a>
389 }
 
390 }
391 }
392
393 /*
394 ** Generate javascript to enhance HTML diffs.
395 */
396 void append_diff_javascript(int sideBySide){
397 if( !sideBySide ) return;
398 @ <script>(function(){
399 @ var SCROLL_LEN = 25;
400 @ function initSbsDiff(diff){
401 @ var txtCols = diff.querySelectorAll('.difftxtcol');
402 @ var txtPres = diff.querySelectorAll('.difftxtcol pre');
403 @ var width = Math.max(txtPres[0].scrollWidth, txtPres[1].scrollWidth);
404 @ for(var i=0; i<2; i++){
405 @ txtPres[i].style.width = width + 'px';
406 @ txtCols[i].onscroll = function(e){
407 @ txtCols[0].scrollLeft = txtCols[1].scrollLeft = this.scrollLeft;
408 @ };
409 @ }
410 @ diff.tabIndex = 0;
411 @ diff.onkeydown = function(e){
412 @ e = e || event;
413 @ var len = {37: -SCROLL_LEN, 39: SCROLL_LEN}[e.keyCode];
414 @ if( !len ) return;
415 @ txtCols[0].scrollLeft += len;
416 @ return false;
417 @ };
418 @ }
419 @
420 @ var diffs = document.querySelectorAll('.sbsdiffcols');
421 @ for(var i=0; i<diffs.length; i++){
422 @ initSbsDiff(diffs[i]);
423 @ }
424 @ }())</script>
425 }
426
427 /*
428 ** Construct an appropriate diffFlag for text_diff() based on query
429 ** parameters and the to boolean arguments.
430 */
@@ -675,10 +701,11 @@
701 const char *zOldName = db_column_text(&q, 4);
702 append_file_change_line(zName, zOld, zNew, zOldName, diffFlags,pRe,mperm);
703 }
704 db_finalize(&q);
705 }
706 append_diff_javascript(sideBySide);
707 style_footer();
708 }
709
710 /*
711 ** WEBPAGE: winfo
@@ -988,11 +1015,11 @@
1015 pFileTo = manifest_file_next(pTo, 0);
1016 }
1017 }
1018 manifest_destroy(pFrom);
1019 manifest_destroy(pTo);
1020 append_diff_javascript(sideBySide);
1021 style_footer();
1022 }
1023
1024 #if INTERFACE
1025 /*
@@ -1244,85 +1271,74 @@
1271 */
1272 void diff_page(void){
1273 int v1, v2;
1274 int isPatch;
1275 int sideBySide;
 
1276 char *zV1;
1277 char *zV2;
1278 const char *zRe;
1279 ReCompiled *pRe = 0;
1280 u64 diffFlags;
 
1281
1282 login_check_credentials();
1283 if( !g.perm.Read ){ login_needed(); return; }
1284 v1 = name_to_rid_www("v1");
1285 v2 = name_to_rid_www("v2");
1286 if( v1==0 || v2==0 ) fossil_redirect_home();
1287 zRe = P("regex");
1288 if( zRe ) re_compile(&pRe, zRe, 0);
 
1289 isPatch = P("patch")!=0;
1290 if( isPatch ){
1291 Blob c1, c2, *pOut;
1292 pOut = cgi_output_blob();
1293 cgi_set_content_type("text/plain");
1294 diffFlags = 4;
1295 content_get(v1, &c1);
1296 content_get(v2, &c2);
1297 text_diff(&c1, &c2, pOut, pRe, diffFlags);
1298 blob_reset(&c1);
1299 blob_reset(&c2);
1300 return;
1301 }
1302
1303 sideBySide = !is_false(PD("sbs","1"));
1304 zV1 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v1);
1305 zV2 = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", v2);
1306 diffFlags = construct_diff_flags(1, sideBySide) | DIFF_HTML;
1307
1308 style_header("Diff");
1309 style_submenu_element("Patch", "Patch", "%s/fdiff?v1=%T&v2=%T&patch",
1310 g.zTop, P("v1"), P("v2"));
1311 if( !sideBySide ){
1312 style_submenu_element("Side-by-side Diff", "sbsdiff",
1313 "%s/fdiff?v1=%T&v2=%T&sbs=1",
1314 g.zTop, P("v1"), P("v2"));
1315 }else{
1316 style_submenu_element("Unified Diff", "udiff",
1317 "%s/fdiff?v1=%T&v2=%T&sbs=0",
1318 g.zTop, P("v1"), P("v2"));
1319 }
1320
1321 if( P("smhdr")!=0 ){
1322 @ <h2>Differences From Artifact
1323 @ %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a> To
1324 @ %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>.</h2>
1325 }else{
1326 @ <h2>Differences From
1327 @ Artifact %z(href("%R/artifact/%S",zV1))[%S(zV1)]</a>:</h2>
1328 object_description(v1, 0, 0);
1329 @ <h2>To Artifact %z(href("%R/artifact/%S",zV2))[%S(zV2)]</a>:</h2>
1330 object_description(v2, 0, 0);
1331 }
1332 if( pRe ){
1333 @ <b>Only differences that match regular expression "%h(zRe)"
1334 @ are shown.</b>
1335 }
1336 @ <hr />
1337 append_diff(zV1, zV2, diffFlags, pRe);
1338 append_diff_javascript(sideBySide);
1339 style_footer();
 
 
 
 
 
 
 
 
 
1340 }
1341
1342 /*
1343 ** WEBPAGE: raw
1344 ** URL: /raw?name=ARTIFACTID&m=TYPE
@@ -1427,11 +1443,11 @@
1443 if( !g.perm.Read ){ login_needed(); return; }
1444 if( rid==0 ) fossil_redirect_home();
1445 if( g.perm.Admin ){
1446 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1447 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1448 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#delshun",
1449 g.zTop, zUuid);
1450 }else{
1451 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1452 g.zTop, zUuid);
1453 }
@@ -1577,11 +1593,11 @@
1593 if( !g.perm.Read ){ login_needed(); return; }
1594 if( rid==0 ) fossil_redirect_home();
1595 if( g.perm.Admin ){
1596 const char *zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1597 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1598 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1599 g.zTop, zUuid);
1600 }else{
1601 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1602 g.zTop, zUuid);
1603 }
@@ -1685,11 +1701,11 @@
1701 rid = name_to_rid_www("name");
1702 if( rid==0 ){ fossil_redirect_home(); }
1703 zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
1704 if( g.perm.Admin ){
1705 if( db_exists("SELECT 1 FROM shun WHERE uuid='%s'", zUuid) ){
1706 style_submenu_element("Unshun","Unshun", "%s/shun?accept=%s&sub=1#accshun",
1707 g.zTop, zUuid);
1708 }else{
1709 style_submenu_element("Shun","Shun", "%s/shun?shun=%s#addshun",
1710 g.zTop, zUuid);
1711 }
@@ -2205,38 +2221,38 @@
2221 form_begin(0, "%R/ci_edit");
2222 login_insert_csrf_secret();
2223 @ <div><input type="hidden" name="r" value="%S(zUuid)" />
2224 @ <table border="0" cellspacing="10">
2225
2226 @ <tr><th align="right" valign="top">User:</th>
2227 @ <td valign="top">
2228 @ <input type="text" name="u" size="20" value="%h(zNewUser)" />
2229 @ </td></tr>
2230
2231 @ <tr><th align="right" valign="top">Comment:</th>
2232 @ <td valign="top">
2233 @ <textarea name="c" rows="10" cols="80">%h(zNewComment)</textarea>
2234 @ </td></tr>
2235
2236 @ <tr><th align="right" valign="top">Check-in Time:</th>
2237 @ <td valign="top">
2238 @ <input type="text" name="dt" size="20" value="%h(zNewDate)" />
2239 @ </td></tr>
2240
2241 if( zChngTime ){
2242 @ <tr><th align="right" valign="top">Timestamp of this change:</th>
2243 @ <td valign="top">
2244 @ <input type="text" name="chngtime" size="20" value="%h(zChngTime)" />
2245 @ </td></tr>
2246 }
2247
2248 @ <tr><th align="right" valign="top">Background Color:</th>
2249 @ <td valign="top">
2250 render_color_chooser(fNewPropagateColor, zNewColor, "pclr", "clr", "clrcust");
2251 @ </td></tr>
2252
2253 @ <tr><th align="right" valign="top">Tags:</th>
2254 @ <td valign="top">
2255 @ <label><input type="checkbox" id="newtag" name="newtag"%s(zNewTagFlag) />
2256 @ Add the following new tag name to this check-in:</label>
2257 @ <input type="text" style="width:15;" name="tagname" value="%h(zNewTag)"
2258 @ onkeyup="gebi('newtag').checked=!!this.value" />
@@ -2265,11 +2281,11 @@
2281 }
2282 }
2283 db_finalize(&q);
2284 @ </td></tr>
2285
2286 @ <tr><th align="right" valign="top">Branching:</th>
2287 @ <td valign="top">
2288 @ <label><input id="newbr" type="checkbox" name="newbr"%s(zNewBrFlag) />
2289 @ Make this check-in the start of a new branch named:</label>
2290 @ <input type="text" style="width:15;" name="brname" value="%h(zNewBranch)"
2291 @ onkeyup="gebi('newbr').checked=!!this.value" />
@@ -2278,11 +2294,11 @@
2294 if( is_a_leaf(rid)
2295 && !db_exists("SELECT 1 FROM tagxref "
2296 " WHERE tagid=%d AND rid=%d AND tagtype>0",
2297 TAG_CLOSED, rid)
2298 ){
2299 @ <tr><th align="right" valign="top">Leaf Closure:</th>
2300 @ <td valign="top">
2301 @ <label><input type="checkbox" name="close"%s(zCloseFlag) />
2302 @ Mark this leaf as "closed" so that it no longer appears on the
2303 @ "leaves" page and is no longer labeled as a "<b>Leaf</b>".</label>
2304 @ </td></tr>
2305
--- src/json_status.c
+++ src/json_status.c
@@ -157,10 +157,11 @@
157157
while( db_step(&q)==SQLITE_ROW ){
158158
const char *zLabel = "MERGED_WITH";
159159
switch( db_column_int(&q, 1) ){
160160
case -1: zLabel = "CHERRYPICK "; break;
161161
case -2: zLabel = "BACKOUT "; break;
162
+ case -4: zLabel = "INTEGRATE "; break;
162163
}
163164
blob_append(report, zPrefix, nPrefix);
164165
blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
165166
}
166167
db_finalize(&q);
167168
--- src/json_status.c
+++ src/json_status.c
@@ -157,10 +157,11 @@
157 while( db_step(&q)==SQLITE_ROW ){
158 const char *zLabel = "MERGED_WITH";
159 switch( db_column_int(&q, 1) ){
160 case -1: zLabel = "CHERRYPICK "; break;
161 case -2: zLabel = "BACKOUT "; break;
 
162 }
163 blob_append(report, zPrefix, nPrefix);
164 blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
165 }
166 db_finalize(&q);
167
--- src/json_status.c
+++ src/json_status.c
@@ -157,10 +157,11 @@
157 while( db_step(&q)==SQLITE_ROW ){
158 const char *zLabel = "MERGED_WITH";
159 switch( db_column_int(&q, 1) ){
160 case -1: zLabel = "CHERRYPICK "; break;
161 case -2: zLabel = "BACKOUT "; break;
162 case -4: zLabel = "INTEGRATE "; break;
163 }
164 blob_append(report, zPrefix, nPrefix);
165 blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
166 }
167 db_finalize(&q);
168
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -98,11 +98,11 @@
9898
@ SELECT
9999
@ NULL,
100100
@ blob.rid,
101101
@ uuid,
102102
@ CAST(strftime('%%s',event.mtime) AS INTEGER),
103
- @ datetime(event.mtime,'utc'),
103
+ @ datetime(event.mtime),
104104
@ coalesce(ecomment, comment),
105105
@ coalesce(euser, user),
106106
@ blob.rid IN leaf,
107107
@ bgcolor,
108108
@ event.type,
109109
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -98,11 +98,11 @@
98 @ SELECT
99 @ NULL,
100 @ blob.rid,
101 @ uuid,
102 @ CAST(strftime('%%s',event.mtime) AS INTEGER),
103 @ datetime(event.mtime,'utc'),
104 @ coalesce(ecomment, comment),
105 @ coalesce(euser, user),
106 @ blob.rid IN leaf,
107 @ bgcolor,
108 @ event.type,
109
--- src/json_timeline.c
+++ src/json_timeline.c
@@ -98,11 +98,11 @@
98 @ SELECT
99 @ NULL,
100 @ blob.rid,
101 @ uuid,
102 @ CAST(strftime('%%s',event.mtime) AS INTEGER),
103 @ datetime(event.mtime),
104 @ coalesce(ecomment, comment),
105 @ coalesce(euser, user),
106 @ blob.rid IN leaf,
107 @ bgcolor,
108 @ event.type,
109
--- src/login.c
+++ src/login.c
@@ -1046,10 +1046,11 @@
10461046
** Zeroes out g.perm and calls login_set_capabilities(zCap,flags).
10471047
*/
10481048
void login_replace_capabilities(const char *zCap, unsigned flags){
10491049
memset(&g.perm, 0, sizeof(g.perm));
10501050
login_set_capabilities(zCap, flags);
1051
+ login_anon_once = 1;
10511052
}
10521053
10531054
/*
10541055
** If the current login lacks any of the capabilities listed in
10551056
** the input, then return 0. If all capabilities are present, then
10561057
10571058
ADDED src/lookslike.c
--- src/login.c
+++ src/login.c
@@ -1046,10 +1046,11 @@
1046 ** Zeroes out g.perm and calls login_set_capabilities(zCap,flags).
1047 */
1048 void login_replace_capabilities(const char *zCap, unsigned flags){
1049 memset(&g.perm, 0, sizeof(g.perm));
1050 login_set_capabilities(zCap, flags);
 
1051 }
1052
1053 /*
1054 ** If the current login lacks any of the capabilities listed in
1055 ** the input, then return 0. If all capabilities are present, then
1056
1057 DDED src/lookslike.c
--- src/login.c
+++ src/login.c
@@ -1046,10 +1046,11 @@
1046 ** Zeroes out g.perm and calls login_set_capabilities(zCap,flags).
1047 */
1048 void login_replace_capabilities(const char *zCap, unsigned flags){
1049 memset(&g.perm, 0, sizeof(g.perm));
1050 login_set_capabilities(zCap, flags);
1051 login_anon_once = 1;
1052 }
1053
1054 /*
1055 ** If the current login lacks any of the capabilities listed in
1056 ** the input, then return 0. If all capabilities are present, then
1057
1058 DDED src/lookslike.c
--- a/src/lookslike.c
+++ b/src/lookslike.c
@@ -0,0 +1,119 @@
1
+utf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
2
+
3
+/*
4
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
5
+** to convey status information about the blob content.
6
+*/
7
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
8
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
9
+** high-level check, not intended to be used for any application-level
10
+** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
11
+
12
+/*
13
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
14
+** to convey status information about the blob content.
15
+*/
16
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
17
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
18
+
19
+/*
20
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
21
+** to convey status information about the blob content.
22
+*/
23
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
24
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(cCR tatus i10ormation a02LOOK_BINARY, 0) & LOOK_BI were LOOK_NUL ((int)0x00LONE_CR 20d ") || L(" or ")
25
+ /* ^^^^^ F tatus i10ormation a08/* One or more Nfossil_is were LOOK_NUL ((int)0x00LONE_LF ((int)0x00000010 ")
26
+ /* ^^^^^ no=08ere LOOK_NUL ((/LF paiLF ((int)0x00000010") || L20F ((int)0x00000010") || L("updaten 0;
27
+#define L(GLOB1" andf8() an88((blob), LOO4f8() and looks_like_utf16() routines used
28
+** to 2onvey status i10ormation a8efine LOOK_NONE ((in04#define LOOK_NONE ((int)0x0000000020/* Nothing sp10ial was found. */
29
+#08fine LOOK_NUL ((int)0x00000001) /* One or more N20ssil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0)define LOOK_CR [i+n]!=0&&SQL. This is onlCRLFere LOOK_ne or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
30
+
31
+/*
32
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
33
+** to convey status information about the blob content.
34
+*/
35
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
36
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
37
+
38
+/*
39
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
40
+** to convey status information about the blob content.
41
+*/
42
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
43
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(const char *zTxt){
44
+ if( zTxt==0 || zTxt[0]==0 ) return 0;
45
+#define L(GLOB) 0==sqlite3_strlike("%" GLOB "%",zTxt, '%')
46
+ return L(";") || L("'")
47
+ || L("select") || L("order") || L("drop")
48
+ || L(" and ") || L(" or ")
49
+ /* ^^^^^ noting that \n and \t should also be checked */
50
+ || L("null") || L("delete") || L("update")
51
+ |;<num> Repeatest_looks_like_utflooks_like_utf_testshort *z = (unsigned short1]==0possible UTF-32. */
52
+ if( z[0]z[0]==0xfffeutf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
53
+
54
+/*
55
+** Output flflags |= LOOK_CR;
56
+F | flags |= LOOK_LF; | flags |= LOOK_CR;flags |= LOOK_CR;
57
+F | flags |= LOOK_LF; | flags |= LOOK_CR;f8() and looks_like_utf16() roututf8((blob), LOOKf8() and looks_like_utf16() routines used
58
+** to convey status information about the blob content.
59
+*/
60
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
61
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blobflags |= LOOK_CR;(blob), Lz[i+n]!=0&&SQL. This is only a
62
+** high-level check, not intended to be used for any application-level
63
+** logic other tMore chars, next char is--n>0() and flags |= LOOK_LF; | * to convey status informatiBF LOOK_BINARY) != nformationBF LOOK_BINARY) != LOO((int)0x00000000) /* NothingBF LOOK_BINARY) != int)0x0000BF LOOK_BINARY) != LOOK ((int)0x00000001) /* One BF LOOK_BINARY) != ),flags |= LOOK_CR;
64
+ K_CR CRLFurn 0;
65
+#define L(GLOB) 0=LF (rop")
66
+ || L(" andf8() an88((blob), LOOKf8() and looks_like_utf16() routines used
67
+** to convey status i10ormation about the blob content.
68
+*/
69
+#define LOOK_NONE ((int)0x0000000020More chars, next char is0/* Nothing special was found. */
70
+#define LOOK_NUL , c2;
71
+ if( c2>=0xC0 ){
72
+ *def = &lb_tab[(2*c2)-0x180];
73
+ if( c2>=0xe80 ){
74
+ if( ((c2<0xc2) || (c2>=0xf4) || ((c&0xc0)!=0x80)) &&
75
+ (((c2!=0xf4) || (c>=0x90)) &c = (c2 >= 0xe0) ? (c2<<1)+1 : ' '|flags |= LOOK_CR;
76
+ intended to be used for any application-level
77
+** logic other than in defense against spiders F | flags |= LOOK_LF; | * to convey status informat** to convey status information about the blob content.
78
+*/
79
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
80
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
81
+** high-level check, not intended to be used for any application-level
82
+** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
83
+
84
+/*
85
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
86
+** to convey status information about the blob content.
87
+*/
88
+#define LOOK_NONE ((int)0((blob), LOOK_BINARY, 0) & LO{
89
+ *def || (c> ){
90
+ return 1 }c>=0x8tf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
91
+
92
+/*
93
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
94
+** to convey status information about the blob content.
95
+*/
96
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
97
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
98
+** high-level check, not intended to be used for any application-level
99
+** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
100
+
101
+/*
102
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
103
+** to convey status information about the blob content.
104
+*/
105
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
106
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOKY, 0) & LOOK_BINARY) }utf8((blob), LOOKK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
107
+
108
+/*
109
+** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
110
+** to convey status information about the blob content.
111
+*/
112
+#define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
113
+#define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is o1if( flags&stopFlags ) break;
114
+ n -= sizeof(WCHAR_T);
115
+ if( n< break/*bRevUnicodefUtf16((int)0x00000000) utf8((blob), LOOK_BINARY, 0) & LfUnicode = 0;
116
+ }else{
117
+&bRevUnicode) || fForceUtEF, 0xBB, 0xBFlookFlags = fUnicode ? :
118
+und. */
119
+#define
--- a/src/lookslike.c
+++ b/src/lookslike.c
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
--- a/src/lookslike.c
+++ b/src/lookslike.c
@@ -0,0 +1,119 @@
1 utf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
2
3 /*
4 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
5 ** to convey status information about the blob content.
6 */
7 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
8 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
9 ** high-level check, not intended to be used for any application-level
10 ** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
11
12 /*
13 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
14 ** to convey status information about the blob content.
15 */
16 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
17 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
18
19 /*
20 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
21 ** to convey status information about the blob content.
22 */
23 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
24 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(cCR tatus i10ormation a02LOOK_BINARY, 0) & LOOK_BI were LOOK_NUL ((int)0x00LONE_CR 20d ") || L(" or ")
25 /* ^^^^^ F tatus i10ormation a08/* One or more Nfossil_is were LOOK_NUL ((int)0x00LONE_LF ((int)0x00000010 ")
26 /* ^^^^^ no=08ere LOOK_NUL ((/LF paiLF ((int)0x00000010") || L20F ((int)0x00000010") || L("updaten 0;
27 #define L(GLOB1" andf8() an88((blob), LOO4f8() and looks_like_utf16() routines used
28 ** to 2onvey status i10ormation a8efine LOOK_NONE ((in04#define LOOK_NONE ((int)0x0000000020/* Nothing sp10ial was found. */
29 #08fine LOOK_NUL ((int)0x00000001) /* One or more N20ssil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0)define LOOK_CR [i+n]!=0&&SQL. This is onlCRLFere LOOK_ne or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only aited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
30
31 /*
32 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
33 ** to convey status information about the blob content.
34 */
35 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
36 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), LRY, 0) & LOOK_BINARY) != LOOK_NONE)
37
38 /*
39 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
40 ** to convey status information about the blob content.
41 */
42 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
43 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lmight_be_sql(const char *zTxt){
44 if( zTxt==0 || zTxt[0]==0 ) return 0;
45 #define L(GLOB) 0==sqlite3_strlike("%" GLOB "%",zTxt, '%')
46 return L(";") || L("'")
47 || L("select") || L("order") || L("drop")
48 || L(" and ") || L(" or ")
49 /* ^^^^^ noting that \n and \t should also be checked */
50 || L("null") || L("delete") || L("update")
51 |;<num> Repeatest_looks_like_utflooks_like_utf_testshort *z = (unsigned short1]==0possible UTF-32. */
52 if( z[0]z[0]==0xfffeutf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
53
54 /*
55 ** Output flflags |= LOOK_CR;
56 F | flags |= LOOK_LF; | flags |= LOOK_CR;flags |= LOOK_CR;
57 F | flags |= LOOK_LF; | flags |= LOOK_CR;f8() and looks_like_utf16() roututf8((blob), LOOKf8() and looks_like_utf16() routines used
58 ** to convey status information about the blob content.
59 */
60 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
61 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blobflags |= LOOK_CR;(blob), Lz[i+n]!=0&&SQL. This is only a
62 ** high-level check, not intended to be used for any application-level
63 ** logic other tMore chars, next char is--n>0() and flags |= LOOK_LF; | * to convey status informatiBF LOOK_BINARY) != nformationBF LOOK_BINARY) != LOO((int)0x00000000) /* NothingBF LOOK_BINARY) != int)0x0000BF LOOK_BINARY) != LOOK ((int)0x00000001) /* One BF LOOK_BINARY) != ),flags |= LOOK_CR;
64 K_CR CRLFurn 0;
65 #define L(GLOB) 0=LF (rop")
66 || L(" andf8() an88((blob), LOOKf8() and looks_like_utf16() routines used
67 ** to convey status i10ormation about the blob content.
68 */
69 #define LOOK_NONE ((int)0x0000000020More chars, next char is0/* Nothing special was found. */
70 #define LOOK_NUL , c2;
71 if( c2>=0xC0 ){
72 *def = &lb_tab[(2*c2)-0x180];
73 if( c2>=0xe80 ){
74 if( ((c2<0xc2) || (c2>=0xf4) || ((c&0xc0)!=0x80)) &&
75 (((c2!=0xf4) || (c>=0x90)) &c = (c2 >= 0xe0) ? (c2<<1)+1 : ' '|flags |= LOOK_CR;
76 intended to be used for any application-level
77 ** logic other than in defense against spiders F | flags |= LOOK_LF; | * to convey status informat** to convey status information about the blob content.
78 */
79 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
80 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
81 ** high-level check, not intended to be used for any application-level
82 ** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
83
84 /*
85 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
86 ** to convey status information about the blob content.
87 */
88 #define LOOK_NONE ((int)0((blob), LOOK_BINARY, 0) & LO{
89 *def || (c> ){
90 return 1 }c>=0x8tf8((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
91
92 /*
93 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
94 ** to convey status information about the blob content.
95 */
96 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
97 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is only a
98 ** high-level check, not intended to be used for any application-level
99 ** logic other than in defense against spiders in limited context((blob), LOOK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
100
101 /*
102 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
103 ** to convey status information about the blob content.
104 */
105 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
106 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOKY, 0) & LOOK_BINARY) }utf8((blob), LOOKK_BINARY, 0) & LOOK_BINARY) != LOOK_NONE)
107
108 /*
109 ** Output flags for the looks_like_utf8() and looks_like_utf16() routines used
110 ** to convey status information about the blob content.
111 */
112 #define LOOK_NONE ((int)0x00000000) /* Nothing special was found. */
113 #define LOOK_NUL ((int)0x00000001) /* One or more Nfossil_isalnumne LOOK_NUL ((int)0x00000001) /* One or more Nutf8((blob), Lz[i+n]!=0&&SQL. This is o1if( flags&stopFlags ) break;
114 n -= sizeof(WCHAR_T);
115 if( n< break/*bRevUnicodefUtf16((int)0x00000000) utf8((blob), LOOK_BINARY, 0) & LfUnicode = 0;
116 }else{
117 &bRevUnicode) || fForceUtEF, 0xBB, 0xBFlookFlags = fUnicode ? :
118 und. */
119 #define
+2
--- src/main.c
+++ src/main.c
@@ -159,10 +159,11 @@
159159
int markPrivate; /* All new artifacts are private if true */
160160
int clockSkewSeen; /* True if clocks on client and server out of sync */
161161
int wikiFlags; /* Wiki conversion flags applied to %w and %W */
162162
char isHTTP; /* True if server/CGI modes, else assume CLI. */
163163
char javascriptHyperlink; /* If true, set href= using script, not HTML */
164
+ Blob httpHeader; /* Complete text of the HTTP request header */
164165
165166
int urlIsFile; /* True if a "file:" url */
166167
int urlIsHttps; /* True if a "https:" url */
167168
int urlIsSsh; /* True if an "ssh:" url */
168169
char *urlName; /* Hostname for http: or filename for file: */
@@ -529,10 +530,11 @@
529530
int idx;
530531
int rc;
531532
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
532533
memset(&g, 0, sizeof(g));
533534
g.now = time(0);
535
+ g.httpHeader = empty_blob;
534536
#ifdef FOSSIL_ENABLE_JSON
535537
#if defined(NDEBUG)
536538
g.json.errorDetailParanoia = 2 /* FIXME: make configurable
537539
One problem we have here is that this
538540
code is needed before the db is opened,
539541
--- src/main.c
+++ src/main.c
@@ -159,10 +159,11 @@
159 int markPrivate; /* All new artifacts are private if true */
160 int clockSkewSeen; /* True if clocks on client and server out of sync */
161 int wikiFlags; /* Wiki conversion flags applied to %w and %W */
162 char isHTTP; /* True if server/CGI modes, else assume CLI. */
163 char javascriptHyperlink; /* If true, set href= using script, not HTML */
 
164
165 int urlIsFile; /* True if a "file:" url */
166 int urlIsHttps; /* True if a "https:" url */
167 int urlIsSsh; /* True if an "ssh:" url */
168 char *urlName; /* Hostname for http: or filename for file: */
@@ -529,10 +530,11 @@
529 int idx;
530 int rc;
531 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
532 memset(&g, 0, sizeof(g));
533 g.now = time(0);
 
534 #ifdef FOSSIL_ENABLE_JSON
535 #if defined(NDEBUG)
536 g.json.errorDetailParanoia = 2 /* FIXME: make configurable
537 One problem we have here is that this
538 code is needed before the db is opened,
539
--- src/main.c
+++ src/main.c
@@ -159,10 +159,11 @@
159 int markPrivate; /* All new artifacts are private if true */
160 int clockSkewSeen; /* True if clocks on client and server out of sync */
161 int wikiFlags; /* Wiki conversion flags applied to %w and %W */
162 char isHTTP; /* True if server/CGI modes, else assume CLI. */
163 char javascriptHyperlink; /* If true, set href= using script, not HTML */
164 Blob httpHeader; /* Complete text of the HTTP request header */
165
166 int urlIsFile; /* True if a "file:" url */
167 int urlIsHttps; /* True if a "https:" url */
168 int urlIsSsh; /* True if an "ssh:" url */
169 char *urlName; /* Hostname for http: or filename for file: */
@@ -529,10 +530,11 @@
530 int idx;
531 int rc;
532 sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
533 memset(&g, 0, sizeof(g));
534 g.now = time(0);
535 g.httpHeader = empty_blob;
536 #ifdef FOSSIL_ENABLE_JSON
537 #if defined(NDEBUG)
538 g.json.errorDetailParanoia = 2 /* FIXME: make configurable
539 One problem we have here is that this
540 code is needed before the db is opened,
541
+12 -2
--- src/main.mk
+++ src/main.mk
@@ -67,10 +67,11 @@
6767
$(SRCDIR)/json_timeline.c \
6868
$(SRCDIR)/json_user.c \
6969
$(SRCDIR)/json_wiki.c \
7070
$(SRCDIR)/leaf.c \
7171
$(SRCDIR)/login.c \
72
+ $(SRCDIR)/lookslike.c \
7273
$(SRCDIR)/main.c \
7374
$(SRCDIR)/manifest.c \
7475
$(SRCDIR)/markdown.c \
7576
$(SRCDIR)/markdown_html.c \
7677
$(SRCDIR)/md5.c \
@@ -175,10 +176,11 @@
175176
$(OBJDIR)/json_timeline_.c \
176177
$(OBJDIR)/json_user_.c \
177178
$(OBJDIR)/json_wiki_.c \
178179
$(OBJDIR)/leaf_.c \
179180
$(OBJDIR)/login_.c \
181
+ $(OBJDIR)/lookslike_.c \
180182
$(OBJDIR)/main_.c \
181183
$(OBJDIR)/manifest_.c \
182184
$(OBJDIR)/markdown_.c \
183185
$(OBJDIR)/markdown_html_.c \
184186
$(OBJDIR)/md5_.c \
@@ -283,10 +285,11 @@
283285
$(OBJDIR)/json_timeline.o \
284286
$(OBJDIR)/json_user.o \
285287
$(OBJDIR)/json_wiki.o \
286288
$(OBJDIR)/leaf.o \
287289
$(OBJDIR)/login.o \
290
+ $(OBJDIR)/lookslike.o \
288291
$(OBJDIR)/main.o \
289292
$(OBJDIR)/manifest.o \
290293
$(OBJDIR)/markdown.o \
291294
$(OBJDIR)/markdown_html.o \
292295
$(OBJDIR)/md5.o \
@@ -402,11 +405,11 @@
402405
403406
404407
$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
405408
$(OBJDIR)/mkindex $(TRANS_SRC) >$@
406409
$(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
407
- $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
410
+ $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
408411
touch $(OBJDIR)/headers
409412
$(OBJDIR)/headers: Makefile
410413
$(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
411414
Makefile:
412415
$(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -792,10 +795,17 @@
792795
793796
$(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
794797
$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
795798
796799
$(OBJDIR)/login.h: $(OBJDIR)/headers
800
+$(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
801
+ $(OBJDIR)/translate $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
802
+
803
+$(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
804
+ $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
805
+
806
+$(OBJDIR)/lookslike.h: $(OBJDIR)/headers
797807
$(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
798808
$(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c
799809
800810
$(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
801811
$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c
@@ -1153,11 +1163,11 @@
11531163
$(OBJDIR)/zip.h: $(OBJDIR)/headers
11541164
$(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
11551165
$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
11561166
11571167
$(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1158
- $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
1168
+ $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -Dsqlite3_strglob=strglob -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
11591169
11601170
$(OBJDIR)/th.o: $(SRCDIR)/th.c
11611171
$(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
11621172
11631173
$(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
11641174
--- src/main.mk
+++ src/main.mk
@@ -67,10 +67,11 @@
67 $(SRCDIR)/json_timeline.c \
68 $(SRCDIR)/json_user.c \
69 $(SRCDIR)/json_wiki.c \
70 $(SRCDIR)/leaf.c \
71 $(SRCDIR)/login.c \
 
72 $(SRCDIR)/main.c \
73 $(SRCDIR)/manifest.c \
74 $(SRCDIR)/markdown.c \
75 $(SRCDIR)/markdown_html.c \
76 $(SRCDIR)/md5.c \
@@ -175,10 +176,11 @@
175 $(OBJDIR)/json_timeline_.c \
176 $(OBJDIR)/json_user_.c \
177 $(OBJDIR)/json_wiki_.c \
178 $(OBJDIR)/leaf_.c \
179 $(OBJDIR)/login_.c \
 
180 $(OBJDIR)/main_.c \
181 $(OBJDIR)/manifest_.c \
182 $(OBJDIR)/markdown_.c \
183 $(OBJDIR)/markdown_html_.c \
184 $(OBJDIR)/md5_.c \
@@ -283,10 +285,11 @@
283 $(OBJDIR)/json_timeline.o \
284 $(OBJDIR)/json_user.o \
285 $(OBJDIR)/json_wiki.o \
286 $(OBJDIR)/leaf.o \
287 $(OBJDIR)/login.o \
 
288 $(OBJDIR)/main.o \
289 $(OBJDIR)/manifest.o \
290 $(OBJDIR)/markdown.o \
291 $(OBJDIR)/markdown_html.o \
292 $(OBJDIR)/md5.o \
@@ -402,11 +405,11 @@
402
403
404 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
405 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
406 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
407 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
408 touch $(OBJDIR)/headers
409 $(OBJDIR)/headers: Makefile
410 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
411 Makefile:
412 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -792,10 +795,17 @@
792
793 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
794 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
795
796 $(OBJDIR)/login.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
797 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
798 $(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c
799
800 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
801 $(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c
@@ -1153,11 +1163,11 @@
1153 $(OBJDIR)/zip.h: $(OBJDIR)/headers
1154 $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
1155 $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
1156
1157 $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1158 $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
1159
1160 $(OBJDIR)/th.o: $(SRCDIR)/th.c
1161 $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
1162
1163 $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
1164
--- src/main.mk
+++ src/main.mk
@@ -67,10 +67,11 @@
67 $(SRCDIR)/json_timeline.c \
68 $(SRCDIR)/json_user.c \
69 $(SRCDIR)/json_wiki.c \
70 $(SRCDIR)/leaf.c \
71 $(SRCDIR)/login.c \
72 $(SRCDIR)/lookslike.c \
73 $(SRCDIR)/main.c \
74 $(SRCDIR)/manifest.c \
75 $(SRCDIR)/markdown.c \
76 $(SRCDIR)/markdown_html.c \
77 $(SRCDIR)/md5.c \
@@ -175,10 +176,11 @@
176 $(OBJDIR)/json_timeline_.c \
177 $(OBJDIR)/json_user_.c \
178 $(OBJDIR)/json_wiki_.c \
179 $(OBJDIR)/leaf_.c \
180 $(OBJDIR)/login_.c \
181 $(OBJDIR)/lookslike_.c \
182 $(OBJDIR)/main_.c \
183 $(OBJDIR)/manifest_.c \
184 $(OBJDIR)/markdown_.c \
185 $(OBJDIR)/markdown_html_.c \
186 $(OBJDIR)/md5_.c \
@@ -283,10 +285,11 @@
285 $(OBJDIR)/json_timeline.o \
286 $(OBJDIR)/json_user.o \
287 $(OBJDIR)/json_wiki.o \
288 $(OBJDIR)/leaf.o \
289 $(OBJDIR)/login.o \
290 $(OBJDIR)/lookslike.o \
291 $(OBJDIR)/main.o \
292 $(OBJDIR)/manifest.o \
293 $(OBJDIR)/markdown.o \
294 $(OBJDIR)/markdown_html.o \
295 $(OBJDIR)/md5.o \
@@ -402,11 +405,11 @@
405
406
407 $(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
408 $(OBJDIR)/mkindex $(TRANS_SRC) >$@
409 $(OBJDIR)/headers: $(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
410 $(OBJDIR)/makeheaders $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/json_.c:$(OBJDIR)/json.h $(OBJDIR)/json_artifact_.c:$(OBJDIR)/json_artifact.h $(OBJDIR)/json_branch_.c:$(OBJDIR)/json_branch.h $(OBJDIR)/json_config_.c:$(OBJDIR)/json_config.h $(OBJDIR)/json_diff_.c:$(OBJDIR)/json_diff.h $(OBJDIR)/json_dir_.c:$(OBJDIR)/json_dir.h $(OBJDIR)/json_finfo_.c:$(OBJDIR)/json_finfo.h $(OBJDIR)/json_login_.c:$(OBJDIR)/json_login.h $(OBJDIR)/json_query_.c:$(OBJDIR)/json_query.h $(OBJDIR)/json_report_.c:$(OBJDIR)/json_report.h $(OBJDIR)/json_status_.c:$(OBJDIR)/json_status.h $(OBJDIR)/json_tag_.c:$(OBJDIR)/json_tag.h $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/unicode_.c:$(OBJDIR)/unicode.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/utf8_.c:$(OBJDIR)/utf8.h $(OBJDIR)/util_.c:$(OBJDIR)/util.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/wysiwyg_.c:$(OBJDIR)/wysiwyg.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
411 touch $(OBJDIR)/headers
412 $(OBJDIR)/headers: Makefile
413 $(OBJDIR)/json.o $(OBJDIR)/json_artifact.o $(OBJDIR)/json_branch.o $(OBJDIR)/json_config.o $(OBJDIR)/json_diff.o $(OBJDIR)/json_dir.o $(OBJDIR)/json_finfo.o $(OBJDIR)/json_login.o $(OBJDIR)/json_query.o $(OBJDIR)/json_report.o $(OBJDIR)/json_status.o $(OBJDIR)/json_tag.o $(OBJDIR)/json_timeline.o $(OBJDIR)/json_user.o $(OBJDIR)/json_wiki.o : $(SRCDIR)/json_detail.h
414 Makefile:
415 $(OBJDIR)/add_.c: $(SRCDIR)/add.c $(OBJDIR)/translate
@@ -792,10 +795,17 @@
795
796 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
797 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
798
799 $(OBJDIR)/login.h: $(OBJDIR)/headers
800 $(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
801 $(OBJDIR)/translate $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
802
803 $(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
804 $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
805
806 $(OBJDIR)/lookslike.h: $(OBJDIR)/headers
807 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
808 $(OBJDIR)/translate $(SRCDIR)/main.c >$(OBJDIR)/main_.c
809
810 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
811 $(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c
@@ -1153,11 +1163,11 @@
1163 $(OBJDIR)/zip.h: $(OBJDIR)/headers
1164 $(OBJDIR)/sqlite3.o: $(SRCDIR)/sqlite3.c
1165 $(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o
1166
1167 $(OBJDIR)/shell.o: $(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
1168 $(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -Dsqlite3_strglob=strglob -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o
1169
1170 $(OBJDIR)/th.o: $(SRCDIR)/th.c
1171 $(XTCC) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o
1172
1173 $(OBJDIR)/th_lang.o: $(SRCDIR)/th_lang.c
1174
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -70,10 +70,11 @@
7070
json_timeline
7171
json_user
7272
json_wiki
7373
leaf
7474
login
75
+ lookslike
7576
main
7677
manifest
7778
markdown
7879
markdown_html
7980
md5
@@ -296,10 +297,11 @@
296297
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
297298
298299
writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
299300
set opt {-Dmain=sqlite3_shell}
300301
append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
302
+append opt " -Dsqlite3_strglob=strglob"
301303
writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
302304
303305
writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
304306
writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
305307
306308
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -70,10 +70,11 @@
70 json_timeline
71 json_user
72 json_wiki
73 leaf
74 login
 
75 main
76 manifest
77 markdown
78 markdown_html
79 md5
@@ -296,10 +297,11 @@
296 writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
297
298 writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
299 set opt {-Dmain=sqlite3_shell}
300 append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
 
301 writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
302
303 writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
304 writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
305
306
--- src/makemake.tcl
+++ src/makemake.tcl
@@ -70,10 +70,11 @@
70 json_timeline
71 json_user
72 json_wiki
73 leaf
74 login
75 lookslike
76 main
77 manifest
78 markdown
79 markdown_html
80 md5
@@ -296,10 +297,11 @@
297 writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/sqlite3.c -o \$(OBJDIR)/sqlite3.o\n"
298
299 writeln "\$(OBJDIR)/shell.o:\t\$(SRCDIR)/shell.c \$(SRCDIR)/sqlite3.h"
300 set opt {-Dmain=sqlite3_shell}
301 append opt " -DSQLITE_OMIT_LOAD_EXTENSION=1"
302 append opt " -Dsqlite3_strglob=strglob"
303 writeln "\t\$(XTCC) $opt -c \$(SRCDIR)/shell.c -o \$(OBJDIR)/shell.o\n"
304
305 writeln "\$(OBJDIR)/th.o:\t\$(SRCDIR)/th.c"
306 writeln "\t\$(XTCC) -c \$(SRCDIR)/th.c -o \$(OBJDIR)/th.o\n"
307
308
+20 -7
--- src/merge.c
+++ src/merge.c
@@ -91,19 +91,22 @@
9191
** files whose names differ only in case are taken
9292
** to be the same file.
9393
**
9494
** -f|--force Force the merge even if it would be a no-op.
9595
**
96
+** --integrate Merged branch will be closed when committing.
97
+**
9698
** -n|--dry-run If given, display instead of run actions
9799
**
98100
** -v|--verbose Show additional details of the merge
99101
*/
100102
void merge_cmd(void){
101103
int vid; /* Current version "V" */
102104
int mid; /* Version we are merging from "M" */
103105
int pid; /* The pivot version - most recent common ancestor P */
104106
int verboseFlag; /* True if the -v|--verbose option is present */
107
+ int integrateFlag; /* True if the --integrate option is present */
105108
int pickFlag; /* True if the --cherrypick option is present */
106109
int backoutFlag; /* True if the --backout option is present */
107110
int dryRunFlag; /* True if the --dry-run or -n option is present */
108111
int forceFlag; /* True if the --force or -f option is present */
109112
const char *zBinGlob; /* The value of --binary */
@@ -128,10 +131,11 @@
128131
verboseFlag = find_option("verbose","v",0)!=0;
129132
if( !verboseFlag ){
130133
verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
131134
}
132135
pickFlag = find_option("cherrypick",0,0)!=0;
136
+ integrateFlag = find_option("integrate",0,0)!=0;
133137
backoutFlag = find_option("backout",0,0)!=0;
134138
debugFlag = find_option("debug",0,0)!=0;
135139
zBinGlob = find_option("binary",0,1);
136140
dryRunFlag = find_option("dry-run","n",0)!=0;
137141
if( !dryRunFlag ){
@@ -162,12 +166,12 @@
162166
** has not already been merged into the current checkout and (3)
163167
** the leaf is not closed and (4) the leaf is in the same branch
164168
** as the current checkout.
165169
*/
166170
Stmt q;
167
- if( pickFlag || backoutFlag ){
168
- fossil_fatal("cannot use --cherrypick or --backout with a fork merge");
171
+ if( pickFlag || backoutFlag || integrateFlag){
172
+ fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge");
169173
}
170174
mid = db_int(0,
171175
"SELECT leaf.rid"
172176
" FROM leaf, event"
173177
" WHERE leaf.rid=event.objid"
@@ -220,10 +224,13 @@
220224
}
221225
if( pickFlag ){
222226
fossil_fatal("incompatible options: --cherrypick & --baseline");
223227
}
224228
}else if( pickFlag || backoutFlag ){
229
+ if( integrateFlag ){
230
+ fossil_fatal("incompatible options: --integrate & --cherrypick or --backout");
231
+ }
225232
pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
226233
if( pid<=0 ){
227234
fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
228235
}
229236
}else{
@@ -251,12 +258,16 @@
251258
if( !forceFlag && mid==pid ){
252259
fossil_print("Merge skipped because it is a no-op. "
253260
" Use --force to override.\n");
254261
return;
255262
}
263
+ if( integrateFlag && !is_a_leaf(mid) ){
264
+ fossil_warning("ignoring --integrate: %s is not a leaf", g.argv[2]);
265
+ integrateFlag = 0;
266
+ }
256267
if( verboseFlag ){
257
- print_checkin_description(mid, 12, "merge-from:");
268
+ print_checkin_description(mid, 12, integrateFlag?"integrate:":"merge-from:");
258269
print_checkin_description(pid, 12, "baseline:");
259270
}
260271
vfile_check_signature(vid, CKSIG_ENOTFILE);
261272
db_begin_transaction();
262273
if( !dryRunFlag ) undo_begin();
@@ -434,12 +445,12 @@
434445
int idv;
435446
const char *zName;
436447
char *zFullName;
437448
db_multi_exec(
438449
"INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
439
- " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
440
- vid, idm
450
+ " SELECT %d,%d,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
451
+ vid, integrateFlag?5:3, idm
441452
);
442453
idv = db_last_insert_rowid();
443454
db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
444455
zName = db_column_text(&q, 2);
445456
zFullName = mprintf("%s%s", g.zLocalRoot, zName);
@@ -474,12 +485,12 @@
474485
/* Copy content from idm over into idv. Overwrite idv. */
475486
fossil_print("UPDATE %s\n", zName);
476487
if( !dryRunFlag ){
477488
undo_save(zName);
478489
db_multi_exec(
479
- "UPDATE vfile SET mtime=0, mrid=%d, chnged=2, islink=%d "
480
- " WHERE id=%d", ridm, islinkm, idv
490
+ "UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d "
491
+ " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, idv
481492
);
482493
vfile_to_disk(0, idv, 0, 0);
483494
}
484495
}
485496
db_finalize(&q);
@@ -644,11 +655,13 @@
644655
" WHERE type='ci' AND objid=%d",
645656
mid
646657
);
647658
}else if( backoutFlag ){
648659
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);
660
+ }else if( integrateFlag ){
661
+ db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-4,%d)",mid);
649662
}else{
650663
db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
651664
}
652665
undo_finish();
653666
db_end_transaction(dryRunFlag);
654667
}
655668
--- src/merge.c
+++ src/merge.c
@@ -91,19 +91,22 @@
91 ** files whose names differ only in case are taken
92 ** to be the same file.
93 **
94 ** -f|--force Force the merge even if it would be a no-op.
95 **
 
 
96 ** -n|--dry-run If given, display instead of run actions
97 **
98 ** -v|--verbose Show additional details of the merge
99 */
100 void merge_cmd(void){
101 int vid; /* Current version "V" */
102 int mid; /* Version we are merging from "M" */
103 int pid; /* The pivot version - most recent common ancestor P */
104 int verboseFlag; /* True if the -v|--verbose option is present */
 
105 int pickFlag; /* True if the --cherrypick option is present */
106 int backoutFlag; /* True if the --backout option is present */
107 int dryRunFlag; /* True if the --dry-run or -n option is present */
108 int forceFlag; /* True if the --force or -f option is present */
109 const char *zBinGlob; /* The value of --binary */
@@ -128,10 +131,11 @@
128 verboseFlag = find_option("verbose","v",0)!=0;
129 if( !verboseFlag ){
130 verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
131 }
132 pickFlag = find_option("cherrypick",0,0)!=0;
 
133 backoutFlag = find_option("backout",0,0)!=0;
134 debugFlag = find_option("debug",0,0)!=0;
135 zBinGlob = find_option("binary",0,1);
136 dryRunFlag = find_option("dry-run","n",0)!=0;
137 if( !dryRunFlag ){
@@ -162,12 +166,12 @@
162 ** has not already been merged into the current checkout and (3)
163 ** the leaf is not closed and (4) the leaf is in the same branch
164 ** as the current checkout.
165 */
166 Stmt q;
167 if( pickFlag || backoutFlag ){
168 fossil_fatal("cannot use --cherrypick or --backout with a fork merge");
169 }
170 mid = db_int(0,
171 "SELECT leaf.rid"
172 " FROM leaf, event"
173 " WHERE leaf.rid=event.objid"
@@ -220,10 +224,13 @@
220 }
221 if( pickFlag ){
222 fossil_fatal("incompatible options: --cherrypick & --baseline");
223 }
224 }else if( pickFlag || backoutFlag ){
 
 
 
225 pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
226 if( pid<=0 ){
227 fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
228 }
229 }else{
@@ -251,12 +258,16 @@
251 if( !forceFlag && mid==pid ){
252 fossil_print("Merge skipped because it is a no-op. "
253 " Use --force to override.\n");
254 return;
255 }
 
 
 
 
256 if( verboseFlag ){
257 print_checkin_description(mid, 12, "merge-from:");
258 print_checkin_description(pid, 12, "baseline:");
259 }
260 vfile_check_signature(vid, CKSIG_ENOTFILE);
261 db_begin_transaction();
262 if( !dryRunFlag ) undo_begin();
@@ -434,12 +445,12 @@
434 int idv;
435 const char *zName;
436 char *zFullName;
437 db_multi_exec(
438 "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
439 " SELECT %d,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
440 vid, idm
441 );
442 idv = db_last_insert_rowid();
443 db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
444 zName = db_column_text(&q, 2);
445 zFullName = mprintf("%s%s", g.zLocalRoot, zName);
@@ -474,12 +485,12 @@
474 /* Copy content from idm over into idv. Overwrite idv. */
475 fossil_print("UPDATE %s\n", zName);
476 if( !dryRunFlag ){
477 undo_save(zName);
478 db_multi_exec(
479 "UPDATE vfile SET mtime=0, mrid=%d, chnged=2, islink=%d "
480 " WHERE id=%d", ridm, islinkm, idv
481 );
482 vfile_to_disk(0, idv, 0, 0);
483 }
484 }
485 db_finalize(&q);
@@ -644,11 +655,13 @@
644 " WHERE type='ci' AND objid=%d",
645 mid
646 );
647 }else if( backoutFlag ){
648 db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);
 
 
649 }else{
650 db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
651 }
652 undo_finish();
653 db_end_transaction(dryRunFlag);
654 }
655
--- src/merge.c
+++ src/merge.c
@@ -91,19 +91,22 @@
91 ** files whose names differ only in case are taken
92 ** to be the same file.
93 **
94 ** -f|--force Force the merge even if it would be a no-op.
95 **
96 ** --integrate Merged branch will be closed when committing.
97 **
98 ** -n|--dry-run If given, display instead of run actions
99 **
100 ** -v|--verbose Show additional details of the merge
101 */
102 void merge_cmd(void){
103 int vid; /* Current version "V" */
104 int mid; /* Version we are merging from "M" */
105 int pid; /* The pivot version - most recent common ancestor P */
106 int verboseFlag; /* True if the -v|--verbose option is present */
107 int integrateFlag; /* True if the --integrate option is present */
108 int pickFlag; /* True if the --cherrypick option is present */
109 int backoutFlag; /* True if the --backout option is present */
110 int dryRunFlag; /* True if the --dry-run or -n option is present */
111 int forceFlag; /* True if the --force or -f option is present */
112 const char *zBinGlob; /* The value of --binary */
@@ -128,10 +131,11 @@
131 verboseFlag = find_option("verbose","v",0)!=0;
132 if( !verboseFlag ){
133 verboseFlag = find_option("detail",0,0)!=0; /* deprecated */
134 }
135 pickFlag = find_option("cherrypick",0,0)!=0;
136 integrateFlag = find_option("integrate",0,0)!=0;
137 backoutFlag = find_option("backout",0,0)!=0;
138 debugFlag = find_option("debug",0,0)!=0;
139 zBinGlob = find_option("binary",0,1);
140 dryRunFlag = find_option("dry-run","n",0)!=0;
141 if( !dryRunFlag ){
@@ -162,12 +166,12 @@
166 ** has not already been merged into the current checkout and (3)
167 ** the leaf is not closed and (4) the leaf is in the same branch
168 ** as the current checkout.
169 */
170 Stmt q;
171 if( pickFlag || backoutFlag || integrateFlag){
172 fossil_fatal("cannot use --backout, --cherrypick or --integrate with a fork merge");
173 }
174 mid = db_int(0,
175 "SELECT leaf.rid"
176 " FROM leaf, event"
177 " WHERE leaf.rid=event.objid"
@@ -220,10 +224,13 @@
224 }
225 if( pickFlag ){
226 fossil_fatal("incompatible options: --cherrypick & --baseline");
227 }
228 }else if( pickFlag || backoutFlag ){
229 if( integrateFlag ){
230 fossil_fatal("incompatible options: --integrate & --cherrypick or --backout");
231 }
232 pid = db_int(0, "SELECT pid FROM plink WHERE cid=%d AND isprim", mid);
233 if( pid<=0 ){
234 fossil_fatal("cannot find an ancestor for %s", g.argv[2]);
235 }
236 }else{
@@ -251,12 +258,16 @@
258 if( !forceFlag && mid==pid ){
259 fossil_print("Merge skipped because it is a no-op. "
260 " Use --force to override.\n");
261 return;
262 }
263 if( integrateFlag && !is_a_leaf(mid) ){
264 fossil_warning("ignoring --integrate: %s is not a leaf", g.argv[2]);
265 integrateFlag = 0;
266 }
267 if( verboseFlag ){
268 print_checkin_description(mid, 12, integrateFlag?"integrate:":"merge-from:");
269 print_checkin_description(pid, 12, "baseline:");
270 }
271 vfile_check_signature(vid, CKSIG_ENOTFILE);
272 db_begin_transaction();
273 if( !dryRunFlag ) undo_begin();
@@ -434,12 +445,12 @@
445 int idv;
446 const char *zName;
447 char *zFullName;
448 db_multi_exec(
449 "INSERT INTO vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname)"
450 " SELECT %d,%d,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=%d",
451 vid, integrateFlag?5:3, idm
452 );
453 idv = db_last_insert_rowid();
454 db_multi_exec("UPDATE fv SET idv=%d WHERE rowid=%d", idv, rowid);
455 zName = db_column_text(&q, 2);
456 zFullName = mprintf("%s%s", g.zLocalRoot, zName);
@@ -474,12 +485,12 @@
485 /* Copy content from idm over into idv. Overwrite idv. */
486 fossil_print("UPDATE %s\n", zName);
487 if( !dryRunFlag ){
488 undo_save(zName);
489 db_multi_exec(
490 "UPDATE vfile SET mtime=0, mrid=%d, chnged=%d, islink=%d "
491 " WHERE id=%d", ridm, integrateFlag?4:2, islinkm, idv
492 );
493 vfile_to_disk(0, idv, 0, 0);
494 }
495 }
496 db_finalize(&q);
@@ -644,11 +655,13 @@
655 " WHERE type='ci' AND objid=%d",
656 mid
657 );
658 }else if( backoutFlag ){
659 db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-2,%d)",pid);
660 }else if( integrateFlag ){
661 db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(-4,%d)",mid);
662 }else{
663 db_multi_exec("INSERT OR IGNORE INTO vmerge(id,merge) VALUES(0,%d)", mid);
664 }
665 undo_finish();
666 db_end_transaction(dryRunFlag);
667 }
668
+23 -4
--- src/merge3.c
+++ src/merge3.c
@@ -340,16 +340,35 @@
340340
blob_reset(&file);
341341
return rc;
342342
}
343343
344344
/*
345
-** COMMAND: test-3-way-merge
345
+** COMMAND: 3-way-merge*
346
+**
347
+** Usage: %fossil 3-way-merge BASELINE V1 V2 MERGED
348
+**
349
+** Inputs are files BASELINE, V1, and V2. The file MERGED is generated
350
+** as output.
351
+**
352
+** BASELINE is a common ancestor of two files V1 and V2 that have diverging
353
+** edits. The generated output file MERGED is the combination of all
354
+** changes in both V1 and V2.
355
+**
356
+** This command has no effect on the Fossil repository. It is a utility
357
+** command made available for the convenience of users. This command can
358
+** be used, for example, to help import changes from an upstream project.
346359
**
347
-** Usage: %fossil test-3-way-merge PIVOT V1 V2 MERGED
360
+** Suppose an upstream project has a file named "Xup.c" which is imported
361
+** with modifications to the local project as "Xlocal.c". Suppose further
362
+** that the "Xbase.c" is an exact copy of the last imported "Xup.c".
363
+** Then to import the latest "Xup.c" while preserving all the local changes:
348364
**
349
-** Combine change in going from PIVOT->VERSION1 with the change going
350
-** from PIVOT->VERSION2 and write the combined changes into MERGED.
365
+** fossil 3-way-merge Xbase.c Xlocal.c Xup.c Xlocal.c
366
+** cp Xup.c Xbase.c
367
+** # Verify that everything still works
368
+** fossil commit
369
+**
351370
*/
352371
void delta_3waymerge_cmd(void){
353372
Blob pivot, v1, v2, merged;
354373
if( g.argc!=6 ){
355374
usage("PIVOT V1 V2 MERGED");
356375
--- src/merge3.c
+++ src/merge3.c
@@ -340,16 +340,35 @@
340 blob_reset(&file);
341 return rc;
342 }
343
344 /*
345 ** COMMAND: test-3-way-merge
 
 
 
 
 
 
 
 
 
 
 
 
 
346 **
347 ** Usage: %fossil test-3-way-merge PIVOT V1 V2 MERGED
 
 
 
348 **
349 ** Combine change in going from PIVOT->VERSION1 with the change going
350 ** from PIVOT->VERSION2 and write the combined changes into MERGED.
 
 
 
351 */
352 void delta_3waymerge_cmd(void){
353 Blob pivot, v1, v2, merged;
354 if( g.argc!=6 ){
355 usage("PIVOT V1 V2 MERGED");
356
--- src/merge3.c
+++ src/merge3.c
@@ -340,16 +340,35 @@
340 blob_reset(&file);
341 return rc;
342 }
343
344 /*
345 ** COMMAND: 3-way-merge*
346 **
347 ** Usage: %fossil 3-way-merge BASELINE V1 V2 MERGED
348 **
349 ** Inputs are files BASELINE, V1, and V2. The file MERGED is generated
350 ** as output.
351 **
352 ** BASELINE is a common ancestor of two files V1 and V2 that have diverging
353 ** edits. The generated output file MERGED is the combination of all
354 ** changes in both V1 and V2.
355 **
356 ** This command has no effect on the Fossil repository. It is a utility
357 ** command made available for the convenience of users. This command can
358 ** be used, for example, to help import changes from an upstream project.
359 **
360 ** Suppose an upstream project has a file named "Xup.c" which is imported
361 ** with modifications to the local project as "Xlocal.c". Suppose further
362 ** that the "Xbase.c" is an exact copy of the last imported "Xup.c".
363 ** Then to import the latest "Xup.c" while preserving all the local changes:
364 **
365 ** fossil 3-way-merge Xbase.c Xlocal.c Xup.c Xlocal.c
366 ** cp Xup.c Xbase.c
367 ** # Verify that everything still works
368 ** fossil commit
369 **
370 */
371 void delta_3waymerge_cmd(void){
372 Blob pivot, v1, v2, merged;
373 if( g.argc!=6 ){
374 usage("PIVOT V1 V2 MERGED");
375
+11 -10
--- src/schema.c
+++ src/schema.c
@@ -475,25 +475,25 @@
475475
@ --
476476
@ -- The file.rid field is 0 for files or folders that have been
477477
@ -- added but not yet committed.
478478
@ --
479479
@ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
480
-@ -- been edited or which have been subjected to a 3-way merge.
480
+@ -- been edited or which have been subjected to a 3-way merge.
481481
@ -- Vfile.chnged is 2 if the file has been replaced from a different
482482
@ -- version by the merge and 3 if the file has been added by a merge.
483
-@ -- The difference between vfile.chnged==2 and a regular add is that
484
-@ -- with vfile.chnged==2 we know that the current version of the file
485
-@ -- is already in the repository.
486
-@ --
483
+@ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been
484
+@ -- done by an --integrate merge. The difference between vfile.chnged==2|4
485
+@ -- and a regular add is that with vfile.chnged==2|4 we know that the
486
+@ -- current version of the file is already in the repository.
487487
@ --
488488
@ CREATE TABLE vfile(
489489
@ id INTEGER PRIMARY KEY, -- ID of the checked out file
490490
@ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
491
-@ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
492
-@ deleted BOOLEAN DEFAULT 0, -- True if deleted
491
+@ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add
492
+@ deleted BOOLEAN DEFAULT 0, -- True if deleted
493493
@ isexe BOOLEAN, -- True if file should be executable
494
-@ islink BOOLEAN, -- True if file should be symlink
494
+@ islink BOOLEAN, -- True if file should be symlink
495495
@ rid INTEGER, -- Originally from this repository record
496496
@ mrid INTEGER, -- Based on this record due to a merge
497497
@ mtime INTEGER, -- Mtime of file on disk. sec since 1970
498498
@ pathname TEXT, -- Full pathname relative to root
499499
@ origname TEXT, -- Original pathname. NULL if unchanged
@@ -502,12 +502,13 @@
502502
@
503503
@ -- This table holds a record of uncommitted merges in the local
504504
@ -- file tree. If a VFILE entry with id has merged with another
505505
@ -- record, there is an entry in this table with (id,merge) where
506506
@ -- merge is the RECORD table entry that the file merged against.
507
-@ -- An id of 0 here means the version record itself. When id==(-1)
508
-@ -- that is a cherrypick merge and id==(-2) is a backout merge.
507
+@ -- An id of 0 or <-3 here means the version record itself. When
508
+@ -- id==(-1) that is a cherrypick merge, id==(-2) that is a
509
+@ -- backout merge and id==(-4) is a integrate merge.
509510
@
510511
@ CREATE TABLE vmerge(
511512
@ id INTEGER REFERENCES vfile, -- VFILE entry that has been merged
512513
@ merge INTEGER, -- Merged with this record
513514
@ UNIQUE(id, merge)
514515
--- src/schema.c
+++ src/schema.c
@@ -475,25 +475,25 @@
475 @ --
476 @ -- The file.rid field is 0 for files or folders that have been
477 @ -- added but not yet committed.
478 @ --
479 @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
480 @ -- been edited or which have been subjected to a 3-way merge.
481 @ -- Vfile.chnged is 2 if the file has been replaced from a different
482 @ -- version by the merge and 3 if the file has been added by a merge.
483 @ -- The difference between vfile.chnged==2 and a regular add is that
484 @ -- with vfile.chnged==2 we know that the current version of the file
485 @ -- is already in the repository.
486 @ --
487 @ --
488 @ CREATE TABLE vfile(
489 @ id INTEGER PRIMARY KEY, -- ID of the checked out file
490 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
491 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add
492 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
493 @ isexe BOOLEAN, -- True if file should be executable
494 @ islink BOOLEAN, -- True if file should be symlink
495 @ rid INTEGER, -- Originally from this repository record
496 @ mrid INTEGER, -- Based on this record due to a merge
497 @ mtime INTEGER, -- Mtime of file on disk. sec since 1970
498 @ pathname TEXT, -- Full pathname relative to root
499 @ origname TEXT, -- Original pathname. NULL if unchanged
@@ -502,12 +502,13 @@
502 @
503 @ -- This table holds a record of uncommitted merges in the local
504 @ -- file tree. If a VFILE entry with id has merged with another
505 @ -- record, there is an entry in this table with (id,merge) where
506 @ -- merge is the RECORD table entry that the file merged against.
507 @ -- An id of 0 here means the version record itself. When id==(-1)
508 @ -- that is a cherrypick merge and id==(-2) is a backout merge.
 
509 @
510 @ CREATE TABLE vmerge(
511 @ id INTEGER REFERENCES vfile, -- VFILE entry that has been merged
512 @ merge INTEGER, -- Merged with this record
513 @ UNIQUE(id, merge)
514
--- src/schema.c
+++ src/schema.c
@@ -475,25 +475,25 @@
475 @ --
476 @ -- The file.rid field is 0 for files or folders that have been
477 @ -- added but not yet committed.
478 @ --
479 @ -- Vfile.chnged is 0 for unmodified files, 1 for files that have
480 @ -- been edited or which have been subjected to a 3-way merge.
481 @ -- Vfile.chnged is 2 if the file has been replaced from a different
482 @ -- version by the merge and 3 if the file has been added by a merge.
483 @ -- Vfile.chnged is 4|5 is the same as 2|3, but the operation has been
484 @ -- done by an --integrate merge. The difference between vfile.chnged==2|4
485 @ -- and a regular add is that with vfile.chnged==2|4 we know that the
486 @ -- current version of the file is already in the repository.
487 @ --
488 @ CREATE TABLE vfile(
489 @ id INTEGER PRIMARY KEY, -- ID of the checked out file
490 @ vid INTEGER REFERENCES blob, -- The baseline this file is part of.
491 @ chnged INT DEFAULT 0, -- 0:unchnged 1:edited 2:m-chng 3:m-add 4:i-chng 5:i-add
492 @ deleted BOOLEAN DEFAULT 0, -- True if deleted
493 @ isexe BOOLEAN, -- True if file should be executable
494 @ islink BOOLEAN, -- True if file should be symlink
495 @ rid INTEGER, -- Originally from this repository record
496 @ mrid INTEGER, -- Based on this record due to a merge
497 @ mtime INTEGER, -- Mtime of file on disk. sec since 1970
498 @ pathname TEXT, -- Full pathname relative to root
499 @ origname TEXT, -- Original pathname. NULL if unchanged
@@ -502,12 +502,13 @@
502 @
503 @ -- This table holds a record of uncommitted merges in the local
504 @ -- file tree. If a VFILE entry with id has merged with another
505 @ -- record, there is an entry in this table with (id,merge) where
506 @ -- merge is the RECORD table entry that the file merged against.
507 @ -- An id of 0 or <-3 here means the version record itself. When
508 @ -- id==(-1) that is a cherrypick merge, id==(-2) that is a
509 @ -- backout merge and id==(-4) is a integrate merge.
510 @
511 @ CREATE TABLE vmerge(
512 @ id INTEGER REFERENCES vfile, -- VFILE entry that has been merged
513 @ merge INTEGER, -- Merged with this record
514 @ UNIQUE(id, merge)
515
+29 -7
--- src/search.c
+++ src/search.c
@@ -166,20 +166,35 @@
166166
167167
/*
168168
** Testing the search function.
169169
**
170170
** COMMAND: search*
171
-** %fossil search pattern...
171
+** %fossil search [-all|-a] [-limit|-n #] pattern...
172
+**
173
+** Search for timeline entries matching all words
174
+** provided on the command line. Whole-word matches
175
+** scope more highly than partial matches.
172176
**
173
-** Search for timeline entries matching the pattern.
177
+** Outputs, by default, some top-N fraction of the
178
+** results. The -all option can be used to output
179
+** all matches, regardless of their search score.
180
+** -limit can be used to limit the number of entries
181
+** returned.
174182
*/
175183
void search_cmd(void){
176184
Search *p;
177185
Blob pattern;
178186
int i;
187
+ Blob sql = empty_blob;
179188
Stmt q;
180189
int iBest;
190
+ char fAll = NULL != find_option("all", "a", 0); /* If set, do not lop
191
+ off the end of the
192
+ results. */
193
+ char const * zLimit = find_option("limit","n",1);
194
+ int const nLimit = zLimit ? atoi(zLimit) : -1; /* Max number of entries
195
+ to list */
181196
182197
db_must_be_within_tree();
183198
if( g.argc<2 ) return;
184199
blob_init(&pattern, g.argv[2], -1);
185200
for(i=3; i<g.argc; i++){
@@ -198,13 +213,20 @@
198213
" score(coalesce(ecomment,comment)) AS y"
199214
" FROM event, blob"
200215
" WHERE blob.rid=event.objid AND y>0;"
201216
);
202217
iBest = db_int(0, "SELECT max(x) FROM srch");
203
- db_prepare(&q,
204
- "SELECT rid, uuid, date, comment, 0, 0 FROM srch"
205
- " WHERE x>%d ORDER BY x DESC, date DESC",
206
- iBest/3
207
- );
218
+ blob_append(&sql,
219
+ "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
220
+ "WHERE 1 ", -1);
221
+ if(!fAll){
222
+ blob_appendf(&sql,"AND x>%d ", iBest/3);
223
+ }
224
+ blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
225
+ if(nLimit>0){
226
+ blob_appendf(&sql, "LIMIT %d", nLimit);
227
+ }
228
+ db_prepare(&q, blob_str(&sql));
229
+ blob_reset(&sql);
208230
print_timeline(&q, 1000, 0);
209231
db_finalize(&q);
210232
}
211233
--- src/search.c
+++ src/search.c
@@ -166,20 +166,35 @@
166
167 /*
168 ** Testing the search function.
169 **
170 ** COMMAND: search*
171 ** %fossil search pattern...
 
 
 
 
172 **
173 ** Search for timeline entries matching the pattern.
 
 
 
 
174 */
175 void search_cmd(void){
176 Search *p;
177 Blob pattern;
178 int i;
 
179 Stmt q;
180 int iBest;
 
 
 
 
 
 
181
182 db_must_be_within_tree();
183 if( g.argc<2 ) return;
184 blob_init(&pattern, g.argv[2], -1);
185 for(i=3; i<g.argc; i++){
@@ -198,13 +213,20 @@
198 " score(coalesce(ecomment,comment)) AS y"
199 " FROM event, blob"
200 " WHERE blob.rid=event.objid AND y>0;"
201 );
202 iBest = db_int(0, "SELECT max(x) FROM srch");
203 db_prepare(&q,
204 "SELECT rid, uuid, date, comment, 0, 0 FROM srch"
205 " WHERE x>%d ORDER BY x DESC, date DESC",
206 iBest/3
207 );
 
 
 
 
 
 
 
208 print_timeline(&q, 1000, 0);
209 db_finalize(&q);
210 }
211
--- src/search.c
+++ src/search.c
@@ -166,20 +166,35 @@
166
167 /*
168 ** Testing the search function.
169 **
170 ** COMMAND: search*
171 ** %fossil search [-all|-a] [-limit|-n #] pattern...
172 **
173 ** Search for timeline entries matching all words
174 ** provided on the command line. Whole-word matches
175 ** scope more highly than partial matches.
176 **
177 ** Outputs, by default, some top-N fraction of the
178 ** results. The -all option can be used to output
179 ** all matches, regardless of their search score.
180 ** -limit can be used to limit the number of entries
181 ** returned.
182 */
183 void search_cmd(void){
184 Search *p;
185 Blob pattern;
186 int i;
187 Blob sql = empty_blob;
188 Stmt q;
189 int iBest;
190 char fAll = NULL != find_option("all", "a", 0); /* If set, do not lop
191 off the end of the
192 results. */
193 char const * zLimit = find_option("limit","n",1);
194 int const nLimit = zLimit ? atoi(zLimit) : -1; /* Max number of entries
195 to list */
196
197 db_must_be_within_tree();
198 if( g.argc<2 ) return;
199 blob_init(&pattern, g.argv[2], -1);
200 for(i=3; i<g.argc; i++){
@@ -198,13 +213,20 @@
213 " score(coalesce(ecomment,comment)) AS y"
214 " FROM event, blob"
215 " WHERE blob.rid=event.objid AND y>0;"
216 );
217 iBest = db_int(0, "SELECT max(x) FROM srch");
218 blob_append(&sql,
219 "SELECT rid, uuid, date, comment, 0, 0 FROM srch "
220 "WHERE 1 ", -1);
221 if(!fAll){
222 blob_appendf(&sql,"AND x>%d ", iBest/3);
223 }
224 blob_append(&sql, "ORDER BY x DESC, date DESC ", -1);
225 if(nLimit>0){
226 blob_appendf(&sql, "LIMIT %d", nLimit);
227 }
228 db_prepare(&q, blob_str(&sql));
229 blob_reset(&sql);
230 print_timeline(&q, 1000, 0);
231 db_finalize(&q);
232 }
233
+29 -29
--- src/setup.c
+++ src/setup.c
@@ -197,62 +197,62 @@
197197
@ </td><td class="usetupColumnLayout">
198198
@ <span class="note">Notes:</span>
199199
@ <ol>
200200
@ <li><p>The permission flags are as follows:</p>
201201
@ <table>
202
- @ <tr><td valign="top"><b>a</b></td>
202
+ @ <tr><th valign="top">a</th>
203203
@ <td><i>Admin:</i> Create and delete users</td></tr>
204
- @ <tr><td valign="top"><b>b</b></td>
204
+ @ <tr><th valign="top">b</th>
205205
@ <td><i>Attach:</i> Add attachments to wiki or tickets</td></tr>
206
- @ <tr><td valign="top"><b>c</b></td>
206
+ @ <tr><th valign="top">c</th>
207207
@ <td><i>Append-Tkt:</i> Append to tickets</td></tr>
208
- @ <tr><td valign="top"><b>d</b></td>
208
+ @ <tr><th valign="top">d</th>
209209
@ <td><i>Delete:</i> Delete wiki and tickets</td></tr>
210
- @ <tr><td valign="top"><b>e</b></td>
210
+ @ <tr><th valign="top">e</th>
211211
@ <td><i>Email:</i> View sensitive data such as EMail addresses</td></tr>
212
- @ <tr><td valign="top"><b>f</b></td>
212
+ @ <tr><th valign="top">f</th>
213213
@ <td><i>New-Wiki:</i> Create new wiki pages</td></tr>
214
- @ <tr><td valign="top"><b>g</b></td>
214
+ @ <tr><th valign="top">g</th>
215215
@ <td><i>Clone:</i> Clone the repository</td></tr>
216
- @ <tr><td valign="top"><b>h</b></td>
216
+ @ <tr><th valign="top">h</th>
217217
@ <td><i>Hyperlinks:</i> Show hyperlinks to detailed
218218
@ repository history</td></tr>
219
- @ <tr><td valign="top"><b>i</b></td>
219
+ @ <tr><th valign="top">i</th>
220220
@ <td><i>Check-In:</i> Commit new versions in the repository</td></tr>
221
- @ <tr><td valign="top"><b>j</b></td>
221
+ @ <tr><th valign="top">j</th>
222222
@ <td><i>Read-Wiki:</i> View wiki pages</td></tr>
223
- @ <tr><td valign="top"><b>k</b></td>
223
+ @ <tr><th valign="top">k</th>
224224
@ <td><i>Write-Wiki:</i> Edit wiki pages</td></tr>
225
- @ <tr><td valign="top"><b>l</b></td>
225
+ @ <tr><th valign="top">l</th>
226226
@ <td><i>Mod-Wiki:</i> Moderator for wiki pages</td></tr>
227
- @ <tr><td valign="top"><b>m</b></td>
227
+ @ <tr><th valign="top">m</th>
228228
@ <td><i>Append-Wiki:</i> Append to wiki pages</td></tr>
229
- @ <tr><td valign="top"><b>n</b></td>
229
+ @ <tr><th valign="top">n</th>
230230
@ <td><i>New-Tkt:</i> Create new tickets</td></tr>
231
- @ <tr><td valign="top"><b>o</b></td>
231
+ @ <tr><th valign="top">o</th>
232232
@ <td><i>Check-Out:</i> Check out versions</td></tr>
233
- @ <tr><td valign="top"><b>p</b></td>
233
+ @ <tr><th valign="top">p</th>
234234
@ <td><i>Password:</i> Change your own password</td></tr>
235
- @ <tr><td valign="top"><b>q</b></td>
235
+ @ <tr><th valign="top">q</th>
236236
@ <td><i>Mod-Tkt:</i> Moderator for tickets</td></tr>
237
- @ <tr><td valign="top"><b>r</b></td>
237
+ @ <tr><th valign="top">r</th>
238238
@ <td><i>Read-Tkt:</i> View tickets</td></tr>
239
- @ <tr><td valign="top"><b>s</b></td>
239
+ @ <tr><th valign="top">s</th>
240240
@ <td><i>Setup/Super-user:</i> Setup and configure this website</td></tr>
241
- @ <tr><td valign="top"><b>t</b></td>
241
+ @ <tr><th valign="top">t</th>
242242
@ <td><i>Tkt-Report:</i> Create new bug summary reports</td></tr>
243
- @ <tr><td valign="top"><b>u</b></td>
243
+ @ <tr><th valign="top">u</th>
244244
@ <td><i>Reader:</i> Inherit privileges of
245245
@ user <tt>reader</tt></td></tr>
246
- @ <tr><td valign="top"><b>v</b></td>
246
+ @ <tr><th valign="top">v</th>
247247
@ <td><i>Developer:</i> Inherit privileges of
248248
@ user <tt>developer</tt></td></tr>
249
- @ <tr><td valign="top"><b>w</b></td>
249
+ @ <tr><th valign="top">w</th>
250250
@ <td><i>Write-Tkt:</i> Edit tickets</td></tr>
251
- @ <tr><td valign="top"><b>x</b></td>
251
+ @ <tr><th valign="top">x</th>
252252
@ <td><i>Private:</i> Push and/or pull private branches</td></tr>
253
- @ <tr><td valign="top"><b>z</b></td>
253
+ @ <tr><th valign="top">z</th>
254254
@ <td><i>Zip download:</i> Download a baseline via the
255255
@ <tt>/zip</tt> URL even without
256256
@ check<span class="capability">o</span>ut
257257
@ and <span class="capability">h</span>istory permissions</td></tr>
258258
@ </table>
@@ -1062,23 +1062,23 @@
10621062
@
10631063
@ <form action="%s(g.zTop)/setup_login_group" method="post"><div>
10641064
login_insert_csrf_secret();
10651065
@ <blockquote><table border="0">
10661066
@
1067
- @ <tr><td align="right"><b>Repository filename in group to join:</b></td>
1067
+ @ <tr><th align="right">Repository filename in group to join:</th>
10681068
@ <td width="5"></td><td>
10691069
@ <input type="text" size="50" value="%h(zRepo)" name="repo"></td></tr>
10701070
@
1071
- @ <tr><td align="right"><b>Login on the above repo:</b></td>
1071
+ @ <tr><th align="right">Login on the above repo:</th>
10721072
@ <td width="5"></td><td>
10731073
@ <input type="text" size="20" value="%h(zLogin)" name="login"></td></tr>
10741074
@
1075
- @ <tr><td align="right"><b>Password:</b></td>
1075
+ @ <tr><th align="right">Password:</th>
10761076
@ <td width="5"></td><td>
10771077
@ <input type="password" size="20" name="pw"></td></tr>
10781078
@
1079
- @ <tr><td align="right"><b>Name of login-group:</b></td>
1079
+ @ <tr><th align="right">Name of login-group:</th>
10801080
@ <td width="5"></td><td>
10811081
@ <input type="text" size="30" value="%h(zNewName)" name="newname">
10821082
@ (only used if creating a new login-group).</td></tr>
10831083
@
10841084
@ <tr><td colspan="3" align="center">
10851085
--- src/setup.c
+++ src/setup.c
@@ -197,62 +197,62 @@
197 @ </td><td class="usetupColumnLayout">
198 @ <span class="note">Notes:</span>
199 @ <ol>
200 @ <li><p>The permission flags are as follows:</p>
201 @ <table>
202 @ <tr><td valign="top"><b>a</b></td>
203 @ <td><i>Admin:</i> Create and delete users</td></tr>
204 @ <tr><td valign="top"><b>b</b></td>
205 @ <td><i>Attach:</i> Add attachments to wiki or tickets</td></tr>
206 @ <tr><td valign="top"><b>c</b></td>
207 @ <td><i>Append-Tkt:</i> Append to tickets</td></tr>
208 @ <tr><td valign="top"><b>d</b></td>
209 @ <td><i>Delete:</i> Delete wiki and tickets</td></tr>
210 @ <tr><td valign="top"><b>e</b></td>
211 @ <td><i>Email:</i> View sensitive data such as EMail addresses</td></tr>
212 @ <tr><td valign="top"><b>f</b></td>
213 @ <td><i>New-Wiki:</i> Create new wiki pages</td></tr>
214 @ <tr><td valign="top"><b>g</b></td>
215 @ <td><i>Clone:</i> Clone the repository</td></tr>
216 @ <tr><td valign="top"><b>h</b></td>
217 @ <td><i>Hyperlinks:</i> Show hyperlinks to detailed
218 @ repository history</td></tr>
219 @ <tr><td valign="top"><b>i</b></td>
220 @ <td><i>Check-In:</i> Commit new versions in the repository</td></tr>
221 @ <tr><td valign="top"><b>j</b></td>
222 @ <td><i>Read-Wiki:</i> View wiki pages</td></tr>
223 @ <tr><td valign="top"><b>k</b></td>
224 @ <td><i>Write-Wiki:</i> Edit wiki pages</td></tr>
225 @ <tr><td valign="top"><b>l</b></td>
226 @ <td><i>Mod-Wiki:</i> Moderator for wiki pages</td></tr>
227 @ <tr><td valign="top"><b>m</b></td>
228 @ <td><i>Append-Wiki:</i> Append to wiki pages</td></tr>
229 @ <tr><td valign="top"><b>n</b></td>
230 @ <td><i>New-Tkt:</i> Create new tickets</td></tr>
231 @ <tr><td valign="top"><b>o</b></td>
232 @ <td><i>Check-Out:</i> Check out versions</td></tr>
233 @ <tr><td valign="top"><b>p</b></td>
234 @ <td><i>Password:</i> Change your own password</td></tr>
235 @ <tr><td valign="top"><b>q</b></td>
236 @ <td><i>Mod-Tkt:</i> Moderator for tickets</td></tr>
237 @ <tr><td valign="top"><b>r</b></td>
238 @ <td><i>Read-Tkt:</i> View tickets</td></tr>
239 @ <tr><td valign="top"><b>s</b></td>
240 @ <td><i>Setup/Super-user:</i> Setup and configure this website</td></tr>
241 @ <tr><td valign="top"><b>t</b></td>
242 @ <td><i>Tkt-Report:</i> Create new bug summary reports</td></tr>
243 @ <tr><td valign="top"><b>u</b></td>
244 @ <td><i>Reader:</i> Inherit privileges of
245 @ user <tt>reader</tt></td></tr>
246 @ <tr><td valign="top"><b>v</b></td>
247 @ <td><i>Developer:</i> Inherit privileges of
248 @ user <tt>developer</tt></td></tr>
249 @ <tr><td valign="top"><b>w</b></td>
250 @ <td><i>Write-Tkt:</i> Edit tickets</td></tr>
251 @ <tr><td valign="top"><b>x</b></td>
252 @ <td><i>Private:</i> Push and/or pull private branches</td></tr>
253 @ <tr><td valign="top"><b>z</b></td>
254 @ <td><i>Zip download:</i> Download a baseline via the
255 @ <tt>/zip</tt> URL even without
256 @ check<span class="capability">o</span>ut
257 @ and <span class="capability">h</span>istory permissions</td></tr>
258 @ </table>
@@ -1062,23 +1062,23 @@
1062 @
1063 @ <form action="%s(g.zTop)/setup_login_group" method="post"><div>
1064 login_insert_csrf_secret();
1065 @ <blockquote><table border="0">
1066 @
1067 @ <tr><td align="right"><b>Repository filename in group to join:</b></td>
1068 @ <td width="5"></td><td>
1069 @ <input type="text" size="50" value="%h(zRepo)" name="repo"></td></tr>
1070 @
1071 @ <tr><td align="right"><b>Login on the above repo:</b></td>
1072 @ <td width="5"></td><td>
1073 @ <input type="text" size="20" value="%h(zLogin)" name="login"></td></tr>
1074 @
1075 @ <tr><td align="right"><b>Password:</b></td>
1076 @ <td width="5"></td><td>
1077 @ <input type="password" size="20" name="pw"></td></tr>
1078 @
1079 @ <tr><td align="right"><b>Name of login-group:</b></td>
1080 @ <td width="5"></td><td>
1081 @ <input type="text" size="30" value="%h(zNewName)" name="newname">
1082 @ (only used if creating a new login-group).</td></tr>
1083 @
1084 @ <tr><td colspan="3" align="center">
1085
--- src/setup.c
+++ src/setup.c
@@ -197,62 +197,62 @@
197 @ </td><td class="usetupColumnLayout">
198 @ <span class="note">Notes:</span>
199 @ <ol>
200 @ <li><p>The permission flags are as follows:</p>
201 @ <table>
202 @ <tr><th valign="top">a</th>
203 @ <td><i>Admin:</i> Create and delete users</td></tr>
204 @ <tr><th valign="top">b</th>
205 @ <td><i>Attach:</i> Add attachments to wiki or tickets</td></tr>
206 @ <tr><th valign="top">c</th>
207 @ <td><i>Append-Tkt:</i> Append to tickets</td></tr>
208 @ <tr><th valign="top">d</th>
209 @ <td><i>Delete:</i> Delete wiki and tickets</td></tr>
210 @ <tr><th valign="top">e</th>
211 @ <td><i>Email:</i> View sensitive data such as EMail addresses</td></tr>
212 @ <tr><th valign="top">f</th>
213 @ <td><i>New-Wiki:</i> Create new wiki pages</td></tr>
214 @ <tr><th valign="top">g</th>
215 @ <td><i>Clone:</i> Clone the repository</td></tr>
216 @ <tr><th valign="top">h</th>
217 @ <td><i>Hyperlinks:</i> Show hyperlinks to detailed
218 @ repository history</td></tr>
219 @ <tr><th valign="top">i</th>
220 @ <td><i>Check-In:</i> Commit new versions in the repository</td></tr>
221 @ <tr><th valign="top">j</th>
222 @ <td><i>Read-Wiki:</i> View wiki pages</td></tr>
223 @ <tr><th valign="top">k</th>
224 @ <td><i>Write-Wiki:</i> Edit wiki pages</td></tr>
225 @ <tr><th valign="top">l</th>
226 @ <td><i>Mod-Wiki:</i> Moderator for wiki pages</td></tr>
227 @ <tr><th valign="top">m</th>
228 @ <td><i>Append-Wiki:</i> Append to wiki pages</td></tr>
229 @ <tr><th valign="top">n</th>
230 @ <td><i>New-Tkt:</i> Create new tickets</td></tr>
231 @ <tr><th valign="top">o</th>
232 @ <td><i>Check-Out:</i> Check out versions</td></tr>
233 @ <tr><th valign="top">p</th>
234 @ <td><i>Password:</i> Change your own password</td></tr>
235 @ <tr><th valign="top">q</th>
236 @ <td><i>Mod-Tkt:</i> Moderator for tickets</td></tr>
237 @ <tr><th valign="top">r</th>
238 @ <td><i>Read-Tkt:</i> View tickets</td></tr>
239 @ <tr><th valign="top">s</th>
240 @ <td><i>Setup/Super-user:</i> Setup and configure this website</td></tr>
241 @ <tr><th valign="top">t</th>
242 @ <td><i>Tkt-Report:</i> Create new bug summary reports</td></tr>
243 @ <tr><th valign="top">u</th>
244 @ <td><i>Reader:</i> Inherit privileges of
245 @ user <tt>reader</tt></td></tr>
246 @ <tr><th valign="top">v</th>
247 @ <td><i>Developer:</i> Inherit privileges of
248 @ user <tt>developer</tt></td></tr>
249 @ <tr><th valign="top">w</th>
250 @ <td><i>Write-Tkt:</i> Edit tickets</td></tr>
251 @ <tr><th valign="top">x</th>
252 @ <td><i>Private:</i> Push and/or pull private branches</td></tr>
253 @ <tr><th valign="top">z</th>
254 @ <td><i>Zip download:</i> Download a baseline via the
255 @ <tt>/zip</tt> URL even without
256 @ check<span class="capability">o</span>ut
257 @ and <span class="capability">h</span>istory permissions</td></tr>
258 @ </table>
@@ -1062,23 +1062,23 @@
1062 @
1063 @ <form action="%s(g.zTop)/setup_login_group" method="post"><div>
1064 login_insert_csrf_secret();
1065 @ <blockquote><table border="0">
1066 @
1067 @ <tr><th align="right">Repository filename in group to join:</th>
1068 @ <td width="5"></td><td>
1069 @ <input type="text" size="50" value="%h(zRepo)" name="repo"></td></tr>
1070 @
1071 @ <tr><th align="right">Login on the above repo:</th>
1072 @ <td width="5"></td><td>
1073 @ <input type="text" size="20" value="%h(zLogin)" name="login"></td></tr>
1074 @
1075 @ <tr><th align="right">Password:</th>
1076 @ <td width="5"></td><td>
1077 @ <input type="password" size="20" name="pw"></td></tr>
1078 @
1079 @ <tr><th align="right">Name of login-group:</th>
1080 @ <td width="5"></td><td>
1081 @ <input type="text" size="30" value="%h(zNewName)" name="newname">
1082 @ (only used if creating a new login-group).</td></tr>
1083 @
1084 @ <tr><td colspan="3" align="center">
1085
+9 -14
--- src/shell.c
+++ src/shell.c
@@ -63,18 +63,23 @@
6363
#if defined(_WIN32) || defined(WIN32)
6464
# include <io.h>
6565
#define isatty(h) _isatty(h)
6666
#define access(f,m) _access((f),(m))
6767
#undef popen
68
-#define popen(a,b) _popen((a),(b))
68
+#define popen _popen
6969
#undef pclose
7070
#define pclose _pclose
7171
#else
7272
/* Make sure isatty() has a prototype.
7373
*/
7474
extern int isatty(int);
7575
#endif
76
+
77
+/* popen and pclose are not C89 functions and so are sometimes omitted from
78
+** the <stdio.h> header */
79
+FILE *popen(const char*,const char*);
80
+int pclose(FILE*);
7681
7782
#if defined(_WIN32_WCE)
7883
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
7984
* thus we always assume that we have a console. That can be
8085
* overridden with the -batch command line option.
@@ -1719,11 +1724,10 @@
17191724
|| (c=='\n' && pc==cQuote)
17201725
|| (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
17211726
|| (c==EOF && pc==cQuote)
17221727
){
17231728
do{ p->n--; }while( p->z[p->n]!=cQuote );
1724
- p->z[p->n] = 0;
17251729
p->cTerm = c;
17261730
break;
17271731
}
17281732
if( pc==cQuote && c!='\r' ){
17291733
fprintf(stderr, "%s:%d: unescaped %c character\n",
@@ -1730,11 +1734,10 @@
17301734
p->zFile, p->nLine, cQuote);
17311735
}
17321736
if( c==EOF ){
17331737
fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
17341738
p->zFile, startLine, cQuote);
1735
- p->z[p->n] = 0;
17361739
p->cTerm = EOF;
17371740
break;
17381741
}
17391742
csv_append_char(p, c);
17401743
pc = c;
@@ -1746,13 +1749,13 @@
17461749
}
17471750
if( c=='\n' ){
17481751
p->nLine++;
17491752
if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
17501753
}
1751
- p->z[p->n] = 0;
17521754
p->cTerm = c;
17531755
}
1756
+ if( p->z ) p->z[p->n] = 0;
17541757
return p->z;
17551758
}
17561759
17571760
/*
17581761
** If an input line begins with "." then invoke this routine to
@@ -1797,21 +1800,18 @@
17971800
n = strlen30(azArg[0]);
17981801
c = azArg[0][0];
17991802
if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
18001803
const char *zDestFile = 0;
18011804
const char *zDb = 0;
1802
- const char *zKey = 0;
18031805
sqlite3 *pDest;
18041806
sqlite3_backup *pBackup;
18051807
int j;
18061808
for(j=1; j<nArg; j++){
18071809
const char *z = azArg[j];
18081810
if( z[0]=='-' ){
18091811
while( z[0]=='-' ) z++;
1810
- if( strcmp(z,"key")==0 && j<nArg-1 ){
1811
- zKey = azArg[++j];
1812
- }else
1812
+ /* No options to process at this time */
18131813
{
18141814
fprintf(stderr, "unknown option: %s\n", azArg[j]);
18151815
return 1;
18161816
}
18171817
}else if( zDestFile==0 ){
@@ -1833,15 +1833,10 @@
18331833
if( rc!=SQLITE_OK ){
18341834
fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
18351835
sqlite3_close(pDest);
18361836
return 1;
18371837
}
1838
-#ifdef SQLITE_HAS_CODEC
1839
- sqlite3_key(pDest, zKey, (int)strlen(zKey));
1840
-#else
1841
- (void)zKey;
1842
-#endif
18431838
open_db(p);
18441839
pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
18451840
if( pBackup==0 ){
18461841
fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
18471842
sqlite3_close(pDest);
@@ -2667,11 +2662,11 @@
26672662
break;
26682663
26692664
/* sqlite3_test_control(int, uint) */
26702665
case SQLITE_TESTCTRL_PENDING_BYTE:
26712666
if( nArg==3 ){
2672
- unsigned int opt = (unsigned int)integerValue(azArg[2]);
2667
+ unsigned int opt = (unsigned int)integerValue(azArg[2]);
26732668
rc = sqlite3_test_control(testctrl, opt);
26742669
fprintf(p->out, "%d (0x%08x)\n", rc, rc);
26752670
} else {
26762671
fprintf(stderr,"Error: testctrl %s takes a single unsigned"
26772672
" int option\n", azArg[1]);
26782673
--- src/shell.c
+++ src/shell.c
@@ -63,18 +63,23 @@
63 #if defined(_WIN32) || defined(WIN32)
64 # include <io.h>
65 #define isatty(h) _isatty(h)
66 #define access(f,m) _access((f),(m))
67 #undef popen
68 #define popen(a,b) _popen((a),(b))
69 #undef pclose
70 #define pclose _pclose
71 #else
72 /* Make sure isatty() has a prototype.
73 */
74 extern int isatty(int);
75 #endif
 
 
 
 
 
76
77 #if defined(_WIN32_WCE)
78 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
79 * thus we always assume that we have a console. That can be
80 * overridden with the -batch command line option.
@@ -1719,11 +1724,10 @@
1719 || (c=='\n' && pc==cQuote)
1720 || (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
1721 || (c==EOF && pc==cQuote)
1722 ){
1723 do{ p->n--; }while( p->z[p->n]!=cQuote );
1724 p->z[p->n] = 0;
1725 p->cTerm = c;
1726 break;
1727 }
1728 if( pc==cQuote && c!='\r' ){
1729 fprintf(stderr, "%s:%d: unescaped %c character\n",
@@ -1730,11 +1734,10 @@
1730 p->zFile, p->nLine, cQuote);
1731 }
1732 if( c==EOF ){
1733 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1734 p->zFile, startLine, cQuote);
1735 p->z[p->n] = 0;
1736 p->cTerm = EOF;
1737 break;
1738 }
1739 csv_append_char(p, c);
1740 pc = c;
@@ -1746,13 +1749,13 @@
1746 }
1747 if( c=='\n' ){
1748 p->nLine++;
1749 if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
1750 }
1751 p->z[p->n] = 0;
1752 p->cTerm = c;
1753 }
 
1754 return p->z;
1755 }
1756
1757 /*
1758 ** If an input line begins with "." then invoke this routine to
@@ -1797,21 +1800,18 @@
1797 n = strlen30(azArg[0]);
1798 c = azArg[0][0];
1799 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1800 const char *zDestFile = 0;
1801 const char *zDb = 0;
1802 const char *zKey = 0;
1803 sqlite3 *pDest;
1804 sqlite3_backup *pBackup;
1805 int j;
1806 for(j=1; j<nArg; j++){
1807 const char *z = azArg[j];
1808 if( z[0]=='-' ){
1809 while( z[0]=='-' ) z++;
1810 if( strcmp(z,"key")==0 && j<nArg-1 ){
1811 zKey = azArg[++j];
1812 }else
1813 {
1814 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1815 return 1;
1816 }
1817 }else if( zDestFile==0 ){
@@ -1833,15 +1833,10 @@
1833 if( rc!=SQLITE_OK ){
1834 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1835 sqlite3_close(pDest);
1836 return 1;
1837 }
1838 #ifdef SQLITE_HAS_CODEC
1839 sqlite3_key(pDest, zKey, (int)strlen(zKey));
1840 #else
1841 (void)zKey;
1842 #endif
1843 open_db(p);
1844 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1845 if( pBackup==0 ){
1846 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1847 sqlite3_close(pDest);
@@ -2667,11 +2662,11 @@
2667 break;
2668
2669 /* sqlite3_test_control(int, uint) */
2670 case SQLITE_TESTCTRL_PENDING_BYTE:
2671 if( nArg==3 ){
2672 unsigned int opt = (unsigned int)integerValue(azArg[2]);
2673 rc = sqlite3_test_control(testctrl, opt);
2674 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
2675 } else {
2676 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2677 " int option\n", azArg[1]);
2678
--- src/shell.c
+++ src/shell.c
@@ -63,18 +63,23 @@
63 #if defined(_WIN32) || defined(WIN32)
64 # include <io.h>
65 #define isatty(h) _isatty(h)
66 #define access(f,m) _access((f),(m))
67 #undef popen
68 #define popen _popen
69 #undef pclose
70 #define pclose _pclose
71 #else
72 /* Make sure isatty() has a prototype.
73 */
74 extern int isatty(int);
75 #endif
76
77 /* popen and pclose are not C89 functions and so are sometimes omitted from
78 ** the <stdio.h> header */
79 FILE *popen(const char*,const char*);
80 int pclose(FILE*);
81
82 #if defined(_WIN32_WCE)
83 /* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
84 * thus we always assume that we have a console. That can be
85 * overridden with the -batch command line option.
@@ -1719,11 +1724,10 @@
1724 || (c=='\n' && pc==cQuote)
1725 || (c=='\n' && pc=='\r' && p->n>2 && p->z[p->n-2]==cQuote)
1726 || (c==EOF && pc==cQuote)
1727 ){
1728 do{ p->n--; }while( p->z[p->n]!=cQuote );
 
1729 p->cTerm = c;
1730 break;
1731 }
1732 if( pc==cQuote && c!='\r' ){
1733 fprintf(stderr, "%s:%d: unescaped %c character\n",
@@ -1730,11 +1734,10 @@
1734 p->zFile, p->nLine, cQuote);
1735 }
1736 if( c==EOF ){
1737 fprintf(stderr, "%s:%d: unterminated %c-quoted field\n",
1738 p->zFile, startLine, cQuote);
 
1739 p->cTerm = EOF;
1740 break;
1741 }
1742 csv_append_char(p, c);
1743 pc = c;
@@ -1746,13 +1749,13 @@
1749 }
1750 if( c=='\n' ){
1751 p->nLine++;
1752 if( p->n>1 && p->z[p->n-1]=='\r' ) p->n--;
1753 }
 
1754 p->cTerm = c;
1755 }
1756 if( p->z ) p->z[p->n] = 0;
1757 return p->z;
1758 }
1759
1760 /*
1761 ** If an input line begins with "." then invoke this routine to
@@ -1797,21 +1800,18 @@
1800 n = strlen30(azArg[0]);
1801 c = azArg[0][0];
1802 if( c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0 ){
1803 const char *zDestFile = 0;
1804 const char *zDb = 0;
 
1805 sqlite3 *pDest;
1806 sqlite3_backup *pBackup;
1807 int j;
1808 for(j=1; j<nArg; j++){
1809 const char *z = azArg[j];
1810 if( z[0]=='-' ){
1811 while( z[0]=='-' ) z++;
1812 /* No options to process at this time */
 
 
1813 {
1814 fprintf(stderr, "unknown option: %s\n", azArg[j]);
1815 return 1;
1816 }
1817 }else if( zDestFile==0 ){
@@ -1833,15 +1833,10 @@
1833 if( rc!=SQLITE_OK ){
1834 fprintf(stderr, "Error: cannot open \"%s\"\n", zDestFile);
1835 sqlite3_close(pDest);
1836 return 1;
1837 }
 
 
 
 
 
1838 open_db(p);
1839 pBackup = sqlite3_backup_init(pDest, "main", p->db, zDb);
1840 if( pBackup==0 ){
1841 fprintf(stderr, "Error: %s\n", sqlite3_errmsg(pDest));
1842 sqlite3_close(pDest);
@@ -2667,11 +2662,11 @@
2662 break;
2663
2664 /* sqlite3_test_control(int, uint) */
2665 case SQLITE_TESTCTRL_PENDING_BYTE:
2666 if( nArg==3 ){
2667 unsigned int opt = (unsigned int)integerValue(azArg[2]);
2668 rc = sqlite3_test_control(testctrl, opt);
2669 fprintf(p->out, "%d (0x%08x)\n", rc, rc);
2670 } else {
2671 fprintf(stderr,"Error: testctrl %s takes a single unsigned"
2672 " int option\n", azArg[1]);
2673
+7 -6
--- src/shun.c
+++ src/shun.c
@@ -133,20 +133,21 @@
133133
@ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
134134
@ <input type="submit" name="add" value="Shun" />
135135
@ </div></form>
136136
@ </blockquote>
137137
@
138
+ @ <a name="delshun"></a>
138139
@ <p>Enter the UUID of a previous shunned artifact to cause it to be
139140
@ accepted again in the repository. The artifact content is not
140141
@ restored because the content is unknown. The only change is that
141142
@ the formerly shunned artifact will be accepted on subsequent sync
142143
@ operations.</p>
143144
@
144145
@ <blockquote>
145146
@ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
146147
login_insert_csrf_secret();
147
- @ <input type="text" name="uuid" size="50" />
148
+ @ <input type="text" name="uuid" value="%h(PD("accept", ""))" size="50" />
148149
@ <input type="submit" name="sub" value="Accept" />
149150
@ </div></form>
150151
@ </blockquote>
151152
@
152153
@ <p>Press the Rebuild button below to rebuild the repository. The
@@ -293,28 +294,28 @@
293294
" FROM rcvfrom LEFT JOIN user USING(uid)"
294295
" WHERE rcvid=%d",
295296
rcvid
296297
);
297298
@ <table cellspacing="15" cellpadding="0" border="0">
298
- @ <tr><td valign="top" align="right"><b>rcvid:</b></td>
299
+ @ <tr><th valign="top" align="right">rcvid:</th>
299300
@ <td valign="top">%d(rcvid)</td></tr>
300301
if( db_step(&q)==SQLITE_ROW ){
301302
const char *zUser = db_column_text(&q, 0);
302303
const char *zDate = db_column_text(&q, 1);
303304
const char *zIpAddr = db_column_text(&q, 2);
304
- @ <tr><td valign="top" align="right"><b>User:</b></td>
305
+ @ <tr><th valign="top" align="right">User:</th>
305306
@ <td valign="top">%s(zUser)</td></tr>
306
- @ <tr><td valign="top" align="right"><b>Date:</b></td>
307
+ @ <tr><th valign="top" align="right">Date:</th>
307308
@ <td valign="top">%s(zDate)</td></tr>
308
- @ <tr><td valign="top" align="right"><b>IP&nbsp;Address:</b></td>
309
+ @ <tr><th valign="top" align="right">IP&nbsp;Address:</th>
309310
@ <td valign="top">%s(zIpAddr)</td></tr>
310311
}
311312
db_finalize(&q);
312313
db_prepare(&q,
313314
"SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid
314315
);
315
- @ <tr><td valign="top" align="right"><b>Artifacts:</b></td>
316
+ @ <tr><th valign="top" align="right">Artifacts:</th>
316317
@ <td valign="top">
317318
while( db_step(&q)==SQLITE_ROW ){
318319
int rid = db_column_int(&q, 0);
319320
const char *zUuid = db_column_text(&q, 1);
320321
int size = db_column_int(&q, 2);
321322
--- src/shun.c
+++ src/shun.c
@@ -133,20 +133,21 @@
133 @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
134 @ <input type="submit" name="add" value="Shun" />
135 @ </div></form>
136 @ </blockquote>
137 @
 
138 @ <p>Enter the UUID of a previous shunned artifact to cause it to be
139 @ accepted again in the repository. The artifact content is not
140 @ restored because the content is unknown. The only change is that
141 @ the formerly shunned artifact will be accepted on subsequent sync
142 @ operations.</p>
143 @
144 @ <blockquote>
145 @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
146 login_insert_csrf_secret();
147 @ <input type="text" name="uuid" size="50" />
148 @ <input type="submit" name="sub" value="Accept" />
149 @ </div></form>
150 @ </blockquote>
151 @
152 @ <p>Press the Rebuild button below to rebuild the repository. The
@@ -293,28 +294,28 @@
293 " FROM rcvfrom LEFT JOIN user USING(uid)"
294 " WHERE rcvid=%d",
295 rcvid
296 );
297 @ <table cellspacing="15" cellpadding="0" border="0">
298 @ <tr><td valign="top" align="right"><b>rcvid:</b></td>
299 @ <td valign="top">%d(rcvid)</td></tr>
300 if( db_step(&q)==SQLITE_ROW ){
301 const char *zUser = db_column_text(&q, 0);
302 const char *zDate = db_column_text(&q, 1);
303 const char *zIpAddr = db_column_text(&q, 2);
304 @ <tr><td valign="top" align="right"><b>User:</b></td>
305 @ <td valign="top">%s(zUser)</td></tr>
306 @ <tr><td valign="top" align="right"><b>Date:</b></td>
307 @ <td valign="top">%s(zDate)</td></tr>
308 @ <tr><td valign="top" align="right"><b>IP&nbsp;Address:</b></td>
309 @ <td valign="top">%s(zIpAddr)</td></tr>
310 }
311 db_finalize(&q);
312 db_prepare(&q,
313 "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid
314 );
315 @ <tr><td valign="top" align="right"><b>Artifacts:</b></td>
316 @ <td valign="top">
317 while( db_step(&q)==SQLITE_ROW ){
318 int rid = db_column_int(&q, 0);
319 const char *zUuid = db_column_text(&q, 1);
320 int size = db_column_int(&q, 2);
321
--- src/shun.c
+++ src/shun.c
@@ -133,20 +133,21 @@
133 @ <input type="text" name="uuid" value="%h(PD("shun",""))" size="50" />
134 @ <input type="submit" name="add" value="Shun" />
135 @ </div></form>
136 @ </blockquote>
137 @
138 @ <a name="delshun"></a>
139 @ <p>Enter the UUID of a previous shunned artifact to cause it to be
140 @ accepted again in the repository. The artifact content is not
141 @ restored because the content is unknown. The only change is that
142 @ the formerly shunned artifact will be accepted on subsequent sync
143 @ operations.</p>
144 @
145 @ <blockquote>
146 @ <form method="post" action="%s(g.zTop)/%s(g.zPath)"><div>
147 login_insert_csrf_secret();
148 @ <input type="text" name="uuid" value="%h(PD("accept", ""))" size="50" />
149 @ <input type="submit" name="sub" value="Accept" />
150 @ </div></form>
151 @ </blockquote>
152 @
153 @ <p>Press the Rebuild button below to rebuild the repository. The
@@ -293,28 +294,28 @@
294 " FROM rcvfrom LEFT JOIN user USING(uid)"
295 " WHERE rcvid=%d",
296 rcvid
297 );
298 @ <table cellspacing="15" cellpadding="0" border="0">
299 @ <tr><th valign="top" align="right">rcvid:</th>
300 @ <td valign="top">%d(rcvid)</td></tr>
301 if( db_step(&q)==SQLITE_ROW ){
302 const char *zUser = db_column_text(&q, 0);
303 const char *zDate = db_column_text(&q, 1);
304 const char *zIpAddr = db_column_text(&q, 2);
305 @ <tr><th valign="top" align="right">User:</th>
306 @ <td valign="top">%s(zUser)</td></tr>
307 @ <tr><th valign="top" align="right">Date:</th>
308 @ <td valign="top">%s(zDate)</td></tr>
309 @ <tr><th valign="top" align="right">IP&nbsp;Address:</th>
310 @ <td valign="top">%s(zIpAddr)</td></tr>
311 }
312 db_finalize(&q);
313 db_prepare(&q,
314 "SELECT rid, uuid, size FROM blob WHERE rcvid=%d", rcvid
315 );
316 @ <tr><th valign="top" align="right">Artifacts:</th>
317 @ <td valign="top">
318 while( db_step(&q)==SQLITE_ROW ){
319 int rid = db_column_int(&q, 0);
320 const char *zUuid = db_column_text(&q, 1);
321 int size = db_column_int(&q, 2);
322
+1513 -1094
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -399,13 +399,10 @@
399399
** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
400400
** assert() macro is enabled, each call into the Win32 native heap subsystem
401401
** will cause HeapValidate to be called. If heap validation should fail, an
402402
** assertion will be triggered.
403403
**
404
-** (Historical note: There used to be several other options, but we've
405
-** pared it down to just these three.)
406
-**
407404
** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
408405
** the default.
409406
*/
410407
#if defined(SQLITE_SYSTEM_MALLOC) \
411408
+ defined(SQLITE_WIN32_MALLOC) \
@@ -439,24 +436,17 @@
439436
*/
440437
#if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
441438
# define _XOPEN_SOURCE 600
442439
#endif
443440
444
-/*
445
-** The TCL headers are only needed when compiling the TCL bindings.
446
-*/
447
-#if defined(SQLITE_TCL) || defined(TCLSH)
448
-# include <tcl.h>
449
-#endif
450
-
451441
/*
452442
** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
453443
** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
454444
** make it true by defining or undefining NDEBUG.
455445
**
456
-** Setting NDEBUG makes the code smaller and run faster by disabling the
457
-** number assert() statements in the code. So we want the default action
446
+** Setting NDEBUG makes the code smaller and faster by disabling the
447
+** assert() statements in the code. So we want the default action
458448
** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
459449
** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
460450
** feature.
461451
*/
462452
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
@@ -522,11 +512,11 @@
522512
** hint of unplanned behavior.
523513
**
524514
** In other words, ALWAYS and NEVER are added for defensive code.
525515
**
526516
** When doing coverage testing ALWAYS and NEVER are hard-coded to
527
-** be true and false so that the unreachable code then specify will
517
+** be true and false so that the unreachable code they specify will
528518
** not be counted as untested code.
529519
*/
530520
#if defined(SQLITE_COVERAGE_TEST)
531521
# define ALWAYS(X) (1)
532522
# define NEVER(X) (0)
@@ -546,20 +536,16 @@
546536
#define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
547537
548538
/*
549539
** The macro unlikely() is a hint that surrounds a boolean
550540
** expression that is usually false. Macro likely() surrounds
551
-** a boolean expression that is usually true. GCC is able to
552
-** use these hints to generate better code, sometimes.
541
+** a boolean expression that is usually true. These hints could,
542
+** in theory, be used by the compiler to generate better code, but
543
+** currently they are just comments for human readers.
553544
*/
554
-#if defined(__GNUC__) && 0
555
-# define likely(X) __builtin_expect((X),1)
556
-# define unlikely(X) __builtin_expect((X),0)
557
-#else
558
-# define likely(X) !!(X)
559
-# define unlikely(X) !!(X)
560
-#endif
545
+#define likely(X) (X)
546
+#define unlikely(X) (X)
561547
562548
/************** Include sqlite3.h in the middle of sqliteInt.h ***************/
563549
/************** Begin file sqlite3.h *****************************************/
564550
/*
565551
** 2001 September 15
@@ -670,11 +656,11 @@
670656
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671657
** [sqlite_version()] and [sqlite_source_id()].
672658
*/
673659
#define SQLITE_VERSION "3.8.0"
674660
#define SQLITE_VERSION_NUMBER 3008000
675
-#define SQLITE_SOURCE_ID "2013-07-09 03:04:32 52a49cbc1621094b2fe2b021209b768d29e0426b"
661
+#define SQLITE_SOURCE_ID "2013-08-06 07:45:08 924f7e4d7a8fa2fe9100836663f3733b6e1a9084"
676662
677663
/*
678664
** CAPI3REF: Run-Time Library Version Numbers
679665
** KEYWORDS: sqlite3_version, sqlite3_sourceid
680666
**
@@ -1039,10 +1025,11 @@
10391025
#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
10401026
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
10411027
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
10421028
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
10431029
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
1030
+#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
10441031
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
10451032
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
10461033
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
10471034
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
10481035
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -3120,13 +3107,14 @@
31203107
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
31213108
** database connection D. An example use for this
31223109
** interface is to keep a GUI updated during a large query.
31233110
**
31243111
** ^The parameter P is passed through as the only parameter to the
3125
-** callback function X. ^The parameter N is the number of
3112
+** callback function X. ^The parameter N is the approximate number of
31263113
** [virtual machine instructions] that are evaluated between successive
3127
-** invocations of the callback X.
3114
+** invocations of the callback X. ^If N is less than one then the progress
3115
+** handler is disabled.
31283116
**
31293117
** ^Only a single progress handler may be defined at one time per
31303118
** [database connection]; setting a new progress handler cancels the
31313119
** old one. ^Setting parameter X to NULL disables the progress handler.
31323120
** ^The progress handler is also disabled by setting N to a value less
@@ -4742,45 +4730,53 @@
47424730
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
47434731
47444732
/*
47454733
** CAPI3REF: Function Auxiliary Data
47464734
**
4747
-** The following two functions may be used by scalar SQL functions to
4735
+** These functions may be used by (non-aggregate) SQL functions to
47484736
** associate metadata with argument values. If the same value is passed to
47494737
** multiple invocations of the same SQL function during query execution, under
4750
-** some circumstances the associated metadata may be preserved. This may
4751
-** be used, for example, to add a regular-expression matching scalar
4752
-** function. The compiled version of the regular expression is stored as
4753
-** metadata associated with the SQL value passed as the regular expression
4754
-** pattern. The compiled regular expression can be reused on multiple
4755
-** invocations of the same function so that the original pattern string
4756
-** does not need to be recompiled on each invocation.
4738
+** some circumstances the associated metadata may be preserved. An example
4739
+** of where this might be useful is in a regular-expression matching
4740
+** function. The compiled version of the regular expression can be stored as
4741
+** metadata associated with the pattern string.
4742
+** Then as long as the pattern string remains the same,
4743
+** the compiled regular expression can be reused on multiple
4744
+** invocations of the same function.
47574745
**
47584746
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
47594747
** associated by the sqlite3_set_auxdata() function with the Nth argument
4760
-** value to the application-defined function. ^If no metadata has been ever
4761
-** been set for the Nth argument of the function, or if the corresponding
4762
-** function parameter has changed since the meta-data was set,
4763
-** then sqlite3_get_auxdata() returns a NULL pointer.
4764
-**
4765
-** ^The sqlite3_set_auxdata() interface saves the metadata
4766
-** pointed to by its 3rd parameter as the metadata for the N-th
4767
-** argument of the application-defined function. Subsequent
4768
-** calls to sqlite3_get_auxdata() might return this data, if it has
4769
-** not been destroyed.
4770
-** ^If it is not NULL, SQLite will invoke the destructor
4771
-** function given by the 4th parameter to sqlite3_set_auxdata() on
4772
-** the metadata when the corresponding function parameter changes
4773
-** or when the SQL statement completes, whichever comes first.
4774
-**
4775
-** SQLite is free to call the destructor and drop metadata on any
4776
-** parameter of any function at any time. ^The only guarantee is that
4777
-** the destructor will be called before the metadata is dropped.
4748
+** value to the application-defined function. ^If there is no metadata
4749
+** associated with the function argument, this sqlite3_get_auxdata() interface
4750
+** returns a NULL pointer.
4751
+**
4752
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
4753
+** argument of the application-defined function. ^Subsequent
4754
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
4755
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
4756
+** NULL if the metadata has been discarded.
4757
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
4758
+** SQLite will invoke the destructor function X with parameter P exactly
4759
+** once, when the metadata is discarded.
4760
+** SQLite is free to discard the metadata at any time, including: <ul>
4761
+** <li> when the corresponding function parameter changes, or
4762
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
4763
+** SQL statement, or
4764
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
4765
+** <li> during the original sqlite3_set_auxdata() call when a memory
4766
+** allocation error occurs. </ul>)^
4767
+**
4768
+** Note the last bullet in particular. The destructor X in
4769
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
4770
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
4771
+** should be called near the end of the function implementation and the
4772
+** function implementation should not make any use of P after
4773
+** sqlite3_set_auxdata() has been called.
47784774
**
47794775
** ^(In practice, metadata is preserved between function calls for
4780
-** expressions that are constant at compile time. This includes literal
4781
-** values and [parameters].)^
4776
+** function parameters that are compile-time constants, including literal
4777
+** values and [parameters] and expressions composed from the same.)^
47824778
**
47834779
** These routines must be called from the same thread in which
47844780
** the SQL function is running.
47854781
*/
47864782
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
@@ -5689,14 +5685,27 @@
56895685
**
56905686
** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
56915687
** on the list of automatic extensions is a harmless no-op. ^No entry point
56925688
** will be called more than once for each database connection that is opened.
56935689
**
5694
-** See also: [sqlite3_reset_auto_extension()].
5690
+** See also: [sqlite3_reset_auto_extension()]
5691
+** and [sqlite3_cancel_auto_extension()]
56955692
*/
56965693
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
56975694
5695
+/*
5696
+** CAPI3REF: Cancel Automatic Extension Loading
5697
+**
5698
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
5699
+** initialization routine X that was registered using a prior call to
5700
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
5701
+** routine returns 1 if initialization routine X was successfully
5702
+** unregistered and it returns 0 if X was not on the list of initialization
5703
+** routines.
5704
+*/
5705
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
5706
+
56985707
/*
56995708
** CAPI3REF: Reset Automatic Extension Loading
57005709
**
57015710
** ^This interface disables all automatic extensions previously
57025711
** registered using [sqlite3_auto_extension()].
@@ -6805,10 +6814,16 @@
68056814
** transaction rollback or database recovery operations are not included.
68066815
** If an IO or other error occurs while writing a page to disk, the effect
68076816
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
68086817
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
68096818
** </dd>
6819
+**
6820
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
6821
+** <dd>This parameter returns zero for the current value if and only if
6822
+** all foreign key constraints (deferred or immediate) have been
6823
+** resolved.)^ ^The highwater mark is always 0.
6824
+** </dd>
68106825
** </dl>
68116826
*/
68126827
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
68136828
#define SQLITE_DBSTATUS_CACHE_USED 1
68146829
#define SQLITE_DBSTATUS_SCHEMA_USED 2
@@ -6817,11 +6832,12 @@
68176832
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
68186833
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
68196834
#define SQLITE_DBSTATUS_CACHE_HIT 7
68206835
#define SQLITE_DBSTATUS_CACHE_MISS 8
68216836
#define SQLITE_DBSTATUS_CACHE_WRITE 9
6822
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
6837
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
6838
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
68236839
68246840
68256841
/*
68266842
** CAPI3REF: Prepared Statement Status
68276843
**
@@ -8795,11 +8811,10 @@
87958811
87968812
/*
87978813
** The names of the following types declared in vdbeInt.h are required
87988814
** for the VdbeOp definition.
87998815
*/
8800
-typedef struct VdbeFunc VdbeFunc;
88018816
typedef struct Mem Mem;
88028817
typedef struct SubProgram SubProgram;
88038818
88048819
/*
88058820
** A single instruction of the virtual machine has an opcode
@@ -8819,11 +8834,10 @@
88198834
void *p; /* Generic pointer */
88208835
char *z; /* Pointer to data for string (char array) types */
88218836
i64 *pI64; /* Used when p4type is P4_INT64 */
88228837
double *pReal; /* Used when p4type is P4_REAL */
88238838
FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
8824
- VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */
88258839
CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
88268840
Mem *pMem; /* Used when p4type is P4_MEM */
88278841
VTable *pVtab; /* Used when p4type is P4_VTAB */
88288842
KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
88298843
int *ai; /* Used when p4type is P4_INTARRAY */
@@ -8873,11 +8887,10 @@
88738887
#define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
88748888
#define P4_STATIC (-2) /* Pointer to a static string */
88758889
#define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
88768890
#define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
88778891
#define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
8878
-#define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
88798892
#define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
88808893
#define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
88818894
#define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
88828895
#define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
88838896
#define P4_REAL (-12) /* P4 is a 64-bit floating point value */
@@ -8930,155 +8943,155 @@
89308943
*/
89318944
/************** Include opcodes.h in the middle of vdbe.h ********************/
89328945
/************** Begin file opcodes.h *****************************************/
89338946
/* Automatically generated. Do not edit */
89348947
/* See the mkopcodeh.awk script for details */
8935
-#define OP_Goto 1
8936
-#define OP_Gosub 2
8937
-#define OP_Return 3
8938
-#define OP_Yield 4
8939
-#define OP_HaltIfNull 5
8940
-#define OP_Halt 6
8941
-#define OP_Integer 7
8942
-#define OP_Int64 8
8943
-#define OP_Real 130 /* same as TK_FLOAT */
8944
-#define OP_String8 94 /* same as TK_STRING */
8945
-#define OP_String 9
8946
-#define OP_Null 10
8947
-#define OP_Blob 11
8948
-#define OP_Variable 12
8949
-#define OP_Move 13
8950
-#define OP_Copy 14
8951
-#define OP_SCopy 15
8952
-#define OP_ResultRow 16
8953
-#define OP_Concat 91 /* same as TK_CONCAT */
8948
+#define OP_Function 1
8949
+#define OP_Savepoint 2
8950
+#define OP_AutoCommit 3
8951
+#define OP_Transaction 4
8952
+#define OP_SorterNext 5
8953
+#define OP_Prev 6
8954
+#define OP_Next 7
8955
+#define OP_AggStep 8
8956
+#define OP_Checkpoint 9
8957
+#define OP_JournalMode 10
8958
+#define OP_Vacuum 11
8959
+#define OP_VFilter 12
8960
+#define OP_VUpdate 13
8961
+#define OP_Goto 14
8962
+#define OP_Gosub 15
8963
+#define OP_Return 16
8964
+#define OP_Yield 17
8965
+#define OP_HaltIfNull 18
8966
+#define OP_Not 19 /* same as TK_NOT */
8967
+#define OP_Halt 20
8968
+#define OP_Integer 21
8969
+#define OP_Int64 22
8970
+#define OP_String 23
8971
+#define OP_Null 24
8972
+#define OP_Blob 25
8973
+#define OP_Variable 26
8974
+#define OP_Move 27
8975
+#define OP_Copy 28
8976
+#define OP_SCopy 29
8977
+#define OP_ResultRow 30
8978
+#define OP_CollSeq 31
8979
+#define OP_AddImm 32
8980
+#define OP_MustBeInt 33
8981
+#define OP_RealAffinity 34
8982
+#define OP_Permutation 35
8983
+#define OP_Compare 36
8984
+#define OP_Jump 37
8985
+#define OP_Once 38
8986
+#define OP_If 39
8987
+#define OP_IfNot 40
8988
+#define OP_Column 41
8989
+#define OP_Affinity 42
8990
+#define OP_MakeRecord 43
8991
+#define OP_Count 44
8992
+#define OP_ReadCookie 45
8993
+#define OP_SetCookie 46
8994
+#define OP_VerifyCookie 47
8995
+#define OP_OpenRead 48
8996
+#define OP_OpenWrite 49
8997
+#define OP_OpenAutoindex 50
8998
+#define OP_OpenEphemeral 51
8999
+#define OP_SorterOpen 52
9000
+#define OP_OpenPseudo 53
9001
+#define OP_Close 54
9002
+#define OP_SeekLt 55
9003
+#define OP_SeekLe 56
9004
+#define OP_SeekGe 57
9005
+#define OP_SeekGt 58
9006
+#define OP_Seek 59
9007
+#define OP_NotFound 60
9008
+#define OP_Found 61
9009
+#define OP_IsUnique 62
9010
+#define OP_NotExists 63
9011
+#define OP_Sequence 64
9012
+#define OP_NewRowid 65
9013
+#define OP_Insert 66
9014
+#define OP_InsertInt 67
9015
+#define OP_Or 68 /* same as TK_OR */
9016
+#define OP_And 69 /* same as TK_AND */
9017
+#define OP_Delete 70
9018
+#define OP_ResetCount 71
9019
+#define OP_SorterCompare 72
9020
+#define OP_IsNull 73 /* same as TK_ISNULL */
9021
+#define OP_NotNull 74 /* same as TK_NOTNULL */
9022
+#define OP_Ne 75 /* same as TK_NE */
9023
+#define OP_Eq 76 /* same as TK_EQ */
9024
+#define OP_Gt 77 /* same as TK_GT */
9025
+#define OP_Le 78 /* same as TK_LE */
9026
+#define OP_Lt 79 /* same as TK_LT */
9027
+#define OP_Ge 80 /* same as TK_GE */
9028
+#define OP_SorterData 81
9029
+#define OP_BitAnd 82 /* same as TK_BITAND */
9030
+#define OP_BitOr 83 /* same as TK_BITOR */
9031
+#define OP_ShiftLeft 84 /* same as TK_LSHIFT */
9032
+#define OP_ShiftRight 85 /* same as TK_RSHIFT */
89549033
#define OP_Add 86 /* same as TK_PLUS */
89559034
#define OP_Subtract 87 /* same as TK_MINUS */
89569035
#define OP_Multiply 88 /* same as TK_STAR */
89579036
#define OP_Divide 89 /* same as TK_SLASH */
89589037
#define OP_Remainder 90 /* same as TK_REM */
8959
-#define OP_CollSeq 17
8960
-#define OP_Function 18
8961
-#define OP_BitAnd 82 /* same as TK_BITAND */
8962
-#define OP_BitOr 83 /* same as TK_BITOR */
8963
-#define OP_ShiftLeft 84 /* same as TK_LSHIFT */
8964
-#define OP_ShiftRight 85 /* same as TK_RSHIFT */
8965
-#define OP_AddImm 20
8966
-#define OP_MustBeInt 21
8967
-#define OP_RealAffinity 22
9038
+#define OP_Concat 91 /* same as TK_CONCAT */
9039
+#define OP_RowKey 92
9040
+#define OP_BitNot 93 /* same as TK_BITNOT */
9041
+#define OP_String8 94 /* same as TK_STRING */
9042
+#define OP_RowData 95
9043
+#define OP_Rowid 96
9044
+#define OP_NullRow 97
9045
+#define OP_Last 98
9046
+#define OP_SorterSort 99
9047
+#define OP_Sort 100
9048
+#define OP_Rewind 101
9049
+#define OP_SorterInsert 102
9050
+#define OP_IdxInsert 103
9051
+#define OP_IdxDelete 104
9052
+#define OP_IdxRowid 105
9053
+#define OP_IdxLT 106
9054
+#define OP_IdxGE 107
9055
+#define OP_Destroy 108
9056
+#define OP_Clear 109
9057
+#define OP_CreateIndex 110
9058
+#define OP_CreateTable 111
9059
+#define OP_ParseSchema 112
9060
+#define OP_LoadAnalysis 113
9061
+#define OP_DropTable 114
9062
+#define OP_DropIndex 115
9063
+#define OP_DropTrigger 116
9064
+#define OP_IntegrityCk 117
9065
+#define OP_RowSetAdd 118
9066
+#define OP_RowSetRead 119
9067
+#define OP_RowSetTest 120
9068
+#define OP_Program 121
9069
+#define OP_Param 122
9070
+#define OP_FkCounter 123
9071
+#define OP_FkIfZero 124
9072
+#define OP_MemMax 125
9073
+#define OP_IfPos 126
9074
+#define OP_IfNeg 127
9075
+#define OP_IfZero 128
9076
+#define OP_AggFinal 129
9077
+#define OP_Real 130 /* same as TK_FLOAT */
9078
+#define OP_IncrVacuum 131
9079
+#define OP_Expire 132
9080
+#define OP_TableLock 133
9081
+#define OP_VBegin 134
9082
+#define OP_VCreate 135
9083
+#define OP_VDestroy 136
9084
+#define OP_VOpen 137
9085
+#define OP_VColumn 138
9086
+#define OP_VNext 139
9087
+#define OP_VRename 140
89689088
#define OP_ToText 141 /* same as TK_TO_TEXT */
89699089
#define OP_ToBlob 142 /* same as TK_TO_BLOB */
89709090
#define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
89719091
#define OP_ToInt 144 /* same as TK_TO_INT */
89729092
#define OP_ToReal 145 /* same as TK_TO_REAL */
8973
-#define OP_Eq 76 /* same as TK_EQ */
8974
-#define OP_Ne 75 /* same as TK_NE */
8975
-#define OP_Lt 79 /* same as TK_LT */
8976
-#define OP_Le 78 /* same as TK_LE */
8977
-#define OP_Gt 77 /* same as TK_GT */
8978
-#define OP_Ge 80 /* same as TK_GE */
8979
-#define OP_Permutation 23
8980
-#define OP_Compare 24
8981
-#define OP_Jump 25
8982
-#define OP_And 69 /* same as TK_AND */
8983
-#define OP_Or 68 /* same as TK_OR */
8984
-#define OP_Not 19 /* same as TK_NOT */
8985
-#define OP_BitNot 93 /* same as TK_BITNOT */
8986
-#define OP_Once 26
8987
-#define OP_If 27
8988
-#define OP_IfNot 28
8989
-#define OP_IsNull 73 /* same as TK_ISNULL */
8990
-#define OP_NotNull 74 /* same as TK_NOTNULL */
8991
-#define OP_Column 29
8992
-#define OP_Affinity 30
8993
-#define OP_MakeRecord 31
8994
-#define OP_Count 32
8995
-#define OP_Savepoint 33
8996
-#define OP_AutoCommit 34
8997
-#define OP_Transaction 35
8998
-#define OP_ReadCookie 36
8999
-#define OP_SetCookie 37
9000
-#define OP_VerifyCookie 38
9001
-#define OP_OpenRead 39
9002
-#define OP_OpenWrite 40
9003
-#define OP_OpenAutoindex 41
9004
-#define OP_OpenEphemeral 42
9005
-#define OP_SorterOpen 43
9006
-#define OP_OpenPseudo 44
9007
-#define OP_Close 45
9008
-#define OP_SeekLt 46
9009
-#define OP_SeekLe 47
9010
-#define OP_SeekGe 48
9011
-#define OP_SeekGt 49
9012
-#define OP_Seek 50
9013
-#define OP_NotFound 51
9014
-#define OP_Found 52
9015
-#define OP_IsUnique 53
9016
-#define OP_NotExists 54
9017
-#define OP_Sequence 55
9018
-#define OP_NewRowid 56
9019
-#define OP_Insert 57
9020
-#define OP_InsertInt 58
9021
-#define OP_Delete 59
9022
-#define OP_ResetCount 60
9023
-#define OP_SorterCompare 61
9024
-#define OP_SorterData 62
9025
-#define OP_RowKey 63
9026
-#define OP_RowData 64
9027
-#define OP_Rowid 65
9028
-#define OP_NullRow 66
9029
-#define OP_Last 67
9030
-#define OP_SorterSort 70
9031
-#define OP_Sort 71
9032
-#define OP_Rewind 72
9033
-#define OP_SorterNext 81
9034
-#define OP_Prev 92
9035
-#define OP_Next 95
9036
-#define OP_SorterInsert 96
9037
-#define OP_IdxInsert 97
9038
-#define OP_IdxDelete 98
9039
-#define OP_IdxRowid 99
9040
-#define OP_IdxLT 100
9041
-#define OP_IdxGE 101
9042
-#define OP_Destroy 102
9043
-#define OP_Clear 103
9044
-#define OP_CreateIndex 104
9045
-#define OP_CreateTable 105
9046
-#define OP_ParseSchema 106
9047
-#define OP_LoadAnalysis 107
9048
-#define OP_DropTable 108
9049
-#define OP_DropIndex 109
9050
-#define OP_DropTrigger 110
9051
-#define OP_IntegrityCk 111
9052
-#define OP_RowSetAdd 112
9053
-#define OP_RowSetRead 113
9054
-#define OP_RowSetTest 114
9055
-#define OP_Program 115
9056
-#define OP_Param 116
9057
-#define OP_FkCounter 117
9058
-#define OP_FkIfZero 118
9059
-#define OP_MemMax 119
9060
-#define OP_IfPos 120
9061
-#define OP_IfNeg 121
9062
-#define OP_IfZero 122
9063
-#define OP_AggStep 123
9064
-#define OP_AggFinal 124
9065
-#define OP_Checkpoint 125
9066
-#define OP_JournalMode 126
9067
-#define OP_Vacuum 127
9068
-#define OP_IncrVacuum 128
9069
-#define OP_Expire 129
9070
-#define OP_TableLock 131
9071
-#define OP_VBegin 132
9072
-#define OP_VCreate 133
9073
-#define OP_VDestroy 134
9074
-#define OP_VOpen 135
9075
-#define OP_VFilter 136
9076
-#define OP_VColumn 137
9077
-#define OP_VNext 138
9078
-#define OP_VRename 139
9079
-#define OP_VUpdate 140
90809093
#define OP_Pagecount 146
90819094
#define OP_MaxPgcnt 147
90829095
#define OP_Trace 148
90839096
#define OP_Noop 149
90849097
#define OP_Explain 150
@@ -9094,28 +9107,28 @@
90949107
#define OPFLG_IN2 0x0008 /* in2: P2 is an input */
90959108
#define OPFLG_IN3 0x0010 /* in3: P3 is an input */
90969109
#define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
90979110
#define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
90989111
#define OPFLG_INITIALIZER {\
9099
-/* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
9100
-/* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
9101
-/* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
9102
-/* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
9103
-/* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
9104
-/* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
9105
-/* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
9106
-/* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
9107
-/* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
9108
-/* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
9109
-/* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
9110
-/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\
9111
-/* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
9112
-/* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
9113
-/* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
9114
-/* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
9115
-/* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
9116
-/* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
9112
+/* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
9113
+/* 8 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01,\
9114
+/* 16 */ 0x04, 0x04, 0x10, 0x24, 0x00, 0x02, 0x02, 0x02,\
9115
+/* 24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00,\
9116
+/* 32 */ 0x04, 0x05, 0x04, 0x00, 0x00, 0x01, 0x01, 0x05,\
9117
+/* 40 */ 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\
9118
+/* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\
9119
+/* 56 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\
9120
+/* 64 */ 0x02, 0x02, 0x00, 0x00, 0x4c, 0x4c, 0x00, 0x00,\
9121
+/* 72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
9122
+/* 80 */ 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
9123
+/* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02, 0x00,\
9124
+/* 96 */ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08,\
9125
+/* 104 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02,\
9126
+/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\
9127
+/* 120 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05, 0x05,\
9128
+/* 128 */ 0x05, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,\
9129
+/* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x04, 0x04,\
91179130
/* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
91189131
91199132
/************** End of opcodes.h *********************************************/
91209133
/************** Continuing where we left off in vdbe.h ***********************/
91219134
@@ -9161,11 +9174,11 @@
91619174
SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
91629175
SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
91639176
SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
91649177
SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
91659178
SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
9166
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
9179
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
91679180
SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
91689181
#ifndef SQLITE_OMIT_TRACE
91699182
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
91709183
#endif
91719184
@@ -10117,11 +10130,11 @@
1011710130
void *pAuthArg; /* 1st argument to the access auth function */
1011810131
#endif
1011910132
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
1012010133
int (*xProgress)(void *); /* The progress callback */
1012110134
void *pProgressArg; /* Argument to the progress callback */
10122
- int nProgressOps; /* Number of opcodes for progress callback */
10135
+ unsigned nProgressOps; /* Number of opcodes for progress callback */
1012310136
#endif
1012410137
#ifndef SQLITE_OMIT_VIRTUALTABLE
1012510138
int nVTrans; /* Allocated size of aVTrans */
1012610139
Hash aModule; /* populated by sqlite3_create_module() */
1012710140
VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
@@ -10135,10 +10148,11 @@
1013510148
Savepoint *pSavepoint; /* List of active savepoints */
1013610149
int busyTimeout; /* Busy handler timeout, in msec */
1013710150
int nSavepoint; /* Number of non-transaction savepoints */
1013810151
int nStatement; /* Number of nested statement-transactions */
1013910152
i64 nDeferredCons; /* Net deferred constraints this transaction. */
10153
+ i64 nDeferredImmCons; /* Net deferred immediate constraints */
1014010154
int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
1014110155
1014210156
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
1014310157
/* The following variables are all protected by the STATIC_MASTER
1014410158
** mutex, not by sqlite3.mutex. They are used by code in notify.c.
@@ -10190,10 +10204,13 @@
1019010204
#define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
1019110205
#define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
1019210206
#define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
1019310207
#define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
1019410208
#define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
10209
+#define SQLITE_DeferFKs 0x00800000 /* Defer all FK constraints */
10210
+#define SQLITE_QueryOnly 0x01000000 /* Disable database changes */
10211
+
1019510212
1019610213
/*
1019710214
** Bits of the sqlite3.dbOptFlags field that are used by the
1019810215
** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
1019910216
** selectively disable various optimizations.
@@ -10336,10 +10353,11 @@
1033610353
** OP_Savepoint instruction.
1033710354
*/
1033810355
struct Savepoint {
1033910356
char *zName; /* Savepoint name (nul-terminated) */
1034010357
i64 nDeferredCons; /* Number of deferred fk violations */
10358
+ i64 nDeferredImmCons; /* Number of deferred imm fk. */
1034110359
Savepoint *pNext; /* Parent savepoint (if any) */
1034210360
};
1034310361
1034410362
/*
1034510363
** The following are used as the second parameter to sqlite3Savepoint(),
@@ -10654,16 +10672,20 @@
1065410672
1065510673
/*
1065610674
** An instance of the following structure is passed as the first
1065710675
** argument to sqlite3VdbeKeyCompare and is used to control the
1065810676
** comparison of the two index keys.
10677
+**
10678
+** Note that aSortOrder[] and aColl[] have nField+1 slots. There
10679
+** are nField slots for the columns of an index then one extra slot
10680
+** for the rowid at the end.
1065910681
*/
1066010682
struct KeyInfo {
1066110683
sqlite3 *db; /* The database connection */
1066210684
u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
10663
- u16 nField; /* Number of entries in aColl[] */
10664
- u8 *aSortOrder; /* Sort order for each column. May be NULL */
10685
+ u16 nField; /* Maximum index for aColl[] and aSortOrder[] */
10686
+ u8 *aSortOrder; /* Sort order for each column. */
1066510687
CollSeq *aColl[1]; /* Collating sequence for each term of the key */
1066610688
};
1066710689
1066810690
/*
1066910691
** An instance of the following structure holds information about a
@@ -10728,10 +10750,11 @@
1072810750
char *zColAff; /* String defining the affinity of each column */
1072910751
Index *pNext; /* The next index associated with the same table */
1073010752
Schema *pSchema; /* Schema containing this index */
1073110753
u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
1073210754
char **azColl; /* Array of collation sequence names for index */
10755
+ Expr *pPartIdxWhere; /* WHERE clause for partial indices */
1073310756
int tnum; /* DB Page containing root of this index */
1073410757
u16 nColumn; /* Number of columns in table used by this index */
1073510758
u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
1073610759
unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
1073710760
unsigned bUnordered:1; /* Use this index for == or IN queries only */
@@ -11208,10 +11231,11 @@
1120811231
#define NC_HasAgg 0x02 /* One or more aggregate functions seen */
1120911232
#define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
1121011233
#define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
1121111234
#define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only
1121211235
** if no other resolution is available */
11236
+#define NC_PartIdx 0x20 /* True if resolving a partial index WHERE */
1121311237
1121411238
/*
1121511239
** An instance of the following structure contains all information
1121611240
** needed to generate code for a single SELECT statement.
1121711241
**
@@ -11262,10 +11286,11 @@
1126211286
#define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
1126311287
#define SF_UseSorter 0x0040 /* Sort using a sorter */
1126411288
#define SF_Values 0x0080 /* Synthesized from VALUES clause */
1126511289
#define SF_Materialize 0x0100 /* Force materialization of views */
1126611290
#define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
11291
+#define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
1126711292
1126811293
1126911294
/*
1127011295
** The results of a select can be distributed in several ways. The
1127111296
** "SRT" prefix means "SELECT Result Type".
@@ -11383,19 +11408,21 @@
1138311408
u8 nTempInUse; /* Number of aTempReg[] currently checked out */
1138411409
u8 nColCache; /* Number of entries in aColCache[] */
1138511410
u8 iColCache; /* Next entry in aColCache[] to replace */
1138611411
u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
1138711412
u8 mayAbort; /* True if statement may throw an ABORT exception */
11413
+ u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
1138811414
int aTempReg[8]; /* Holding area for temporary registers */
1138911415
int nRangeReg; /* Size of the temporary register block */
1139011416
int iRangeReg; /* First register in temporary register block */
1139111417
int nErr; /* Number of errors seen */
1139211418
int nTab; /* Number of previously allocated VDBE cursors */
1139311419
int nMem; /* Number of memory cells used so far */
1139411420
int nSet; /* Number of sets used so far */
1139511421
int nOnce; /* Number of OP_Once instructions so far */
1139611422
int ckBase; /* Base register of data during check constraints */
11423
+ int iPartIdxTab; /* Table corresponding to a partial index */
1139711424
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
1139811425
int iCacheCnt; /* Counter used to generate aColCache[].lru values */
1139911426
struct yColCache {
1140011427
int iTable; /* Table cursor number */
1140111428
int iColumn; /* Table column number */
@@ -11973,11 +12000,11 @@
1197312000
SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
1197412001
SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
1197512002
SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
1197612003
SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
1197712004
SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
11978
- Token*, int, int);
12005
+ Expr*, int, int);
1197912006
SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
1198012007
SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
1198112008
SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
1198212009
Expr*,ExprList*,u16,Expr*,Expr*);
1198312010
SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
@@ -12021,12 +12048,13 @@
1202112048
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
1202212049
SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
1202312050
SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
1202412051
SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
1202512052
SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
12026
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
12027
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
12053
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
12054
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
12055
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
1202812056
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
1202912057
SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
1203012058
SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
1203112059
SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
1203212060
SQLITE_PRIVATE void sqlite3PrngSaveState(void);
@@ -12049,11 +12077,11 @@
1204912077
SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
1205012078
SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
1205112079
SQLITE_PRIVATE int sqlite3IsRowid(const char*);
1205212080
SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
1205312081
SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
12054
-SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
12082
+SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
1205512083
SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
1205612084
int*,int,int,int,int,int*);
1205712085
SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
1205812086
SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
1205912087
SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
@@ -12252,10 +12280,11 @@
1225212280
SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
1225312281
SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
1225412282
SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
1225512283
SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
1225612284
SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
12285
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
1225712286
SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
1225812287
SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
1225912288
SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
1226012289
SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
1226112290
SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
@@ -12271,10 +12300,11 @@
1227112300
SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
1227212301
SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
1227312302
SQLITE_PRIVATE void sqlite3SchemaClear(void *);
1227412303
SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
1227512304
SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
12305
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
1227612306
SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
1227712307
SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
1227812308
void (*)(sqlite3_context*,int,sqlite3_value **),
1227912309
void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
1228012310
FuncDestructor *pDestructor
@@ -13223,10 +13253,13 @@
1322313253
typedef struct VdbeSorter VdbeSorter;
1322413254
1322513255
/* Opaque type used by the explainer */
1322613256
typedef struct Explain Explain;
1322713257
13258
+/* Elements of the linked list at Vdbe.pAuxData */
13259
+typedef struct AuxData AuxData;
13260
+
1322813261
/*
1322913262
** A cursor is a pointer into a single BTree within a database file.
1323013263
** The cursor can seek to a BTree entry with a particular key, or
1323113264
** loop over all entries of the Btree. You can also insert new BTree
1323213265
** entries or retrieve the key or data from the entry that the cursor
@@ -13409,27 +13442,23 @@
1340913442
*/
1341013443
#ifdef SQLITE_DEBUG
1341113444
#define memIsValid(M) ((M)->flags & MEM_Invalid)==0
1341213445
#endif
1341313446
13414
-
13415
-/* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
13416
-** additional information about auxiliary information bound to arguments
13417
-** of the function. This is used to implement the sqlite3_get_auxdata()
13418
-** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data
13419
-** that can be associated with a constant argument to a function. This
13420
-** allows functions such as "regexp" to compile their constant regular
13421
-** expression argument once and reused the compiled code for multiple
13422
-** invocations.
13447
+/*
13448
+** Each auxilliary data pointer stored by a user defined function
13449
+** implementation calling sqlite3_set_auxdata() is stored in an instance
13450
+** of this structure. All such structures associated with a single VM
13451
+** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
13452
+** when the VM is halted (if not before).
1342313453
*/
13424
-struct VdbeFunc {
13425
- FuncDef *pFunc; /* The definition of the function */
13426
- int nAux; /* Number of entries allocated for apAux[] */
13427
- struct AuxData {
13428
- void *pAux; /* Aux data for the i-th argument */
13429
- void (*xDelete)(void *); /* Destructor for the aux data */
13430
- } apAux[1]; /* One slot for each function argument */
13454
+struct AuxData {
13455
+ int iOp; /* Instruction number of OP_Function opcode */
13456
+ int iArg; /* Index of function argument. */
13457
+ void *pAux; /* Aux data pointer */
13458
+ void (*xDelete)(void *); /* Destructor for the aux data */
13459
+ AuxData *pNext; /* Next element in list */
1343113460
};
1343213461
1343313462
/*
1343413463
** The "context" argument for a installable function. A pointer to an
1343513464
** instance of this structure is the first argument to the routines used
@@ -13443,16 +13472,17 @@
1344313472
** This structure is defined inside of vdbeInt.h because it uses substructures
1344413473
** (Mem) which are only defined there.
1344513474
*/
1344613475
struct sqlite3_context {
1344713476
FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
13448
- VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
1344913477
Mem s; /* The return value is stored here */
1345013478
Mem *pMem; /* Memory cell used to store aggregate context */
1345113479
CollSeq *pColl; /* Collating sequence */
1345213480
int isError; /* Error code returned by the function. */
1345313481
int skipFlag; /* Skip skip accumulator loading if true */
13482
+ int iOp; /* Instruction number of OP_Function */
13483
+ Vdbe *pVdbe; /* The VM that owns this context */
1345413484
};
1345513485
1345613486
/*
1345713487
** An Explain object accumulates indented output which is helpful
1345813488
** in describing recursive data structures.
@@ -13530,10 +13560,11 @@
1353013560
#ifndef SQLITE_OMIT_TRACE
1353113561
i64 startTime; /* Time when query started - used for profiling */
1353213562
#endif
1353313563
i64 nFkConstraint; /* Number of imm. FK constraints this VM */
1353413564
i64 nStmtDefCons; /* Number of def. constraints when stmt started */
13565
+ i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
1353513566
char *zSql; /* Text of the SQL statement that generated this */
1353613567
void *pFree; /* Free this when deleting the vdbe */
1353713568
#ifdef SQLITE_DEBUG
1353813569
FILE *trace; /* Write an execution trace here, if not NULL */
1353913570
#endif
@@ -13546,10 +13577,11 @@
1354613577
int nFrame; /* Number of frames in pFrame list */
1354713578
u32 expmask; /* Binding to these vars invalidates VM */
1354813579
SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
1354913580
int nOnceFlag; /* Size of array aOnceFlag[] */
1355013581
u8 *aOnceFlag; /* Flags for OP_Once */
13582
+ AuxData *pAuxData; /* Linked list of auxdata allocations */
1355113583
};
1355213584
1355313585
/*
1355413586
** The following are allowed values for Vdbe.magic
1355513587
*/
@@ -13569,11 +13601,11 @@
1356913601
#endif
1357013602
SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
1357113603
SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
1357213604
SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
1357313605
SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
13574
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
13606
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
1357513607
1357613608
int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
1357713609
SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
1357813610
SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
1357913611
SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
@@ -13889,10 +13921,20 @@
1388913921
}
1389013922
*pHighwater = 0;
1389113923
*pCurrent = nRet;
1389213924
break;
1389313925
}
13926
+
13927
+ /* Set *pCurrent to non-zero if there are unresolved deferred foreign
13928
+ ** key constraints. Set *pCurrent to zero if all foreign key constraints
13929
+ ** have been satisfied. The *pHighwater is always set to zero.
13930
+ */
13931
+ case SQLITE_DBSTATUS_DEFERRED_FKS: {
13932
+ *pHighwater = 0;
13933
+ *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
13934
+ break;
13935
+ }
1389413936
1389513937
default: {
1389613938
rc = SQLITE_ERROR;
1389713939
}
1389813940
}
@@ -22658,91 +22700,91 @@
2265822700
/* Automatically generated. Do not edit */
2265922701
/* See the mkopcodec.awk script for details. */
2266022702
#if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
2266122703
SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
2266222704
static const char *const azName[] = { "?",
22663
- /* 1 */ "Goto",
22664
- /* 2 */ "Gosub",
22665
- /* 3 */ "Return",
22666
- /* 4 */ "Yield",
22667
- /* 5 */ "HaltIfNull",
22668
- /* 6 */ "Halt",
22669
- /* 7 */ "Integer",
22670
- /* 8 */ "Int64",
22671
- /* 9 */ "String",
22672
- /* 10 */ "Null",
22673
- /* 11 */ "Blob",
22674
- /* 12 */ "Variable",
22675
- /* 13 */ "Move",
22676
- /* 14 */ "Copy",
22677
- /* 15 */ "SCopy",
22678
- /* 16 */ "ResultRow",
22679
- /* 17 */ "CollSeq",
22680
- /* 18 */ "Function",
22705
+ /* 1 */ "Function",
22706
+ /* 2 */ "Savepoint",
22707
+ /* 3 */ "AutoCommit",
22708
+ /* 4 */ "Transaction",
22709
+ /* 5 */ "SorterNext",
22710
+ /* 6 */ "Prev",
22711
+ /* 7 */ "Next",
22712
+ /* 8 */ "AggStep",
22713
+ /* 9 */ "Checkpoint",
22714
+ /* 10 */ "JournalMode",
22715
+ /* 11 */ "Vacuum",
22716
+ /* 12 */ "VFilter",
22717
+ /* 13 */ "VUpdate",
22718
+ /* 14 */ "Goto",
22719
+ /* 15 */ "Gosub",
22720
+ /* 16 */ "Return",
22721
+ /* 17 */ "Yield",
22722
+ /* 18 */ "HaltIfNull",
2268122723
/* 19 */ "Not",
22682
- /* 20 */ "AddImm",
22683
- /* 21 */ "MustBeInt",
22684
- /* 22 */ "RealAffinity",
22685
- /* 23 */ "Permutation",
22686
- /* 24 */ "Compare",
22687
- /* 25 */ "Jump",
22688
- /* 26 */ "Once",
22689
- /* 27 */ "If",
22690
- /* 28 */ "IfNot",
22691
- /* 29 */ "Column",
22692
- /* 30 */ "Affinity",
22693
- /* 31 */ "MakeRecord",
22694
- /* 32 */ "Count",
22695
- /* 33 */ "Savepoint",
22696
- /* 34 */ "AutoCommit",
22697
- /* 35 */ "Transaction",
22698
- /* 36 */ "ReadCookie",
22699
- /* 37 */ "SetCookie",
22700
- /* 38 */ "VerifyCookie",
22701
- /* 39 */ "OpenRead",
22702
- /* 40 */ "OpenWrite",
22703
- /* 41 */ "OpenAutoindex",
22704
- /* 42 */ "OpenEphemeral",
22705
- /* 43 */ "SorterOpen",
22706
- /* 44 */ "OpenPseudo",
22707
- /* 45 */ "Close",
22708
- /* 46 */ "SeekLt",
22709
- /* 47 */ "SeekLe",
22710
- /* 48 */ "SeekGe",
22711
- /* 49 */ "SeekGt",
22712
- /* 50 */ "Seek",
22713
- /* 51 */ "NotFound",
22714
- /* 52 */ "Found",
22715
- /* 53 */ "IsUnique",
22716
- /* 54 */ "NotExists",
22717
- /* 55 */ "Sequence",
22718
- /* 56 */ "NewRowid",
22719
- /* 57 */ "Insert",
22720
- /* 58 */ "InsertInt",
22721
- /* 59 */ "Delete",
22722
- /* 60 */ "ResetCount",
22723
- /* 61 */ "SorterCompare",
22724
- /* 62 */ "SorterData",
22725
- /* 63 */ "RowKey",
22726
- /* 64 */ "RowData",
22727
- /* 65 */ "Rowid",
22728
- /* 66 */ "NullRow",
22729
- /* 67 */ "Last",
22724
+ /* 20 */ "Halt",
22725
+ /* 21 */ "Integer",
22726
+ /* 22 */ "Int64",
22727
+ /* 23 */ "String",
22728
+ /* 24 */ "Null",
22729
+ /* 25 */ "Blob",
22730
+ /* 26 */ "Variable",
22731
+ /* 27 */ "Move",
22732
+ /* 28 */ "Copy",
22733
+ /* 29 */ "SCopy",
22734
+ /* 30 */ "ResultRow",
22735
+ /* 31 */ "CollSeq",
22736
+ /* 32 */ "AddImm",
22737
+ /* 33 */ "MustBeInt",
22738
+ /* 34 */ "RealAffinity",
22739
+ /* 35 */ "Permutation",
22740
+ /* 36 */ "Compare",
22741
+ /* 37 */ "Jump",
22742
+ /* 38 */ "Once",
22743
+ /* 39 */ "If",
22744
+ /* 40 */ "IfNot",
22745
+ /* 41 */ "Column",
22746
+ /* 42 */ "Affinity",
22747
+ /* 43 */ "MakeRecord",
22748
+ /* 44 */ "Count",
22749
+ /* 45 */ "ReadCookie",
22750
+ /* 46 */ "SetCookie",
22751
+ /* 47 */ "VerifyCookie",
22752
+ /* 48 */ "OpenRead",
22753
+ /* 49 */ "OpenWrite",
22754
+ /* 50 */ "OpenAutoindex",
22755
+ /* 51 */ "OpenEphemeral",
22756
+ /* 52 */ "SorterOpen",
22757
+ /* 53 */ "OpenPseudo",
22758
+ /* 54 */ "Close",
22759
+ /* 55 */ "SeekLt",
22760
+ /* 56 */ "SeekLe",
22761
+ /* 57 */ "SeekGe",
22762
+ /* 58 */ "SeekGt",
22763
+ /* 59 */ "Seek",
22764
+ /* 60 */ "NotFound",
22765
+ /* 61 */ "Found",
22766
+ /* 62 */ "IsUnique",
22767
+ /* 63 */ "NotExists",
22768
+ /* 64 */ "Sequence",
22769
+ /* 65 */ "NewRowid",
22770
+ /* 66 */ "Insert",
22771
+ /* 67 */ "InsertInt",
2273022772
/* 68 */ "Or",
2273122773
/* 69 */ "And",
22732
- /* 70 */ "SorterSort",
22733
- /* 71 */ "Sort",
22734
- /* 72 */ "Rewind",
22774
+ /* 70 */ "Delete",
22775
+ /* 71 */ "ResetCount",
22776
+ /* 72 */ "SorterCompare",
2273522777
/* 73 */ "IsNull",
2273622778
/* 74 */ "NotNull",
2273722779
/* 75 */ "Ne",
2273822780
/* 76 */ "Eq",
2273922781
/* 77 */ "Gt",
2274022782
/* 78 */ "Le",
2274122783
/* 79 */ "Lt",
2274222784
/* 80 */ "Ge",
22743
- /* 81 */ "SorterNext",
22785
+ /* 81 */ "SorterData",
2274422786
/* 82 */ "BitAnd",
2274522787
/* 83 */ "BitOr",
2274622788
/* 84 */ "ShiftLeft",
2274722789
/* 85 */ "ShiftRight",
2274822790
/* 86 */ "Add",
@@ -22749,59 +22791,59 @@
2274922791
/* 87 */ "Subtract",
2275022792
/* 88 */ "Multiply",
2275122793
/* 89 */ "Divide",
2275222794
/* 90 */ "Remainder",
2275322795
/* 91 */ "Concat",
22754
- /* 92 */ "Prev",
22796
+ /* 92 */ "RowKey",
2275522797
/* 93 */ "BitNot",
2275622798
/* 94 */ "String8",
22757
- /* 95 */ "Next",
22758
- /* 96 */ "SorterInsert",
22759
- /* 97 */ "IdxInsert",
22760
- /* 98 */ "IdxDelete",
22761
- /* 99 */ "IdxRowid",
22762
- /* 100 */ "IdxLT",
22763
- /* 101 */ "IdxGE",
22764
- /* 102 */ "Destroy",
22765
- /* 103 */ "Clear",
22766
- /* 104 */ "CreateIndex",
22767
- /* 105 */ "CreateTable",
22768
- /* 106 */ "ParseSchema",
22769
- /* 107 */ "LoadAnalysis",
22770
- /* 108 */ "DropTable",
22771
- /* 109 */ "DropIndex",
22772
- /* 110 */ "DropTrigger",
22773
- /* 111 */ "IntegrityCk",
22774
- /* 112 */ "RowSetAdd",
22775
- /* 113 */ "RowSetRead",
22776
- /* 114 */ "RowSetTest",
22777
- /* 115 */ "Program",
22778
- /* 116 */ "Param",
22779
- /* 117 */ "FkCounter",
22780
- /* 118 */ "FkIfZero",
22781
- /* 119 */ "MemMax",
22782
- /* 120 */ "IfPos",
22783
- /* 121 */ "IfNeg",
22784
- /* 122 */ "IfZero",
22785
- /* 123 */ "AggStep",
22786
- /* 124 */ "AggFinal",
22787
- /* 125 */ "Checkpoint",
22788
- /* 126 */ "JournalMode",
22789
- /* 127 */ "Vacuum",
22790
- /* 128 */ "IncrVacuum",
22791
- /* 129 */ "Expire",
22799
+ /* 95 */ "RowData",
22800
+ /* 96 */ "Rowid",
22801
+ /* 97 */ "NullRow",
22802
+ /* 98 */ "Last",
22803
+ /* 99 */ "SorterSort",
22804
+ /* 100 */ "Sort",
22805
+ /* 101 */ "Rewind",
22806
+ /* 102 */ "SorterInsert",
22807
+ /* 103 */ "IdxInsert",
22808
+ /* 104 */ "IdxDelete",
22809
+ /* 105 */ "IdxRowid",
22810
+ /* 106 */ "IdxLT",
22811
+ /* 107 */ "IdxGE",
22812
+ /* 108 */ "Destroy",
22813
+ /* 109 */ "Clear",
22814
+ /* 110 */ "CreateIndex",
22815
+ /* 111 */ "CreateTable",
22816
+ /* 112 */ "ParseSchema",
22817
+ /* 113 */ "LoadAnalysis",
22818
+ /* 114 */ "DropTable",
22819
+ /* 115 */ "DropIndex",
22820
+ /* 116 */ "DropTrigger",
22821
+ /* 117 */ "IntegrityCk",
22822
+ /* 118 */ "RowSetAdd",
22823
+ /* 119 */ "RowSetRead",
22824
+ /* 120 */ "RowSetTest",
22825
+ /* 121 */ "Program",
22826
+ /* 122 */ "Param",
22827
+ /* 123 */ "FkCounter",
22828
+ /* 124 */ "FkIfZero",
22829
+ /* 125 */ "MemMax",
22830
+ /* 126 */ "IfPos",
22831
+ /* 127 */ "IfNeg",
22832
+ /* 128 */ "IfZero",
22833
+ /* 129 */ "AggFinal",
2279222834
/* 130 */ "Real",
22793
- /* 131 */ "TableLock",
22794
- /* 132 */ "VBegin",
22795
- /* 133 */ "VCreate",
22796
- /* 134 */ "VDestroy",
22797
- /* 135 */ "VOpen",
22798
- /* 136 */ "VFilter",
22799
- /* 137 */ "VColumn",
22800
- /* 138 */ "VNext",
22801
- /* 139 */ "VRename",
22802
- /* 140 */ "VUpdate",
22835
+ /* 131 */ "IncrVacuum",
22836
+ /* 132 */ "Expire",
22837
+ /* 133 */ "TableLock",
22838
+ /* 134 */ "VBegin",
22839
+ /* 135 */ "VCreate",
22840
+ /* 136 */ "VDestroy",
22841
+ /* 137 */ "VOpen",
22842
+ /* 138 */ "VColumn",
22843
+ /* 139 */ "VNext",
22844
+ /* 140 */ "VRename",
2280322845
/* 141 */ "ToText",
2280422846
/* 142 */ "ToBlob",
2280522847
/* 143 */ "ToNumeric",
2280622848
/* 144 */ "ToInt",
2280722849
/* 145 */ "ToReal",
@@ -30454,10 +30496,11 @@
3045430496
*/
3045530497
#if SQLITE_OS_WIN /* This file is used for Windows only */
3045630498
3045730499
#ifdef __CYGWIN__
3045830500
# include <sys/cygwin.h>
30501
+/* # include <errno.h> */
3045930502
#endif
3046030503
3046130504
/*
3046230505
** Include code that is common to all os_*.c files
3046330506
*/
@@ -30874,10 +30917,11 @@
3087430917
* zero for the default behavior.
3087530918
*/
3087630919
#ifndef SQLITE_WIN32_HEAP_FLAGS
3087730920
# define SQLITE_WIN32_HEAP_FLAGS (0)
3087830921
#endif
30922
+
3087930923
3088030924
/*
3088130925
** The winMemData structure stores information required by the Win32-specific
3088230926
** sqlite3_mem_methods implementation.
3088330927
*/
@@ -34339,14 +34383,14 @@
3433934383
OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
3434034384
osGetCurrentProcessId(), pFd));
3434134385
return SQLITE_OK;
3434234386
}
3434334387
assert( (nMap % winSysInfo.dwPageSize)==0 );
34344
-#if SQLITE_OS_WINRT
34345
- pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
34346
-#else
3434734388
assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
34389
+#if SQLITE_OS_WINRT
34390
+ pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
34391
+#else
3434834392
pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
3434934393
#endif
3435034394
if( pNew==NULL ){
3435134395
osCloseHandle(pFd->hMap);
3435234396
pFd->hMap = NULL;
@@ -34511,10 +34555,19 @@
3451134555
#endif
3451234556
/* caller will handle out of memory */
3451334557
return zConverted;
3451434558
}
3451534559
34560
+/*
34561
+** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is
34562
+** in characters, so we allocate 3 bytes per character assuming worst-case
34563
+** 3-bytes-per-character UTF8.
34564
+*/
34565
+#ifndef SQLITE_WIN32_MAX_PATH
34566
+# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3)
34567
+#endif
34568
+
3451634569
/*
3451734570
** Create a temporary file name in zBuf. zBuf must be big enough to
3451834571
** hold at pVfs->mxPathname characters.
3451934572
*/
3452034573
static int getTempname(int nBuf, char *zBuf){
@@ -34522,53 +34575,74 @@
3452234575
"abcdefghijklmnopqrstuvwxyz"
3452334576
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
3452434577
"0123456789";
3452534578
size_t i, j;
3452634579
int nTempPath;
34527
- char zTempPath[MAX_PATH+2];
34580
+ char zTempPath[SQLITE_WIN32_MAX_PATH+2];
3452834581
3452934582
/* It's odd to simulate an io-error here, but really this is just
3453034583
** using the io-error infrastructure to test that SQLite handles this
3453134584
** function failing.
3453234585
*/
3453334586
SimulateIOError( return SQLITE_IOERR );
3453434587
34535
- memset(zTempPath, 0, MAX_PATH+2);
34536
-
3453734588
if( sqlite3_temp_directory ){
34538
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
34589
+ sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s",
34590
+ sqlite3_temp_directory);
3453934591
}
3454034592
#if !SQLITE_OS_WINRT
3454134593
else if( isNT() ){
3454234594
char *zMulti;
3454334595
WCHAR zWidePath[MAX_PATH];
34544
- osGetTempPathW(MAX_PATH-30, zWidePath);
34596
+ if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){
34597
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
34598
+ return SQLITE_IOERR_GETTEMPPATH;
34599
+ }
3454534600
zMulti = unicodeToUtf8(zWidePath);
3454634601
if( zMulti ){
34547
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
34602
+ sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti);
3454834603
sqlite3_free(zMulti);
3454934604
}else{
3455034605
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
3455134606
return SQLITE_IOERR_NOMEM;
3455234607
}
3455334608
}
3455434609
#ifdef SQLITE_WIN32_HAS_ANSI
3455534610
else{
3455634611
char *zUtf8;
34557
- char zMbcsPath[MAX_PATH];
34558
- osGetTempPathA(MAX_PATH-30, zMbcsPath);
34612
+ char zMbcsPath[SQLITE_WIN32_MAX_PATH];
34613
+ if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){
34614
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
34615
+ return SQLITE_IOERR_GETTEMPPATH;
34616
+ }
3455934617
zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
3456034618
if( zUtf8 ){
34561
- sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
34619
+ sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8);
3456234620
sqlite3_free(zUtf8);
3456334621
}else{
3456434622
OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
3456534623
return SQLITE_IOERR_NOMEM;
3456634624
}
3456734625
}
34568
-#endif
34569
-#endif
34626
+#else
34627
+ else{
34628
+ /*
34629
+ ** Compiled without ANSI support and the current operating system
34630
+ ** is not Windows NT; therefore, just zero the temporary buffer.
34631
+ */
34632
+ memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
34633
+ }
34634
+#endif /* SQLITE_WIN32_HAS_ANSI */
34635
+#else
34636
+ else{
34637
+ /*
34638
+ ** Compiled for WinRT and the sqlite3_temp_directory is not set;
34639
+ ** therefore, just zero the temporary buffer.
34640
+ */
34641
+ memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
34642
+ }
34643
+#endif /* !SQLITE_OS_WINRT */
3457034644
3457134645
/* Check that the output buffer is large enough for the temporary file
3457234646
** name. If it is not, return SQLITE_ERROR.
3457334647
*/
3457434648
nTempPath = sqlite3Strlen30(zTempPath);
@@ -34650,11 +34724,11 @@
3465034724
int cnt = 0;
3465134725
3465234726
/* If argument zPath is a NULL pointer, this function is required to open
3465334727
** a temporary file. Use this buffer to store the file name in.
3465434728
*/
34655
- char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */
34729
+ char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */
3465634730
3465734731
int rc = SQLITE_OK; /* Function Return Code */
3465834732
#if !defined(NDEBUG) || SQLITE_OS_WINCE
3465934733
int eType = flags&0xFFFFFF00; /* Type of file to open */
3466034734
#endif
@@ -34716,12 +34790,11 @@
3471634790
/* If the second argument to this function is NULL, generate a
3471734791
** temporary file name to use
3471834792
*/
3471934793
if( !zUtf8Name ){
3472034794
assert(isDelete && !isOpenJournal);
34721
- memset(zTmpname, 0, MAX_PATH+2);
34722
- rc = getTempname(MAX_PATH+2, zTmpname);
34795
+ rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname);
3472334796
if( rc!=SQLITE_OK ){
3472434797
OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
3472534798
return rc;
3472634799
}
3472734800
zUtf8Name = zTmpname;
@@ -35148,27 +35221,34 @@
3514835221
){
3514935222
3515035223
#if defined(__CYGWIN__)
3515135224
SimulateIOError( return SQLITE_ERROR );
3515235225
UNUSED_PARAMETER(nFull);
35153
- assert( pVfs->mxPathname>=MAX_PATH );
35226
+ assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH );
3515435227
assert( nFull>=pVfs->mxPathname );
3515535228
if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
3515635229
/*
3515735230
** NOTE: We are dealing with a relative path name and the data
3515835231
** directory has been set. Therefore, use it as the basis
3515935232
** for converting the relative path name to an absolute
3516035233
** one by prepending the data directory and a slash.
3516135234
*/
35162
- char zOut[MAX_PATH+1];
35163
- memset(zOut, 0, MAX_PATH+1);
35164
- cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
35165
- MAX_PATH+1);
35235
+ char zOut[SQLITE_WIN32_MAX_PATH+1];
35236
+ if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
35237
+ SQLITE_WIN32_MAX_PATH+1)<0 ){
35238
+ winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
35239
+ zRelative);
35240
+ return SQLITE_CANTOPEN_FULLPATH;
35241
+ }
3516635242
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
3516735243
sqlite3_data_directory, zOut);
3516835244
}else{
35169
- cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
35245
+ if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
35246
+ winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
35247
+ zRelative);
35248
+ return SQLITE_CANTOPEN_FULLPATH;
35249
+ }
3517035250
}
3517135251
return SQLITE_OK;
3517235252
#endif
3517335253
3517435254
#if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
@@ -35506,11 +35586,11 @@
3550635586
*/
3550735587
SQLITE_API int sqlite3_os_init(void){
3550835588
static sqlite3_vfs winVfs = {
3550935589
3, /* iVersion */
3551035590
sizeof(winFile), /* szOsFile */
35511
- MAX_PATH, /* mxPathname */
35591
+ SQLITE_WIN32_MAX_PATH, /* mxPathname */
3551235592
0, /* pNext */
3551335593
"win32", /* zName */
3551435594
0, /* pAppData */
3551535595
winOpen, /* xOpen */
3551635596
winDelete, /* xDelete */
@@ -60131,12 +60211,12 @@
6013160211
** a prior call to sqlite3VdbeMakeLabel().
6013260212
*/
6013360213
SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
6013460214
int j = -1-x;
6013560215
assert( p->magic==VDBE_MAGIC_INIT );
60136
- assert( j>=0 && j<p->nLabel );
60137
- if( p->aLabel ){
60216
+ assert( j<p->nLabel );
60217
+ if( j>=0 && p->aLabel ){
6013860218
p->aLabel[j] = p->nOp;
6013960219
}
6014060220
}
6014160221
6014260222
/*
@@ -60288,44 +60368,64 @@
6028860368
p->readOnly = 1;
6028960369
p->bIsReader = 0;
6029060370
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
6029160371
u8 opcode = pOp->opcode;
6029260372
60293
- pOp->opflags = sqlite3OpcodeProperty[opcode];
60294
- if( opcode==OP_Function || opcode==OP_AggStep ){
60295
- if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
60296
- }else if( opcode==OP_Transaction ){
60297
- if( pOp->p2!=0 ) p->readOnly = 0;
60298
- p->bIsReader = 1;
60299
- }else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){
60300
- p->bIsReader = 1;
60301
- }else if( opcode==OP_Vacuum
60302
- || opcode==OP_JournalMode
60373
+ /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
60374
+ ** cases from this switch! */
60375
+ switch( opcode ){
60376
+ case OP_Function:
60377
+ case OP_AggStep: {
60378
+ if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
60379
+ break;
60380
+ }
60381
+ case OP_Transaction: {
60382
+ if( pOp->p2!=0 ) p->readOnly = 0;
60383
+ /* fall thru */
60384
+ }
60385
+ case OP_AutoCommit:
60386
+ case OP_Savepoint: {
60387
+ p->bIsReader = 1;
60388
+ break;
60389
+ }
6030360390
#ifndef SQLITE_OMIT_WAL
60304
- || opcode==OP_Checkpoint
60391
+ case OP_Checkpoint:
6030560392
#endif
60306
- ){
60307
- p->readOnly = 0;
60308
- p->bIsReader = 1;
60393
+ case OP_Vacuum:
60394
+ case OP_JournalMode: {
60395
+ p->readOnly = 0;
60396
+ p->bIsReader = 1;
60397
+ break;
60398
+ }
6030960399
#ifndef SQLITE_OMIT_VIRTUALTABLE
60310
- }else if( opcode==OP_VUpdate ){
60311
- if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
60312
- }else if( opcode==OP_VFilter ){
60313
- int n;
60314
- assert( p->nOp - i >= 3 );
60315
- assert( pOp[-1].opcode==OP_Integer );
60316
- n = pOp[-1].p1;
60317
- if( n>nMaxArgs ) nMaxArgs = n;
60318
-#endif
60319
- }else if( opcode==OP_Next || opcode==OP_SorterNext ){
60320
- pOp->p4.xAdvance = sqlite3BtreeNext;
60321
- pOp->p4type = P4_ADVANCE;
60322
- }else if( opcode==OP_Prev ){
60323
- pOp->p4.xAdvance = sqlite3BtreePrevious;
60324
- pOp->p4type = P4_ADVANCE;
60325
- }
60326
-
60400
+ case OP_VUpdate: {
60401
+ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
60402
+ break;
60403
+ }
60404
+ case OP_VFilter: {
60405
+ int n;
60406
+ assert( p->nOp - i >= 3 );
60407
+ assert( pOp[-1].opcode==OP_Integer );
60408
+ n = pOp[-1].p1;
60409
+ if( n>nMaxArgs ) nMaxArgs = n;
60410
+ break;
60411
+ }
60412
+#endif
60413
+ case OP_Next:
60414
+ case OP_SorterNext: {
60415
+ pOp->p4.xAdvance = sqlite3BtreeNext;
60416
+ pOp->p4type = P4_ADVANCE;
60417
+ break;
60418
+ }
60419
+ case OP_Prev: {
60420
+ pOp->p4.xAdvance = sqlite3BtreePrevious;
60421
+ pOp->p4type = P4_ADVANCE;
60422
+ break;
60423
+ }
60424
+ }
60425
+
60426
+ pOp->opflags = sqlite3OpcodeProperty[opcode];
6032760427
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
6032860428
assert( -1-pOp->p2<p->nLabel );
6032960429
pOp->p2 = aLabel[-1-pOp->p2];
6033060430
}
6033160431
}
@@ -60456,12 +60556,11 @@
6045660556
/*
6045760557
** Change the P2 operand of instruction addr so that it points to
6045860558
** the address of the next instruction to be coded.
6045960559
*/
6046060560
SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
60461
- assert( addr>=0 || p->db->mallocFailed );
60462
- if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
60561
+ if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
6046360562
}
6046460563
6046560564
6046660565
/*
6046760566
** If the input FuncDef structure is ephemeral, then free it. If
@@ -60493,17 +60592,10 @@
6049360592
}
6049460593
case P4_MPRINTF: {
6049560594
if( db->pnBytesFreed==0 ) sqlite3_free(p4);
6049660595
break;
6049760596
}
60498
- case P4_VDBEFUNC: {
60499
- VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
60500
- freeEphemeralFunction(db, pVdbeFunc->pFunc);
60501
- if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
60502
- sqlite3DbFree(db, pVdbeFunc);
60503
- break;
60504
- }
6050560597
case P4_FUNCDEF: {
6050660598
freeEphemeralFunction(db, (FuncDef*)p4);
6050760599
break;
6050860600
}
6050960601
case P4_MEM: {
@@ -60618,24 +60710,17 @@
6061860710
pOp->p4type = P4_INT32;
6061960711
}else if( zP4==0 ){
6062060712
pOp->p4.p = 0;
6062160713
pOp->p4type = P4_NOTUSED;
6062260714
}else if( n==P4_KEYINFO ){
60623
- KeyInfo *pKeyInfo;
60624
- int nField, nByte;
60625
-
60626
- nField = ((KeyInfo*)zP4)->nField;
60627
- nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
60628
- pKeyInfo = sqlite3DbMallocRaw(0, nByte);
60629
- pOp->p4.pKeyInfo = pKeyInfo;
60630
- if( pKeyInfo ){
60631
- u8 *aSortOrder;
60632
- memcpy((char*)pKeyInfo, zP4, nByte - nField);
60633
- aSortOrder = pKeyInfo->aSortOrder;
60634
- assert( aSortOrder!=0 );
60635
- pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
60636
- memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
60715
+ KeyInfo *pOrig, *pNew;
60716
+
60717
+ pOrig = (KeyInfo*)zP4;
60718
+ pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
60719
+ if( pNew ){
60720
+ memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
60721
+ memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
6063760722
pOp->p4type = P4_KEYINFO;
6063860723
}else{
6063960724
p->db->mallocFailed = 1;
6064060725
pOp->p4type = P4_NOTUSED;
6064160726
}
@@ -61529,10 +61614,14 @@
6152961614
while( p->pDelFrame ){
6153061615
VdbeFrame *pDel = p->pDelFrame;
6153161616
p->pDelFrame = pDel->pParent;
6153261617
sqlite3VdbeFrameDelete(pDel);
6153361618
}
61619
+
61620
+ /* Delete any auxdata allocations made by the VM */
61621
+ sqlite3VdbeDeleteAuxData(p, -1, 0);
61622
+ assert( p->pAuxData==0 );
6153461623
}
6153561624
6153661625
/*
6153761626
** Clean up the VM after execution.
6153861627
**
@@ -61946,10 +62035,11 @@
6194662035
/* If the statement transaction is being rolled back, also restore the
6194762036
** database handles deferred constraint counter to the value it had when
6194862037
** the statement transaction was opened. */
6194962038
if( eOp==SAVEPOINT_ROLLBACK ){
6195062039
db->nDeferredCons = p->nStmtDefCons;
62040
+ db->nDeferredImmCons = p->nStmtDefImmCons;
6195162041
}
6195262042
}
6195362043
return rc;
6195462044
}
6195562045
@@ -61964,11 +62054,13 @@
6196462054
** and write an error message to it. Then return SQLITE_ERROR.
6196562055
*/
6196662056
#ifndef SQLITE_OMIT_FOREIGN_KEY
6196762057
SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
6196862058
sqlite3 *db = p->db;
61969
- if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
62059
+ if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
62060
+ || (!deferred && p->nFkConstraint>0)
62061
+ ){
6197062062
p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
6197162063
p->errorAction = OE_Abort;
6197262064
sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
6197362065
return SQLITE_ERROR;
6197462066
}
@@ -62097,10 +62189,12 @@
6209762189
}else if( rc!=SQLITE_OK ){
6209862190
p->rc = rc;
6209962191
sqlite3RollbackAll(db, SQLITE_OK);
6210062192
}else{
6210162193
db->nDeferredCons = 0;
62194
+ db->nDeferredImmCons = 0;
62195
+ db->flags &= ~SQLITE_DeferFKs;
6210262196
sqlite3CommitInternalChanges(db);
6210362197
}
6210462198
}else{
6210562199
sqlite3RollbackAll(db, SQLITE_OK);
6210662200
}
@@ -62322,24 +62416,39 @@
6232262416
sqlite3VdbeDelete(p);
6232362417
return rc;
6232462418
}
6232562419
6232662420
/*
62327
-** Call the destructor for each auxdata entry in pVdbeFunc for which
62328
-** the corresponding bit in mask is clear. Auxdata entries beyond 31
62329
-** are always destroyed. To destroy all auxdata entries, call this
62330
-** routine with mask==0.
62421
+** If parameter iOp is less than zero, then invoke the destructor for
62422
+** all auxiliary data pointers currently cached by the VM passed as
62423
+** the first argument.
62424
+**
62425
+** Or, if iOp is greater than or equal to zero, then the destructor is
62426
+** only invoked for those auxiliary data pointers created by the user
62427
+** function invoked by the OP_Function opcode at instruction iOp of
62428
+** VM pVdbe, and only then if:
62429
+**
62430
+** * the associated function parameter is the 32nd or later (counting
62431
+** from left to right), or
62432
+**
62433
+** * the corresponding bit in argument mask is clear (where the first
62434
+** function parameter corrsponds to bit 0 etc.).
6233162435
*/
62332
-SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
62333
- int i;
62334
- for(i=0; i<pVdbeFunc->nAux; i++){
62335
- struct AuxData *pAux = &pVdbeFunc->apAux[i];
62336
- if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
62436
+SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
62437
+ AuxData **pp = &pVdbe->pAuxData;
62438
+ while( *pp ){
62439
+ AuxData *pAux = *pp;
62440
+ if( (iOp<0)
62441
+ || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
62442
+ ){
6233762443
if( pAux->xDelete ){
6233862444
pAux->xDelete(pAux->pAux);
6233962445
}
62340
- pAux->pAux = 0;
62446
+ *pp = pAux->pNext;
62447
+ sqlite3DbFree(pVdbe->db, pAux);
62448
+ }else{
62449
+ pp= &pAux->pNext;
6234162450
}
6234262451
}
6234362452
}
6234462453
6234562454
/*
@@ -62854,15 +62963,14 @@
6285462963
*/
6285562964
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
6285662965
int nKey1, const void *pKey1, /* Left key */
6285762966
UnpackedRecord *pPKey2 /* Right key */
6285862967
){
62859
- int d1; /* Offset into aKey[] of next data element */
62968
+ u32 d1; /* Offset into aKey[] of next data element */
6286062969
u32 idx1; /* Offset into aKey[] of next header element */
6286162970
u32 szHdr1; /* Number of bytes in header */
6286262971
int i = 0;
62863
- int nField;
6286462972
int rc = 0;
6286562973
const unsigned char *aKey1 = (const unsigned char *)pKey1;
6286662974
KeyInfo *pKeyInfo;
6286762975
Mem mem1;
6286862976
@@ -62881,32 +62989,42 @@
6288162989
*/
6288262990
/* mem1.u.i = 0; // not needed, here to silence compiler warning */
6288362991
6288462992
idx1 = getVarint32(aKey1, szHdr1);
6288562993
d1 = szHdr1;
62886
- nField = pKeyInfo->nField;
62994
+ assert( pKeyInfo->nField+1>=pPKey2->nField );
6288762995
assert( pKeyInfo->aSortOrder!=0 );
6288862996
while( idx1<szHdr1 && i<pPKey2->nField ){
6288962997
u32 serial_type1;
6289062998
6289162999
/* Read the serial types for the next element in each key. */
6289263000
idx1 += getVarint32( aKey1+idx1, serial_type1 );
62893
- if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
63001
+
63002
+ /* Verify that there is enough key space remaining to avoid
63003
+ ** a buffer overread. The "d1+serial_type1+2" subexpression will
63004
+ ** always be greater than or equal to the amount of required key space.
63005
+ ** Use that approximation to avoid the more expensive call to
63006
+ ** sqlite3VdbeSerialTypeLen() in the common case.
63007
+ */
63008
+ if( d1+serial_type1+2>(u32)nKey1
63009
+ && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
63010
+ ){
63011
+ break;
63012
+ }
6289463013
6289563014
/* Extract the values to be compared.
6289663015
*/
6289763016
d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
6289863017
6289963018
/* Do the comparison
6290063019
*/
62901
- rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
62902
- i<nField ? pKeyInfo->aColl[i] : 0);
63020
+ rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
6290363021
if( rc!=0 ){
6290463022
assert( mem1.zMalloc==0 ); /* See comment below */
6290563023
6290663024
/* Invert the result if we are using DESC sort order. */
62907
- if( i<nField && pKeyInfo->aSortOrder[i] ){
63025
+ if( pKeyInfo->aSortOrder[i] ){
6290863026
rc = -rc;
6290963027
}
6291063028
6291163029
/* If the PREFIX_SEARCH flag is set and all fields except the final
6291263030
** rowid field were equal, then clear the PREFIX_SEARCH flag and set
@@ -63117,11 +63235,11 @@
6311763235
** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
6311863236
** constants) to the value before returning it.
6311963237
**
6312063238
** The returned value must be freed by the caller using sqlite3ValueFree().
6312163239
*/
63122
-SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
63240
+SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
6312363241
assert( iVar>0 );
6312463242
if( v ){
6312563243
Mem *pMem = &v->aVar[iVar-1];
6312663244
if( 0==(pMem->flags & MEM_Null) ){
6312763245
sqlite3_value *pRet = sqlite3ValueNew(v->db);
@@ -63536,11 +63654,13 @@
6353663654
*/
6353763655
if( db->nVdbeActive==0 ){
6353863656
db->u1.isInterrupted = 0;
6353963657
}
6354063658
63541
- assert( db->nVdbeWrite>0 || db->autoCommit==0 || db->nDeferredCons==0 );
63659
+ assert( db->nVdbeWrite>0 || db->autoCommit==0
63660
+ || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
63661
+ );
6354263662
6354363663
#ifndef SQLITE_OMIT_TRACE
6354463664
if( db->xProfile && !db->init.busy ){
6354563665
sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
6354663666
}
@@ -63732,18 +63852,18 @@
6373263852
/*
6373363853
** Return the auxilary data pointer, if any, for the iArg'th argument to
6373463854
** the user-function defined by pCtx.
6373563855
*/
6373663856
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
63737
- VdbeFunc *pVdbeFunc;
63857
+ AuxData *pAuxData;
6373863858
6373963859
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
63740
- pVdbeFunc = pCtx->pVdbeFunc;
63741
- if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
63742
- return 0;
63860
+ for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
63861
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
6374363862
}
63744
- return pVdbeFunc->apAux[iArg].pAux;
63863
+
63864
+ return (pAuxData ? pAuxData->pAux : 0);
6374563865
}
6374663866
6374763867
/*
6374863868
** Set the auxilary data pointer and delete function, for the iArg'th
6374963869
** argument to the user-function defined by pCtx. Any previous value is
@@ -63753,33 +63873,30 @@
6375363873
sqlite3_context *pCtx,
6375463874
int iArg,
6375563875
void *pAux,
6375663876
void (*xDelete)(void*)
6375763877
){
63758
- struct AuxData *pAuxData;
63759
- VdbeFunc *pVdbeFunc;
63760
- if( iArg<0 ) goto failed;
63878
+ AuxData *pAuxData;
63879
+ Vdbe *pVdbe = pCtx->pVdbe;
6376163880
6376263881
assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
63763
- pVdbeFunc = pCtx->pVdbeFunc;
63764
- if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
63765
- int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
63766
- int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
63767
- pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
63768
- if( !pVdbeFunc ){
63769
- goto failed;
63770
- }
63771
- pCtx->pVdbeFunc = pVdbeFunc;
63772
- memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
63773
- pVdbeFunc->nAux = iArg+1;
63774
- pVdbeFunc->pFunc = pCtx->pFunc;
63775
- }
63776
-
63777
- pAuxData = &pVdbeFunc->apAux[iArg];
63778
- if( pAuxData->pAux && pAuxData->xDelete ){
63882
+ if( iArg<0 ) goto failed;
63883
+
63884
+ for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
63885
+ if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
63886
+ }
63887
+ if( pAuxData==0 ){
63888
+ pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
63889
+ if( !pAuxData ) goto failed;
63890
+ pAuxData->iOp = pCtx->iOp;
63891
+ pAuxData->iArg = iArg;
63892
+ pAuxData->pNext = pVdbe->pAuxData;
63893
+ pVdbe->pAuxData = pAuxData;
63894
+ }else if( pAuxData->xDelete ){
6377963895
pAuxData->xDelete(pAuxData->pAux);
6378063896
}
63897
+
6378163898
pAuxData->pAux = pAux;
6378263899
pAuxData->xDelete = xDelete;
6378363900
return;
6378463901
6378563902
failed:
@@ -65384,16 +65501,15 @@
6538465501
Op *pOp; /* Current operation */
6538565502
int rc = SQLITE_OK; /* Value to return */
6538665503
sqlite3 *db = p->db; /* The database */
6538765504
u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
6538865505
u8 encoding = ENC(db); /* The database encoding */
65389
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65390
- int checkProgress; /* True if progress callbacks are enabled */
65391
- int nProgressOps = 0; /* Opcodes executed since progress callback. */
65392
-#endif
6539365506
int iCompare = 0; /* Result of last OP_Compare operation */
6539465507
unsigned nVmStep = 0; /* Number of virtual machine steps */
65508
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65509
+ unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
65510
+#endif
6539565511
Mem *aMem = p->aMem; /* Copy of p->aMem */
6539665512
Mem *pIn1 = 0; /* 1st input operand */
6539765513
Mem *pIn2 = 0; /* 2nd input operand */
6539865514
Mem *pIn3 = 0; /* 3rd input operand */
6539965515
Mem *pOut = 0; /* Output operand */
@@ -65848,11 +65964,19 @@
6584865964
p->pResultSet = 0;
6584965965
db->busyHandler.nBusy = 0;
6585065966
CHECK_FOR_INTERRUPT;
6585165967
sqlite3VdbeIOTraceSql(p);
6585265968
#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65853
- checkProgress = db->xProgress!=0;
65969
+ if( db->xProgress ){
65970
+ assert( 0 < db->nProgressOps );
65971
+ nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1];
65972
+ if( nProgressLimit==0 ){
65973
+ nProgressLimit = db->nProgressOps;
65974
+ }else{
65975
+ nProgressLimit %= (unsigned)db->nProgressOps;
65976
+ }
65977
+ }
6585465978
#endif
6585565979
#ifdef SQLITE_DEBUG
6585665980
sqlite3BeginBenignMalloc();
6585765981
if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
6585865982
int i;
@@ -65895,31 +66019,10 @@
6589566019
sqlite3_interrupt_count--;
6589666020
if( sqlite3_interrupt_count==0 ){
6589766021
sqlite3_interrupt(db);
6589866022
}
6589966023
}
65900
-#endif
65901
-
65902
-#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65903
- /* Call the progress callback if it is configured and the required number
65904
- ** of VDBE ops have been executed (either since this invocation of
65905
- ** sqlite3VdbeExec() or since last time the progress callback was called).
65906
- ** If the progress callback returns non-zero, exit the virtual machine with
65907
- ** a return code SQLITE_ABORT.
65908
- */
65909
- if( checkProgress ){
65910
- if( db->nProgressOps==nProgressOps ){
65911
- int prc;
65912
- prc = db->xProgress(db->pProgressArg);
65913
- if( prc!=0 ){
65914
- rc = SQLITE_INTERRUPT;
65915
- goto vdbe_error_halt;
65916
- }
65917
- nProgressOps = 0;
65918
- }
65919
- nProgressOps++;
65920
- }
6592166024
#endif
6592266025
6592366026
/* On any opcode with the "out2-prerelease" tag, free any
6592466027
** external allocations out of mem[p2] and set mem[p2] to be
6592566028
** an undefined integer. Opcodes will either fill in the integer
@@ -66010,12 +66113,44 @@
6601066113
** The next instruction executed will be
6601166114
** the one at index P2 from the beginning of
6601266115
** the program.
6601366116
*/
6601466117
case OP_Goto: { /* jump */
66015
- CHECK_FOR_INTERRUPT;
6601666118
pc = pOp->p2 - 1;
66119
+
66120
+ /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
66121
+ ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
66122
+ ** completion. Check to see if sqlite3_interrupt() has been called
66123
+ ** or if the progress callback needs to be invoked.
66124
+ **
66125
+ ** This code uses unstructured "goto" statements and does not look clean.
66126
+ ** But that is not due to sloppy coding habits. The code is written this
66127
+ ** way for performance, to avoid having to run the interrupt and progress
66128
+ ** checks on every opcode. This helps sqlite3_step() to run about 1.5%
66129
+ ** faster according to "valgrind --tool=cachegrind" */
66130
+check_for_interrupt:
66131
+ CHECK_FOR_INTERRUPT;
66132
+#ifndef SQLITE_OMIT_PROGRESS_CALLBACK
66133
+ /* Call the progress callback if it is configured and the required number
66134
+ ** of VDBE ops have been executed (either since this invocation of
66135
+ ** sqlite3VdbeExec() or since last time the progress callback was called).
66136
+ ** If the progress callback returns non-zero, exit the virtual machine with
66137
+ ** a return code SQLITE_ABORT.
66138
+ */
66139
+ if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
66140
+ int prc;
66141
+ prc = db->xProgress(db->pProgressArg);
66142
+ if( prc!=0 ){
66143
+ rc = SQLITE_INTERRUPT;
66144
+ goto vdbe_error_halt;
66145
+ }
66146
+ if( db->xProgress!=0 ){
66147
+ nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
66148
+ }
66149
+ }
66150
+#endif
66151
+
6601766152
break;
6601866153
}
6601966154
6602066155
/* Opcode: Gosub P1 P2 * * *
6602166156
**
@@ -66132,11 +66267,11 @@
6613266267
assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
6613366268
if( rc==SQLITE_BUSY ){
6613466269
p->rc = rc = SQLITE_BUSY;
6613566270
}else{
6613666271
assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
66137
- assert( rc==SQLITE_OK || db->nDeferredCons>0 );
66272
+ assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
6613866273
rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
6613966274
}
6614066275
goto vdbe_return;
6614166276
}
6614266277
@@ -66694,23 +66829,18 @@
6669466829
Deephemeralize(u.ai.pArg);
6669566830
sqlite3VdbeMemStoreType(u.ai.pArg);
6669666831
REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
6669766832
}
6669866833
66699
- assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
66700
- if( pOp->p4type==P4_FUNCDEF ){
66701
- u.ai.ctx.pFunc = pOp->p4.pFunc;
66702
- u.ai.ctx.pVdbeFunc = 0;
66703
- }else{
66704
- u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
66705
- u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
66706
- }
66707
-
66834
+ assert( pOp->p4type==P4_FUNCDEF );
66835
+ u.ai.ctx.pFunc = pOp->p4.pFunc;
6670866836
u.ai.ctx.s.flags = MEM_Null;
6670966837
u.ai.ctx.s.db = db;
6671066838
u.ai.ctx.s.xDel = 0;
6671166839
u.ai.ctx.s.zMalloc = 0;
66840
+ u.ai.ctx.iOp = pc;
66841
+ u.ai.ctx.pVdbe = p;
6671266842
6671366843
/* The output cell may already have a buffer allocated. Move
6671466844
** the pointer to u.ai.ctx.s so in case the user-function can use
6671566845
** the already allocated buffer instead of allocating a new one.
6671666846
*/
@@ -66729,15 +66859,11 @@
6672966859
lastRowid = db->lastRowid;
6673066860
6673166861
/* If any auxiliary data functions have been called by this user function,
6673266862
** immediately call the destructor for any non-static values.
6673366863
*/
66734
- if( u.ai.ctx.pVdbeFunc ){
66735
- sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
66736
- pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
66737
- pOp->p4type = P4_VDBEFUNC;
66738
- }
66864
+ sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
6673966865
6674066866
if( db->mallocFailed ){
6674166867
/* Even though a malloc() has failed, the implementation of the
6674266868
** user function may have called an sqlite3_result_XXX() function
6674366869
** to return a value. The following call releases any resources
@@ -68028,10 +68154,11 @@
6802868154
6802968155
/* Link the new savepoint into the database handle's list. */
6803068156
u.as.pNew->pNext = db->pSavepoint;
6803168157
db->pSavepoint = u.as.pNew;
6803268158
u.as.pNew->nDeferredCons = db->nDeferredCons;
68159
+ u.as.pNew->nDeferredImmCons = db->nDeferredImmCons;
6803368160
}
6803468161
}
6803568162
}else{
6803668163
u.as.iSavepoint = 0;
6803768164
@@ -68115,10 +68242,11 @@
6811568242
if( !isTransaction ){
6811668243
db->nSavepoint--;
6811768244
}
6811868245
}else{
6811968246
db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
68247
+ db->nDeferredImmCons = u.as.pSavepoint->nDeferredImmCons;
6812068248
}
6812168249
6812268250
if( !isTransaction ){
6812368251
rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
6812468252
if( rc!=SQLITE_OK ) goto abort_due_to_error;
@@ -68244,10 +68372,14 @@
6824468372
6824568373
assert( p->bIsReader );
6824668374
assert( p->readOnly==0 || pOp->p2==0 );
6824768375
assert( pOp->p1>=0 && pOp->p1<db->nDb );
6824868376
assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
68377
+ if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
68378
+ rc = SQLITE_READONLY;
68379
+ goto abort_due_to_error;
68380
+ }
6824968381
u.au.pBt = db->aDb[pOp->p1].pBt;
6825068382
6825168383
if( u.au.pBt ){
6825268384
rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
6825368385
if( rc==SQLITE_BUSY ){
@@ -68276,10 +68408,11 @@
6827668408
6827768409
/* Store the current value of the database handles deferred constraint
6827868410
** counter. If the statement transaction needs to be rolled back,
6827968411
** the value of this counter needs to be restored too. */
6828068412
p->nStmtDefCons = db->nDeferredCons;
68413
+ p->nStmtDefImmCons = db->nDeferredImmCons;
6828168414
}
6828268415
}
6828368416
break;
6828468417
}
6828568418
@@ -69851,11 +69984,10 @@
6985169984
#if 0 /* local variables moved into u.br */
6985269985
VdbeCursor *pC;
6985369986
int res;
6985469987
#endif /* local variables moved into u.br */
6985569988
69856
- CHECK_FOR_INTERRUPT;
6985769989
assert( pOp->p1>=0 && pOp->p1<p->nCursor );
6985869990
assert( pOp->p5<=ArraySize(p->aCounter) );
6985969991
u.br.pC = p->apCsr[pOp->p1];
6986069992
if( u.br.pC==0 ){
6986169993
break; /* See ticket #2273 */
@@ -69880,11 +70012,11 @@
6988070012
#ifdef SQLITE_TEST
6988170013
sqlite3_search_count++;
6988270014
#endif
6988370015
}
6988470016
u.br.pC->rowidIsValid = 0;
69885
- break;
70017
+ goto check_for_interrupt;
6988670018
}
6988770019
6988870020
/* Opcode: IdxInsert P1 P2 P3 * P5
6988970021
**
6989070022
** Register P2 holds an SQL index key made using the
@@ -70426,11 +70558,11 @@
7042670558
*/
7042770559
case OP_RowSetRead: { /* jump, in1, out3 */
7042870560
#if 0 /* local variables moved into u.cb */
7042970561
i64 val;
7043070562
#endif /* local variables moved into u.cb */
70431
- CHECK_FOR_INTERRUPT;
70563
+
7043270564
pIn1 = &aMem[pOp->p1];
7043370565
if( (pIn1->flags & MEM_RowSet)==0
7043470566
|| sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
7043570567
){
7043670568
/* The boolean index is empty */
@@ -70438,11 +70570,11 @@
7043870570
pc = pOp->p2 - 1;
7043970571
}else{
7044070572
/* A value was pulled from the index */
7044170573
sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
7044270574
}
70443
- break;
70575
+ goto check_for_interrupt;
7044470576
}
7044570577
7044670578
/* Opcode: RowSetTest P1 P2 P3 P4
7044770579
**
7044870580
** Register P3 is assumed to hold a 64-bit integer value. If register P1
@@ -70658,11 +70790,13 @@
7065870790
** If P1 is non-zero, the database constraint counter is incremented
7065970791
** (deferred foreign key constraints). Otherwise, if P1 is zero, the
7066070792
** statement counter is incremented (immediate foreign key constraints).
7066170793
*/
7066270794
case OP_FkCounter: {
70663
- if( pOp->p1 ){
70795
+ if( db->flags & SQLITE_DeferFKs ){
70796
+ db->nDeferredImmCons += pOp->p2;
70797
+ }else if( pOp->p1 ){
7066470798
db->nDeferredCons += pOp->p2;
7066570799
}else{
7066670800
p->nFkConstraint += pOp->p2;
7066770801
}
7066870802
break;
@@ -70679,13 +70813,13 @@
7067970813
** zero, the jump is taken if the statement constraint-counter is zero
7068070814
** (immediate foreign key constraint violations).
7068170815
*/
7068270816
case OP_FkIfZero: { /* jump */
7068370817
if( pOp->p1 ){
70684
- if( db->nDeferredCons==0 ) pc = pOp->p2-1;
70818
+ if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
7068570819
}else{
70686
- if( p->nFkConstraint==0 ) pc = pOp->p2-1;
70820
+ if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
7068770821
}
7068870822
break;
7068970823
}
7069070824
#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
7069170825
@@ -71367,11 +71501,11 @@
7136771501
7136871502
if( !u.cp.res ){
7136971503
/* If there is data, jump to P2 */
7137071504
pc = pOp->p2 - 1;
7137171505
}
71372
- break;
71506
+ goto check_for_interrupt;
7137371507
}
7137471508
#endif /* SQLITE_OMIT_VIRTUALTABLE */
7137571509
7137671510
#ifndef SQLITE_OMIT_VIRTUALTABLE
7137771511
/* Opcode: VRename P1 * * P4 *
@@ -74092,15 +74226,24 @@
7409274226
/* Translate the schema name in zDb into a pointer to the corresponding
7409374227
** schema. If not found, pSchema will remain NULL and nothing will match
7409474228
** resulting in an appropriate error message toward the end of this routine
7409574229
*/
7409674230
if( zDb ){
74097
- for(i=0; i<db->nDb; i++){
74098
- assert( db->aDb[i].zName );
74099
- if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
74100
- pSchema = db->aDb[i].pSchema;
74101
- break;
74231
+ testcase( pNC->ncFlags & NC_PartIdx );
74232
+ testcase( pNC->ncFlags & NC_IsCheck );
74233
+ if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
74234
+ /* Silently ignore database qualifiers inside CHECK constraints and partial
74235
+ ** indices. Do not raise errors because that might break legacy and
74236
+ ** because it does not hurt anything to just ignore the database name. */
74237
+ zDb = 0;
74238
+ }else{
74239
+ for(i=0; i<db->nDb; i++){
74240
+ assert( db->aDb[i].zName );
74241
+ if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
74242
+ pSchema = db->aDb[i].pSchema;
74243
+ break;
74244
+ }
7410274245
}
7410374246
}
7410474247
}
7410574248
7410674249
/* Start at the inner-most context and move outward until a match is found */
@@ -74373,10 +74516,43 @@
7437374516
}
7437474517
ExprSetProperty(p, EP_Resolved);
7437574518
}
7437674519
return p;
7437774520
}
74521
+
74522
+/*
74523
+** Report an error that an expression is not valid for a partial index WHERE
74524
+** clause.
74525
+*/
74526
+static void notValidPartIdxWhere(
74527
+ Parse *pParse, /* Leave error message here */
74528
+ NameContext *pNC, /* The name context */
74529
+ const char *zMsg /* Type of error */
74530
+){
74531
+ if( (pNC->ncFlags & NC_PartIdx)!=0 ){
74532
+ sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
74533
+ zMsg);
74534
+ }
74535
+}
74536
+
74537
+#ifndef SQLITE_OMIT_CHECK
74538
+/*
74539
+** Report an error that an expression is not valid for a CHECK constraint.
74540
+*/
74541
+static void notValidCheckConstraint(
74542
+ Parse *pParse, /* Leave error message here */
74543
+ NameContext *pNC, /* The name context */
74544
+ const char *zMsg /* Type of error */
74545
+){
74546
+ if( (pNC->ncFlags & NC_IsCheck)!=0 ){
74547
+ sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
74548
+ }
74549
+}
74550
+#else
74551
+# define notValidCheckConstraint(P,N,M)
74552
+#endif
74553
+
7437874554
7437974555
/*
7438074556
** This routine is callback for sqlite3WalkExpr().
7438174557
**
7438274558
** Resolve symbolic names into TK_COLUMN operators for the current
@@ -74473,10 +74649,11 @@
7447374649
FuncDef *pDef; /* Information about the function */
7447474650
u8 enc = ENC(pParse->db); /* The database encoding */
7447574651
7447674652
testcase( pExpr->op==TK_CONST_FUNC );
7447774653
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
74654
+ notValidPartIdxWhere(pParse, pNC, "functions");
7447874655
zId = pExpr->u.zToken;
7447974656
nId = sqlite3Strlen30(zId);
7448074657
pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
7448174658
if( pDef==0 ){
7448274659
pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
@@ -74538,31 +74715,25 @@
7453874715
#endif
7453974716
case TK_IN: {
7454074717
testcase( pExpr->op==TK_IN );
7454174718
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
7454274719
int nRef = pNC->nRef;
74543
-#ifndef SQLITE_OMIT_CHECK
74544
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
74545
- sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
74546
- }
74547
-#endif
74720
+ notValidCheckConstraint(pParse, pNC, "subqueries");
74721
+ notValidPartIdxWhere(pParse, pNC, "subqueries");
7454874722
sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
7454974723
assert( pNC->nRef>=nRef );
7455074724
if( nRef!=pNC->nRef ){
7455174725
ExprSetProperty(pExpr, EP_VarSelect);
7455274726
}
7455374727
}
7455474728
break;
7455574729
}
74556
-#ifndef SQLITE_OMIT_CHECK
7455774730
case TK_VARIABLE: {
74558
- if( (pNC->ncFlags & NC_IsCheck)!=0 ){
74559
- sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
74560
- }
74731
+ notValidCheckConstraint(pParse, pNC, "parameters");
74732
+ notValidPartIdxWhere(pParse, pNC, "parameters");
7456174733
break;
7456274734
}
74563
-#endif
7456474735
}
7456574736
return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
7456674737
}
7456774738
7456874739
/*
@@ -74649,11 +74820,11 @@
7464974820
/* Try to match the ORDER BY expression against an expression
7465074821
** in the result set. Return an 1-based index of the matching
7465174822
** result-set entry.
7465274823
*/
7465374824
for(i=0; i<pEList->nExpr; i++){
74654
- if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
74825
+ if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
7465574826
return i+1;
7465674827
}
7465774828
}
7465874829
7465974830
/* If no match, return 0. */
@@ -74877,11 +75048,11 @@
7487775048
pItem->iOrderByCol = 0;
7487875049
if( sqlite3ResolveExprNames(pNC, pE) ){
7487975050
return 1;
7488075051
}
7488175052
for(j=0; j<pSelect->pEList->nExpr; j++){
74882
- if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
75053
+ if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
7488375054
pItem->iOrderByCol = j+1;
7488475055
}
7488575056
}
7488675057
}
7488775058
return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
@@ -75183,10 +75354,52 @@
7518375354
w.xSelectCallback = resolveSelectStep;
7518475355
w.pParse = pParse;
7518575356
w.u.pNC = pOuterNC;
7518675357
sqlite3WalkSelect(&w, p);
7518775358
}
75359
+
75360
+/*
75361
+** Resolve names in expressions that can only reference a single table:
75362
+**
75363
+** * CHECK constraints
75364
+** * WHERE clauses on partial indices
75365
+**
75366
+** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
75367
+** is set to -1 and the Expr.iColumn value is set to the column number.
75368
+**
75369
+** Any errors cause an error message to be set in pParse.
75370
+*/
75371
+SQLITE_PRIVATE void sqlite3ResolveSelfReference(
75372
+ Parse *pParse, /* Parsing context */
75373
+ Table *pTab, /* The table being referenced */
75374
+ int type, /* NC_IsCheck or NC_PartIdx */
75375
+ Expr *pExpr, /* Expression to resolve. May be NULL. */
75376
+ ExprList *pList /* Expression list to resolve. May be NUL. */
75377
+){
75378
+ SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
75379
+ NameContext sNC; /* Name context for pParse->pNewTable */
75380
+ int i; /* Loop counter */
75381
+
75382
+ assert( type==NC_IsCheck || type==NC_PartIdx );
75383
+ memset(&sNC, 0, sizeof(sNC));
75384
+ memset(&sSrc, 0, sizeof(sSrc));
75385
+ sSrc.nSrc = 1;
75386
+ sSrc.a[0].zName = pTab->zName;
75387
+ sSrc.a[0].pTab = pTab;
75388
+ sSrc.a[0].iCursor = -1;
75389
+ sNC.pParse = pParse;
75390
+ sNC.pSrcList = &sSrc;
75391
+ sNC.ncFlags = type;
75392
+ if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
75393
+ if( pList ){
75394
+ for(i=0; i<pList->nExpr; i++){
75395
+ if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
75396
+ return;
75397
+ }
75398
+ }
75399
+ }
75400
+}
7518875401
7518975402
/************** End of resolve.c *********************************************/
7519075403
/************** Begin file expr.c ********************************************/
7519175404
/*
7519275405
** 2001 September 15
@@ -76879,14 +77092,13 @@
7687977092
#endif
7688077093
7688177094
switch( pExpr->op ){
7688277095
case TK_IN: {
7688377096
char affinity; /* Affinity of the LHS of the IN */
76884
- KeyInfo keyInfo; /* Keyinfo for the generated table */
76885
- static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
7688677097
int addr; /* Address of OP_OpenEphemeral instruction */
7688777098
Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
77099
+ KeyInfo *pKeyInfo = 0; /* Key information */
7688877100
7688977101
if( rMayHaveNull ){
7689077102
sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
7689177103
}
7689277104
@@ -76906,13 +77118,11 @@
7690677118
** is used.
7690777119
*/
7690877120
pExpr->iTable = pParse->nTab++;
7690977121
addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
7691077122
if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
76911
- memset(&keyInfo, 0, sizeof(keyInfo));
76912
- keyInfo.nField = 1;
76913
- keyInfo.aSortOrder = &sortOrder;
77123
+ pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
7691477124
7691577125
if( ExprHasProperty(pExpr, EP_xIsSelect) ){
7691677126
/* Case 1: expr IN (SELECT ...)
7691777127
**
7691877128
** Generate code to write the results of the select into the temporary
@@ -76925,15 +77135,16 @@
7692577135
sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
7692677136
dest.affSdst = (u8)affinity;
7692777137
assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
7692877138
pExpr->x.pSelect->iLimit = 0;
7692977139
if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
77140
+ sqlite3DbFree(pParse->db, pKeyInfo);
7693077141
return 0;
7693177142
}
7693277143
pEList = pExpr->x.pSelect->pEList;
76933
- if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
76934
- keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
77144
+ if( pKeyInfo && ALWAYS(pEList!=0 && pEList->nExpr>0) ){
77145
+ pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
7693577146
pEList->a[0].pExpr);
7693677147
}
7693777148
}else if( ALWAYS(pExpr->x.pList!=0) ){
7693877149
/* Case 2: expr IN (exprlist)
7693977150
**
@@ -76948,12 +77159,13 @@
7694877159
int r1, r2, r3;
7694977160
7695077161
if( !affinity ){
7695177162
affinity = SQLITE_AFF_NONE;
7695277163
}
76953
- keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
76954
- keyInfo.aSortOrder = &sortOrder;
77164
+ if( pKeyInfo ){
77165
+ pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
77166
+ }
7695577167
7695677168
/* Loop through each expression in <exprlist>. */
7695777169
r1 = sqlite3GetTempReg(pParse);
7695877170
r2 = sqlite3GetTempReg(pParse);
7695977171
sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
@@ -76988,12 +77200,12 @@
7698877200
}
7698977201
}
7699077202
sqlite3ReleaseTempReg(pParse, r1);
7699177203
sqlite3ReleaseTempReg(pParse, r2);
7699277204
}
76993
- if( !isRowid ){
76994
- sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
77205
+ if( pKeyInfo ){
77206
+ sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
7699577207
}
7699677208
break;
7699777209
}
7699877210
7699977211
case TK_EXISTS:
@@ -77549,19 +77761,24 @@
7754977761
break;
7755077762
}
7755177763
/* Otherwise, fall thru into the TK_COLUMN case */
7755277764
}
7755377765
case TK_COLUMN: {
77554
- if( pExpr->iTable<0 ){
77555
- /* This only happens when coding check constraints */
77556
- assert( pParse->ckBase>0 );
77557
- inReg = pExpr->iColumn + pParse->ckBase;
77558
- }else{
77559
- inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
77560
- pExpr->iColumn, pExpr->iTable, target,
77561
- pExpr->op2);
77562
- }
77766
+ int iTab = pExpr->iTable;
77767
+ if( iTab<0 ){
77768
+ if( pParse->ckBase>0 ){
77769
+ /* Generating CHECK constraints or inserting into partial index */
77770
+ inReg = pExpr->iColumn + pParse->ckBase;
77771
+ break;
77772
+ }else{
77773
+ /* Deleting from a partial index */
77774
+ iTab = pParse->iPartIdxTab;
77775
+ }
77776
+ }
77777
+ inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
77778
+ pExpr->iColumn, iTab, target,
77779
+ pExpr->op2);
7756377780
break;
7756477781
}
7756577782
case TK_INTEGER: {
7756677783
codeInteger(pParse, pExpr, 0, target);
7756777784
break;
@@ -78980,10 +79197,16 @@
7898079197
** Do a deep comparison of two expression trees. Return 0 if the two
7898179198
** expressions are completely identical. Return 1 if they differ only
7898279199
** by a COLLATE operator at the top level. Return 2 if there are differences
7898379200
** other than the top-level COLLATE operator.
7898479201
**
79202
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
79203
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
79204
+**
79205
+** The pA side might be using TK_REGISTER. If that is the case and pB is
79206
+** not using TK_REGISTER but is otherwise equivalent, then still return 0.
79207
+**
7898579208
** Sometimes this routine will return 2 even if the two expressions
7898679209
** really are equivalent. If we cannot prove that the expressions are
7898779210
** identical, we return 2 just to be safe. So if this routine
7898879211
** returns 2, then you do not really know for certain if the two
7898979212
** expressions are the same. But if you get a 0 or 1 return, then you
@@ -78990,33 +79213,36 @@
7899079213
** can be sure the expressions are the same. In the places where
7899179214
** this routine is used, it does not hurt to get an extra 2 - that
7899279215
** just might result in some slightly slower code. But returning
7899379216
** an incorrect 0 or 1 could lead to a malfunction.
7899479217
*/
78995
-SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
79218
+SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
7899679219
if( pA==0||pB==0 ){
7899779220
return pB==pA ? 0 : 2;
7899879221
}
7899979222
assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
7900079223
assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
7900179224
if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
7900279225
return 2;
7900379226
}
7900479227
if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
79005
- if( pA->op!=pB->op ){
79006
- if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
79228
+ if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){
79229
+ if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
7900779230
return 1;
7900879231
}
79009
- if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
79232
+ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
7901079233
return 1;
7901179234
}
7901279235
return 2;
7901379236
}
79014
- if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
79015
- if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
79016
- if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
79017
- if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
79237
+ if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
79238
+ if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
79239
+ if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
79240
+ if( pA->iColumn!=pB->iColumn ) return 2;
79241
+ if( pA->iTable!=pB->iTable
79242
+ && pA->op!=TK_REGISTER
79243
+ && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
7901879244
if( ExprHasProperty(pA, EP_IntValue) ){
7901979245
if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
7902079246
return 2;
7902179247
}
7902279248
}else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
@@ -79030,28 +79256,70 @@
7903079256
7903179257
/*
7903279258
** Compare two ExprList objects. Return 0 if they are identical and
7903379259
** non-zero if they differ in any way.
7903479260
**
79261
+** If any subelement of pB has Expr.iTable==(-1) then it is allowed
79262
+** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
79263
+**
7903579264
** This routine might return non-zero for equivalent ExprLists. The
7903679265
** only consequence will be disabled optimizations. But this routine
7903779266
** must never return 0 if the two ExprList objects are different, or
7903879267
** a malfunction will result.
7903979268
**
7904079269
** Two NULL pointers are considered to be the same. But a NULL pointer
7904179270
** always differs from a non-NULL pointer.
7904279271
*/
79043
-SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
79272
+SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
7904479273
int i;
7904579274
if( pA==0 && pB==0 ) return 0;
7904679275
if( pA==0 || pB==0 ) return 1;
7904779276
if( pA->nExpr!=pB->nExpr ) return 1;
7904879277
for(i=0; i<pA->nExpr; i++){
7904979278
Expr *pExprA = pA->a[i].pExpr;
7905079279
Expr *pExprB = pB->a[i].pExpr;
7905179280
if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
79052
- if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
79281
+ if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
79282
+ }
79283
+ return 0;
79284
+}
79285
+
79286
+/*
79287
+** Return true if we can prove the pE2 will always be true if pE1 is
79288
+** true. Return false if we cannot complete the proof or if pE2 might
79289
+** be false. Examples:
79290
+**
79291
+** pE1: x==5 pE2: x==5 Result: true
79292
+** pE1: x>0 pE2: x==5 Result: false
79293
+** pE1: x=21 pE2: x=21 OR y=43 Result: true
79294
+** pE1: x!=123 pE2: x IS NOT NULL Result: true
79295
+** pE1: x!=?1 pE2: x IS NOT NULL Result: true
79296
+** pE1: x IS NULL pE2: x IS NOT NULL Result: false
79297
+** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false
79298
+**
79299
+** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
79300
+** Expr.iTable<0 then assume a table number given by iTab.
79301
+**
79302
+** When in doubt, return false. Returning true might give a performance
79303
+** improvement. Returning false might cause a performance reduction, but
79304
+** it will always give the correct answer and is hence always safe.
79305
+*/
79306
+SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
79307
+ if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
79308
+ return 1;
79309
+ }
79310
+ if( pE2->op==TK_OR
79311
+ && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
79312
+ || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
79313
+ ){
79314
+ return 1;
79315
+ }
79316
+ if( pE2->op==TK_NOTNULL
79317
+ && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
79318
+ && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
79319
+ ){
79320
+ return 1;
7905379321
}
7905479322
return 0;
7905579323
}
7905679324
7905779325
/*
@@ -79232,11 +79500,11 @@
7923279500
/* Check to see if pExpr is a duplicate of another aggregate
7923379501
** function that is already in the pAggInfo structure
7923479502
*/
7923579503
struct AggInfo_func *pItem = pAggInfo->aFunc;
7923679504
for(i=0; i<pAggInfo->nFunc; i++, pItem++){
79237
- if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
79505
+ if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
7923879506
break;
7923979507
}
7924079508
}
7924179509
if( i>=pAggInfo->nFunc ){
7924279510
/* pExpr is original. Make a new entry in pAggInfo->aFunc[]
@@ -80649,10 +80917,11 @@
8064980917
int i; /* Loop counter */
8065080918
int topOfLoop; /* The top of the loop */
8065180919
int endOfLoop; /* The end of the loop */
8065280920
int jZeroRows = -1; /* Jump from here if number of rows is zero */
8065380921
int iDb; /* Index of database containing pTab */
80922
+ u8 needTableCnt = 1; /* True to count the table */
8065480923
int regTabname = iMem++; /* Register containing table name */
8065580924
int regIdxname = iMem++; /* Register containing index name */
8065680925
int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
8065780926
#ifdef SQLITE_ENABLE_STAT3
8065880927
int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
@@ -80708,10 +80977,11 @@
8070880977
KeyInfo *pKey;
8070980978
int addrIfNot = 0; /* address of OP_IfNot */
8071080979
int *aChngAddr; /* Array of jump instruction addresses */
8071180980
8071280981
if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
80982
+ if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
8071380983
VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
8071480984
nCol = pIdx->nColumn;
8071580985
aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
8071680986
if( aChngAddr==0 ) continue;
8071780987
pKey = sqlite3IndexKeyinfo(pParse, pIdx);
@@ -80867,48 +81137,45 @@
8086781137
** If K==0 then no entry is made into the sqlite_stat1 table.
8086881138
** If K>0 then it is always the case the D>0 so division by zero
8086981139
** is never possible.
8087081140
*/
8087181141
sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
80872
- if( jZeroRows<0 ){
80873
- jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
80874
- }
81142
+ jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
8087581143
for(i=0; i<nCol; i++){
8087681144
sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
8087781145
sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
8087881146
sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
8087981147
sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
8088081148
sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
8088181149
sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
8088281150
sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
8088381151
}
81152
+ if( pIdx->pPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows);
8088481153
sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
8088581154
sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
8088681155
sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
8088781156
sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
81157
+ if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows);
8088881158
}
8088981159
80890
- /* If the table has no indices, create a single sqlite_stat1 entry
80891
- ** containing NULL as the index name and the row count as the content.
81160
+ /* Create a single sqlite_stat1 entry containing NULL as the index
81161
+ ** name and the row count as the content.
8089281162
*/
80893
- if( pTab->pIndex==0 ){
81163
+ if( pOnlyIdx==0 && needTableCnt ){
8089481164
sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
8089581165
VdbeComment((v, "%s", pTab->zName));
8089681166
sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
8089781167
sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
8089881168
jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
80899
- }else{
80900
- sqlite3VdbeJumpHere(v, jZeroRows);
80901
- jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
80902
- }
80903
- sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
80904
- sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
80905
- sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
80906
- sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
80907
- sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
80908
- if( pParse->nMem<regRec ) pParse->nMem = regRec;
80909
- sqlite3VdbeJumpHere(v, jZeroRows);
81169
+ sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
81170
+ sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
81171
+ sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
81172
+ sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
81173
+ sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
81174
+ sqlite3VdbeJumpHere(v, jZeroRows);
81175
+ }
81176
+ if( pParse->nMem<regRec ) pParse->nMem = regRec;
8091081177
}
8091181178
8091281179
8091381180
/*
8091481181
** Generate code that will cause the most recent index analysis to
@@ -81087,12 +81354,14 @@
8108781354
v = 0;
8108881355
while( (c=z[0])>='0' && c<='9' ){
8108981356
v = v*10 + c - '0';
8109081357
z++;
8109181358
}
81092
- if( i==0 ) pTable->nRowEst = v;
81093
- if( pIndex==0 ) break;
81359
+ if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){
81360
+ if( v>0 ) pTable->nRowEst = v;
81361
+ if( pIndex==0 ) break;
81362
+ }
8109481363
pIndex->aiRowEst[i] = v;
8109581364
if( *z==' ' ) z++;
8109681365
if( strcmp(z, "unordered")==0 ){
8109781366
pIndex->bUnordered = 1;
8109881367
break;
@@ -82528,10 +82797,11 @@
8252882797
*/
8252982798
static void freeIndex(sqlite3 *db, Index *p){
8253082799
#ifndef SQLITE_OMIT_ANALYZE
8253182800
sqlite3DeleteIndexSamples(db, p);
8253282801
#endif
82802
+ sqlite3ExprDelete(db, p->pPartIdxWhere);
8253382803
sqlite3DbFree(db, p->zColAff);
8253482804
sqlite3DbFree(db, p);
8253582805
}
8253682806
8253782807
/*
@@ -83371,11 +83641,12 @@
8337183641
sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
8337283642
"INTEGER PRIMARY KEY");
8337383643
#endif
8337483644
}else{
8337583645
Index *p;
83376
- p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
83646
+ p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
83647
+ 0, sortOrder, 0);
8337783648
if( p ){
8337883649
p->autoIndex = 2;
8337983650
}
8338083651
pList = 0;
8338183652
}
@@ -83666,30 +83937,11 @@
8366683937
8366783938
#ifndef SQLITE_OMIT_CHECK
8366883939
/* Resolve names in all CHECK constraint expressions.
8366983940
*/
8367083941
if( p->pCheck ){
83671
- SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
83672
- NameContext sNC; /* Name context for pParse->pNewTable */
83673
- ExprList *pList; /* List of all CHECK constraints */
83674
- int i; /* Loop counter */
83675
-
83676
- memset(&sNC, 0, sizeof(sNC));
83677
- memset(&sSrc, 0, sizeof(sSrc));
83678
- sSrc.nSrc = 1;
83679
- sSrc.a[0].zName = p->zName;
83680
- sSrc.a[0].pTab = p;
83681
- sSrc.a[0].iCursor = -1;
83682
- sNC.pParse = pParse;
83683
- sNC.pSrcList = &sSrc;
83684
- sNC.ncFlags = NC_IsCheck;
83685
- pList = p->pCheck;
83686
- for(i=0; i<pList->nExpr; i++){
83687
- if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
83688
- return;
83689
- }
83690
- }
83942
+ sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
8369183943
}
8369283944
#endif /* !defined(SQLITE_OMIT_CHECK) */
8369383945
8369483946
/* If the db->init.busy is 1 it means we are reading the SQL off the
8369583947
** "sqlite_master" or "sqlite_temp_master" table on the disk.
@@ -84537,10 +84789,11 @@
8453784789
int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
8453884790
int iSorter; /* Cursor opened by OpenSorter (if in use) */
8453984791
int addr1; /* Address of top of loop */
8454084792
int addr2; /* Address to jump to for next iteration */
8454184793
int tnum; /* Root page of index */
84794
+ int iPartIdxLabel; /* Jump to this label to skip a row */
8454284795
Vdbe *v; /* Generate code into this virtual machine */
8454384796
KeyInfo *pKey; /* KeyInfo for index */
8454484797
int regRecord; /* Register holding assemblied index record */
8454584798
sqlite3 *db = pParse->db; /* The database connection */
8454684799
int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
@@ -84576,12 +84829,13 @@
8457684829
** records into the sorter. */
8457784830
sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
8457884831
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
8457984832
regRecord = sqlite3GetTempReg(pParse);
8458084833
84581
- sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
84834
+ sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
8458284835
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
84836
+ sqlite3VdbeResolveLabel(v, iPartIdxLabel);
8458384837
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
8458484838
sqlite3VdbeJumpHere(v, addr1);
8458584839
addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
8458684840
if( pIndex->onError!=OE_None ){
8458784841
int j2 = sqlite3VdbeCurrentAddr(v) + 3;
@@ -84628,11 +84882,11 @@
8462884882
Token *pName2, /* Second part of index name. May be NULL */
8462984883
SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
8463084884
ExprList *pList, /* A list of columns to be indexed */
8463184885
int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
8463284886
Token *pStart, /* The CREATE token that begins this statement */
84633
- Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
84887
+ Expr *pPIWhere, /* WHERE clause for partial indices */
8463484888
int sortOrder, /* Sort order of primary key when pList==NULL */
8463584889
int ifNotExist /* Omit error if index already exists */
8463684890
){
8463784891
Index *pRet = 0; /* Pointer to return */
8463884892
Table *pTab = 0; /* Table to be indexed */
@@ -84650,11 +84904,10 @@
8465084904
struct ExprList_item *pListItem; /* For looping over pList */
8465184905
int nCol;
8465284906
int nExtra = 0;
8465384907
char *zExtra;
8465484908
84655
- assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
8465684909
assert( pParse->nErr==0 ); /* Never called with prior errors */
8465784910
if( db->mallocFailed || IN_DECLARE_VTAB ){
8465884911
goto exit_create_index;
8465984912
}
8466084913
if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -84696,11 +84949,16 @@
8469684949
assert(0);
8469784950
}
8469884951
pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
8469984952
assert( db->mallocFailed==0 || pTab==0 );
8470084953
if( pTab==0 ) goto exit_create_index;
84701
- assert( db->aDb[iDb].pSchema==pTab->pSchema );
84954
+ if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
84955
+ sqlite3ErrorMsg(pParse,
84956
+ "cannot create a TEMP index on non-TEMP table \"%s\"",
84957
+ pTab->zName);
84958
+ goto exit_create_index;
84959
+ }
8470284960
}else{
8470384961
assert( pName==0 );
8470484962
assert( pStart==0 );
8470584963
pTab = pParse->pNewTable;
8470684964
if( !pTab ) goto exit_create_index;
@@ -84845,10 +85103,15 @@
8484585103
pIndex->nColumn = pList->nExpr;
8484685104
pIndex->onError = (u8)onError;
8484785105
pIndex->uniqNotNull = onError==OE_Abort;
8484885106
pIndex->autoIndex = (u8)(pName==0);
8484985107
pIndex->pSchema = db->aDb[iDb].pSchema;
85108
+ if( pPIWhere ){
85109
+ sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
85110
+ pIndex->pPartIdxWhere = pPIWhere;
85111
+ pPIWhere = 0;
85112
+ }
8485085113
assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
8485185114
8485285115
/* Check to see if we should honor DESC requests on index columns
8485385116
*/
8485485117
if( pDb->pSchema->file_format>=4 ){
@@ -85000,11 +85263,11 @@
8500085263
** If pTblName==0 it means this index is generated as a primary key
8500185264
** or UNIQUE constraint of a CREATE TABLE statement. Since the table
8500285265
** has just been created, it contains no data and the index initialization
8500385266
** step can be skipped.
8500485267
*/
85005
- else{ /* if( db->init.busy==0 ) */
85268
+ else if( pParse->nErr==0 ){
8500685269
Vdbe *v;
8500785270
char *zStmt;
8500885271
int iMem = ++pParse->nMem;
8500985272
8501085273
v = sqlite3GetVdbe(pParse);
@@ -85018,16 +85281,15 @@
8501885281
8501985282
/* Gather the complete text of the CREATE INDEX statement into
8502085283
** the zStmt variable
8502185284
*/
8502285285
if( pStart ){
85023
- assert( pEnd!=0 );
85286
+ int n = (pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
85287
+ if( pName->z[n-1]==';' ) n--;
8502485288
/* A named index with an explicit CREATE INDEX statement */
8502585289
zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
85026
- onError==OE_None ? "" : " UNIQUE",
85027
- (int)(pEnd->z - pName->z) + 1,
85028
- pName->z);
85290
+ onError==OE_None ? "" : " UNIQUE", n, pName->z);
8502985291
}else{
8503085292
/* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
8503185293
/* zStmt = sqlite3MPrintf(""); */
8503285294
zStmt = 0;
8503385295
}
@@ -85079,14 +85341,12 @@
8507985341
pIndex = 0;
8508085342
}
8508185343
8508285344
/* Clean up before exiting */
8508385345
exit_create_index:
85084
- if( pIndex ){
85085
- sqlite3DbFree(db, pIndex->zColAff);
85086
- sqlite3DbFree(db, pIndex);
85087
- }
85346
+ if( pIndex ) freeIndex(db, pIndex);
85347
+ sqlite3ExprDelete(db, pPIWhere);
8508885348
sqlite3ExprListDelete(db, pList);
8508985349
sqlite3SrcListDelete(db, pTblName);
8509085350
sqlite3DbFree(db, zName);
8509185351
return pRet;
8509285352
}
@@ -85960,29 +86220,24 @@
8596086220
** the error.
8596186221
*/
8596286222
SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
8596386223
int i;
8596486224
int nCol = pIdx->nColumn;
85965
- int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
85966
- sqlite3 *db = pParse->db;
85967
- KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
85968
-
85969
- if( pKey ){
85970
- pKey->db = pParse->db;
85971
- pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
85972
- assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
86225
+ KeyInfo *pKey;
86226
+
86227
+ pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
86228
+ if( pKey ){
8597386229
for(i=0; i<nCol; i++){
8597486230
char *zColl = pIdx->azColl[i];
8597586231
assert( zColl );
8597686232
pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
8597786233
pKey->aSortOrder[i] = pIdx->aSortOrder[i];
8597886234
}
85979
- pKey->nField = (u16)nCol;
8598086235
}
8598186236
8598286237
if( pParse->nErr ){
85983
- sqlite3DbFree(db, pKey);
86238
+ sqlite3DbFree(pParse->db, pKey);
8598486239
pKey = 0;
8598586240
}
8598686241
return pKey;
8598786242
}
8598886243
@@ -87058,15 +87313,18 @@
8705887313
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
8705987314
){
8706087315
int i;
8706187316
Index *pIdx;
8706287317
int r1;
87318
+ int iPartIdxLabel;
87319
+ Vdbe *v = pParse->pVdbe;
8706387320
8706487321
for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
8706587322
if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
87066
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
87067
- sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
87323
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
87324
+ sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
87325
+ sqlite3VdbeResolveLabel(v, iPartIdxLabel);
8706887326
}
8706987327
}
8707087328
8707187329
/*
8707287330
** Generate code that will assemble an index key and put it in register
@@ -87076,24 +87334,42 @@
8707687334
**
8707787335
** Return a register number which is the first in a block of
8707887336
** registers that holds the elements of the index key. The
8707987337
** block of registers has already been deallocated by the time
8708087338
** this routine returns.
87339
+**
87340
+** If *piPartIdxLabel is not NULL, fill it in with a label and jump
87341
+** to that label if pIdx is a partial index that should be skipped.
87342
+** A partial index should be skipped if its WHERE clause evaluates
87343
+** to false or null. If pIdx is not a partial index, *piPartIdxLabel
87344
+** will be set to zero which is an empty label that is ignored by
87345
+** sqlite3VdbeResolveLabel().
8708187346
*/
8708287347
SQLITE_PRIVATE int sqlite3GenerateIndexKey(
87083
- Parse *pParse, /* Parsing context */
87084
- Index *pIdx, /* The index for which to generate a key */
87085
- int iCur, /* Cursor number for the pIdx->pTable table */
87086
- int regOut, /* Write the new index key to this register */
87087
- int doMakeRec /* Run the OP_MakeRecord instruction if true */
87348
+ Parse *pParse, /* Parsing context */
87349
+ Index *pIdx, /* The index for which to generate a key */
87350
+ int iCur, /* Cursor number for the pIdx->pTable table */
87351
+ int regOut, /* Write the new index key to this register */
87352
+ int doMakeRec, /* Run the OP_MakeRecord instruction if true */
87353
+ int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
8708887354
){
8708987355
Vdbe *v = pParse->pVdbe;
8709087356
int j;
8709187357
Table *pTab = pIdx->pTable;
8709287358
int regBase;
8709387359
int nCol;
8709487360
87361
+ if( piPartIdxLabel ){
87362
+ if( pIdx->pPartIdxWhere ){
87363
+ *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
87364
+ pParse->iPartIdxTab = iCur;
87365
+ sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
87366
+ SQLITE_JUMPIFNULL);
87367
+ }else{
87368
+ *piPartIdxLabel = 0;
87369
+ }
87370
+ }
8709587371
nCol = pIdx->nColumn;
8709687372
regBase = sqlite3GetTempRange(pParse, nCol+1);
8709787373
sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
8709887374
for(j=0; j<nCol; j++){
8709987375
int idx = pIdx->aiColumn[j];
@@ -89262,11 +89538,14 @@
8926289538
sqlite3ReleaseTempReg(pParse, regRec);
8926389539
sqlite3ReleaseTempRange(pParse, regTemp, nCol);
8926489540
}
8926589541
}
8926689542
89267
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
89543
+ if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
89544
+ && !pParse->pToplevel
89545
+ && !pParse->isMultiWrite
89546
+ ){
8926889547
/* Special case: If this is an INSERT statement that will insert exactly
8926989548
** one row into the table, raise a constraint immediately instead of
8927089549
** incrementing a counter. This is necessary as the VM code is being
8927189550
** generated for will not open a statement transaction. */
8927289551
assert( nIncr==1 );
@@ -89653,11 +89932,13 @@
8965389932
for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
8965489933
Index *pIdx = 0; /* Foreign key index for pFKey */
8965589934
SrcList *pSrc;
8965689935
int *aiCol = 0;
8965789936
89658
- if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
89937
+ if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
89938
+ && !pParse->pToplevel && !pParse->isMultiWrite
89939
+ ){
8965989940
assert( regOld==0 && regNew!=0 );
8966089941
/* Inserting a single row into a parent table cannot cause an immediate
8966189942
** foreign key violation. So do nothing in this case. */
8966289943
continue;
8966389944
}
@@ -91448,12 +91729,22 @@
9144891729
** Add the new records to the indices as we go.
9144991730
*/
9145091731
for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
9145191732
int regIdx;
9145291733
int regR;
91734
+ int addrSkipRow = 0;
9145391735
9145491736
if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
91737
+
91738
+ if( pIdx->pPartIdxWhere ){
91739
+ sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
91740
+ addrSkipRow = sqlite3VdbeMakeLabel(v);
91741
+ pParse->ckBase = regData;
91742
+ sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
91743
+ SQLITE_JUMPIFNULL);
91744
+ pParse->ckBase = 0;
91745
+ }
9145591746
9145691747
/* Create a key for accessing the index entry */
9145791748
regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
9145891749
for(i=0; i<pIdx->nColumn; i++){
9145991750
int idx = pIdx->aiColumn[i];
@@ -91470,10 +91761,11 @@
9147091761
9147191762
/* Find out what action to take in case there is an indexing conflict */
9147291763
onError = pIdx->onError;
9147391764
if( onError==OE_None ){
9147491765
sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
91766
+ sqlite3VdbeResolveLabel(v, addrSkipRow);
9147591767
continue; /* pIdx is not a UNIQUE index */
9147691768
}
9147791769
if( overrideError!=OE_Default ){
9147891770
onError = overrideError;
9147991771
}else if( onError==OE_Default ){
@@ -91539,10 +91831,11 @@
9153991831
seenReplace = 1;
9154091832
break;
9154191833
}
9154291834
}
9154391835
sqlite3VdbeJumpHere(v, j3);
91836
+ sqlite3VdbeResolveLabel(v, addrSkipRow);
9154491837
sqlite3ReleaseTempReg(pParse, regR);
9154591838
}
9154691839
9154791840
if( pbMayReplace ){
9154891841
*pbMayReplace = seenReplace;
@@ -91568,22 +91861,23 @@
9156891861
int appendBias, /* True if this is likely to be an append */
9156991862
int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
9157091863
){
9157191864
int i;
9157291865
Vdbe *v;
91573
- int nIdx;
9157491866
Index *pIdx;
9157591867
u8 pik_flags;
9157691868
int regData;
9157791869
int regRec;
9157891870
9157991871
v = sqlite3GetVdbe(pParse);
9158091872
assert( v!=0 );
9158191873
assert( pTab->pSelect==0 ); /* This table is not a VIEW */
91582
- for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
91583
- for(i=nIdx-1; i>=0; i--){
91874
+ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
9158491875
if( aRegIdx[i]==0 ) continue;
91876
+ if( pIdx->pPartIdxWhere ){
91877
+ sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
91878
+ }
9158591879
sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
9158691880
if( useSeekResult ){
9158791881
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
9158891882
}
9158991883
}
@@ -91681,10 +91975,11 @@
9168191975
**
9168291976
** * The index is over the same set of columns
9168391977
** * The same DESC and ASC markings occurs on all columns
9168491978
** * The same onError processing (OE_Abort, OE_Ignore, etc)
9168591979
** * The same collating sequence on each column
91980
+** * The index has the exact same WHERE clause
9168691981
*/
9168791982
static int xferCompatibleIndex(Index *pDest, Index *pSrc){
9168891983
int i;
9168991984
assert( pDest && pSrc );
9169091985
assert( pDest->pTable!=pSrc->pTable );
@@ -91702,10 +91997,13 @@
9170291997
return 0; /* Different sort orders */
9170391998
}
9170491999
if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
9170592000
return 0; /* Different collating sequences */
9170692001
}
92002
+ }
92003
+ if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
92004
+ return 0; /* Different WHERE clauses */
9170792005
}
9170892006
9170992007
/* If no test above fails then the indices must be compatible */
9171092008
return 1;
9171192009
}
@@ -91858,11 +92156,11 @@
9185892156
if( pSrcIdx==0 ){
9185992157
return 0; /* pDestIdx has no corresponding index in pSrc */
9186092158
}
9186192159
}
9186292160
#ifndef SQLITE_OMIT_CHECK
91863
- if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
92161
+ if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
9186492162
return 0; /* Tables have different CHECK constraints. Ticket #2252 */
9186592163
}
9186692164
#endif
9186792165
#ifndef SQLITE_OMIT_FOREIGN_KEY
9186892166
/* Disallow the transfer optimization if the destination table constains
@@ -92615,15 +92913,18 @@
9261592913
#ifndef SQLITE_CORE
9261692914
/* This case when the file really is being compiled as a loadable
9261792915
** extension */
9261892916
# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
9261992917
# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
92918
+# define SQLITE_EXTENSION_INIT3 \
92919
+ extern const sqlite3_api_routines *sqlite3_api;
9262092920
#else
9262192921
/* This case when the file is being statically linked into the
9262292922
** application */
9262392923
# define SQLITE_EXTENSION_INIT1 /*no-op*/
9262492924
# define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
92925
+# define SQLITE_EXTENSION_INIT3 /*no-op*/
9262592926
#endif
9262692927
9262792928
#endif /* _SQLITE3EXT_H_ */
9262892929
9262992930
/************** End of sqlite3ext.h ******************************************/
@@ -93275,10 +93576,39 @@
9327593576
sqlite3_mutex_leave(mutex);
9327693577
assert( (rc&0xff)==rc );
9327793578
return rc;
9327893579
}
9327993580
}
93581
+
93582
+/*
93583
+** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the
93584
+** set of routines that is invoked for each new database connection, if it
93585
+** is currently on the list. If xInit is not on the list, then this
93586
+** routine is a no-op.
93587
+**
93588
+** Return 1 if xInit was found on the list and removed. Return 0 if xInit
93589
+** was not on the list.
93590
+*/
93591
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
93592
+#if SQLITE_THREADSAFE
93593
+ sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
93594
+#endif
93595
+ int i;
93596
+ int n = 0;
93597
+ wsdAutoextInit;
93598
+ sqlite3_mutex_enter(mutex);
93599
+ for(i=wsdAutoext.nExt-1; i>=0; i--){
93600
+ if( wsdAutoext.aExt[i]==xInit ){
93601
+ wsdAutoext.nExt--;
93602
+ wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
93603
+ n++;
93604
+ break;
93605
+ }
93606
+ }
93607
+ sqlite3_mutex_leave(mutex);
93608
+ return n;
93609
+}
9328093610
9328193611
/*
9328293612
** Reset the automatic extension loading mechanism.
9328393613
*/
9328493614
SQLITE_API void sqlite3_reset_auto_extension(void){
@@ -93516,10 +93846,11 @@
9351693846
{ "empty_result_callbacks", SQLITE_NullCallback },
9351793847
{ "legacy_file_format", SQLITE_LegacyFileFmt },
9351893848
{ "fullfsync", SQLITE_FullFSync },
9351993849
{ "checkpoint_fullfsync", SQLITE_CkptFullFSync },
9352093850
{ "reverse_unordered_selects", SQLITE_ReverseOrder },
93851
+ { "query_only", SQLITE_QueryOnly },
9352193852
#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
9352293853
{ "automatic_index", SQLITE_AutoIndex },
9352393854
#endif
9352493855
#ifdef SQLITE_DEBUG
9352593856
{ "sql_trace", SQLITE_SqlTrace },
@@ -93536,16 +93867,17 @@
9353693867
{ "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
9353793868
9353893869
/* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
9353993870
** flag if there are any active statements. */
9354093871
{ "read_uncommitted", SQLITE_ReadUncommitted },
93541
- { "recursive_triggers", SQLITE_RecTriggers },
93872
+ { "recursive_triggers", SQLITE_RecTriggers },
9354293873
9354393874
/* This flag may only be set if both foreign-key and trigger support
9354493875
** are present in the build. */
9354593876
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
93546
- { "foreign_keys", SQLITE_ForeignKeys },
93877
+ { "foreign_keys", SQLITE_ForeignKeys },
93878
+ { "defer_foreign_keys", SQLITE_DeferFKs },
9354793879
#endif
9354893880
};
9354993881
int i;
9355093882
const struct sPragmaType *p;
9355193883
for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
@@ -93567,10 +93899,11 @@
9356793899
9356893900
if( sqlite3GetBoolean(zRight, 0) ){
9356993901
db->flags |= mask;
9357093902
}else{
9357193903
db->flags &= ~mask;
93904
+ if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
9357293905
}
9357393906
9357493907
/* Many of the flag-pragmas modify the code generated by the SQL
9357593908
** compiler (eg. count_changes). So add an opcode to expire all
9357693909
** compiled SQL statements after modifying a pragma value.
@@ -94736,13 +95069,11 @@
9473695069
cnt++;
9473795070
}
9473895071
}
9473995072
9474095073
/* Make sure sufficient number of registers have been allocated */
94741
- if( pParse->nMem < cnt+4 ){
94742
- pParse->nMem = cnt+4;
94743
- }
95074
+ pParse->nMem = MAX( pParse->nMem, cnt+7 );
9474495075
9474595076
/* Do the b-tree integrity checks */
9474695077
sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
9474795078
sqlite3VdbeChangeP5(v, (u8)i);
9474895079
addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
@@ -94763,16 +95094,19 @@
9476395094
9476495095
if( pTab->pIndex==0 ) continue;
9476595096
addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
9476695097
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
9476795098
sqlite3VdbeJumpHere(v, addr);
95099
+ sqlite3ExprCacheClear(pParse);
9476895100
sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
94769
- sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */
94770
- loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
94771
- sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
95101
+ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
95102
+ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
95103
+ }
95104
+ pParse->nMem = MAX(pParse->nMem, 7+j);
95105
+ loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;
9477295106
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
94773
- int jmp2;
95107
+ int jmp2, jmp3;
9477495108
int r1;
9477595109
static const VdbeOpList idxErr[] = {
9477695110
{ OP_AddImm, 1, -1, 0},
9477795111
{ OP_String8, 0, 3, 0}, /* 1 */
9477895112
{ OP_Rowid, 1, 4, 0},
@@ -94783,47 +95117,38 @@
9478395117
{ OP_Concat, 6, 3, 3},
9478495118
{ OP_ResultRow, 3, 1, 0},
9478595119
{ OP_IfPos, 1, 0, 0}, /* 9 */
9478695120
{ OP_Halt, 0, 0, 0},
9478795121
};
94788
- r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
95122
+ r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
95123
+ sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1); /* increment entry count */
9478995124
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
9479095125
addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
9479195126
sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
9479295127
sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
9479395128
sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
9479495129
sqlite3VdbeJumpHere(v, addr+9);
9479595130
sqlite3VdbeJumpHere(v, jmp2);
95131
+ sqlite3VdbeResolveLabel(v, jmp3);
9479695132
}
94797
- sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
94798
- sqlite3VdbeJumpHere(v, loopTop);
95133
+ sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
95134
+ sqlite3VdbeJumpHere(v, loopTop-1);
95135
+#ifndef SQLITE_OMIT_BTREECOUNT
95136
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
95137
+ "wrong # of entries in index ", P4_STATIC);
9479995138
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
94800
- static const VdbeOpList cntIdx[] = {
94801
- { OP_Integer, 0, 3, 0},
94802
- { OP_Rewind, 0, 0, 0}, /* 1 */
94803
- { OP_AddImm, 3, 1, 0},
94804
- { OP_Next, 0, 0, 0}, /* 3 */
94805
- { OP_Eq, 2, 0, 3}, /* 4 */
94806
- { OP_AddImm, 1, -1, 0},
94807
- { OP_String8, 0, 2, 0}, /* 6 */
94808
- { OP_String8, 0, 3, 0}, /* 7 */
94809
- { OP_Concat, 3, 2, 2},
94810
- { OP_ResultRow, 2, 1, 0},
94811
- };
94812
- addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
95139
+ addr = sqlite3VdbeCurrentAddr(v);
95140
+ sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
9481395141
sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
94814
- sqlite3VdbeJumpHere(v, addr);
94815
- addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
94816
- sqlite3VdbeChangeP1(v, addr+1, j+2);
94817
- sqlite3VdbeChangeP2(v, addr+1, addr+4);
94818
- sqlite3VdbeChangeP1(v, addr+3, j+2);
94819
- sqlite3VdbeChangeP2(v, addr+3, addr+2);
94820
- sqlite3VdbeJumpHere(v, addr+4);
94821
- sqlite3VdbeChangeP4(v, addr+6,
94822
- "wrong # of entries in index ", P4_STATIC);
94823
- sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
94824
- }
95142
+ sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
95143
+ sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);
95144
+ sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
95145
+ sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
95146
+ sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
95147
+ sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
95148
+ }
95149
+#endif /* SQLITE_OMIT_BTREECOUNT */
9482595150
}
9482695151
}
9482795152
addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
9482895153
sqlite3VdbeChangeP2(v, addr, -mxErr);
9482995154
sqlite3VdbeJumpHere(v, addr+1);
@@ -95979,10 +96304,16 @@
9597996304
9598096305
assert( ppStmt );
9598196306
*ppStmt = 0;
9598296307
if( !sqlite3SafetyCheckOk(db) ){
9598396308
return SQLITE_MISUSE_BKPT;
96309
+ }
96310
+ if( nBytes>=0 ){
96311
+ int sz;
96312
+ const char *z = (const char*)zSql;
96313
+ for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
96314
+ nBytes = sz;
9598496315
}
9598596316
sqlite3_mutex_enter(db->mutex);
9598696317
zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
9598796318
if( zSql8 ){
9598896319
rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
@@ -96840,10 +97171,29 @@
9684097171
*/
9684197172
if( pOrderBy==0 && p->iLimit ){
9684297173
sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
9684397174
}
9684497175
}
97176
+
97177
+/*
97178
+** Allocate a KeyInfo object sufficient for an index of N columns.
97179
+**
97180
+** Actually, always allocate one extra column for the rowid at the end
97181
+** of the index. So the KeyInfo returned will have space sufficient for
97182
+** N+1 columns.
97183
+*/
97184
+SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
97185
+ KeyInfo *p = sqlite3DbMallocZero(db,
97186
+ sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
97187
+ if( p ){
97188
+ p->aSortOrder = (u8*)&p->aColl[N+1];
97189
+ p->nField = (u16)N;
97190
+ p->enc = ENC(db);
97191
+ p->db = db;
97192
+ }
97193
+ return p;
97194
+}
9684597195
9684697196
/*
9684797197
** Given an expression list, generate a KeyInfo structure that records
9684897198
** the collating sequence for each expression in that expression list.
9684997199
**
@@ -96857,29 +97207,23 @@
9685797207
** function is responsible for seeing that this structure is eventually
9685897208
** freed. Add the KeyInfo structure to the P4 field of an opcode using
9685997209
** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
9686097210
*/
9686197211
static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
96862
- sqlite3 *db = pParse->db;
9686397212
int nExpr;
9686497213
KeyInfo *pInfo;
9686597214
struct ExprList_item *pItem;
97215
+ sqlite3 *db = pParse->db;
9686697216
int i;
9686797217
9686897218
nExpr = pList->nExpr;
96869
- pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
97219
+ pInfo = sqlite3KeyInfoAlloc(db, nExpr);
9687097220
if( pInfo ){
96871
- pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
96872
- pInfo->nField = (u16)nExpr;
96873
- pInfo->enc = ENC(db);
96874
- pInfo->db = db;
9687597221
for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
9687697222
CollSeq *pColl;
9687797223
pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
96878
- if( !pColl ){
96879
- pColl = db->pDfltColl;
96880
- }
97224
+ if( !pColl ) pColl = db->pDfltColl;
9688197225
pInfo->aColl[i] = pColl;
9688297226
pInfo->aSortOrder[i] = pItem->sortOrder;
9688397227
}
9688497228
}
9688597229
return pInfo;
@@ -97981,27 +98325,21 @@
9798198325
CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
9798298326
int nCol; /* Number of columns in result set */
9798398327
9798498328
assert( p->pRightmost==p );
9798598329
nCol = p->pEList->nExpr;
97986
- pKeyInfo = sqlite3DbMallocZero(db,
97987
- sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
98330
+ pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
9798898331
if( !pKeyInfo ){
9798998332
rc = SQLITE_NOMEM;
9799098333
goto multi_select_end;
9799198334
}
97992
-
97993
- pKeyInfo->enc = ENC(db);
97994
- pKeyInfo->nField = (u16)nCol;
97995
-
9799698335
for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
9799798336
*apColl = multiSelectCollSeq(pParse, p, i);
9799898337
if( 0==*apColl ){
9799998338
*apColl = db->pDfltColl;
9800098339
}
9800198340
}
98002
- pKeyInfo->aSortOrder = (u8*)apColl;
9800398341
9800498342
for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
9800598343
for(i=0; i<2; i++){
9800698344
int addr = pLoop->addrOpenEphm[i];
9800798345
if( addr<0 ){
@@ -98366,16 +98704,12 @@
9836698704
struct ExprList_item *pItem;
9836798705
for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
9836898706
assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
9836998707
aPermute[i] = pItem->iOrderByCol - 1;
9837098708
}
98371
- pKeyMerge =
98372
- sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
98709
+ pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
9837398710
if( pKeyMerge ){
98374
- pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
98375
- pKeyMerge->nField = (u16)nOrderBy;
98376
- pKeyMerge->enc = ENC(db);
9837798711
for(i=0; i<nOrderBy; i++){
9837898712
CollSeq *pColl;
9837998713
Expr *pTerm = pOrderBy->a[i].pExpr;
9838098714
if( pTerm->flags & EP_Collate ){
9838198715
pColl = sqlite3ExprCollSeq(pParse, pTerm);
@@ -98408,16 +98742,12 @@
9840898742
int nExpr = p->pEList->nExpr;
9840998743
assert( nOrderBy>=nExpr || db->mallocFailed );
9841098744
regPrev = pParse->nMem+1;
9841198745
pParse->nMem += nExpr+1;
9841298746
sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
98413
- pKeyDup = sqlite3DbMallocZero(db,
98414
- sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
98747
+ pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
9841598748
if( pKeyDup ){
98416
- pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
98417
- pKeyDup->nField = (u16)nExpr;
98418
- pKeyDup->enc = ENC(db);
9841998749
for(i=0; i<nExpr; i++){
9842098750
pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
9842198751
pKeyDup->aSortOrder[i] = 0;
9842298752
}
9842398753
}
@@ -99679,14 +100009,16 @@
99679100009
** and/or pParse->db->mallocFailed.
99680100010
*/
99681100011
static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
99682100012
Walker w;
99683100013
memset(&w, 0, sizeof(w));
99684
- w.xSelectCallback = convertCompoundSelectToSubquery;
99685100014
w.xExprCallback = exprWalkNoop;
99686100015
w.pParse = pParse;
99687
- sqlite3WalkSelect(&w, pSelect);
100016
+ if( pParse->hasCompound ){
100017
+ w.xSelectCallback = convertCompoundSelectToSubquery;
100018
+ sqlite3WalkSelect(&w, pSelect);
100019
+ }
99688100020
w.xSelectCallback = selectExpander;
99689100021
sqlite3WalkSelect(&w, pSelect);
99690100022
}
99691100023
99692100024
@@ -100216,11 +100548,11 @@
100216100548
** will cause elements to come out in the correct order. This is
100217100549
** an optimization - the correct answer should result regardless.
100218100550
** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
100219100551
** to disable this optimization for testing purposes.
100220100552
*/
100221
- if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
100553
+ if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
100222100554
&& OptimizationEnabled(db, SQLITE_GroupByOrder) ){
100223100555
pOrderBy = 0;
100224100556
}
100225100557
100226100558
/* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
@@ -100237,11 +100569,11 @@
100237100569
** used for both the ORDER BY and DISTINCT processing. As originally
100238100570
** written the query must use a temp-table for at least one of the ORDER
100239100571
** BY and DISTINCT, and an index or separate temp-table for the other.
100240100572
*/
100241100573
if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
100242
- && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
100574
+ && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0
100243100575
){
100244100576
p->selFlags &= ~SF_Distinct;
100245100577
p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
100246100578
pGroupBy = p->pGroupBy;
100247100579
pOrderBy = 0;
@@ -102464,11 +102796,11 @@
102464102796
aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
102465102797
if( aRegIdx==0 ) goto update_cleanup;
102466102798
}
102467102799
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
102468102800
int reg;
102469
- if( hasFK || chngRowid ){
102801
+ if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
102470102802
reg = ++pParse->nMem;
102471102803
}else{
102472102804
reg = 0;
102473102805
for(i=0; i<pIdx->nColumn; i++){
102474102806
if( aXRef[pIdx->aiColumn[i]]>=0 ){
@@ -104070,12 +104402,12 @@
104070104402
int (*x)(sqlite3_vtab *);
104071104403
sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
104072104404
if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
104073104405
rc = x(pVtab);
104074104406
sqlite3DbFree(db, *pzErrmsg);
104075
- *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
104076
- sqlite3_free(pVtab->zErrMsg);
104407
+ *pzErrmsg = pVtab->zErrMsg;
104408
+ pVtab->zErrMsg = 0;
104077104409
}
104078104410
}
104079104411
db->aVTrans = aVTrans;
104080104412
return rc;
104081104413
}
@@ -104391,10 +104723,12 @@
104391104723
typedef struct WhereLoop WhereLoop;
104392104724
typedef struct WherePath WherePath;
104393104725
typedef struct WhereTerm WhereTerm;
104394104726
typedef struct WhereLoopBuilder WhereLoopBuilder;
104395104727
typedef struct WhereScan WhereScan;
104728
+typedef struct WhereOrCost WhereOrCost;
104729
+typedef struct WhereOrSet WhereOrSet;
104396104730
104397104731
/*
104398104732
** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The
104399104733
** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
104400104734
** (Virtual tables can return a larger cost, but let's assume they do not.)
@@ -104497,10 +104831,31 @@
104497104831
u16 nLSlot; /* Number of slots allocated for aLTerm[] */
104498104832
WhereTerm **aLTerm; /* WhereTerms used */
104499104833
WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
104500104834
WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */
104501104835
};
104836
+
104837
+/* This object holds the prerequisites and the cost of running a
104838
+** subquery on one operand of an OR operator in the WHERE clause.
104839
+** See WhereOrSet for additional information
104840
+*/
104841
+struct WhereOrCost {
104842
+ Bitmask prereq; /* Prerequisites */
104843
+ WhereCost rRun; /* Cost of running this subquery */
104844
+ WhereCost nOut; /* Number of outputs for this subquery */
104845
+};
104846
+
104847
+/* The WhereOrSet object holds a set of possible WhereOrCosts that
104848
+** correspond to the subquery(s) of OR-clause processing. At most
104849
+** favorable N_OR_COST elements are retained.
104850
+*/
104851
+#define N_OR_COST 3
104852
+struct WhereOrSet {
104853
+ u16 n; /* Number of valid a[] entries */
104854
+ WhereOrCost a[N_OR_COST]; /* Set of best costs */
104855
+};
104856
+
104502104857
104503104858
/* Forward declaration of methods */
104504104859
static int whereLoopResize(sqlite3*, WhereLoop*, int);
104505104860
104506104861
/*
@@ -104712,11 +105067,11 @@
104712105067
struct WhereLoopBuilder {
104713105068
WhereInfo *pWInfo; /* Information about this WHERE */
104714105069
WhereClause *pWC; /* WHERE clause terms */
104715105070
ExprList *pOrderBy; /* ORDER BY clause */
104716105071
WhereLoop *pNew; /* Template WhereLoop */
104717
- WhereLoop *pBest; /* If non-NULL, store single best loop here */
105072
+ WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
104718105073
};
104719105074
104720105075
/*
104721105076
** The WHERE clause processing routine has two halves. The
104722105077
** first part does the start of the WHERE loop and the second
@@ -104854,10 +105209,58 @@
104854105209
** UPDATE or DELETE might change subsequent WHERE clause results.
104855105210
*/
104856105211
SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo){
104857105212
return pWInfo->okOnePass;
104858105213
}
105214
+
105215
+/*
105216
+** Move the content of pSrc into pDest
105217
+*/
105218
+static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
105219
+ pDest->n = pSrc->n;
105220
+ memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
105221
+}
105222
+
105223
+/*
105224
+** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
105225
+**
105226
+** The new entry might overwrite an existing entry, or it might be
105227
+** appended, or it might be discarded. Do whatever is the right thing
105228
+** so that pSet keeps the N_OR_COST best entries seen so far.
105229
+*/
105230
+static int whereOrInsert(
105231
+ WhereOrSet *pSet, /* The WhereOrSet to be updated */
105232
+ Bitmask prereq, /* Prerequisites of the new entry */
105233
+ WhereCost rRun, /* Run-cost of the new entry */
105234
+ WhereCost nOut /* Number of outputs for the new entry */
105235
+){
105236
+ u16 i;
105237
+ WhereOrCost *p;
105238
+ for(i=pSet->n, p=pSet->a; i>0; i--, p++){
105239
+ if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
105240
+ goto whereOrInsert_done;
105241
+ }
105242
+ if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
105243
+ return 0;
105244
+ }
105245
+ }
105246
+ if( pSet->n<N_OR_COST ){
105247
+ p = &pSet->a[pSet->n++];
105248
+ p->nOut = nOut;
105249
+ }else{
105250
+ p = pSet->a;
105251
+ for(i=1; i<pSet->n; i++){
105252
+ if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
105253
+ }
105254
+ if( p->rRun<=rRun ) return 0;
105255
+ }
105256
+whereOrInsert_done:
105257
+ p->prereq = prereq;
105258
+ p->rRun = rRun;
105259
+ if( p->nOut>nOut ) p->nOut = nOut;
105260
+ return 1;
105261
+}
104859105262
104860105263
/*
104861105264
** Initialize a preallocated WhereClause structure.
104862105265
*/
104863105266
static void whereClauseInit(
@@ -104933,11 +105336,11 @@
104933105336
** the pWC->a[] array.
104934105337
*/
104935105338
static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
104936105339
WhereTerm *pTerm;
104937105340
int idx;
104938
- testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
105341
+ testcase( wtFlags & TERM_VIRTUAL );
104939105342
if( pWC->nTerm>=pWC->nSlot ){
104940105343
WhereTerm *pOld = pWC->a;
104941105344
sqlite3 *db = pWC->pWInfo->pParse->db;
104942105345
pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
104943105346
if( pWC->a==0 ){
@@ -105078,17 +105481,10 @@
105078105481
105079105482
/*
105080105483
** Return TRUE if the given operator is one of the operators that is
105081105484
** allowed for an indexable WHERE clause term. The allowed operators are
105082105485
** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
105083
-**
105084
-** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
105085
-** of one of the following forms: column = expression column > expression
105086
-** column >= expression column < expression column <= expression
105087
-** expression = column expression > column expression >= column
105088
-** expression < column expression <= column column IN
105089
-** (expression-list) column IN (subquery) column IS NULL
105090105486
*/
105091105487
static int allowedOp(int op){
105092105488
assert( TK_GT>TK_EQ && TK_GT<TK_GE );
105093105489
assert( TK_LT>TK_EQ && TK_LT<TK_GE );
105094105490
assert( TK_LE>TK_EQ && TK_LE<TK_GE );
@@ -105403,11 +105799,11 @@
105403105799
op = pRight->op2;
105404105800
}
105405105801
if( op==TK_VARIABLE ){
105406105802
Vdbe *pReprepare = pParse->pReprepare;
105407105803
int iCol = pRight->iColumn;
105408
- pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
105804
+ pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
105409105805
if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
105410105806
z = (char *)sqlite3_value_text(pVal);
105411105807
}
105412105808
sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
105413105809
assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
@@ -105758,12 +106154,10 @@
105758106154
}
105759106155
105760106156
/* At this point, okToChngToIN is true if original pTerm satisfies
105761106157
** case 1. In that case, construct a new virtual term that is
105762106158
** pTerm converted into an IN operator.
105763
- **
105764
- ** EV: R-00211-15100
105765106159
*/
105766106160
if( okToChngToIN ){
105767106161
Expr *pDup; /* A transient duplicate expression */
105768106162
ExprList *pList = 0; /* The RHS of the IN operator */
105769106163
Expr *pLeft = 0; /* The LHS of the IN operator */
@@ -106001,13 +106395,11 @@
106001106395
** wildcard. But if we increment '@', that will push it into the
106002106396
** alphabetic range where case conversions will mess up the
106003106397
** inequality. To avoid this, make sure to also run the full
106004106398
** LIKE on all candidate expressions by clearing the isComplete flag
106005106399
*/
106006
- if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */
106007
-
106008
-
106400
+ if( c=='A'-1 ) isComplete = 0;
106009106401
c = sqlite3UpperToLower[c];
106010106402
}
106011106403
*pC = c + 1;
106012106404
}
106013106405
sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
@@ -106510,11 +106902,11 @@
106510106902
VdbeComment((v, "for %s", pTable->zName));
106511106903
106512106904
/* Fill the automatic index with content */
106513106905
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
106514106906
regRecord = sqlite3GetTempReg(pParse);
106515
- sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
106907
+ sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
106516106908
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
106517106909
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
106518106910
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
106519106911
sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
106520106912
sqlite3VdbeJumpHere(v, addrTop);
@@ -106867,11 +107259,11 @@
106867107259
if( pExpr->op==TK_VARIABLE
106868107260
|| (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
106869107261
){
106870107262
int iVar = pExpr->iColumn;
106871107263
sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
106872
- *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
107264
+ *pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff);
106873107265
return SQLITE_OK;
106874107266
}
106875107267
return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
106876107268
}
106877107269
#endif
@@ -107093,13 +107485,10 @@
107093107485
**
107094107486
** The t2.z='ok' is disabled in the in (2) because it originates
107095107487
** in the ON clause. The term is disabled in (3) because it is not part
107096107488
** of a LEFT OUTER JOIN. In (1), the term is not disabled.
107097107489
**
107098
-** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
107099
-** completely satisfied by indices.
107100
-**
107101107490
** Disabling a term causes that term to not be tested in the inner loop
107102107491
** of the join. Disabling is an optimization. When terms are satisfied
107103107492
** by indices, we disable them to prevent redundant tests in the inner
107104107493
** loop. We would get the correct results if nothing were ever disabled,
107105107494
** but joins might run a little slower. The trick is to disable as much
@@ -107325,11 +107714,11 @@
107325107714
pTerm = pLoop->aLTerm[j];
107326107715
assert( pTerm!=0 );
107327107716
/* The following true for indices with redundant columns.
107328107717
** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
107329107718
testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
107330
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107719
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
107331107720
r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
107332107721
if( r1!=regBase+j ){
107333107722
if( nReg==1 ){
107334107723
sqlite3ReleaseTempReg(pParse, regBase);
107335107724
regBase = r1;
@@ -107525,10 +107914,11 @@
107525107914
WhereLevel *pLevel; /* The where level to be coded */
107526107915
WhereLoop *pLoop; /* The WhereLoop object being coded */
107527107916
WhereClause *pWC; /* Decomposition of the entire WHERE clause */
107528107917
WhereTerm *pTerm; /* A WHERE clause term */
107529107918
Parse *pParse; /* Parsing context */
107919
+ sqlite3 *db; /* Database connection */
107530107920
Vdbe *v; /* The prepared stmt under constructions */
107531107921
struct SrcList_item *pTabItem; /* FROM clause term being coded */
107532107922
int addrBrk; /* Jump here to break out of the loop */
107533107923
int addrCont; /* Jump here to continue with next cycle */
107534107924
int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
@@ -107536,10 +107926,11 @@
107536107926
Bitmask newNotReady; /* Return value */
107537107927
107538107928
pParse = pWInfo->pParse;
107539107929
v = pParse->pVdbe;
107540107930
pWC = &pWInfo->sWC;
107931
+ db = pParse->db;
107541107932
pLevel = &pWInfo->a[iLevel];
107542107933
pLoop = pLevel->pWLoop;
107543107934
pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
107544107935
iCur = pTabItem->iCursor;
107545107936
bRev = (pWInfo->revMask>>iLevel)&1;
@@ -107634,11 +108025,11 @@
107634108025
iReleaseReg = sqlite3GetTempReg(pParse);
107635108026
pTerm = pLoop->aLTerm[0];
107636108027
assert( pTerm!=0 );
107637108028
assert( pTerm->pExpr!=0 );
107638108029
assert( omitTable==0 );
107639
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
108030
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
107640108031
iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
107641108032
addrNxt = pLevel->addrNxt;
107642108033
sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
107643108034
sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
107644108035
sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
@@ -107682,11 +108073,11 @@
107682108073
assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
107683108074
assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
107684108075
assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
107685108076
107686108077
assert( (pStart->wtFlags & TERM_VNULL)==0 );
107687
- testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
108078
+ testcase( pStart->wtFlags & TERM_VIRTUAL );
107688108079
pX = pStart->pExpr;
107689108080
assert( pX!=0 );
107690108081
testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
107691108082
r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
107692108083
sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
@@ -107701,11 +108092,11 @@
107701108092
Expr *pX;
107702108093
pX = pEnd->pExpr;
107703108094
assert( pX!=0 );
107704108095
assert( (pEnd->wtFlags & TERM_VNULL)==0 );
107705108096
testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
107706
- testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
108097
+ testcase( pEnd->wtFlags & TERM_VIRTUAL );
107707108098
memEndValue = ++pParse->nMem;
107708108099
sqlite3ExprCode(pParse, pX->pRight, memEndValue);
107709108100
if( pX->op==TK_LT || pX->op==TK_GT ){
107710108101
testOp = bRev ? OP_Le : OP_Ge;
107711108102
}else{
@@ -107826,11 +108217,11 @@
107826108217
/* Generate code to evaluate all constraint terms using == or IN
107827108218
** and store the values of those terms in an array of registers
107828108219
** starting at regBase.
107829108220
*/
107830108221
regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
107831
- zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
108222
+ zEndAff = sqlite3DbStrDup(db, zStartAff);
107832108223
addrNxt = pLevel->addrNxt;
107833108224
107834108225
/* If we are doing a reverse order scan on an ascending index, or
107835108226
** a forward order scan on a descending index, interchange the
107836108227
** start and end terms (pRangeStart and pRangeEnd).
@@ -107867,11 +108258,11 @@
107867108258
if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
107868108259
zStartAff[nEq] = SQLITE_AFF_NONE;
107869108260
}
107870108261
}
107871108262
nConstraint++;
107872
- testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
108263
+ testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
107873108264
}else if( isMinQuery ){
107874108265
sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
107875108266
nConstraint++;
107876108267
startEq = 0;
107877108268
start_constraints = 1;
@@ -107909,14 +108300,14 @@
107909108300
zEndAff[nEq] = SQLITE_AFF_NONE;
107910108301
}
107911108302
}
107912108303
codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
107913108304
nConstraint++;
107914
- testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
108305
+ testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
107915108306
}
107916
- sqlite3DbFree(pParse->db, zStartAff);
107917
- sqlite3DbFree(pParse->db, zEndAff);
108307
+ sqlite3DbFree(db, zStartAff);
108308
+ sqlite3DbFree(db, zEndAff);
107918108309
107919108310
/* Top of the loop body */
107920108311
pLevel->p2 = sqlite3VdbeCurrentAddr(v);
107921108312
107922108313
/* Check if the index cursor is past the end of the range. */
@@ -108039,11 +108430,11 @@
108039108430
*/
108040108431
if( pWInfo->nLevel>1 ){
108041108432
int nNotReady; /* The number of notReady tables */
108042108433
struct SrcList_item *origSrc; /* Original list of tables */
108043108434
nNotReady = pWInfo->nLevel - iLevel - 1;
108044
- pOrTab = sqlite3StackAllocRaw(pParse->db,
108435
+ pOrTab = sqlite3StackAllocRaw(db,
108045108436
sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
108046108437
if( pOrTab==0 ) return notReady;
108047108438
pOrTab->nAlloc = (u8)(nNotReady + 1);
108048108439
pOrTab->nSrc = pOrTab->nAlloc;
108049108440
memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
@@ -108089,15 +108480,16 @@
108089108480
*/
108090108481
if( pWC->nTerm>1 ){
108091108482
int iTerm;
108092108483
for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
108093108484
Expr *pExpr = pWC->a[iTerm].pExpr;
108485
+ if( &pWC->a[iTerm] == pTerm ) continue;
108094108486
if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
108095
- if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue;
108487
+ if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
108096108488
if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
108097
- pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
108098
- pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
108489
+ pExpr = sqlite3ExprDup(db, pExpr, 0);
108490
+ pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
108099108491
}
108100108492
if( pAndExpr ){
108101108493
pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
108102108494
}
108103108495
}
@@ -108113,11 +108505,11 @@
108113108505
}
108114108506
/* Loop through table entries that match term pOrTerm. */
108115108507
pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
108116108508
WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
108117108509
WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
108118
- assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
108510
+ assert( pSubWInfo || pParse->nErr || db->mallocFailed );
108119108511
if( pSubWInfo ){
108120108512
WhereLoop *pSubLoop;
108121108513
explainOneScan(
108122108514
pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
108123108515
);
@@ -108168,17 +108560,17 @@
108168108560
}
108169108561
pLevel->u.pCovidx = pCov;
108170108562
if( pCov ) pLevel->iIdxCur = iCovCur;
108171108563
if( pAndExpr ){
108172108564
pAndExpr->pLeft = 0;
108173
- sqlite3ExprDelete(pParse->db, pAndExpr);
108565
+ sqlite3ExprDelete(db, pAndExpr);
108174108566
}
108175108567
sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
108176108568
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
108177108569
sqlite3VdbeResolveLabel(v, iLoopBody);
108178108570
108179
- if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
108571
+ if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
108180108572
if( !untestedTerms ) disableTerm(pLevel, pTerm);
108181108573
}else
108182108574
#endif /* SQLITE_OMIT_OR_OPTIMIZATION */
108183108575
108184108576
{
@@ -108195,18 +108587,14 @@
108195108587
}
108196108588
newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
108197108589
108198108590
/* Insert code to test every subexpression that can be completely
108199108591
** computed using the current set of tables.
108200
- **
108201
- ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
108202
- ** the use of indices become tests that are evaluated against each row of
108203
- ** the relevant input tables.
108204108592
*/
108205108593
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
108206108594
Expr *pE;
108207
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
108595
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
108208108596
testcase( pTerm->wtFlags & TERM_CODED );
108209108597
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108210108598
if( (pTerm->prereqAll & newNotReady)!=0 ){
108211108599
testcase( pWInfo->untestedTerms==0
108212108600
&& (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
@@ -108229,13 +108617,12 @@
108229108617
** and we are coding the t1 loop and the t2 loop has not yet coded,
108230108618
** then we cannot use the "t1.a=t2.b" constraint, but we can code
108231108619
** the implied "t1.a=123" constraint.
108232108620
*/
108233108621
for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
108234
- Expr *pE;
108622
+ Expr *pE, *pEAlt;
108235108623
WhereTerm *pAlt;
108236
- Expr sEq;
108237108624
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108238108625
if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
108239108626
if( pTerm->leftCursor!=iCur ) continue;
108240108627
if( pLevel->iLeftJoin ) continue;
108241108628
pE = pTerm->pExpr;
@@ -108245,13 +108632,17 @@
108245108632
if( pAlt==0 ) continue;
108246108633
if( pAlt->wtFlags & (TERM_CODED) ) continue;
108247108634
testcase( pAlt->eOperator & WO_EQ );
108248108635
testcase( pAlt->eOperator & WO_IN );
108249108636
VdbeNoopComment((v, "begin transitive constraint"));
108250
- sEq = *pAlt->pExpr;
108251
- sEq.pLeft = pE->pLeft;
108252
- sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
108637
+ pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
108638
+ if( pEAlt ){
108639
+ *pEAlt = *pAlt->pExpr;
108640
+ pEAlt->pLeft = pE->pLeft;
108641
+ sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
108642
+ sqlite3StackFree(db, pEAlt);
108643
+ }
108253108644
}
108254108645
108255108646
/* For a LEFT OUTER JOIN, generate code that will record the fact that
108256108647
** at least one row of the right table has matched the left table.
108257108648
*/
@@ -108259,11 +108650,11 @@
108259108650
pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
108260108651
sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
108261108652
VdbeComment((v, "record LEFT JOIN hit"));
108262108653
sqlite3ExprCacheClear(pParse);
108263108654
for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
108264
- testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
108655
+ testcase( pTerm->wtFlags & TERM_VIRTUAL );
108265108656
testcase( pTerm->wtFlags & TERM_CODED );
108266108657
if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108267108658
if( (pTerm->prereqAll & newNotReady)!=0 ){
108268108659
assert( pWInfo->untestedTerms );
108269108660
continue;
@@ -108418,16 +108809,16 @@
108418108809
** is better and has fewer dependencies. Or the template will be ignored
108419108810
** and no insert will occur if an existing WhereLoop is faster and has
108420108811
** fewer dependencies than the template. Otherwise a new WhereLoop is
108421108812
** added based on the template.
108422108813
**
108423
-** If pBuilder->pBest is not NULL then we only care about the very
108424
-** best template and that template should be stored in pBuilder->pBest.
108425
-** If pBuilder->pBest is NULL then a list of the best templates are stored
108426
-** in pBuilder->pWInfo->pLoops.
108814
+** If pBuilder->pOrSet is not NULL then we only care about only the
108815
+** prerequisites and rRun and nOut costs of the N best loops. That
108816
+** information is gathered in the pBuilder->pOrSet object. This special
108817
+** processing mode is used only for OR clause processing.
108427108818
**
108428
-** When accumulating multiple loops (when pBuilder->pBest is NULL) we
108819
+** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
108429108820
** still might overwrite similar loops with the new template if the
108430108821
** template is better. Loops may be overwritten if the following
108431108822
** conditions are met:
108432108823
**
108433108824
** (1) They have the same iTab.
@@ -108440,34 +108831,26 @@
108440108831
static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
108441108832
WhereLoop **ppPrev, *p, *pNext = 0;
108442108833
WhereInfo *pWInfo = pBuilder->pWInfo;
108443108834
sqlite3 *db = pWInfo->pParse->db;
108444108835
108445
- /* If pBuilder->pBest is defined, then only keep track of the single
108446
- ** best WhereLoop. pBuilder->pBest->maskSelf==0 indicates that no
108447
- ** prior WhereLoops have been evaluated and that the current pTemplate
108448
- ** is therefore the first and hence the best and should be retained.
108836
+ /* If pBuilder->pOrSet is defined, then only keep track of the costs
108837
+ ** and prereqs.
108449108838
*/
108450
- if( (p = pBuilder->pBest)!=0 ){
108451
- if( p->maskSelf!=0 ){
108452
- WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108453
- WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108454
- if( rCost < rTemplate ){
108455
- testcase( rCost==rTemplate-1 );
108456
- goto whereLoopInsert_noop;
108457
- }
108458
- if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){
108459
- goto whereLoopInsert_noop;
108460
- }
108461
- }
108839
+ if( pBuilder->pOrSet!=0 ){
108840
+#if WHERETRACE_ENABLED
108841
+ u16 n = pBuilder->pOrSet->n;
108842
+ int x =
108843
+#endif
108844
+ whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
108845
+ pTemplate->nOut);
108462108846
#if WHERETRACE_ENABLED
108463108847
if( sqlite3WhereTrace & 0x8 ){
108464
- sqlite3DebugPrintf(p->maskSelf==0 ? "ins-init: " : "ins-best: ");
108848
+ sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
108465108849
whereLoopPrint(pTemplate, pWInfo->pTabList);
108466108850
}
108467108851
#endif
108468
- whereLoopXfer(db, p, pTemplate);
108469108852
return SQLITE_OK;
108470108853
}
108471108854
108472108855
/* Search for an existing WhereLoop to overwrite, or which takes
108473108856
** priority over pTemplate.
@@ -108557,11 +108940,11 @@
108557108940
108558108941
/* Jump here if the insert is a no-op */
108559108942
whereLoopInsert_noop:
108560108943
#if WHERETRACE_ENABLED
108561108944
if( sqlite3WhereTrace & 0x8 ){
108562
- sqlite3DebugPrintf(pBuilder->pBest ? "ins-skip: " : "ins-noop: ");
108945
+ sqlite3DebugPrintf("ins-noop: ");
108563108946
whereLoopPrint(pTemplate, pWInfo->pTabList);
108564108947
}
108565108948
#endif
108566108949
return SQLITE_OK;
108567108950
}
@@ -108708,11 +109091,12 @@
108708109091
rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108709109092
}else if( (pTerm->eOperator & WO_IN)
108710109093
&& !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108711109094
rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108712109095
}
108713
- if( rc==SQLITE_OK ) pNew->nOut = whereCost(nOut);
109096
+ assert( nOut==0 || rc==SQLITE_OK );
109097
+ if( nOut ) pNew->nOut = whereCost(nOut);
108714109098
}
108715109099
#endif
108716109100
if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
108717109101
/* Each row involves a step of the index, then a binary search of
108718109102
** the main table */
@@ -108780,10 +109164,21 @@
108780109164
if( x<BMS-1 ) m |= MASKBIT(x);
108781109165
}
108782109166
return m;
108783109167
}
108784109168
109169
+/* Check to see if a partial index with pPartIndexWhere can be used
109170
+** in the current query. Return true if it can be and false if not.
109171
+*/
109172
+static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
109173
+ int i;
109174
+ WhereTerm *pTerm;
109175
+ for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
109176
+ if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
109177
+ }
109178
+ return 0;
109179
+}
108785109180
108786109181
/*
108787109182
** Add all WhereLoop objects for a single table of the join where the table
108788109183
** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
108789109184
** a b-tree table, not a virtual table.
@@ -108803,15 +109198,17 @@
108803109198
int rc = SQLITE_OK; /* Return code */
108804109199
int iSortIdx = 1; /* Index number */
108805109200
int b; /* A boolean value */
108806109201
WhereCost rSize; /* number of rows in the table */
108807109202
WhereCost rLogSize; /* Logarithm of the number of rows in the table */
109203
+ WhereClause *pWC; /* The parsed WHERE clause */
108808109204
108809109205
pNew = pBuilder->pNew;
108810109206
pWInfo = pBuilder->pWInfo;
108811109207
pTabList = pWInfo->pTabList;
108812109208
pSrc = pTabList->a + pNew->iTab;
109209
+ pWC = pBuilder->pWC;
108813109210
assert( !IsVirtual(pSrc->pTab) );
108814109211
108815109212
if( pSrc->pIndex ){
108816109213
/* An INDEXED BY clause specifies a particular index to use */
108817109214
pProbe = pSrc->pIndex;
@@ -108839,19 +109236,18 @@
108839109236
}
108840109237
rSize = whereCost(pSrc->pTab->nRowEst);
108841109238
rLogSize = estLog(rSize);
108842109239
108843109240
/* Automatic indexes */
108844
- if( !pBuilder->pBest
109241
+ if( !pBuilder->pOrSet
108845109242
&& (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
108846109243
&& pSrc->pIndex==0
108847109244
&& !pSrc->viaCoroutine
108848109245
&& !pSrc->notIndexed
108849109246
&& !pSrc->isCorrelated
108850109247
){
108851109248
/* Generate auto-index WhereLoops */
108852
- WhereClause *pWC = pBuilder->pWC;
108853109249
WhereTerm *pTerm;
108854109250
WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
108855109251
for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
108856109252
if( pTerm->prereqRight & pNew->maskSelf ) continue;
108857109253
if( termCanDriveIndex(pTerm, pSrc, 0) ){
@@ -108877,10 +109273,14 @@
108877109273
}
108878109274
108879109275
/* Loop over all indices
108880109276
*/
108881109277
for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
109278
+ if( pProbe->pPartIdxWhere!=0
109279
+ && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
109280
+ continue; /* Partial index inappropriate for this query */
109281
+ }
108882109282
pNew->u.btree.nEq = 0;
108883109283
pNew->nLTerm = 0;
108884109284
pNew->iSortIdx = 0;
108885109285
pNew->rSetup = 0;
108886109286
pNew->prereq = mExtra;
@@ -109125,11 +109525,11 @@
109125109525
WhereTerm *pTerm, *pWCEnd;
109126109526
int rc = SQLITE_OK;
109127109527
int iCur;
109128109528
WhereClause tempWC;
109129109529
WhereLoopBuilder sSubBuild;
109130
- WhereLoop sBest;
109530
+ WhereOrSet sSum, sCur, sPrev;
109131109531
struct SrcList_item *pItem;
109132109532
109133109533
pWC = pBuilder->pWC;
109134109534
if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
109135109535
pWCEnd = pWC->a + pWC->nTerm;
@@ -109140,20 +109540,18 @@
109140109540
&& (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
109141109541
){
109142109542
WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
109143109543
WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
109144109544
WhereTerm *pOrTerm;
109145
- WhereCost rTotal = 0;
109146
- WhereCost nRow = 0;
109147
- Bitmask prereq = mExtra;
109545
+ int once = 1;
109546
+ int i, j;
109148109547
109149
- whereLoopInit(&sBest);
109150109548
pItem = pWInfo->pTabList->a + pNew->iTab;
109151109549
iCur = pItem->iCursor;
109152109550
sSubBuild = *pBuilder;
109153109551
sSubBuild.pOrderBy = 0;
109154
- sSubBuild.pBest = &sBest;
109552
+ sSubBuild.pOrSet = &sCur;
109155109553
109156109554
for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
109157109555
if( (pOrTerm->eOperator & WO_AND)!=0 ){
109158109556
sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
109159109557
}else if( pOrTerm->leftCursor==iCur ){
@@ -109164,43 +109562,52 @@
109164109562
tempWC.a = pOrTerm;
109165109563
sSubBuild.pWC = &tempWC;
109166109564
}else{
109167109565
continue;
109168109566
}
109169
- sBest.maskSelf = 0;
109170
- sBest.rSetup = 0;
109171
- sBest.rRun = 0;
109567
+ sCur.n = 0;
109172109568
#ifndef SQLITE_OMIT_VIRTUALTABLE
109173109569
if( IsVirtual(pItem->pTab) ){
109174109570
rc = whereLoopAddVirtual(&sSubBuild);
109571
+ for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra;
109175109572
}else
109176109573
#endif
109177109574
{
109178109575
rc = whereLoopAddBtree(&sSubBuild, mExtra);
109179109576
}
109180
- /* sBest.maskSelf is always zero if an error occurs */
109181
- assert( rc==SQLITE_OK || sBest.maskSelf==0 );
109182
- if( sBest.maskSelf==0 ) break;
109183
- assert( sBest.rSetup==0 );
109184
- rTotal = whereCostAdd(rTotal, sBest.rRun);
109185
- nRow = whereCostAdd(nRow, sBest.nOut);
109186
- prereq |= sBest.prereq;
109187
- }
109188
- assert( pNew->nLSlot>=1 );
109189
- if( sBest.maskSelf ){
109190
- pNew->nLTerm = 1;
109191
- pNew->aLTerm[0] = pTerm;
109192
- pNew->wsFlags = WHERE_MULTI_OR;
109193
- pNew->rSetup = 0;
109577
+ assert( rc==SQLITE_OK || sCur.n==0 );
109578
+ if( sCur.n==0 ){
109579
+ sSum.n = 0;
109580
+ break;
109581
+ }else if( once ){
109582
+ whereOrMove(&sSum, &sCur);
109583
+ once = 0;
109584
+ }else{
109585
+ whereOrMove(&sPrev, &sSum);
109586
+ sSum.n = 0;
109587
+ for(i=0; i<sPrev.n; i++){
109588
+ for(j=0; j<sCur.n; j++){
109589
+ whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq,
109590
+ whereCostAdd(sPrev.a[i].rRun, sCur.a[j].rRun),
109591
+ whereCostAdd(sPrev.a[i].nOut, sCur.a[j].nOut));
109592
+ }
109593
+ }
109594
+ }
109595
+ }
109596
+ pNew->nLTerm = 1;
109597
+ pNew->aLTerm[0] = pTerm;
109598
+ pNew->wsFlags = WHERE_MULTI_OR;
109599
+ pNew->rSetup = 0;
109600
+ pNew->iSortIdx = 0;
109601
+ memset(&pNew->u, 0, sizeof(pNew->u));
109602
+ for(i=0; rc==SQLITE_OK && i<sSum.n; i++){
109194109603
/* TUNING: Multiple by 3.5 for the secondary table lookup */
109195
- pNew->rRun = rTotal + 18; assert( 18==whereCost(7)-whereCost(2) );
109196
- pNew->nOut = nRow;
109197
- pNew->prereq = prereq;
109198
- memset(&pNew->u, 0, sizeof(pNew->u));
109604
+ pNew->rRun = sSum.a[i].rRun + 18;
109605
+ pNew->nOut = sSum.a[i].nOut;
109606
+ pNew->prereq = sSum.a[i].prereq;
109199109607
rc = whereLoopInsert(pBuilder, pNew);
109200109608
}
109201
- whereLoopClear(pWInfo->pParse->db, &sBest);
109202109609
}
109203109610
}
109204109611
return rc;
109205109612
}
109206109613
@@ -109810,11 +110217,11 @@
109810110217
pLoop->u.btree.nEq = 1;
109811110218
/* TUNING: Cost of a rowid lookup is 10 */
109812110219
pLoop->rRun = 33; /* 33==whereCost(10) */
109813110220
}else{
109814110221
for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
109815
- if( pIdx->onError==OE_None ) continue;
110222
+ if( pIdx->onError==OE_None || pIdx->pPartIdxWhere!=0 ) continue;
109816110223
for(j=0; j<pIdx->nColumn; j++){
109817110224
pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
109818110225
if( pTerm==0 ) break;
109819110226
whereLoopResize(pWInfo->pParse->db, pLoop, j);
109820110227
pLoop->aLTerm[j] = pTerm;
@@ -110003,11 +110410,12 @@
110003110410
pWInfo->wctrlFlags = wctrlFlags;
110004110411
pWInfo->savedNQueryLoop = pParse->nQueryLoop;
110005110412
pMaskSet = &pWInfo->sMaskSet;
110006110413
sWLB.pWInfo = pWInfo;
110007110414
sWLB.pWC = &pWInfo->sWC;
110008
- sWLB.pNew = (WhereLoop*)&pWInfo->a[nTabList];
110415
+ sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
110416
+ assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
110009110417
whereLoopInit(sWLB.pNew);
110010110418
#ifdef SQLITE_DEBUG
110011110419
sWLB.pNew->cId = '*';
110012110420
#endif
110013110421
@@ -110015,11 +110423,11 @@
110015110423
** subexpression is separated by an AND operator.
110016110424
*/
110017110425
initMaskSet(pMaskSet);
110018110426
whereClauseInit(&pWInfo->sWC, pWInfo);
110019110427
sqlite3ExprCodeConstants(pParse, pWhere);
110020
- whereSplit(&pWInfo->sWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
110428
+ whereSplit(&pWInfo->sWC, pWhere, TK_AND);
110021110429
sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110022110430
110023110431
/* Special case: a WHERE clause that is constant. Evaluate the
110024110432
** expression and either jump over all of the code or fall thru.
110025110433
*/
@@ -110649,11 +111057,11 @@
110649111057
#endif
110650111058
#define sqlite3ParserARG_SDECL Parse *pParse;
110651111059
#define sqlite3ParserARG_PDECL ,Parse *pParse
110652111060
#define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
110653111061
#define sqlite3ParserARG_STORE yypParser->pParse = pParse
110654
-#define YYNSTATE 627
111062
+#define YYNSTATE 628
110655111063
#define YYNRULE 327
110656111064
#define YYFALLBACK 1
110657111065
#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
110658111066
#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
110659111067
#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
@@ -110722,167 +111130,167 @@
110722111130
** shifting non-terminals after a reduce.
110723111131
** yy_default[] Default action for each state.
110724111132
*/
110725111133
#define YY_ACTTAB_COUNT (1564)
110726111134
static const YYACTIONTYPE yy_action[] = {
110727
- /* 0 */ 309, 955, 184, 417, 2, 171, 624, 594, 56, 56,
111135
+ /* 0 */ 310, 956, 184, 418, 2, 171, 625, 595, 56, 56,
110728111136
/* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
110729
- /* 20 */ 52, 52, 51, 233, 620, 619, 298, 620, 619, 234,
110730
- /* 30 */ 587, 581, 56, 56, 56, 56, 19, 54, 54, 54,
110731
- /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 605, 57,
110732
- /* 50 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110733
- /* 60 */ 56, 56, 541, 54, 54, 54, 54, 53, 53, 52,
110734
- /* 70 */ 52, 52, 51, 233, 309, 594, 325, 196, 195, 194,
111137
+ /* 20 */ 52, 52, 51, 233, 621, 620, 299, 621, 620, 234,
111138
+ /* 30 */ 588, 582, 56, 56, 56, 56, 19, 54, 54, 54,
111139
+ /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 606, 57,
111140
+ /* 50 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111141
+ /* 60 */ 56, 56, 542, 54, 54, 54, 54, 53, 53, 52,
111142
+ /* 70 */ 52, 52, 51, 233, 310, 595, 326, 196, 195, 194,
110735111143
/* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110736
- /* 90 */ 51, 233, 617, 616, 165, 617, 616, 380, 377, 376,
110737
- /* 100 */ 407, 532, 576, 576, 587, 581, 303, 422, 375, 59,
111144
+ /* 90 */ 51, 233, 618, 617, 165, 618, 617, 381, 378, 377,
111145
+ /* 100 */ 408, 533, 577, 577, 588, 582, 304, 423, 376, 59,
110738111146
/* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
110739
- /* 120 */ 574, 545, 65, 57, 58, 48, 579, 578, 580, 580,
111147
+ /* 120 */ 575, 546, 65, 57, 58, 48, 580, 579, 581, 581,
110740111148
/* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
110741
- /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 223,
110742
- /* 150 */ 539, 420, 170, 176, 138, 280, 383, 275, 382, 168,
110743
- /* 160 */ 489, 551, 409, 668, 620, 619, 271, 438, 409, 438,
110744
- /* 170 */ 550, 604, 67, 482, 507, 618, 599, 412, 587, 581,
110745
- /* 180 */ 600, 483, 618, 412, 618, 598, 91, 439, 440, 439,
110746
- /* 190 */ 335, 598, 73, 669, 222, 266, 480, 57, 58, 48,
110747
- /* 200 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
110748
- /* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110749
- /* 220 */ 51, 233, 309, 279, 232, 231, 1, 132, 200, 385,
110750
- /* 230 */ 620, 619, 617, 616, 278, 435, 289, 563, 175, 262,
110751
- /* 240 */ 409, 264, 437, 497, 436, 166, 441, 568, 336, 568,
110752
- /* 250 */ 201, 537, 587, 581, 599, 412, 165, 594, 600, 380,
110753
- /* 260 */ 377, 376, 597, 598, 92, 523, 618, 569, 569, 592,
110754
- /* 270 */ 375, 57, 58, 48, 579, 578, 580, 580, 55, 55,
110755
- /* 280 */ 56, 56, 56, 56, 597, 54, 54, 54, 54, 53,
110756
- /* 290 */ 53, 52, 52, 52, 51, 233, 309, 463, 617, 616,
110757
- /* 300 */ 590, 590, 590, 174, 272, 396, 409, 272, 409, 548,
110758
- /* 310 */ 397, 620, 619, 68, 326, 620, 619, 620, 619, 618,
110759
- /* 320 */ 546, 412, 618, 412, 471, 594, 587, 581, 472, 598,
110760
- /* 330 */ 92, 598, 92, 52, 52, 52, 51, 233, 513, 512,
110761
- /* 340 */ 206, 322, 363, 464, 221, 57, 58, 48, 579, 578,
110762
- /* 350 */ 580, 580, 55, 55, 56, 56, 56, 56, 529, 54,
111149
+ /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 223,
111150
+ /* 150 */ 540, 421, 170, 176, 138, 281, 384, 276, 383, 168,
111151
+ /* 160 */ 490, 552, 410, 669, 621, 620, 272, 439, 410, 439,
111152
+ /* 170 */ 551, 605, 67, 483, 508, 619, 600, 413, 588, 582,
111153
+ /* 180 */ 601, 484, 619, 413, 619, 599, 91, 440, 441, 440,
111154
+ /* 190 */ 336, 599, 73, 670, 222, 267, 481, 57, 58, 48,
111155
+ /* 200 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
111156
+ /* 210 */ 671, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111157
+ /* 220 */ 51, 233, 310, 280, 232, 231, 1, 132, 200, 386,
111158
+ /* 230 */ 621, 620, 618, 617, 279, 436, 290, 564, 175, 263,
111159
+ /* 240 */ 410, 265, 438, 498, 437, 166, 442, 569, 337, 569,
111160
+ /* 250 */ 201, 538, 588, 582, 600, 413, 165, 595, 601, 381,
111161
+ /* 260 */ 378, 377, 598, 599, 92, 524, 619, 570, 570, 593,
111162
+ /* 270 */ 376, 57, 58, 48, 580, 579, 581, 581, 55, 55,
111163
+ /* 280 */ 56, 56, 56, 56, 598, 54, 54, 54, 54, 53,
111164
+ /* 290 */ 53, 52, 52, 52, 51, 233, 310, 464, 618, 617,
111165
+ /* 300 */ 591, 591, 591, 174, 273, 397, 410, 273, 410, 549,
111166
+ /* 310 */ 398, 621, 620, 68, 327, 621, 620, 621, 620, 619,
111167
+ /* 320 */ 547, 413, 619, 413, 472, 595, 588, 582, 473, 599,
111168
+ /* 330 */ 92, 599, 92, 52, 52, 52, 51, 233, 514, 513,
111169
+ /* 340 */ 206, 323, 364, 465, 221, 57, 58, 48, 580, 579,
111170
+ /* 350 */ 581, 581, 55, 55, 56, 56, 56, 56, 530, 54,
110763111171
/* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
110764
- /* 370 */ 309, 396, 409, 396, 597, 372, 386, 530, 347, 617,
110765
- /* 380 */ 616, 575, 202, 617, 616, 617, 616, 412, 620, 619,
110766
- /* 390 */ 145, 255, 346, 254, 577, 598, 74, 351, 45, 489,
110767
- /* 400 */ 587, 581, 235, 189, 464, 544, 167, 296, 187, 469,
110768
- /* 410 */ 479, 67, 62, 39, 618, 546, 597, 345, 573, 57,
110769
- /* 420 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
111172
+ /* 370 */ 310, 397, 410, 397, 598, 373, 387, 531, 348, 618,
111173
+ /* 380 */ 617, 576, 202, 618, 617, 618, 617, 413, 621, 620,
111174
+ /* 390 */ 145, 255, 347, 254, 578, 599, 74, 352, 45, 490,
111175
+ /* 400 */ 588, 582, 235, 189, 465, 545, 167, 297, 187, 470,
111176
+ /* 410 */ 480, 67, 62, 39, 619, 547, 598, 346, 574, 57,
111177
+ /* 420 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
110770111178
/* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
110771
- /* 440 */ 52, 52, 51, 233, 309, 562, 558, 407, 528, 576,
110772
- /* 450 */ 576, 344, 255, 346, 254, 182, 617, 616, 503, 504,
110773
- /* 460 */ 314, 409, 557, 235, 166, 271, 409, 352, 564, 181,
110774
- /* 470 */ 407, 546, 576, 576, 587, 581, 412, 537, 556, 561,
110775
- /* 480 */ 517, 412, 618, 249, 598, 16, 7, 36, 467, 598,
110776
- /* 490 */ 92, 516, 618, 57, 58, 48, 579, 578, 580, 580,
110777
- /* 500 */ 55, 55, 56, 56, 56, 56, 541, 54, 54, 54,
110778
- /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 327,
110779
- /* 520 */ 572, 571, 525, 558, 560, 394, 871, 246, 409, 248,
110780
- /* 530 */ 171, 392, 594, 219, 407, 409, 576, 576, 502, 557,
110781
- /* 540 */ 364, 145, 510, 412, 407, 229, 576, 576, 587, 581,
110782
- /* 550 */ 412, 598, 92, 381, 269, 556, 166, 400, 598, 69,
110783
- /* 560 */ 501, 419, 945, 199, 945, 198, 546, 57, 58, 48,
110784
- /* 570 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
110785
- /* 580 */ 568, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110786
- /* 590 */ 51, 233, 309, 317, 419, 944, 508, 944, 308, 597,
110787
- /* 600 */ 594, 565, 490, 212, 173, 247, 423, 615, 614, 613,
110788
- /* 610 */ 323, 197, 143, 405, 572, 571, 489, 66, 50, 47,
110789
- /* 620 */ 146, 594, 587, 581, 232, 231, 559, 427, 67, 555,
110790
- /* 630 */ 15, 618, 186, 543, 303, 421, 35, 206, 432, 423,
110791
- /* 640 */ 552, 57, 58, 48, 579, 578, 580, 580, 55, 55,
111179
+ /* 440 */ 52, 52, 51, 233, 310, 563, 559, 408, 529, 577,
111180
+ /* 450 */ 577, 345, 255, 347, 254, 182, 618, 617, 504, 505,
111181
+ /* 460 */ 315, 410, 558, 235, 166, 272, 410, 353, 565, 181,
111182
+ /* 470 */ 408, 547, 577, 577, 588, 582, 413, 538, 557, 562,
111183
+ /* 480 */ 518, 413, 619, 249, 599, 16, 7, 36, 468, 599,
111184
+ /* 490 */ 92, 517, 619, 57, 58, 48, 580, 579, 581, 581,
111185
+ /* 500 */ 55, 55, 56, 56, 56, 56, 542, 54, 54, 54,
111186
+ /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 328,
111187
+ /* 520 */ 573, 572, 526, 559, 561, 395, 872, 246, 410, 248,
111188
+ /* 530 */ 171, 393, 595, 219, 408, 410, 577, 577, 503, 558,
111189
+ /* 540 */ 365, 145, 511, 413, 408, 229, 577, 577, 588, 582,
111190
+ /* 550 */ 413, 599, 92, 382, 270, 557, 166, 401, 599, 69,
111191
+ /* 560 */ 502, 420, 946, 199, 946, 198, 547, 57, 58, 48,
111192
+ /* 570 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
111193
+ /* 580 */ 569, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111194
+ /* 590 */ 51, 233, 310, 318, 420, 945, 509, 945, 309, 598,
111195
+ /* 600 */ 595, 566, 491, 212, 173, 247, 424, 616, 615, 614,
111196
+ /* 610 */ 324, 197, 143, 406, 573, 572, 490, 66, 50, 47,
111197
+ /* 620 */ 146, 595, 588, 582, 232, 231, 560, 428, 67, 556,
111198
+ /* 630 */ 15, 619, 186, 544, 304, 422, 35, 206, 433, 424,
111199
+ /* 640 */ 553, 57, 58, 48, 580, 579, 581, 581, 55, 55,
110792111200
/* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
110793
- /* 660 */ 53, 52, 52, 52, 51, 233, 309, 569, 569, 260,
110794
- /* 670 */ 268, 597, 12, 373, 568, 166, 409, 313, 409, 420,
110795
- /* 680 */ 409, 473, 473, 365, 618, 50, 47, 146, 597, 594,
110796
- /* 690 */ 468, 412, 166, 412, 351, 412, 587, 581, 32, 598,
110797
- /* 700 */ 94, 598, 97, 598, 95, 627, 625, 329, 142, 50,
110798
- /* 710 */ 47, 146, 333, 349, 358, 57, 58, 48, 579, 578,
110799
- /* 720 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
111201
+ /* 660 */ 53, 52, 52, 52, 51, 233, 310, 570, 570, 261,
111202
+ /* 670 */ 269, 598, 12, 374, 569, 166, 410, 314, 410, 421,
111203
+ /* 680 */ 410, 474, 474, 366, 619, 50, 47, 146, 598, 595,
111204
+ /* 690 */ 256, 413, 166, 413, 352, 413, 588, 582, 32, 599,
111205
+ /* 700 */ 94, 599, 97, 599, 95, 628, 626, 330, 142, 50,
111206
+ /* 710 */ 47, 146, 334, 350, 359, 57, 58, 48, 580, 579,
111207
+ /* 720 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
110800111208
/* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
110801
- /* 740 */ 309, 409, 388, 412, 409, 22, 565, 404, 212, 362,
110802
- /* 750 */ 389, 598, 104, 359, 409, 156, 412, 409, 603, 412,
110803
- /* 760 */ 537, 331, 569, 569, 598, 103, 493, 598, 105, 412,
110804
- /* 770 */ 587, 581, 412, 260, 549, 618, 11, 598, 106, 521,
110805
- /* 780 */ 598, 133, 169, 457, 456, 170, 35, 601, 618, 57,
110806
- /* 790 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110807
- /* 800 */ 56, 56, 409, 54, 54, 54, 54, 53, 53, 52,
110808
- /* 810 */ 52, 52, 51, 233, 309, 409, 259, 412, 409, 50,
110809
- /* 820 */ 47, 146, 357, 318, 355, 598, 134, 527, 352, 337,
110810
- /* 830 */ 412, 409, 356, 412, 357, 409, 357, 618, 598, 98,
110811
- /* 840 */ 129, 598, 102, 618, 587, 581, 412, 21, 235, 618,
110812
- /* 850 */ 412, 618, 211, 143, 598, 101, 30, 167, 598, 93,
110813
- /* 860 */ 350, 535, 203, 57, 58, 48, 579, 578, 580, 580,
110814
- /* 870 */ 55, 55, 56, 56, 56, 56, 409, 54, 54, 54,
110815
- /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 409,
110816
- /* 890 */ 526, 412, 409, 425, 215, 305, 597, 551, 141, 598,
110817
- /* 900 */ 100, 40, 409, 38, 412, 409, 550, 412, 409, 228,
110818
- /* 910 */ 220, 314, 598, 77, 500, 598, 96, 412, 587, 581,
110819
- /* 920 */ 412, 338, 253, 412, 218, 598, 137, 379, 598, 136,
110820
- /* 930 */ 28, 598, 135, 270, 715, 210, 481, 57, 58, 48,
110821
- /* 940 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
110822
- /* 950 */ 409, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110823
- /* 960 */ 51, 233, 309, 409, 272, 412, 409, 315, 147, 597,
110824
- /* 970 */ 272, 626, 2, 598, 76, 209, 409, 127, 412, 618,
110825
- /* 980 */ 126, 412, 409, 621, 235, 618, 598, 90, 374, 598,
110826
- /* 990 */ 89, 412, 587, 581, 27, 260, 350, 412, 618, 598,
110827
- /* 1000 */ 75, 321, 541, 541, 125, 598, 88, 320, 278, 597,
110828
- /* 1010 */ 618, 57, 46, 48, 579, 578, 580, 580, 55, 55,
110829
- /* 1020 */ 56, 56, 56, 56, 409, 54, 54, 54, 54, 53,
110830
- /* 1030 */ 53, 52, 52, 52, 51, 233, 309, 409, 450, 412,
110831
- /* 1040 */ 164, 284, 282, 272, 609, 424, 304, 598, 87, 370,
110832
- /* 1050 */ 409, 477, 412, 409, 608, 409, 607, 602, 618, 618,
110833
- /* 1060 */ 598, 99, 586, 585, 122, 412, 587, 581, 412, 618,
110834
- /* 1070 */ 412, 618, 618, 598, 86, 366, 598, 17, 598, 85,
110835
- /* 1080 */ 319, 185, 519, 518, 583, 582, 58, 48, 579, 578,
110836
- /* 1090 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
111209
+ /* 740 */ 310, 410, 389, 413, 410, 22, 566, 405, 212, 363,
111210
+ /* 750 */ 390, 599, 104, 360, 410, 156, 413, 410, 604, 413,
111211
+ /* 760 */ 538, 332, 570, 570, 599, 103, 494, 599, 105, 413,
111212
+ /* 770 */ 588, 582, 413, 261, 550, 619, 11, 599, 106, 522,
111213
+ /* 780 */ 599, 133, 169, 458, 457, 170, 35, 602, 619, 57,
111214
+ /* 790 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111215
+ /* 800 */ 56, 56, 410, 54, 54, 54, 54, 53, 53, 52,
111216
+ /* 810 */ 52, 52, 51, 233, 310, 410, 260, 413, 410, 50,
111217
+ /* 820 */ 47, 146, 358, 319, 356, 599, 134, 528, 353, 338,
111218
+ /* 830 */ 413, 410, 357, 413, 358, 410, 358, 619, 599, 98,
111219
+ /* 840 */ 129, 599, 102, 619, 588, 582, 413, 21, 235, 619,
111220
+ /* 850 */ 413, 619, 211, 143, 599, 101, 30, 167, 599, 93,
111221
+ /* 860 */ 351, 536, 203, 57, 58, 48, 580, 579, 581, 581,
111222
+ /* 870 */ 55, 55, 56, 56, 56, 56, 410, 54, 54, 54,
111223
+ /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 410,
111224
+ /* 890 */ 527, 413, 410, 426, 215, 306, 598, 552, 141, 599,
111225
+ /* 900 */ 100, 40, 410, 38, 413, 410, 551, 413, 410, 228,
111226
+ /* 910 */ 220, 315, 599, 77, 501, 599, 96, 413, 588, 582,
111227
+ /* 920 */ 413, 339, 253, 413, 218, 599, 137, 380, 599, 136,
111228
+ /* 930 */ 28, 599, 135, 271, 716, 210, 482, 57, 58, 48,
111229
+ /* 940 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
111230
+ /* 950 */ 410, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111231
+ /* 960 */ 51, 233, 310, 410, 273, 413, 410, 316, 147, 598,
111232
+ /* 970 */ 273, 627, 2, 599, 76, 209, 410, 127, 413, 619,
111233
+ /* 980 */ 126, 413, 410, 622, 235, 619, 599, 90, 375, 599,
111234
+ /* 990 */ 89, 413, 588, 582, 27, 261, 351, 413, 619, 599,
111235
+ /* 1000 */ 75, 322, 542, 542, 125, 599, 88, 321, 279, 598,
111236
+ /* 1010 */ 619, 57, 46, 48, 580, 579, 581, 581, 55, 55,
111237
+ /* 1020 */ 56, 56, 56, 56, 410, 54, 54, 54, 54, 53,
111238
+ /* 1030 */ 53, 52, 52, 52, 51, 233, 310, 410, 451, 413,
111239
+ /* 1040 */ 164, 285, 283, 273, 610, 425, 305, 599, 87, 371,
111240
+ /* 1050 */ 410, 478, 413, 410, 609, 410, 608, 603, 619, 619,
111241
+ /* 1060 */ 599, 99, 587, 586, 122, 413, 588, 582, 413, 619,
111242
+ /* 1070 */ 413, 619, 619, 599, 86, 367, 599, 17, 599, 85,
111243
+ /* 1080 */ 320, 185, 520, 519, 584, 583, 58, 48, 580, 579,
111244
+ /* 1090 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
110837111245
/* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
110838
- /* 1110 */ 309, 584, 409, 412, 409, 260, 260, 260, 408, 591,
110839
- /* 1120 */ 474, 598, 84, 170, 409, 466, 518, 412, 121, 412,
110840
- /* 1130 */ 618, 618, 618, 618, 618, 598, 83, 598, 72, 412,
110841
- /* 1140 */ 587, 581, 51, 233, 625, 329, 470, 598, 71, 257,
110842
- /* 1150 */ 159, 120, 14, 462, 157, 158, 117, 260, 448, 447,
110843
- /* 1160 */ 446, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110844
- /* 1170 */ 56, 56, 618, 54, 54, 54, 54, 53, 53, 52,
110845
- /* 1180 */ 52, 52, 51, 233, 44, 403, 260, 3, 409, 459,
110846
- /* 1190 */ 260, 413, 619, 118, 398, 10, 25, 24, 554, 348,
110847
- /* 1200 */ 217, 618, 406, 412, 409, 618, 4, 44, 403, 618,
110848
- /* 1210 */ 3, 598, 82, 618, 413, 619, 455, 542, 115, 412,
110849
- /* 1220 */ 538, 401, 536, 274, 506, 406, 251, 598, 81, 216,
110850
- /* 1230 */ 273, 563, 618, 243, 453, 618, 154, 618, 618, 618,
110851
- /* 1240 */ 449, 416, 623, 110, 401, 618, 409, 236, 64, 123,
110852
- /* 1250 */ 487, 41, 42, 531, 563, 204, 409, 267, 43, 411,
110853
- /* 1260 */ 410, 412, 265, 592, 108, 618, 107, 434, 332, 598,
110854
- /* 1270 */ 80, 412, 618, 263, 41, 42, 443, 618, 409, 598,
110855
- /* 1280 */ 70, 43, 411, 410, 433, 261, 592, 149, 618, 597,
110856
- /* 1290 */ 256, 237, 188, 412, 590, 590, 590, 589, 588, 13,
110857
- /* 1300 */ 618, 598, 18, 328, 235, 618, 44, 403, 360, 3,
110858
- /* 1310 */ 418, 461, 339, 413, 619, 227, 124, 590, 590, 590,
110859
- /* 1320 */ 589, 588, 13, 618, 406, 409, 618, 409, 139, 34,
110860
- /* 1330 */ 403, 387, 3, 148, 622, 312, 413, 619, 311, 330,
110861
- /* 1340 */ 412, 460, 412, 401, 180, 353, 412, 406, 598, 79,
110862
- /* 1350 */ 598, 78, 250, 563, 598, 9, 618, 612, 611, 610,
110863
- /* 1360 */ 618, 8, 452, 442, 242, 415, 401, 618, 239, 235,
110864
- /* 1370 */ 179, 238, 428, 41, 42, 288, 563, 618, 618, 618,
110865
- /* 1380 */ 43, 411, 410, 618, 144, 592, 618, 618, 177, 61,
110866
- /* 1390 */ 618, 596, 391, 620, 619, 287, 41, 42, 414, 618,
110867
- /* 1400 */ 293, 30, 393, 43, 411, 410, 292, 618, 592, 31,
110868
- /* 1410 */ 618, 395, 291, 60, 230, 37, 590, 590, 590, 589,
110869
- /* 1420 */ 588, 13, 214, 553, 183, 290, 172, 301, 300, 299,
110870
- /* 1430 */ 178, 297, 595, 563, 451, 29, 285, 390, 540, 590,
110871
- /* 1440 */ 590, 590, 589, 588, 13, 283, 520, 534, 150, 533,
110872
- /* 1450 */ 241, 281, 384, 192, 191, 324, 515, 514, 276, 240,
110873
- /* 1460 */ 510, 523, 307, 511, 128, 592, 509, 225, 226, 486,
110874
- /* 1470 */ 485, 224, 152, 491, 464, 306, 484, 163, 153, 371,
110875
- /* 1480 */ 478, 151, 162, 258, 369, 161, 367, 208, 475, 476,
110876
- /* 1490 */ 26, 160, 465, 140, 361, 131, 590, 590, 590, 116,
110877
- /* 1500 */ 119, 454, 343, 155, 114, 342, 113, 112, 445, 111,
110878
- /* 1510 */ 130, 109, 431, 316, 426, 430, 23, 429, 20, 606,
110879
- /* 1520 */ 190, 507, 255, 341, 244, 63, 294, 593, 310, 570,
110880
- /* 1530 */ 277, 402, 354, 235, 567, 496, 495, 492, 494, 302,
110881
- /* 1540 */ 458, 378, 286, 245, 566, 5, 252, 547, 193, 444,
110882
- /* 1550 */ 233, 340, 207, 524, 368, 505, 334, 522, 499, 399,
110883
- /* 1560 */ 295, 498, 956, 488,
111246
+ /* 1110 */ 310, 585, 410, 413, 410, 261, 261, 261, 409, 592,
111247
+ /* 1120 */ 475, 599, 84, 170, 410, 467, 519, 413, 121, 413,
111248
+ /* 1130 */ 619, 619, 619, 619, 619, 599, 83, 599, 72, 413,
111249
+ /* 1140 */ 588, 582, 51, 233, 626, 330, 471, 599, 71, 258,
111250
+ /* 1150 */ 159, 120, 14, 463, 157, 158, 117, 261, 449, 448,
111251
+ /* 1160 */ 447, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111252
+ /* 1170 */ 56, 56, 619, 54, 54, 54, 54, 53, 53, 52,
111253
+ /* 1180 */ 52, 52, 51, 233, 44, 404, 261, 3, 410, 460,
111254
+ /* 1190 */ 261, 414, 620, 118, 399, 10, 25, 24, 555, 349,
111255
+ /* 1200 */ 217, 619, 407, 413, 410, 619, 4, 44, 404, 619,
111256
+ /* 1210 */ 3, 599, 82, 619, 414, 620, 456, 543, 115, 413,
111257
+ /* 1220 */ 539, 402, 537, 275, 507, 407, 251, 599, 81, 216,
111258
+ /* 1230 */ 274, 564, 619, 243, 454, 619, 154, 619, 619, 619,
111259
+ /* 1240 */ 450, 417, 624, 110, 402, 619, 410, 236, 64, 123,
111260
+ /* 1250 */ 488, 41, 42, 532, 564, 204, 410, 268, 43, 412,
111261
+ /* 1260 */ 411, 413, 266, 593, 108, 619, 107, 435, 333, 599,
111262
+ /* 1270 */ 80, 413, 619, 264, 41, 42, 444, 619, 410, 599,
111263
+ /* 1280 */ 70, 43, 412, 411, 434, 262, 593, 149, 619, 598,
111264
+ /* 1290 */ 257, 237, 188, 413, 591, 591, 591, 590, 589, 13,
111265
+ /* 1300 */ 619, 599, 18, 329, 235, 619, 44, 404, 361, 3,
111266
+ /* 1310 */ 419, 462, 340, 414, 620, 227, 124, 591, 591, 591,
111267
+ /* 1320 */ 590, 589, 13, 619, 407, 410, 619, 410, 139, 34,
111268
+ /* 1330 */ 404, 388, 3, 148, 623, 313, 414, 620, 312, 331,
111269
+ /* 1340 */ 413, 461, 413, 402, 180, 354, 413, 407, 599, 79,
111270
+ /* 1350 */ 599, 78, 250, 564, 599, 9, 619, 613, 612, 611,
111271
+ /* 1360 */ 619, 8, 453, 443, 242, 416, 402, 619, 239, 235,
111272
+ /* 1370 */ 179, 238, 429, 41, 42, 289, 564, 619, 619, 619,
111273
+ /* 1380 */ 43, 412, 411, 619, 144, 593, 619, 619, 177, 61,
111274
+ /* 1390 */ 619, 597, 392, 621, 620, 288, 41, 42, 415, 619,
111275
+ /* 1400 */ 294, 30, 394, 43, 412, 411, 293, 619, 593, 31,
111276
+ /* 1410 */ 619, 396, 292, 60, 230, 37, 591, 591, 591, 590,
111277
+ /* 1420 */ 589, 13, 214, 554, 183, 291, 172, 302, 301, 300,
111278
+ /* 1430 */ 178, 298, 596, 564, 452, 29, 286, 391, 541, 591,
111279
+ /* 1440 */ 591, 591, 590, 589, 13, 284, 521, 535, 150, 534,
111280
+ /* 1450 */ 241, 282, 385, 192, 191, 325, 516, 515, 277, 240,
111281
+ /* 1460 */ 511, 524, 308, 512, 128, 593, 510, 225, 226, 487,
111282
+ /* 1470 */ 486, 224, 152, 492, 465, 307, 485, 163, 153, 372,
111283
+ /* 1480 */ 479, 151, 162, 259, 370, 161, 368, 208, 476, 477,
111284
+ /* 1490 */ 26, 160, 469, 466, 362, 140, 591, 591, 591, 116,
111285
+ /* 1500 */ 119, 455, 344, 155, 114, 343, 113, 112, 446, 111,
111286
+ /* 1510 */ 131, 109, 432, 317, 130, 431, 23, 20, 430, 427,
111287
+ /* 1520 */ 190, 63, 255, 342, 244, 607, 295, 287, 311, 594,
111288
+ /* 1530 */ 278, 508, 496, 235, 493, 571, 497, 568, 495, 403,
111289
+ /* 1540 */ 459, 379, 355, 245, 193, 303, 567, 296, 341, 5,
111290
+ /* 1550 */ 445, 548, 506, 207, 525, 500, 335, 489, 252, 369,
111291
+ /* 1560 */ 400, 499, 523, 233,
110884111292
};
110885111293
static const YYCODETYPE yy_lookahead[] = {
110886111294
/* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
110887111295
/* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
110888111296
/* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
@@ -111030,21 +111438,21 @@
111030111438
/* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
111031111439
/* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
111032111440
/* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
111033111441
/* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
111034111442
/* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
111035
- /* 1490 */ 135, 156, 189, 68, 157, 218, 129, 130, 131, 22,
111443
+ /* 1490 */ 135, 156, 199, 189, 157, 68, 129, 130, 131, 22,
111036111444
/* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
111037
- /* 1510 */ 218, 189, 40, 157, 38, 157, 240, 157, 240, 153,
111038
- /* 1520 */ 196, 181, 105, 106, 107, 243, 198, 166, 111, 230,
111039
- /* 1530 */ 176, 226, 239, 116, 230, 176, 166, 166, 176, 148,
111040
- /* 1540 */ 199, 177, 209, 209, 166, 196, 239, 208, 185, 199,
111041
- /* 1550 */ 92, 209, 233, 173, 234, 182, 139, 173, 182, 191,
111042
- /* 1560 */ 195, 182, 250, 186,
111445
+ /* 1510 */ 218, 189, 40, 157, 218, 157, 240, 240, 157, 38,
111446
+ /* 1520 */ 196, 243, 105, 106, 107, 153, 198, 209, 111, 166,
111447
+ /* 1530 */ 176, 181, 166, 116, 166, 230, 176, 230, 176, 226,
111448
+ /* 1540 */ 199, 177, 239, 209, 185, 148, 166, 195, 209, 196,
111449
+ /* 1550 */ 199, 208, 182, 233, 173, 182, 139, 186, 239, 234,
111450
+ /* 1560 */ 191, 182, 173, 92,
111043111451
};
111044111452
#define YY_SHIFT_USE_DFLT (-70)
111045
-#define YY_SHIFT_COUNT (416)
111453
+#define YY_SHIFT_COUNT (417)
111046111454
#define YY_SHIFT_MIN (-69)
111047111455
#define YY_SHIFT_MAX (1487)
111048111456
static const short yy_shift_ofst[] = {
111049111457
/* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
111050111458
/* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
@@ -111057,44 +111465,44 @@
111057111465
/* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
111058111466
/* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
111059111467
/* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
111060111468
/* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111061111469
/* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
111062
- /* 130 */ 732, 868, 231, 1051, 1458, -70, -70, -70, 1367, 57,
111470
+ /* 130 */ 732, 868, 231, 1051, 1471, -70, -70, -70, 1367, 57,
111063111471
/* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
111064111472
/* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111065111473
/* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111066111474
/* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111067111475
/* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
111068111476
/* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
111069111477
/* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
111070111478
/* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
111071111479
/* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
111072
- /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1476, 1308, 1308,
111073
- /* 240 */ 1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
111074
- /* 250 */ 1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
111075
- /* 260 */ 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
111076
- /* 270 */ 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
111077
- /* 280 */ 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
111078
- /* 290 */ 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
111079
- /* 300 */ 1338, 1338, 1338, -70, -70, -70, -70, -70, -70, 1013,
111080
- /* 310 */ 467, 612, 84, 179, -28, 870, 410, 761, 760, 667,
111081
- /* 320 */ 650, 531, 220, 361, 331, 125, 127, 97, 1306, 1300,
111082
- /* 330 */ 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
111083
- /* 340 */ 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
111084
- /* 350 */ 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
111085
- /* 360 */ 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960, 1057,
111086
- /* 370 */ 1031, 1030, 899, 938, 982, 936, 972, 958, 910, 955,
111087
- /* 380 */ 875, 885, 908, 857, 859, 867, 804, 590, 834, 747,
111088
- /* 390 */ 818, 513, 611, 741, 673, 637, 611, 606, 603, 579,
111089
- /* 400 */ 501, 541, 468, 386, 445, 395, 376, 281, 185, 120,
111090
- /* 410 */ 92, 75, 45, 114, 25, 11, 5,
111480
+ /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1481, 1308, 1308,
111481
+ /* 240 */ 1472, 1472, 1308, 1477, 1427, 1275, 1487, 1487, 1487, 1487,
111482
+ /* 250 */ 1308, 1461, 1275, 1477, 1427, 1427, 1275, 1308, 1461, 1355,
111483
+ /* 260 */ 1441, 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348,
111484
+ /* 270 */ 1348, 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408,
111485
+ /* 280 */ 1348, 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308,
111486
+ /* 290 */ 1280, 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346,
111487
+ /* 300 */ 1338, 1338, 1338, 1338, -70, -70, -70, -70, -70, -70,
111488
+ /* 310 */ 1013, 467, 612, 84, 179, -28, 870, 410, 761, 760,
111489
+ /* 320 */ 667, 650, 531, 220, 361, 331, 125, 127, 97, 1306,
111490
+ /* 330 */ 1300, 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174,
111491
+ /* 340 */ 1139, 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184,
111492
+ /* 350 */ 1174, 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152,
111493
+ /* 360 */ 1147, 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960,
111494
+ /* 370 */ 1057, 1031, 1030, 899, 938, 982, 936, 972, 958, 910,
111495
+ /* 380 */ 955, 875, 885, 908, 857, 859, 867, 804, 590, 834,
111496
+ /* 390 */ 747, 818, 513, 611, 741, 673, 637, 611, 606, 603,
111497
+ /* 400 */ 579, 501, 541, 468, 386, 445, 395, 376, 281, 185,
111498
+ /* 410 */ 120, 92, 75, 45, 114, 25, 11, 5,
111091111499
};
111092111500
#define YY_REDUCE_USE_DFLT (-169)
111093
-#define YY_REDUCE_COUNT (308)
111501
+#define YY_REDUCE_COUNT (309)
111094111502
#define YY_REDUCE_MIN (-168)
111095
-#define YY_REDUCE_MAX (1391)
111503
+#define YY_REDUCE_MAX (1397)
111096111504
static const short yy_reduce_ofst[] = {
111097111505
/* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
111098111506
/* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
111099111507
/* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
111100111508
/* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
@@ -111111,87 +111519,87 @@
111111111519
/* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
111112111520
/* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
111113111521
/* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
111114111522
/* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
111115111523
/* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
111116
- /* 190 */ -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
111117
- /* 200 */ 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
111118
- /* 210 */ 1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
111119
- /* 220 */ 1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
111120
- /* 230 */ 1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
111121
- /* 240 */ 1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
111122
- /* 250 */ 1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
111123
- /* 260 */ 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
111124
- /* 270 */ 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
111125
- /* 280 */ 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
111126
- /* 290 */ 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
111127
- /* 300 */ 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
111524
+ /* 190 */ -168, 1389, 1381, 1371, 1379, 1373, 1370, 1343, 1352, 1369,
111525
+ /* 200 */ 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1325, 1320, 1352,
111526
+ /* 210 */ 1352, 1343, 1380, 1353, 1397, 1351, 1339, 1334, 1319, 1341,
111527
+ /* 220 */ 1303, 1364, 1359, 1368, 1362, 1366, 1360, 1350, 1354, 1318,
111528
+ /* 230 */ 1313, 1307, 1305, 1363, 1328, 1324, 1372, 1278, 1361, 1358,
111529
+ /* 240 */ 1277, 1276, 1356, 1296, 1322, 1309, 1317, 1315, 1314, 1312,
111530
+ /* 250 */ 1345, 1347, 1302, 1292, 1311, 1304, 1293, 1337, 1335, 1252,
111531
+ /* 260 */ 1248, 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301,
111532
+ /* 270 */ 1295, 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274,
111533
+ /* 280 */ 1281, 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266,
111534
+ /* 290 */ 1189, 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219,
111535
+ /* 300 */ 1216, 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
111128111536
};
111129111537
static const YYACTIONTYPE yy_default[] = {
111130
- /* 0 */ 632, 866, 954, 954, 866, 866, 954, 954, 954, 756,
111131
- /* 10 */ 954, 954, 954, 864, 954, 954, 784, 784, 928, 954,
111132
- /* 20 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111133
- /* 30 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111134
- /* 40 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111135
- /* 50 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111136
- /* 60 */ 954, 954, 954, 954, 954, 954, 954, 671, 760, 790,
111137
- /* 70 */ 954, 954, 954, 954, 954, 954, 954, 954, 927, 929,
111138
- /* 80 */ 798, 797, 907, 771, 795, 788, 792, 867, 860, 861,
111139
- /* 90 */ 859, 863, 868, 954, 791, 827, 844, 826, 838, 843,
111140
- /* 100 */ 850, 842, 839, 829, 828, 830, 831, 954, 954, 954,
111141
- /* 110 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111142
- /* 120 */ 954, 954, 954, 658, 725, 954, 954, 954, 954, 954,
111143
- /* 130 */ 954, 954, 954, 832, 833, 847, 846, 845, 954, 663,
111144
- /* 140 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111145
- /* 150 */ 934, 932, 954, 879, 954, 954, 954, 954, 954, 954,
111146
- /* 160 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111147
- /* 170 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111148
- /* 180 */ 638, 756, 756, 756, 632, 954, 954, 954, 946, 760,
111149
- /* 190 */ 750, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111150
- /* 200 */ 954, 954, 954, 800, 739, 917, 919, 954, 900, 737,
111151
- /* 210 */ 660, 758, 673, 748, 640, 794, 773, 773, 912, 794,
111152
- /* 220 */ 912, 696, 719, 954, 784, 954, 784, 693, 784, 773,
111153
- /* 230 */ 862, 954, 954, 954, 757, 748, 954, 939, 764, 764,
111154
- /* 240 */ 931, 931, 764, 806, 729, 794, 736, 736, 736, 736,
111155
- /* 250 */ 764, 655, 794, 806, 729, 729, 764, 655, 906, 904,
111156
- /* 260 */ 764, 764, 655, 764, 655, 764, 655, 872, 727, 727,
111157
- /* 270 */ 727, 711, 876, 876, 872, 727, 696, 727, 711, 727,
111158
- /* 280 */ 727, 777, 772, 777, 772, 777, 772, 764, 764, 954,
111159
- /* 290 */ 789, 778, 787, 785, 794, 954, 714, 648, 648, 637,
111160
- /* 300 */ 637, 637, 637, 951, 951, 946, 698, 698, 681, 954,
111161
- /* 310 */ 954, 954, 954, 954, 954, 954, 881, 954, 954, 954,
111162
- /* 320 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 633,
111163
- /* 330 */ 941, 954, 954, 938, 954, 954, 954, 954, 799, 954,
111164
- /* 340 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 916,
111165
- /* 350 */ 954, 954, 954, 954, 954, 954, 954, 910, 954, 954,
111166
- /* 360 */ 954, 954, 954, 954, 903, 902, 954, 954, 954, 954,
111167
- /* 370 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111168
- /* 380 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111169
- /* 390 */ 954, 954, 786, 954, 779, 954, 865, 954, 954, 954,
111170
- /* 400 */ 954, 954, 954, 954, 954, 954, 954, 742, 815, 954,
111171
- /* 410 */ 814, 818, 813, 665, 954, 646, 954, 629, 634, 950,
111172
- /* 420 */ 953, 952, 949, 948, 947, 942, 940, 937, 936, 935,
111173
- /* 430 */ 933, 930, 926, 885, 883, 890, 889, 888, 887, 886,
111174
- /* 440 */ 884, 882, 880, 801, 796, 793, 925, 878, 738, 735,
111175
- /* 450 */ 734, 654, 943, 909, 918, 805, 804, 807, 915, 914,
111176
- /* 460 */ 913, 911, 908, 895, 803, 802, 730, 870, 869, 657,
111177
- /* 470 */ 899, 898, 897, 901, 905, 896, 766, 656, 653, 662,
111178
- /* 480 */ 717, 718, 726, 724, 723, 722, 721, 720, 716, 664,
111179
- /* 490 */ 672, 710, 695, 694, 875, 877, 874, 873, 703, 702,
111180
- /* 500 */ 708, 707, 706, 705, 704, 701, 700, 699, 692, 691,
111181
- /* 510 */ 697, 690, 713, 712, 709, 689, 733, 732, 731, 728,
111182
- /* 520 */ 688, 687, 686, 818, 685, 684, 824, 823, 811, 854,
111183
- /* 530 */ 753, 752, 751, 763, 762, 775, 774, 809, 808, 776,
111184
- /* 540 */ 761, 755, 754, 770, 769, 768, 767, 759, 749, 781,
111185
- /* 550 */ 783, 782, 780, 856, 765, 853, 924, 923, 922, 921,
111186
- /* 560 */ 920, 858, 857, 825, 822, 676, 677, 893, 892, 894,
111187
- /* 570 */ 891, 679, 678, 675, 674, 855, 744, 743, 851, 848,
111188
- /* 580 */ 840, 836, 852, 849, 841, 837, 835, 834, 820, 819,
111189
- /* 590 */ 817, 816, 812, 821, 667, 745, 741, 740, 810, 747,
111190
- /* 600 */ 746, 683, 682, 680, 661, 659, 652, 650, 649, 651,
111191
- /* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666,
111192
- /* 620 */ 665, 639, 636, 635, 631, 630, 628,
111538
+ /* 0 */ 633, 867, 955, 955, 867, 867, 955, 955, 955, 757,
111539
+ /* 10 */ 955, 955, 955, 865, 955, 955, 785, 785, 929, 955,
111540
+ /* 20 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111541
+ /* 30 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111542
+ /* 40 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111543
+ /* 50 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111544
+ /* 60 */ 955, 955, 955, 955, 955, 955, 955, 672, 761, 791,
111545
+ /* 70 */ 955, 955, 955, 955, 955, 955, 955, 955, 928, 930,
111546
+ /* 80 */ 799, 798, 908, 772, 796, 789, 793, 868, 861, 862,
111547
+ /* 90 */ 860, 864, 869, 955, 792, 828, 845, 827, 839, 844,
111548
+ /* 100 */ 851, 843, 840, 830, 829, 831, 832, 955, 955, 955,
111549
+ /* 110 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111550
+ /* 120 */ 955, 955, 955, 659, 726, 955, 955, 955, 955, 955,
111551
+ /* 130 */ 955, 955, 955, 833, 834, 848, 847, 846, 955, 664,
111552
+ /* 140 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111553
+ /* 150 */ 935, 933, 955, 880, 955, 955, 955, 955, 955, 955,
111554
+ /* 160 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111555
+ /* 170 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111556
+ /* 180 */ 639, 757, 757, 757, 633, 955, 955, 955, 947, 761,
111557
+ /* 190 */ 751, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111558
+ /* 200 */ 955, 955, 955, 801, 740, 918, 920, 955, 901, 738,
111559
+ /* 210 */ 661, 759, 674, 749, 641, 795, 774, 774, 913, 795,
111560
+ /* 220 */ 913, 697, 720, 955, 785, 955, 785, 694, 785, 774,
111561
+ /* 230 */ 863, 955, 955, 955, 758, 749, 955, 940, 765, 765,
111562
+ /* 240 */ 932, 932, 765, 807, 730, 795, 737, 737, 737, 737,
111563
+ /* 250 */ 765, 656, 795, 807, 730, 730, 795, 765, 656, 907,
111564
+ /* 260 */ 905, 765, 765, 656, 765, 656, 765, 656, 873, 728,
111565
+ /* 270 */ 728, 728, 712, 877, 877, 873, 728, 697, 728, 712,
111566
+ /* 280 */ 728, 728, 778, 773, 778, 773, 778, 773, 765, 765,
111567
+ /* 290 */ 955, 790, 779, 788, 786, 795, 955, 715, 649, 649,
111568
+ /* 300 */ 638, 638, 638, 638, 952, 952, 947, 699, 699, 682,
111569
+ /* 310 */ 955, 955, 955, 955, 955, 955, 955, 882, 955, 955,
111570
+ /* 320 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111571
+ /* 330 */ 634, 942, 955, 955, 939, 955, 955, 955, 955, 800,
111572
+ /* 340 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111573
+ /* 350 */ 917, 955, 955, 955, 955, 955, 955, 955, 911, 955,
111574
+ /* 360 */ 955, 955, 955, 955, 955, 904, 903, 955, 955, 955,
111575
+ /* 370 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111576
+ /* 380 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111577
+ /* 390 */ 955, 955, 955, 787, 955, 780, 955, 866, 955, 955,
111578
+ /* 400 */ 955, 955, 955, 955, 955, 955, 955, 955, 743, 816,
111579
+ /* 410 */ 955, 815, 819, 814, 666, 955, 647, 955, 630, 635,
111580
+ /* 420 */ 951, 954, 953, 950, 949, 948, 943, 941, 938, 937,
111581
+ /* 430 */ 936, 934, 931, 927, 886, 884, 891, 890, 889, 888,
111582
+ /* 440 */ 887, 885, 883, 881, 802, 797, 794, 926, 879, 739,
111583
+ /* 450 */ 736, 735, 655, 944, 910, 919, 806, 805, 808, 916,
111584
+ /* 460 */ 915, 914, 912, 909, 896, 804, 803, 731, 871, 870,
111585
+ /* 470 */ 658, 900, 899, 898, 902, 906, 897, 767, 657, 654,
111586
+ /* 480 */ 663, 718, 719, 727, 725, 724, 723, 722, 721, 717,
111587
+ /* 490 */ 665, 673, 711, 696, 695, 876, 878, 875, 874, 704,
111588
+ /* 500 */ 703, 709, 708, 707, 706, 705, 702, 701, 700, 693,
111589
+ /* 510 */ 692, 698, 691, 714, 713, 710, 690, 734, 733, 732,
111590
+ /* 520 */ 729, 689, 688, 687, 819, 686, 685, 825, 824, 812,
111591
+ /* 530 */ 855, 754, 753, 752, 764, 763, 776, 775, 810, 809,
111592
+ /* 540 */ 777, 762, 756, 755, 771, 770, 769, 768, 760, 750,
111593
+ /* 550 */ 782, 784, 783, 781, 857, 766, 854, 925, 924, 923,
111594
+ /* 560 */ 922, 921, 859, 858, 826, 823, 677, 678, 894, 893,
111595
+ /* 570 */ 895, 892, 680, 679, 676, 675, 856, 745, 744, 852,
111596
+ /* 580 */ 849, 841, 837, 853, 850, 842, 838, 836, 835, 821,
111597
+ /* 590 */ 820, 818, 817, 813, 822, 668, 746, 742, 741, 811,
111598
+ /* 600 */ 748, 747, 684, 683, 681, 662, 660, 653, 651, 650,
111599
+ /* 610 */ 652, 648, 646, 645, 644, 643, 642, 671, 670, 669,
111600
+ /* 620 */ 667, 666, 640, 637, 636, 632, 631, 629,
111193111601
};
111194111602
111195111603
/* The next table maps tokens into fallback tokens. If a construct
111196111604
** like the following:
111197111605
**
@@ -111659,11 +112067,11 @@
111659112067
/* 237 */ "case_operand ::=",
111660112068
/* 238 */ "exprlist ::= nexprlist",
111661112069
/* 239 */ "exprlist ::=",
111662112070
/* 240 */ "nexprlist ::= nexprlist COMMA expr",
111663112071
/* 241 */ "nexprlist ::= expr",
111664
- /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
112072
+ /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
111665112073
/* 243 */ "uniqueflag ::= UNIQUE",
111666112074
/* 244 */ "uniqueflag ::=",
111667112075
/* 245 */ "idxlist_opt ::=",
111668112076
/* 246 */ "idxlist_opt ::= LP idxlist RP",
111669112077
/* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
@@ -112378,11 +112786,11 @@
112378112786
{ 224, 0 },
112379112787
{ 220, 1 },
112380112788
{ 220, 0 },
112381112789
{ 215, 3 },
112382112790
{ 215, 1 },
112383
- { 147, 11 },
112791
+ { 147, 12 },
112384112792
{ 227, 1 },
112385112793
{ 227, 0 },
112386112794
{ 178, 0 },
112387112795
{ 178, 3 },
112388112796
{ 187, 5 },
@@ -112820,10 +113228,11 @@
112820113228
case 114: /* select ::= select multiselect_op oneselect */
112821113229
{
112822113230
if( yymsp[0].minor.yy159 ){
112823113231
yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
112824113232
yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
113233
+ if( yymsp[-1].minor.yy392!=TK_ALL ) pParse->hasCompound = 1;
112825113234
}else{
112826113235
sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
112827113236
}
112828113237
yygotominor.yy159 = yymsp[0].minor.yy159;
112829113238
}
@@ -113382,15 +113791,15 @@
113382113791
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
113383113792
break;
113384113793
case 241: /* nexprlist ::= expr */
113385113794
{yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
113386113795
break;
113387
- case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
113796
+ case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
113388113797
{
113389
- sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
113390
- sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
113391
- &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
113798
+ sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
113799
+ sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy442, yymsp[-10].minor.yy392,
113800
+ &yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
113392113801
}
113393113802
break;
113394113803
case 243: /* uniqueflag ::= UNIQUE */
113395113804
case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
113396113805
{yygotominor.yy392 = OE_Abort;}
@@ -114312,11 +114721,10 @@
114312114721
*tokenType = TK_SPACE;
114313114722
return i;
114314114723
}
114315114724
case '-': {
114316114725
if( z[1]=='-' ){
114317
- /* IMP: R-50417-27976 -- syntax diagram for comments */
114318114726
for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
114319114727
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
114320114728
return i;
114321114729
}
114322114730
*tokenType = TK_MINUS;
@@ -114345,11 +114753,10 @@
114345114753
case '/': {
114346114754
if( z[1]!='*' || z[2]==0 ){
114347114755
*tokenType = TK_SLASH;
114348114756
return 1;
114349114757
}
114350
- /* IMP: R-50417-27976 -- syntax diagram for comments */
114351114758
for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
114352114759
if( c ) i++;
114353114760
*tokenType = TK_SPACE; /* IMP: R-22934-25134 */
114354114761
return i;
114355114762
}
@@ -116127,10 +116534,12 @@
116127116534
}
116128116535
sqlite3BtreeLeaveAll(db);
116129116536
116130116537
/* Any deferred constraint violations have now been resolved. */
116131116538
db->nDeferredCons = 0;
116539
+ db->nDeferredImmCons = 0;
116540
+ db->flags &= ~SQLITE_DeferFKs;
116132116541
116133116542
/* If one has been configured, invoke the rollback-hook callback */
116134116543
if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
116135116544
db->xRollbackCallback(db->pRollbackArg);
116136116545
}
@@ -116188,10 +116597,11 @@
116188116597
case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break;
116189116598
case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break;
116190116599
case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
116191116600
case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
116192116601
case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
116602
+ case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break;
116193116603
case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
116194116604
case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
116195116605
case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
116196116606
case SQLITE_FULL: zName = "SQLITE_FULL"; break;
116197116607
case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
@@ -116388,11 +116798,11 @@
116388116798
void *pArg
116389116799
){
116390116800
sqlite3_mutex_enter(db->mutex);
116391116801
if( nOps>0 ){
116392116802
db->xProgress = xProgress;
116393
- db->nProgressOps = nOps;
116803
+ db->nProgressOps = (unsigned)nOps;
116394116804
db->pProgressArg = pArg;
116395116805
}else{
116396116806
db->xProgress = 0;
116397116807
db->nProgressOps = 0;
116398116808
db->pProgressArg = 0;
@@ -117543,11 +117953,11 @@
117543117953
db->autoCommit = 1;
117544117954
db->nextAutovac = -1;
117545117955
db->szMmap = sqlite3GlobalConfig.szMmap;
117546117956
db->nextPagesize = 0;
117547117957
db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
117548
-#if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
117958
+#if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
117549117959
| SQLITE_AutoIndex
117550117960
#endif
117551117961
#if SQLITE_DEFAULT_FILE_FORMAT<4
117552117962
| SQLITE_LegacyFileFmt
117553117963
#endif
@@ -119087,11 +119497,11 @@
119087119497
119088119498
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
119089119499
119090119500
/* If not building as part of the core, include sqlite3ext.h. */
119091119501
#ifndef SQLITE_CORE
119092
-SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
119502
+SQLITE_EXTENSION_INIT3
119093119503
#endif
119094119504
119095119505
/************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
119096119506
/************** Begin file fts3_tokenizer.h **********************************/
119097119507
/*
@@ -124995,11 +125405,14 @@
124995125405
124996125406
#if !SQLITE_CORE
124997125407
/*
124998125408
** Initialize API pointer table, if required.
124999125409
*/
125000
-SQLITE_API int sqlite3_extension_init(
125410
+#ifdef _WIN32
125411
+__declspec(dllexport)
125412
+#endif
125413
+SQLITE_API int sqlite3_fts3_init(
125001125414
sqlite3 *db,
125002125415
char **pzErrMsg,
125003125416
const sqlite3_api_routines *pApi
125004125417
){
125005125418
SQLITE_EXTENSION_INIT2(pApi)
@@ -128013,11 +128426,11 @@
128013128426
}
128014128427
128015128428
128016128429
#ifdef SQLITE_TEST
128017128430
128018
-/* #include <tcl.h> */
128431
+#include <tcl.h>
128019128432
/* #include <string.h> */
128020128433
128021128434
/*
128022128435
** Implementation of a special SQL scalar function for testing tokenizers
128023128436
** designed to be used in concert with the Tcl testing framework. This
@@ -140042,11 +140455,14 @@
140042140455
(void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
140043140456
);
140044140457
}
140045140458
140046140459
#if !SQLITE_CORE
140047
-SQLITE_API int sqlite3_extension_init(
140460
+#ifdef _WIN32
140461
+__declspec(dllexport)
140462
+#endif
140463
+SQLITE_API int sqlite3_rtree_init(
140048140464
sqlite3 *db,
140049140465
char **pzErrMsg,
140050140466
const sqlite3_api_routines *pApi
140051140467
){
140052140468
SQLITE_EXTENSION_INIT2(pApi)
@@ -140544,11 +140960,14 @@
140544140960
140545140961
return rc;
140546140962
}
140547140963
140548140964
#if !SQLITE_CORE
140549
-SQLITE_API int sqlite3_extension_init(
140965
+#ifdef _WIN32
140966
+__declspec(dllexport)
140967
+#endif
140968
+SQLITE_API int sqlite3_icu_init(
140550140969
sqlite3 *db,
140551140970
char **pzErrMsg,
140552140971
const sqlite3_api_routines *pApi
140553140972
){
140554140973
SQLITE_EXTENSION_INIT2(pApi)
140555140974
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -399,13 +399,10 @@
399 ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
400 ** assert() macro is enabled, each call into the Win32 native heap subsystem
401 ** will cause HeapValidate to be called. If heap validation should fail, an
402 ** assertion will be triggered.
403 **
404 ** (Historical note: There used to be several other options, but we've
405 ** pared it down to just these three.)
406 **
407 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
408 ** the default.
409 */
410 #if defined(SQLITE_SYSTEM_MALLOC) \
411 + defined(SQLITE_WIN32_MALLOC) \
@@ -439,24 +436,17 @@
439 */
440 #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
441 # define _XOPEN_SOURCE 600
442 #endif
443
444 /*
445 ** The TCL headers are only needed when compiling the TCL bindings.
446 */
447 #if defined(SQLITE_TCL) || defined(TCLSH)
448 # include <tcl.h>
449 #endif
450
451 /*
452 ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
453 ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
454 ** make it true by defining or undefining NDEBUG.
455 **
456 ** Setting NDEBUG makes the code smaller and run faster by disabling the
457 ** number assert() statements in the code. So we want the default action
458 ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
459 ** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
460 ** feature.
461 */
462 #if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
@@ -522,11 +512,11 @@
522 ** hint of unplanned behavior.
523 **
524 ** In other words, ALWAYS and NEVER are added for defensive code.
525 **
526 ** When doing coverage testing ALWAYS and NEVER are hard-coded to
527 ** be true and false so that the unreachable code then specify will
528 ** not be counted as untested code.
529 */
530 #if defined(SQLITE_COVERAGE_TEST)
531 # define ALWAYS(X) (1)
532 # define NEVER(X) (0)
@@ -546,20 +536,16 @@
546 #define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
547
548 /*
549 ** The macro unlikely() is a hint that surrounds a boolean
550 ** expression that is usually false. Macro likely() surrounds
551 ** a boolean expression that is usually true. GCC is able to
552 ** use these hints to generate better code, sometimes.
 
553 */
554 #if defined(__GNUC__) && 0
555 # define likely(X) __builtin_expect((X),1)
556 # define unlikely(X) __builtin_expect((X),0)
557 #else
558 # define likely(X) !!(X)
559 # define unlikely(X) !!(X)
560 #endif
561
562 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
563 /************** Begin file sqlite3.h *****************************************/
564 /*
565 ** 2001 September 15
@@ -670,11 +656,11 @@
670 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
671 ** [sqlite_version()] and [sqlite_source_id()].
672 */
673 #define SQLITE_VERSION "3.8.0"
674 #define SQLITE_VERSION_NUMBER 3008000
675 #define SQLITE_SOURCE_ID "2013-07-09 03:04:32 52a49cbc1621094b2fe2b021209b768d29e0426b"
676
677 /*
678 ** CAPI3REF: Run-Time Library Version Numbers
679 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
680 **
@@ -1039,10 +1025,11 @@
1039 #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
1040 #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
1041 #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
1042 #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
1043 #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
 
1044 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
1045 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
1046 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
1047 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
1048 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -3120,13 +3107,14 @@
3120 ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
3121 ** database connection D. An example use for this
3122 ** interface is to keep a GUI updated during a large query.
3123 **
3124 ** ^The parameter P is passed through as the only parameter to the
3125 ** callback function X. ^The parameter N is the number of
3126 ** [virtual machine instructions] that are evaluated between successive
3127 ** invocations of the callback X.
 
3128 **
3129 ** ^Only a single progress handler may be defined at one time per
3130 ** [database connection]; setting a new progress handler cancels the
3131 ** old one. ^Setting parameter X to NULL disables the progress handler.
3132 ** ^The progress handler is also disabled by setting N to a value less
@@ -4742,45 +4730,53 @@
4742 SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
4743
4744 /*
4745 ** CAPI3REF: Function Auxiliary Data
4746 **
4747 ** The following two functions may be used by scalar SQL functions to
4748 ** associate metadata with argument values. If the same value is passed to
4749 ** multiple invocations of the same SQL function during query execution, under
4750 ** some circumstances the associated metadata may be preserved. This may
4751 ** be used, for example, to add a regular-expression matching scalar
4752 ** function. The compiled version of the regular expression is stored as
4753 ** metadata associated with the SQL value passed as the regular expression
4754 ** pattern. The compiled regular expression can be reused on multiple
4755 ** invocations of the same function so that the original pattern string
4756 ** does not need to be recompiled on each invocation.
4757 **
4758 ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
4759 ** associated by the sqlite3_set_auxdata() function with the Nth argument
4760 ** value to the application-defined function. ^If no metadata has been ever
4761 ** been set for the Nth argument of the function, or if the corresponding
4762 ** function parameter has changed since the meta-data was set,
4763 ** then sqlite3_get_auxdata() returns a NULL pointer.
4764 **
4765 ** ^The sqlite3_set_auxdata() interface saves the metadata
4766 ** pointed to by its 3rd parameter as the metadata for the N-th
4767 ** argument of the application-defined function. Subsequent
4768 ** calls to sqlite3_get_auxdata() might return this data, if it has
4769 ** not been destroyed.
4770 ** ^If it is not NULL, SQLite will invoke the destructor
4771 ** function given by the 4th parameter to sqlite3_set_auxdata() on
4772 ** the metadata when the corresponding function parameter changes
4773 ** or when the SQL statement completes, whichever comes first.
4774 **
4775 ** SQLite is free to call the destructor and drop metadata on any
4776 ** parameter of any function at any time. ^The only guarantee is that
4777 ** the destructor will be called before the metadata is dropped.
 
 
 
 
 
 
 
 
4778 **
4779 ** ^(In practice, metadata is preserved between function calls for
4780 ** expressions that are constant at compile time. This includes literal
4781 ** values and [parameters].)^
4782 **
4783 ** These routines must be called from the same thread in which
4784 ** the SQL function is running.
4785 */
4786 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
@@ -5689,14 +5685,27 @@
5689 **
5690 ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
5691 ** on the list of automatic extensions is a harmless no-op. ^No entry point
5692 ** will be called more than once for each database connection that is opened.
5693 **
5694 ** See also: [sqlite3_reset_auto_extension()].
 
5695 */
5696 SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
5697
 
 
 
 
 
 
 
 
 
 
 
 
5698 /*
5699 ** CAPI3REF: Reset Automatic Extension Loading
5700 **
5701 ** ^This interface disables all automatic extensions previously
5702 ** registered using [sqlite3_auto_extension()].
@@ -6805,10 +6814,16 @@
6805 ** transaction rollback or database recovery operations are not included.
6806 ** If an IO or other error occurs while writing a page to disk, the effect
6807 ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
6808 ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
6809 ** </dd>
 
 
 
 
 
 
6810 ** </dl>
6811 */
6812 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
6813 #define SQLITE_DBSTATUS_CACHE_USED 1
6814 #define SQLITE_DBSTATUS_SCHEMA_USED 2
@@ -6817,11 +6832,12 @@
6817 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
6818 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6819 #define SQLITE_DBSTATUS_CACHE_HIT 7
6820 #define SQLITE_DBSTATUS_CACHE_MISS 8
6821 #define SQLITE_DBSTATUS_CACHE_WRITE 9
6822 #define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
 
6823
6824
6825 /*
6826 ** CAPI3REF: Prepared Statement Status
6827 **
@@ -8795,11 +8811,10 @@
8795
8796 /*
8797 ** The names of the following types declared in vdbeInt.h are required
8798 ** for the VdbeOp definition.
8799 */
8800 typedef struct VdbeFunc VdbeFunc;
8801 typedef struct Mem Mem;
8802 typedef struct SubProgram SubProgram;
8803
8804 /*
8805 ** A single instruction of the virtual machine has an opcode
@@ -8819,11 +8834,10 @@
8819 void *p; /* Generic pointer */
8820 char *z; /* Pointer to data for string (char array) types */
8821 i64 *pI64; /* Used when p4type is P4_INT64 */
8822 double *pReal; /* Used when p4type is P4_REAL */
8823 FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
8824 VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */
8825 CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
8826 Mem *pMem; /* Used when p4type is P4_MEM */
8827 VTable *pVtab; /* Used when p4type is P4_VTAB */
8828 KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
8829 int *ai; /* Used when p4type is P4_INTARRAY */
@@ -8873,11 +8887,10 @@
8873 #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
8874 #define P4_STATIC (-2) /* Pointer to a static string */
8875 #define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
8876 #define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
8877 #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
8878 #define P4_VDBEFUNC (-7) /* P4 is a pointer to a VdbeFunc structure */
8879 #define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
8880 #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
8881 #define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
8882 #define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
8883 #define P4_REAL (-12) /* P4 is a 64-bit floating point value */
@@ -8930,155 +8943,155 @@
8930 */
8931 /************** Include opcodes.h in the middle of vdbe.h ********************/
8932 /************** Begin file opcodes.h *****************************************/
8933 /* Automatically generated. Do not edit */
8934 /* See the mkopcodeh.awk script for details */
8935 #define OP_Goto 1
8936 #define OP_Gosub 2
8937 #define OP_Return 3
8938 #define OP_Yield 4
8939 #define OP_HaltIfNull 5
8940 #define OP_Halt 6
8941 #define OP_Integer 7
8942 #define OP_Int64 8
8943 #define OP_Real 130 /* same as TK_FLOAT */
8944 #define OP_String8 94 /* same as TK_STRING */
8945 #define OP_String 9
8946 #define OP_Null 10
8947 #define OP_Blob 11
8948 #define OP_Variable 12
8949 #define OP_Move 13
8950 #define OP_Copy 14
8951 #define OP_SCopy 15
8952 #define OP_ResultRow 16
8953 #define OP_Concat 91 /* same as TK_CONCAT */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8954 #define OP_Add 86 /* same as TK_PLUS */
8955 #define OP_Subtract 87 /* same as TK_MINUS */
8956 #define OP_Multiply 88 /* same as TK_STAR */
8957 #define OP_Divide 89 /* same as TK_SLASH */
8958 #define OP_Remainder 90 /* same as TK_REM */
8959 #define OP_CollSeq 17
8960 #define OP_Function 18
8961 #define OP_BitAnd 82 /* same as TK_BITAND */
8962 #define OP_BitOr 83 /* same as TK_BITOR */
8963 #define OP_ShiftLeft 84 /* same as TK_LSHIFT */
8964 #define OP_ShiftRight 85 /* same as TK_RSHIFT */
8965 #define OP_AddImm 20
8966 #define OP_MustBeInt 21
8967 #define OP_RealAffinity 22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8968 #define OP_ToText 141 /* same as TK_TO_TEXT */
8969 #define OP_ToBlob 142 /* same as TK_TO_BLOB */
8970 #define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
8971 #define OP_ToInt 144 /* same as TK_TO_INT */
8972 #define OP_ToReal 145 /* same as TK_TO_REAL */
8973 #define OP_Eq 76 /* same as TK_EQ */
8974 #define OP_Ne 75 /* same as TK_NE */
8975 #define OP_Lt 79 /* same as TK_LT */
8976 #define OP_Le 78 /* same as TK_LE */
8977 #define OP_Gt 77 /* same as TK_GT */
8978 #define OP_Ge 80 /* same as TK_GE */
8979 #define OP_Permutation 23
8980 #define OP_Compare 24
8981 #define OP_Jump 25
8982 #define OP_And 69 /* same as TK_AND */
8983 #define OP_Or 68 /* same as TK_OR */
8984 #define OP_Not 19 /* same as TK_NOT */
8985 #define OP_BitNot 93 /* same as TK_BITNOT */
8986 #define OP_Once 26
8987 #define OP_If 27
8988 #define OP_IfNot 28
8989 #define OP_IsNull 73 /* same as TK_ISNULL */
8990 #define OP_NotNull 74 /* same as TK_NOTNULL */
8991 #define OP_Column 29
8992 #define OP_Affinity 30
8993 #define OP_MakeRecord 31
8994 #define OP_Count 32
8995 #define OP_Savepoint 33
8996 #define OP_AutoCommit 34
8997 #define OP_Transaction 35
8998 #define OP_ReadCookie 36
8999 #define OP_SetCookie 37
9000 #define OP_VerifyCookie 38
9001 #define OP_OpenRead 39
9002 #define OP_OpenWrite 40
9003 #define OP_OpenAutoindex 41
9004 #define OP_OpenEphemeral 42
9005 #define OP_SorterOpen 43
9006 #define OP_OpenPseudo 44
9007 #define OP_Close 45
9008 #define OP_SeekLt 46
9009 #define OP_SeekLe 47
9010 #define OP_SeekGe 48
9011 #define OP_SeekGt 49
9012 #define OP_Seek 50
9013 #define OP_NotFound 51
9014 #define OP_Found 52
9015 #define OP_IsUnique 53
9016 #define OP_NotExists 54
9017 #define OP_Sequence 55
9018 #define OP_NewRowid 56
9019 #define OP_Insert 57
9020 #define OP_InsertInt 58
9021 #define OP_Delete 59
9022 #define OP_ResetCount 60
9023 #define OP_SorterCompare 61
9024 #define OP_SorterData 62
9025 #define OP_RowKey 63
9026 #define OP_RowData 64
9027 #define OP_Rowid 65
9028 #define OP_NullRow 66
9029 #define OP_Last 67
9030 #define OP_SorterSort 70
9031 #define OP_Sort 71
9032 #define OP_Rewind 72
9033 #define OP_SorterNext 81
9034 #define OP_Prev 92
9035 #define OP_Next 95
9036 #define OP_SorterInsert 96
9037 #define OP_IdxInsert 97
9038 #define OP_IdxDelete 98
9039 #define OP_IdxRowid 99
9040 #define OP_IdxLT 100
9041 #define OP_IdxGE 101
9042 #define OP_Destroy 102
9043 #define OP_Clear 103
9044 #define OP_CreateIndex 104
9045 #define OP_CreateTable 105
9046 #define OP_ParseSchema 106
9047 #define OP_LoadAnalysis 107
9048 #define OP_DropTable 108
9049 #define OP_DropIndex 109
9050 #define OP_DropTrigger 110
9051 #define OP_IntegrityCk 111
9052 #define OP_RowSetAdd 112
9053 #define OP_RowSetRead 113
9054 #define OP_RowSetTest 114
9055 #define OP_Program 115
9056 #define OP_Param 116
9057 #define OP_FkCounter 117
9058 #define OP_FkIfZero 118
9059 #define OP_MemMax 119
9060 #define OP_IfPos 120
9061 #define OP_IfNeg 121
9062 #define OP_IfZero 122
9063 #define OP_AggStep 123
9064 #define OP_AggFinal 124
9065 #define OP_Checkpoint 125
9066 #define OP_JournalMode 126
9067 #define OP_Vacuum 127
9068 #define OP_IncrVacuum 128
9069 #define OP_Expire 129
9070 #define OP_TableLock 131
9071 #define OP_VBegin 132
9072 #define OP_VCreate 133
9073 #define OP_VDestroy 134
9074 #define OP_VOpen 135
9075 #define OP_VFilter 136
9076 #define OP_VColumn 137
9077 #define OP_VNext 138
9078 #define OP_VRename 139
9079 #define OP_VUpdate 140
9080 #define OP_Pagecount 146
9081 #define OP_MaxPgcnt 147
9082 #define OP_Trace 148
9083 #define OP_Noop 149
9084 #define OP_Explain 150
@@ -9094,28 +9107,28 @@
9094 #define OPFLG_IN2 0x0008 /* in2: P2 is an input */
9095 #define OPFLG_IN3 0x0010 /* in3: P3 is an input */
9096 #define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
9097 #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
9098 #define OPFLG_INITIALIZER {\
9099 /* 0 */ 0x00, 0x01, 0x01, 0x04, 0x04, 0x10, 0x00, 0x02,\
9100 /* 8 */ 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x24,\
9101 /* 16 */ 0x00, 0x00, 0x00, 0x24, 0x04, 0x05, 0x04, 0x00,\
9102 /* 24 */ 0x00, 0x01, 0x01, 0x05, 0x05, 0x00, 0x00, 0x00,\
9103 /* 32 */ 0x02, 0x00, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00,\
9104 /* 40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11,\
9105 /* 48 */ 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11, 0x02,\
9106 /* 56 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
9107 /* 64 */ 0x00, 0x02, 0x00, 0x01, 0x4c, 0x4c, 0x01, 0x01,\
9108 /* 72 */ 0x01, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
9109 /* 80 */ 0x15, 0x01, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
9110 /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x01, 0x24, 0x02, 0x01,\
9111 /* 96 */ 0x08, 0x08, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
9112 /* 104 */ 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
9113 /* 112 */ 0x0c, 0x45, 0x15, 0x01, 0x02, 0x00, 0x01, 0x08,\
9114 /* 120 */ 0x05, 0x05, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00,\
9115 /* 128 */ 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,\
9116 /* 136 */ 0x01, 0x00, 0x01, 0x00, 0x00, 0x04, 0x04, 0x04,\
9117 /* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
9118
9119 /************** End of opcodes.h *********************************************/
9120 /************** Continuing where we left off in vdbe.h ***********************/
9121
@@ -9161,11 +9174,11 @@
9161 SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
9162 SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
9163 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
9164 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
9165 SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
9166 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe*, int, u8);
9167 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
9168 #ifndef SQLITE_OMIT_TRACE
9169 SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
9170 #endif
9171
@@ -10117,11 +10130,11 @@
10117 void *pAuthArg; /* 1st argument to the access auth function */
10118 #endif
10119 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
10120 int (*xProgress)(void *); /* The progress callback */
10121 void *pProgressArg; /* Argument to the progress callback */
10122 int nProgressOps; /* Number of opcodes for progress callback */
10123 #endif
10124 #ifndef SQLITE_OMIT_VIRTUALTABLE
10125 int nVTrans; /* Allocated size of aVTrans */
10126 Hash aModule; /* populated by sqlite3_create_module() */
10127 VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
@@ -10135,10 +10148,11 @@
10135 Savepoint *pSavepoint; /* List of active savepoints */
10136 int busyTimeout; /* Busy handler timeout, in msec */
10137 int nSavepoint; /* Number of non-transaction savepoints */
10138 int nStatement; /* Number of nested statement-transactions */
10139 i64 nDeferredCons; /* Net deferred constraints this transaction. */
 
10140 int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
10141
10142 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
10143 /* The following variables are all protected by the STATIC_MASTER
10144 ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
@@ -10190,10 +10204,13 @@
10190 #define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
10191 #define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
10192 #define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
10193 #define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
10194 #define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
 
 
 
10195
10196 /*
10197 ** Bits of the sqlite3.dbOptFlags field that are used by the
10198 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
10199 ** selectively disable various optimizations.
@@ -10336,10 +10353,11 @@
10336 ** OP_Savepoint instruction.
10337 */
10338 struct Savepoint {
10339 char *zName; /* Savepoint name (nul-terminated) */
10340 i64 nDeferredCons; /* Number of deferred fk violations */
 
10341 Savepoint *pNext; /* Parent savepoint (if any) */
10342 };
10343
10344 /*
10345 ** The following are used as the second parameter to sqlite3Savepoint(),
@@ -10654,16 +10672,20 @@
10654
10655 /*
10656 ** An instance of the following structure is passed as the first
10657 ** argument to sqlite3VdbeKeyCompare and is used to control the
10658 ** comparison of the two index keys.
 
 
 
 
10659 */
10660 struct KeyInfo {
10661 sqlite3 *db; /* The database connection */
10662 u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
10663 u16 nField; /* Number of entries in aColl[] */
10664 u8 *aSortOrder; /* Sort order for each column. May be NULL */
10665 CollSeq *aColl[1]; /* Collating sequence for each term of the key */
10666 };
10667
10668 /*
10669 ** An instance of the following structure holds information about a
@@ -10728,10 +10750,11 @@
10728 char *zColAff; /* String defining the affinity of each column */
10729 Index *pNext; /* The next index associated with the same table */
10730 Schema *pSchema; /* Schema containing this index */
10731 u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
10732 char **azColl; /* Array of collation sequence names for index */
 
10733 int tnum; /* DB Page containing root of this index */
10734 u16 nColumn; /* Number of columns in table used by this index */
10735 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10736 unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
10737 unsigned bUnordered:1; /* Use this index for == or IN queries only */
@@ -11208,10 +11231,11 @@
11208 #define NC_HasAgg 0x02 /* One or more aggregate functions seen */
11209 #define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
11210 #define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
11211 #define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only
11212 ** if no other resolution is available */
 
11213
11214 /*
11215 ** An instance of the following structure contains all information
11216 ** needed to generate code for a single SELECT statement.
11217 **
@@ -11262,10 +11286,11 @@
11262 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
11263 #define SF_UseSorter 0x0040 /* Sort using a sorter */
11264 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
11265 #define SF_Materialize 0x0100 /* Force materialization of views */
11266 #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
 
11267
11268
11269 /*
11270 ** The results of a select can be distributed in several ways. The
11271 ** "SRT" prefix means "SELECT Result Type".
@@ -11383,19 +11408,21 @@
11383 u8 nTempInUse; /* Number of aTempReg[] currently checked out */
11384 u8 nColCache; /* Number of entries in aColCache[] */
11385 u8 iColCache; /* Next entry in aColCache[] to replace */
11386 u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
11387 u8 mayAbort; /* True if statement may throw an ABORT exception */
 
11388 int aTempReg[8]; /* Holding area for temporary registers */
11389 int nRangeReg; /* Size of the temporary register block */
11390 int iRangeReg; /* First register in temporary register block */
11391 int nErr; /* Number of errors seen */
11392 int nTab; /* Number of previously allocated VDBE cursors */
11393 int nMem; /* Number of memory cells used so far */
11394 int nSet; /* Number of sets used so far */
11395 int nOnce; /* Number of OP_Once instructions so far */
11396 int ckBase; /* Base register of data during check constraints */
 
11397 int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
11398 int iCacheCnt; /* Counter used to generate aColCache[].lru values */
11399 struct yColCache {
11400 int iTable; /* Table cursor number */
11401 int iColumn; /* Table column number */
@@ -11973,11 +12000,11 @@
11973 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
11974 SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
11975 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
11976 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
11977 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
11978 Token*, int, int);
11979 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
11980 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
11981 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
11982 Expr*,ExprList*,u16,Expr*,Expr*);
11983 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
@@ -12021,12 +12048,13 @@
12021 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
12022 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
12023 SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
12024 SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
12025 SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
12026 SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*);
12027 SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*);
 
12028 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
12029 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
12030 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
12031 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
12032 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
@@ -12049,11 +12077,11 @@
12049 SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
12050 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
12051 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
12052 SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
12053 SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
12054 SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int);
12055 SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
12056 int*,int,int,int,int,int*);
12057 SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
12058 SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
12059 SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
@@ -12252,10 +12280,11 @@
12252 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
12253 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
12254 SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
12255 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
12256 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
 
12257 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
12258 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
12259 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
12260 SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
12261 SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
@@ -12271,10 +12300,11 @@
12271 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
12272 SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
12273 SQLITE_PRIVATE void sqlite3SchemaClear(void *);
12274 SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
12275 SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
 
12276 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
12277 SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
12278 void (*)(sqlite3_context*,int,sqlite3_value **),
12279 void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
12280 FuncDestructor *pDestructor
@@ -13223,10 +13253,13 @@
13223 typedef struct VdbeSorter VdbeSorter;
13224
13225 /* Opaque type used by the explainer */
13226 typedef struct Explain Explain;
13227
 
 
 
13228 /*
13229 ** A cursor is a pointer into a single BTree within a database file.
13230 ** The cursor can seek to a BTree entry with a particular key, or
13231 ** loop over all entries of the Btree. You can also insert new BTree
13232 ** entries or retrieve the key or data from the entry that the cursor
@@ -13409,27 +13442,23 @@
13409 */
13410 #ifdef SQLITE_DEBUG
13411 #define memIsValid(M) ((M)->flags & MEM_Invalid)==0
13412 #endif
13413
13414
13415 /* A VdbeFunc is just a FuncDef (defined in sqliteInt.h) that contains
13416 ** additional information about auxiliary information bound to arguments
13417 ** of the function. This is used to implement the sqlite3_get_auxdata()
13418 ** and sqlite3_set_auxdata() APIs. The "auxdata" is some auxiliary data
13419 ** that can be associated with a constant argument to a function. This
13420 ** allows functions such as "regexp" to compile their constant regular
13421 ** expression argument once and reused the compiled code for multiple
13422 ** invocations.
13423 */
13424 struct VdbeFunc {
13425 FuncDef *pFunc; /* The definition of the function */
13426 int nAux; /* Number of entries allocated for apAux[] */
13427 struct AuxData {
13428 void *pAux; /* Aux data for the i-th argument */
13429 void (*xDelete)(void *); /* Destructor for the aux data */
13430 } apAux[1]; /* One slot for each function argument */
13431 };
13432
13433 /*
13434 ** The "context" argument for a installable function. A pointer to an
13435 ** instance of this structure is the first argument to the routines used
@@ -13443,16 +13472,17 @@
13443 ** This structure is defined inside of vdbeInt.h because it uses substructures
13444 ** (Mem) which are only defined there.
13445 */
13446 struct sqlite3_context {
13447 FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
13448 VdbeFunc *pVdbeFunc; /* Auxilary data, if created. */
13449 Mem s; /* The return value is stored here */
13450 Mem *pMem; /* Memory cell used to store aggregate context */
13451 CollSeq *pColl; /* Collating sequence */
13452 int isError; /* Error code returned by the function. */
13453 int skipFlag; /* Skip skip accumulator loading if true */
 
 
13454 };
13455
13456 /*
13457 ** An Explain object accumulates indented output which is helpful
13458 ** in describing recursive data structures.
@@ -13530,10 +13560,11 @@
13530 #ifndef SQLITE_OMIT_TRACE
13531 i64 startTime; /* Time when query started - used for profiling */
13532 #endif
13533 i64 nFkConstraint; /* Number of imm. FK constraints this VM */
13534 i64 nStmtDefCons; /* Number of def. constraints when stmt started */
 
13535 char *zSql; /* Text of the SQL statement that generated this */
13536 void *pFree; /* Free this when deleting the vdbe */
13537 #ifdef SQLITE_DEBUG
13538 FILE *trace; /* Write an execution trace here, if not NULL */
13539 #endif
@@ -13546,10 +13577,11 @@
13546 int nFrame; /* Number of frames in pFrame list */
13547 u32 expmask; /* Binding to these vars invalidates VM */
13548 SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
13549 int nOnceFlag; /* Size of array aOnceFlag[] */
13550 u8 *aOnceFlag; /* Flags for OP_Once */
 
13551 };
13552
13553 /*
13554 ** The following are allowed values for Vdbe.magic
13555 */
@@ -13569,11 +13601,11 @@
13569 #endif
13570 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
13571 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
13572 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
13573 SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
13574 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
13575
13576 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
13577 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
13578 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
13579 SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
@@ -13889,10 +13921,20 @@
13889 }
13890 *pHighwater = 0;
13891 *pCurrent = nRet;
13892 break;
13893 }
 
 
 
 
 
 
 
 
 
 
13894
13895 default: {
13896 rc = SQLITE_ERROR;
13897 }
13898 }
@@ -22658,91 +22700,91 @@
22658 /* Automatically generated. Do not edit */
22659 /* See the mkopcodec.awk script for details. */
22660 #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
22661 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
22662 static const char *const azName[] = { "?",
22663 /* 1 */ "Goto",
22664 /* 2 */ "Gosub",
22665 /* 3 */ "Return",
22666 /* 4 */ "Yield",
22667 /* 5 */ "HaltIfNull",
22668 /* 6 */ "Halt",
22669 /* 7 */ "Integer",
22670 /* 8 */ "Int64",
22671 /* 9 */ "String",
22672 /* 10 */ "Null",
22673 /* 11 */ "Blob",
22674 /* 12 */ "Variable",
22675 /* 13 */ "Move",
22676 /* 14 */ "Copy",
22677 /* 15 */ "SCopy",
22678 /* 16 */ "ResultRow",
22679 /* 17 */ "CollSeq",
22680 /* 18 */ "Function",
22681 /* 19 */ "Not",
22682 /* 20 */ "AddImm",
22683 /* 21 */ "MustBeInt",
22684 /* 22 */ "RealAffinity",
22685 /* 23 */ "Permutation",
22686 /* 24 */ "Compare",
22687 /* 25 */ "Jump",
22688 /* 26 */ "Once",
22689 /* 27 */ "If",
22690 /* 28 */ "IfNot",
22691 /* 29 */ "Column",
22692 /* 30 */ "Affinity",
22693 /* 31 */ "MakeRecord",
22694 /* 32 */ "Count",
22695 /* 33 */ "Savepoint",
22696 /* 34 */ "AutoCommit",
22697 /* 35 */ "Transaction",
22698 /* 36 */ "ReadCookie",
22699 /* 37 */ "SetCookie",
22700 /* 38 */ "VerifyCookie",
22701 /* 39 */ "OpenRead",
22702 /* 40 */ "OpenWrite",
22703 /* 41 */ "OpenAutoindex",
22704 /* 42 */ "OpenEphemeral",
22705 /* 43 */ "SorterOpen",
22706 /* 44 */ "OpenPseudo",
22707 /* 45 */ "Close",
22708 /* 46 */ "SeekLt",
22709 /* 47 */ "SeekLe",
22710 /* 48 */ "SeekGe",
22711 /* 49 */ "SeekGt",
22712 /* 50 */ "Seek",
22713 /* 51 */ "NotFound",
22714 /* 52 */ "Found",
22715 /* 53 */ "IsUnique",
22716 /* 54 */ "NotExists",
22717 /* 55 */ "Sequence",
22718 /* 56 */ "NewRowid",
22719 /* 57 */ "Insert",
22720 /* 58 */ "InsertInt",
22721 /* 59 */ "Delete",
22722 /* 60 */ "ResetCount",
22723 /* 61 */ "SorterCompare",
22724 /* 62 */ "SorterData",
22725 /* 63 */ "RowKey",
22726 /* 64 */ "RowData",
22727 /* 65 */ "Rowid",
22728 /* 66 */ "NullRow",
22729 /* 67 */ "Last",
22730 /* 68 */ "Or",
22731 /* 69 */ "And",
22732 /* 70 */ "SorterSort",
22733 /* 71 */ "Sort",
22734 /* 72 */ "Rewind",
22735 /* 73 */ "IsNull",
22736 /* 74 */ "NotNull",
22737 /* 75 */ "Ne",
22738 /* 76 */ "Eq",
22739 /* 77 */ "Gt",
22740 /* 78 */ "Le",
22741 /* 79 */ "Lt",
22742 /* 80 */ "Ge",
22743 /* 81 */ "SorterNext",
22744 /* 82 */ "BitAnd",
22745 /* 83 */ "BitOr",
22746 /* 84 */ "ShiftLeft",
22747 /* 85 */ "ShiftRight",
22748 /* 86 */ "Add",
@@ -22749,59 +22791,59 @@
22749 /* 87 */ "Subtract",
22750 /* 88 */ "Multiply",
22751 /* 89 */ "Divide",
22752 /* 90 */ "Remainder",
22753 /* 91 */ "Concat",
22754 /* 92 */ "Prev",
22755 /* 93 */ "BitNot",
22756 /* 94 */ "String8",
22757 /* 95 */ "Next",
22758 /* 96 */ "SorterInsert",
22759 /* 97 */ "IdxInsert",
22760 /* 98 */ "IdxDelete",
22761 /* 99 */ "IdxRowid",
22762 /* 100 */ "IdxLT",
22763 /* 101 */ "IdxGE",
22764 /* 102 */ "Destroy",
22765 /* 103 */ "Clear",
22766 /* 104 */ "CreateIndex",
22767 /* 105 */ "CreateTable",
22768 /* 106 */ "ParseSchema",
22769 /* 107 */ "LoadAnalysis",
22770 /* 108 */ "DropTable",
22771 /* 109 */ "DropIndex",
22772 /* 110 */ "DropTrigger",
22773 /* 111 */ "IntegrityCk",
22774 /* 112 */ "RowSetAdd",
22775 /* 113 */ "RowSetRead",
22776 /* 114 */ "RowSetTest",
22777 /* 115 */ "Program",
22778 /* 116 */ "Param",
22779 /* 117 */ "FkCounter",
22780 /* 118 */ "FkIfZero",
22781 /* 119 */ "MemMax",
22782 /* 120 */ "IfPos",
22783 /* 121 */ "IfNeg",
22784 /* 122 */ "IfZero",
22785 /* 123 */ "AggStep",
22786 /* 124 */ "AggFinal",
22787 /* 125 */ "Checkpoint",
22788 /* 126 */ "JournalMode",
22789 /* 127 */ "Vacuum",
22790 /* 128 */ "IncrVacuum",
22791 /* 129 */ "Expire",
22792 /* 130 */ "Real",
22793 /* 131 */ "TableLock",
22794 /* 132 */ "VBegin",
22795 /* 133 */ "VCreate",
22796 /* 134 */ "VDestroy",
22797 /* 135 */ "VOpen",
22798 /* 136 */ "VFilter",
22799 /* 137 */ "VColumn",
22800 /* 138 */ "VNext",
22801 /* 139 */ "VRename",
22802 /* 140 */ "VUpdate",
22803 /* 141 */ "ToText",
22804 /* 142 */ "ToBlob",
22805 /* 143 */ "ToNumeric",
22806 /* 144 */ "ToInt",
22807 /* 145 */ "ToReal",
@@ -30454,10 +30496,11 @@
30454 */
30455 #if SQLITE_OS_WIN /* This file is used for Windows only */
30456
30457 #ifdef __CYGWIN__
30458 # include <sys/cygwin.h>
 
30459 #endif
30460
30461 /*
30462 ** Include code that is common to all os_*.c files
30463 */
@@ -30874,10 +30917,11 @@
30874 * zero for the default behavior.
30875 */
30876 #ifndef SQLITE_WIN32_HEAP_FLAGS
30877 # define SQLITE_WIN32_HEAP_FLAGS (0)
30878 #endif
 
30879
30880 /*
30881 ** The winMemData structure stores information required by the Win32-specific
30882 ** sqlite3_mem_methods implementation.
30883 */
@@ -34339,14 +34383,14 @@
34339 OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
34340 osGetCurrentProcessId(), pFd));
34341 return SQLITE_OK;
34342 }
34343 assert( (nMap % winSysInfo.dwPageSize)==0 );
34344 #if SQLITE_OS_WINRT
34345 pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap);
34346 #else
34347 assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
 
 
 
34348 pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
34349 #endif
34350 if( pNew==NULL ){
34351 osCloseHandle(pFd->hMap);
34352 pFd->hMap = NULL;
@@ -34511,10 +34555,19 @@
34511 #endif
34512 /* caller will handle out of memory */
34513 return zConverted;
34514 }
34515
 
 
 
 
 
 
 
 
 
34516 /*
34517 ** Create a temporary file name in zBuf. zBuf must be big enough to
34518 ** hold at pVfs->mxPathname characters.
34519 */
34520 static int getTempname(int nBuf, char *zBuf){
@@ -34522,53 +34575,74 @@
34522 "abcdefghijklmnopqrstuvwxyz"
34523 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
34524 "0123456789";
34525 size_t i, j;
34526 int nTempPath;
34527 char zTempPath[MAX_PATH+2];
34528
34529 /* It's odd to simulate an io-error here, but really this is just
34530 ** using the io-error infrastructure to test that SQLite handles this
34531 ** function failing.
34532 */
34533 SimulateIOError( return SQLITE_IOERR );
34534
34535 memset(zTempPath, 0, MAX_PATH+2);
34536
34537 if( sqlite3_temp_directory ){
34538 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
 
34539 }
34540 #if !SQLITE_OS_WINRT
34541 else if( isNT() ){
34542 char *zMulti;
34543 WCHAR zWidePath[MAX_PATH];
34544 osGetTempPathW(MAX_PATH-30, zWidePath);
 
 
 
34545 zMulti = unicodeToUtf8(zWidePath);
34546 if( zMulti ){
34547 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
34548 sqlite3_free(zMulti);
34549 }else{
34550 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
34551 return SQLITE_IOERR_NOMEM;
34552 }
34553 }
34554 #ifdef SQLITE_WIN32_HAS_ANSI
34555 else{
34556 char *zUtf8;
34557 char zMbcsPath[MAX_PATH];
34558 osGetTempPathA(MAX_PATH-30, zMbcsPath);
 
 
 
34559 zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
34560 if( zUtf8 ){
34561 sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
34562 sqlite3_free(zUtf8);
34563 }else{
34564 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
34565 return SQLITE_IOERR_NOMEM;
34566 }
34567 }
34568 #endif
34569 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34570
34571 /* Check that the output buffer is large enough for the temporary file
34572 ** name. If it is not, return SQLITE_ERROR.
34573 */
34574 nTempPath = sqlite3Strlen30(zTempPath);
@@ -34650,11 +34724,11 @@
34650 int cnt = 0;
34651
34652 /* If argument zPath is a NULL pointer, this function is required to open
34653 ** a temporary file. Use this buffer to store the file name in.
34654 */
34655 char zTmpname[MAX_PATH+2]; /* Buffer used to create temp filename */
34656
34657 int rc = SQLITE_OK; /* Function Return Code */
34658 #if !defined(NDEBUG) || SQLITE_OS_WINCE
34659 int eType = flags&0xFFFFFF00; /* Type of file to open */
34660 #endif
@@ -34716,12 +34790,11 @@
34716 /* If the second argument to this function is NULL, generate a
34717 ** temporary file name to use
34718 */
34719 if( !zUtf8Name ){
34720 assert(isDelete && !isOpenJournal);
34721 memset(zTmpname, 0, MAX_PATH+2);
34722 rc = getTempname(MAX_PATH+2, zTmpname);
34723 if( rc!=SQLITE_OK ){
34724 OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
34725 return rc;
34726 }
34727 zUtf8Name = zTmpname;
@@ -35148,27 +35221,34 @@
35148 ){
35149
35150 #if defined(__CYGWIN__)
35151 SimulateIOError( return SQLITE_ERROR );
35152 UNUSED_PARAMETER(nFull);
35153 assert( pVfs->mxPathname>=MAX_PATH );
35154 assert( nFull>=pVfs->mxPathname );
35155 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
35156 /*
35157 ** NOTE: We are dealing with a relative path name and the data
35158 ** directory has been set. Therefore, use it as the basis
35159 ** for converting the relative path name to an absolute
35160 ** one by prepending the data directory and a slash.
35161 */
35162 char zOut[MAX_PATH+1];
35163 memset(zOut, 0, MAX_PATH+1);
35164 cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
35165 MAX_PATH+1);
 
 
 
35166 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
35167 sqlite3_data_directory, zOut);
35168 }else{
35169 cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
 
 
 
 
35170 }
35171 return SQLITE_OK;
35172 #endif
35173
35174 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
@@ -35506,11 +35586,11 @@
35506 */
35507 SQLITE_API int sqlite3_os_init(void){
35508 static sqlite3_vfs winVfs = {
35509 3, /* iVersion */
35510 sizeof(winFile), /* szOsFile */
35511 MAX_PATH, /* mxPathname */
35512 0, /* pNext */
35513 "win32", /* zName */
35514 0, /* pAppData */
35515 winOpen, /* xOpen */
35516 winDelete, /* xDelete */
@@ -60131,12 +60211,12 @@
60131 ** a prior call to sqlite3VdbeMakeLabel().
60132 */
60133 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
60134 int j = -1-x;
60135 assert( p->magic==VDBE_MAGIC_INIT );
60136 assert( j>=0 && j<p->nLabel );
60137 if( p->aLabel ){
60138 p->aLabel[j] = p->nOp;
60139 }
60140 }
60141
60142 /*
@@ -60288,44 +60368,64 @@
60288 p->readOnly = 1;
60289 p->bIsReader = 0;
60290 for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
60291 u8 opcode = pOp->opcode;
60292
60293 pOp->opflags = sqlite3OpcodeProperty[opcode];
60294 if( opcode==OP_Function || opcode==OP_AggStep ){
60295 if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
60296 }else if( opcode==OP_Transaction ){
60297 if( pOp->p2!=0 ) p->readOnly = 0;
60298 p->bIsReader = 1;
60299 }else if( opcode==OP_AutoCommit || opcode==OP_Savepoint ){
60300 p->bIsReader = 1;
60301 }else if( opcode==OP_Vacuum
60302 || opcode==OP_JournalMode
 
 
 
 
 
 
 
60303 #ifndef SQLITE_OMIT_WAL
60304 || opcode==OP_Checkpoint
60305 #endif
60306 ){
60307 p->readOnly = 0;
60308 p->bIsReader = 1;
 
 
 
60309 #ifndef SQLITE_OMIT_VIRTUALTABLE
60310 }else if( opcode==OP_VUpdate ){
60311 if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
60312 }else if( opcode==OP_VFilter ){
60313 int n;
60314 assert( p->nOp - i >= 3 );
60315 assert( pOp[-1].opcode==OP_Integer );
60316 n = pOp[-1].p1;
60317 if( n>nMaxArgs ) nMaxArgs = n;
60318 #endif
60319 }else if( opcode==OP_Next || opcode==OP_SorterNext ){
60320 pOp->p4.xAdvance = sqlite3BtreeNext;
60321 pOp->p4type = P4_ADVANCE;
60322 }else if( opcode==OP_Prev ){
60323 pOp->p4.xAdvance = sqlite3BtreePrevious;
60324 pOp->p4type = P4_ADVANCE;
60325 }
60326
 
 
 
 
 
 
 
 
 
 
60327 if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
60328 assert( -1-pOp->p2<p->nLabel );
60329 pOp->p2 = aLabel[-1-pOp->p2];
60330 }
60331 }
@@ -60456,12 +60556,11 @@
60456 /*
60457 ** Change the P2 operand of instruction addr so that it points to
60458 ** the address of the next instruction to be coded.
60459 */
60460 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
60461 assert( addr>=0 || p->db->mallocFailed );
60462 if( addr>=0 ) sqlite3VdbeChangeP2(p, addr, p->nOp);
60463 }
60464
60465
60466 /*
60467 ** If the input FuncDef structure is ephemeral, then free it. If
@@ -60493,17 +60592,10 @@
60493 }
60494 case P4_MPRINTF: {
60495 if( db->pnBytesFreed==0 ) sqlite3_free(p4);
60496 break;
60497 }
60498 case P4_VDBEFUNC: {
60499 VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
60500 freeEphemeralFunction(db, pVdbeFunc->pFunc);
60501 if( db->pnBytesFreed==0 ) sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
60502 sqlite3DbFree(db, pVdbeFunc);
60503 break;
60504 }
60505 case P4_FUNCDEF: {
60506 freeEphemeralFunction(db, (FuncDef*)p4);
60507 break;
60508 }
60509 case P4_MEM: {
@@ -60618,24 +60710,17 @@
60618 pOp->p4type = P4_INT32;
60619 }else if( zP4==0 ){
60620 pOp->p4.p = 0;
60621 pOp->p4type = P4_NOTUSED;
60622 }else if( n==P4_KEYINFO ){
60623 KeyInfo *pKeyInfo;
60624 int nField, nByte;
60625
60626 nField = ((KeyInfo*)zP4)->nField;
60627 nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
60628 pKeyInfo = sqlite3DbMallocRaw(0, nByte);
60629 pOp->p4.pKeyInfo = pKeyInfo;
60630 if( pKeyInfo ){
60631 u8 *aSortOrder;
60632 memcpy((char*)pKeyInfo, zP4, nByte - nField);
60633 aSortOrder = pKeyInfo->aSortOrder;
60634 assert( aSortOrder!=0 );
60635 pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
60636 memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
60637 pOp->p4type = P4_KEYINFO;
60638 }else{
60639 p->db->mallocFailed = 1;
60640 pOp->p4type = P4_NOTUSED;
60641 }
@@ -61529,10 +61614,14 @@
61529 while( p->pDelFrame ){
61530 VdbeFrame *pDel = p->pDelFrame;
61531 p->pDelFrame = pDel->pParent;
61532 sqlite3VdbeFrameDelete(pDel);
61533 }
 
 
 
 
61534 }
61535
61536 /*
61537 ** Clean up the VM after execution.
61538 **
@@ -61946,10 +62035,11 @@
61946 /* If the statement transaction is being rolled back, also restore the
61947 ** database handles deferred constraint counter to the value it had when
61948 ** the statement transaction was opened. */
61949 if( eOp==SAVEPOINT_ROLLBACK ){
61950 db->nDeferredCons = p->nStmtDefCons;
 
61951 }
61952 }
61953 return rc;
61954 }
61955
@@ -61964,11 +62054,13 @@
61964 ** and write an error message to it. Then return SQLITE_ERROR.
61965 */
61966 #ifndef SQLITE_OMIT_FOREIGN_KEY
61967 SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
61968 sqlite3 *db = p->db;
61969 if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){
 
 
61970 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
61971 p->errorAction = OE_Abort;
61972 sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
61973 return SQLITE_ERROR;
61974 }
@@ -62097,10 +62189,12 @@
62097 }else if( rc!=SQLITE_OK ){
62098 p->rc = rc;
62099 sqlite3RollbackAll(db, SQLITE_OK);
62100 }else{
62101 db->nDeferredCons = 0;
 
 
62102 sqlite3CommitInternalChanges(db);
62103 }
62104 }else{
62105 sqlite3RollbackAll(db, SQLITE_OK);
62106 }
@@ -62322,24 +62416,39 @@
62322 sqlite3VdbeDelete(p);
62323 return rc;
62324 }
62325
62326 /*
62327 ** Call the destructor for each auxdata entry in pVdbeFunc for which
62328 ** the corresponding bit in mask is clear. Auxdata entries beyond 31
62329 ** are always destroyed. To destroy all auxdata entries, call this
62330 ** routine with mask==0.
 
 
 
 
 
 
 
 
 
 
62331 */
62332 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){
62333 int i;
62334 for(i=0; i<pVdbeFunc->nAux; i++){
62335 struct AuxData *pAux = &pVdbeFunc->apAux[i];
62336 if( (i>31 || !(mask&(((u32)1)<<i))) && pAux->pAux ){
 
 
62337 if( pAux->xDelete ){
62338 pAux->xDelete(pAux->pAux);
62339 }
62340 pAux->pAux = 0;
 
 
 
62341 }
62342 }
62343 }
62344
62345 /*
@@ -62854,15 +62963,14 @@
62854 */
62855 SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
62856 int nKey1, const void *pKey1, /* Left key */
62857 UnpackedRecord *pPKey2 /* Right key */
62858 ){
62859 int d1; /* Offset into aKey[] of next data element */
62860 u32 idx1; /* Offset into aKey[] of next header element */
62861 u32 szHdr1; /* Number of bytes in header */
62862 int i = 0;
62863 int nField;
62864 int rc = 0;
62865 const unsigned char *aKey1 = (const unsigned char *)pKey1;
62866 KeyInfo *pKeyInfo;
62867 Mem mem1;
62868
@@ -62881,32 +62989,42 @@
62881 */
62882 /* mem1.u.i = 0; // not needed, here to silence compiler warning */
62883
62884 idx1 = getVarint32(aKey1, szHdr1);
62885 d1 = szHdr1;
62886 nField = pKeyInfo->nField;
62887 assert( pKeyInfo->aSortOrder!=0 );
62888 while( idx1<szHdr1 && i<pPKey2->nField ){
62889 u32 serial_type1;
62890
62891 /* Read the serial types for the next element in each key. */
62892 idx1 += getVarint32( aKey1+idx1, serial_type1 );
62893 if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
 
 
 
 
 
 
 
 
 
 
 
62894
62895 /* Extract the values to be compared.
62896 */
62897 d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
62898
62899 /* Do the comparison
62900 */
62901 rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i],
62902 i<nField ? pKeyInfo->aColl[i] : 0);
62903 if( rc!=0 ){
62904 assert( mem1.zMalloc==0 ); /* See comment below */
62905
62906 /* Invert the result if we are using DESC sort order. */
62907 if( i<nField && pKeyInfo->aSortOrder[i] ){
62908 rc = -rc;
62909 }
62910
62911 /* If the PREFIX_SEARCH flag is set and all fields except the final
62912 ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
@@ -63117,11 +63235,11 @@
63117 ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
63118 ** constants) to the value before returning it.
63119 **
63120 ** The returned value must be freed by the caller using sqlite3ValueFree().
63121 */
63122 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetValue(Vdbe *v, int iVar, u8 aff){
63123 assert( iVar>0 );
63124 if( v ){
63125 Mem *pMem = &v->aVar[iVar-1];
63126 if( 0==(pMem->flags & MEM_Null) ){
63127 sqlite3_value *pRet = sqlite3ValueNew(v->db);
@@ -63536,11 +63654,13 @@
63536 */
63537 if( db->nVdbeActive==0 ){
63538 db->u1.isInterrupted = 0;
63539 }
63540
63541 assert( db->nVdbeWrite>0 || db->autoCommit==0 || db->nDeferredCons==0 );
 
 
63542
63543 #ifndef SQLITE_OMIT_TRACE
63544 if( db->xProfile && !db->init.busy ){
63545 sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
63546 }
@@ -63732,18 +63852,18 @@
63732 /*
63733 ** Return the auxilary data pointer, if any, for the iArg'th argument to
63734 ** the user-function defined by pCtx.
63735 */
63736 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
63737 VdbeFunc *pVdbeFunc;
63738
63739 assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
63740 pVdbeFunc = pCtx->pVdbeFunc;
63741 if( !pVdbeFunc || iArg>=pVdbeFunc->nAux || iArg<0 ){
63742 return 0;
63743 }
63744 return pVdbeFunc->apAux[iArg].pAux;
 
63745 }
63746
63747 /*
63748 ** Set the auxilary data pointer and delete function, for the iArg'th
63749 ** argument to the user-function defined by pCtx. Any previous value is
@@ -63753,33 +63873,30 @@
63753 sqlite3_context *pCtx,
63754 int iArg,
63755 void *pAux,
63756 void (*xDelete)(void*)
63757 ){
63758 struct AuxData *pAuxData;
63759 VdbeFunc *pVdbeFunc;
63760 if( iArg<0 ) goto failed;
63761
63762 assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
63763 pVdbeFunc = pCtx->pVdbeFunc;
63764 if( !pVdbeFunc || pVdbeFunc->nAux<=iArg ){
63765 int nAux = (pVdbeFunc ? pVdbeFunc->nAux : 0);
63766 int nMalloc = sizeof(VdbeFunc) + sizeof(struct AuxData)*iArg;
63767 pVdbeFunc = sqlite3DbRealloc(pCtx->s.db, pVdbeFunc, nMalloc);
63768 if( !pVdbeFunc ){
63769 goto failed;
63770 }
63771 pCtx->pVdbeFunc = pVdbeFunc;
63772 memset(&pVdbeFunc->apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux));
63773 pVdbeFunc->nAux = iArg+1;
63774 pVdbeFunc->pFunc = pCtx->pFunc;
63775 }
63776
63777 pAuxData = &pVdbeFunc->apAux[iArg];
63778 if( pAuxData->pAux && pAuxData->xDelete ){
63779 pAuxData->xDelete(pAuxData->pAux);
63780 }
 
63781 pAuxData->pAux = pAux;
63782 pAuxData->xDelete = xDelete;
63783 return;
63784
63785 failed:
@@ -65384,16 +65501,15 @@
65384 Op *pOp; /* Current operation */
65385 int rc = SQLITE_OK; /* Value to return */
65386 sqlite3 *db = p->db; /* The database */
65387 u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
65388 u8 encoding = ENC(db); /* The database encoding */
65389 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65390 int checkProgress; /* True if progress callbacks are enabled */
65391 int nProgressOps = 0; /* Opcodes executed since progress callback. */
65392 #endif
65393 int iCompare = 0; /* Result of last OP_Compare operation */
65394 unsigned nVmStep = 0; /* Number of virtual machine steps */
 
 
 
65395 Mem *aMem = p->aMem; /* Copy of p->aMem */
65396 Mem *pIn1 = 0; /* 1st input operand */
65397 Mem *pIn2 = 0; /* 2nd input operand */
65398 Mem *pIn3 = 0; /* 3rd input operand */
65399 Mem *pOut = 0; /* Output operand */
@@ -65848,11 +65964,19 @@
65848 p->pResultSet = 0;
65849 db->busyHandler.nBusy = 0;
65850 CHECK_FOR_INTERRUPT;
65851 sqlite3VdbeIOTraceSql(p);
65852 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65853 checkProgress = db->xProgress!=0;
 
 
 
 
 
 
 
 
65854 #endif
65855 #ifdef SQLITE_DEBUG
65856 sqlite3BeginBenignMalloc();
65857 if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
65858 int i;
@@ -65895,31 +66019,10 @@
65895 sqlite3_interrupt_count--;
65896 if( sqlite3_interrupt_count==0 ){
65897 sqlite3_interrupt(db);
65898 }
65899 }
65900 #endif
65901
65902 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65903 /* Call the progress callback if it is configured and the required number
65904 ** of VDBE ops have been executed (either since this invocation of
65905 ** sqlite3VdbeExec() or since last time the progress callback was called).
65906 ** If the progress callback returns non-zero, exit the virtual machine with
65907 ** a return code SQLITE_ABORT.
65908 */
65909 if( checkProgress ){
65910 if( db->nProgressOps==nProgressOps ){
65911 int prc;
65912 prc = db->xProgress(db->pProgressArg);
65913 if( prc!=0 ){
65914 rc = SQLITE_INTERRUPT;
65915 goto vdbe_error_halt;
65916 }
65917 nProgressOps = 0;
65918 }
65919 nProgressOps++;
65920 }
65921 #endif
65922
65923 /* On any opcode with the "out2-prerelease" tag, free any
65924 ** external allocations out of mem[p2] and set mem[p2] to be
65925 ** an undefined integer. Opcodes will either fill in the integer
@@ -66010,12 +66113,44 @@
66010 ** The next instruction executed will be
66011 ** the one at index P2 from the beginning of
66012 ** the program.
66013 */
66014 case OP_Goto: { /* jump */
66015 CHECK_FOR_INTERRUPT;
66016 pc = pOp->p2 - 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66017 break;
66018 }
66019
66020 /* Opcode: Gosub P1 P2 * * *
66021 **
@@ -66132,11 +66267,11 @@
66132 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
66133 if( rc==SQLITE_BUSY ){
66134 p->rc = rc = SQLITE_BUSY;
66135 }else{
66136 assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
66137 assert( rc==SQLITE_OK || db->nDeferredCons>0 );
66138 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
66139 }
66140 goto vdbe_return;
66141 }
66142
@@ -66694,23 +66829,18 @@
66694 Deephemeralize(u.ai.pArg);
66695 sqlite3VdbeMemStoreType(u.ai.pArg);
66696 REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
66697 }
66698
66699 assert( pOp->p4type==P4_FUNCDEF || pOp->p4type==P4_VDBEFUNC );
66700 if( pOp->p4type==P4_FUNCDEF ){
66701 u.ai.ctx.pFunc = pOp->p4.pFunc;
66702 u.ai.ctx.pVdbeFunc = 0;
66703 }else{
66704 u.ai.ctx.pVdbeFunc = (VdbeFunc*)pOp->p4.pVdbeFunc;
66705 u.ai.ctx.pFunc = u.ai.ctx.pVdbeFunc->pFunc;
66706 }
66707
66708 u.ai.ctx.s.flags = MEM_Null;
66709 u.ai.ctx.s.db = db;
66710 u.ai.ctx.s.xDel = 0;
66711 u.ai.ctx.s.zMalloc = 0;
 
 
66712
66713 /* The output cell may already have a buffer allocated. Move
66714 ** the pointer to u.ai.ctx.s so in case the user-function can use
66715 ** the already allocated buffer instead of allocating a new one.
66716 */
@@ -66729,15 +66859,11 @@
66729 lastRowid = db->lastRowid;
66730
66731 /* If any auxiliary data functions have been called by this user function,
66732 ** immediately call the destructor for any non-static values.
66733 */
66734 if( u.ai.ctx.pVdbeFunc ){
66735 sqlite3VdbeDeleteAuxData(u.ai.ctx.pVdbeFunc, pOp->p1);
66736 pOp->p4.pVdbeFunc = u.ai.ctx.pVdbeFunc;
66737 pOp->p4type = P4_VDBEFUNC;
66738 }
66739
66740 if( db->mallocFailed ){
66741 /* Even though a malloc() has failed, the implementation of the
66742 ** user function may have called an sqlite3_result_XXX() function
66743 ** to return a value. The following call releases any resources
@@ -68028,10 +68154,11 @@
68028
68029 /* Link the new savepoint into the database handle's list. */
68030 u.as.pNew->pNext = db->pSavepoint;
68031 db->pSavepoint = u.as.pNew;
68032 u.as.pNew->nDeferredCons = db->nDeferredCons;
 
68033 }
68034 }
68035 }else{
68036 u.as.iSavepoint = 0;
68037
@@ -68115,10 +68242,11 @@
68115 if( !isTransaction ){
68116 db->nSavepoint--;
68117 }
68118 }else{
68119 db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
 
68120 }
68121
68122 if( !isTransaction ){
68123 rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
68124 if( rc!=SQLITE_OK ) goto abort_due_to_error;
@@ -68244,10 +68372,14 @@
68244
68245 assert( p->bIsReader );
68246 assert( p->readOnly==0 || pOp->p2==0 );
68247 assert( pOp->p1>=0 && pOp->p1<db->nDb );
68248 assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
 
 
 
 
68249 u.au.pBt = db->aDb[pOp->p1].pBt;
68250
68251 if( u.au.pBt ){
68252 rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
68253 if( rc==SQLITE_BUSY ){
@@ -68276,10 +68408,11 @@
68276
68277 /* Store the current value of the database handles deferred constraint
68278 ** counter. If the statement transaction needs to be rolled back,
68279 ** the value of this counter needs to be restored too. */
68280 p->nStmtDefCons = db->nDeferredCons;
 
68281 }
68282 }
68283 break;
68284 }
68285
@@ -69851,11 +69984,10 @@
69851 #if 0 /* local variables moved into u.br */
69852 VdbeCursor *pC;
69853 int res;
69854 #endif /* local variables moved into u.br */
69855
69856 CHECK_FOR_INTERRUPT;
69857 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
69858 assert( pOp->p5<=ArraySize(p->aCounter) );
69859 u.br.pC = p->apCsr[pOp->p1];
69860 if( u.br.pC==0 ){
69861 break; /* See ticket #2273 */
@@ -69880,11 +70012,11 @@
69880 #ifdef SQLITE_TEST
69881 sqlite3_search_count++;
69882 #endif
69883 }
69884 u.br.pC->rowidIsValid = 0;
69885 break;
69886 }
69887
69888 /* Opcode: IdxInsert P1 P2 P3 * P5
69889 **
69890 ** Register P2 holds an SQL index key made using the
@@ -70426,11 +70558,11 @@
70426 */
70427 case OP_RowSetRead: { /* jump, in1, out3 */
70428 #if 0 /* local variables moved into u.cb */
70429 i64 val;
70430 #endif /* local variables moved into u.cb */
70431 CHECK_FOR_INTERRUPT;
70432 pIn1 = &aMem[pOp->p1];
70433 if( (pIn1->flags & MEM_RowSet)==0
70434 || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
70435 ){
70436 /* The boolean index is empty */
@@ -70438,11 +70570,11 @@
70438 pc = pOp->p2 - 1;
70439 }else{
70440 /* A value was pulled from the index */
70441 sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
70442 }
70443 break;
70444 }
70445
70446 /* Opcode: RowSetTest P1 P2 P3 P4
70447 **
70448 ** Register P3 is assumed to hold a 64-bit integer value. If register P1
@@ -70658,11 +70790,13 @@
70658 ** If P1 is non-zero, the database constraint counter is incremented
70659 ** (deferred foreign key constraints). Otherwise, if P1 is zero, the
70660 ** statement counter is incremented (immediate foreign key constraints).
70661 */
70662 case OP_FkCounter: {
70663 if( pOp->p1 ){
 
 
70664 db->nDeferredCons += pOp->p2;
70665 }else{
70666 p->nFkConstraint += pOp->p2;
70667 }
70668 break;
@@ -70679,13 +70813,13 @@
70679 ** zero, the jump is taken if the statement constraint-counter is zero
70680 ** (immediate foreign key constraint violations).
70681 */
70682 case OP_FkIfZero: { /* jump */
70683 if( pOp->p1 ){
70684 if( db->nDeferredCons==0 ) pc = pOp->p2-1;
70685 }else{
70686 if( p->nFkConstraint==0 ) pc = pOp->p2-1;
70687 }
70688 break;
70689 }
70690 #endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
70691
@@ -71367,11 +71501,11 @@
71367
71368 if( !u.cp.res ){
71369 /* If there is data, jump to P2 */
71370 pc = pOp->p2 - 1;
71371 }
71372 break;
71373 }
71374 #endif /* SQLITE_OMIT_VIRTUALTABLE */
71375
71376 #ifndef SQLITE_OMIT_VIRTUALTABLE
71377 /* Opcode: VRename P1 * * P4 *
@@ -74092,15 +74226,24 @@
74092 /* Translate the schema name in zDb into a pointer to the corresponding
74093 ** schema. If not found, pSchema will remain NULL and nothing will match
74094 ** resulting in an appropriate error message toward the end of this routine
74095 */
74096 if( zDb ){
74097 for(i=0; i<db->nDb; i++){
74098 assert( db->aDb[i].zName );
74099 if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
74100 pSchema = db->aDb[i].pSchema;
74101 break;
 
 
 
 
 
 
 
 
 
74102 }
74103 }
74104 }
74105
74106 /* Start at the inner-most context and move outward until a match is found */
@@ -74373,10 +74516,43 @@
74373 }
74374 ExprSetProperty(p, EP_Resolved);
74375 }
74376 return p;
74377 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74378
74379 /*
74380 ** This routine is callback for sqlite3WalkExpr().
74381 **
74382 ** Resolve symbolic names into TK_COLUMN operators for the current
@@ -74473,10 +74649,11 @@
74473 FuncDef *pDef; /* Information about the function */
74474 u8 enc = ENC(pParse->db); /* The database encoding */
74475
74476 testcase( pExpr->op==TK_CONST_FUNC );
74477 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
 
74478 zId = pExpr->u.zToken;
74479 nId = sqlite3Strlen30(zId);
74480 pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
74481 if( pDef==0 ){
74482 pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
@@ -74538,31 +74715,25 @@
74538 #endif
74539 case TK_IN: {
74540 testcase( pExpr->op==TK_IN );
74541 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
74542 int nRef = pNC->nRef;
74543 #ifndef SQLITE_OMIT_CHECK
74544 if( (pNC->ncFlags & NC_IsCheck)!=0 ){
74545 sqlite3ErrorMsg(pParse,"subqueries prohibited in CHECK constraints");
74546 }
74547 #endif
74548 sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
74549 assert( pNC->nRef>=nRef );
74550 if( nRef!=pNC->nRef ){
74551 ExprSetProperty(pExpr, EP_VarSelect);
74552 }
74553 }
74554 break;
74555 }
74556 #ifndef SQLITE_OMIT_CHECK
74557 case TK_VARIABLE: {
74558 if( (pNC->ncFlags & NC_IsCheck)!=0 ){
74559 sqlite3ErrorMsg(pParse,"parameters prohibited in CHECK constraints");
74560 }
74561 break;
74562 }
74563 #endif
74564 }
74565 return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
74566 }
74567
74568 /*
@@ -74649,11 +74820,11 @@
74649 /* Try to match the ORDER BY expression against an expression
74650 ** in the result set. Return an 1-based index of the matching
74651 ** result-set entry.
74652 */
74653 for(i=0; i<pEList->nExpr; i++){
74654 if( sqlite3ExprCompare(pEList->a[i].pExpr, pE)<2 ){
74655 return i+1;
74656 }
74657 }
74658
74659 /* If no match, return 0. */
@@ -74877,11 +75048,11 @@
74877 pItem->iOrderByCol = 0;
74878 if( sqlite3ResolveExprNames(pNC, pE) ){
74879 return 1;
74880 }
74881 for(j=0; j<pSelect->pEList->nExpr; j++){
74882 if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr)==0 ){
74883 pItem->iOrderByCol = j+1;
74884 }
74885 }
74886 }
74887 return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
@@ -75183,10 +75354,52 @@
75183 w.xSelectCallback = resolveSelectStep;
75184 w.pParse = pParse;
75185 w.u.pNC = pOuterNC;
75186 sqlite3WalkSelect(&w, p);
75187 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75188
75189 /************** End of resolve.c *********************************************/
75190 /************** Begin file expr.c ********************************************/
75191 /*
75192 ** 2001 September 15
@@ -76879,14 +77092,13 @@
76879 #endif
76880
76881 switch( pExpr->op ){
76882 case TK_IN: {
76883 char affinity; /* Affinity of the LHS of the IN */
76884 KeyInfo keyInfo; /* Keyinfo for the generated table */
76885 static u8 sortOrder = 0; /* Fake aSortOrder for keyInfo */
76886 int addr; /* Address of OP_OpenEphemeral instruction */
76887 Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
 
76888
76889 if( rMayHaveNull ){
76890 sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
76891 }
76892
@@ -76906,13 +77118,11 @@
76906 ** is used.
76907 */
76908 pExpr->iTable = pParse->nTab++;
76909 addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
76910 if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
76911 memset(&keyInfo, 0, sizeof(keyInfo));
76912 keyInfo.nField = 1;
76913 keyInfo.aSortOrder = &sortOrder;
76914
76915 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
76916 /* Case 1: expr IN (SELECT ...)
76917 **
76918 ** Generate code to write the results of the select into the temporary
@@ -76925,15 +77135,16 @@
76925 sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
76926 dest.affSdst = (u8)affinity;
76927 assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
76928 pExpr->x.pSelect->iLimit = 0;
76929 if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
 
76930 return 0;
76931 }
76932 pEList = pExpr->x.pSelect->pEList;
76933 if( ALWAYS(pEList!=0 && pEList->nExpr>0) ){
76934 keyInfo.aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
76935 pEList->a[0].pExpr);
76936 }
76937 }else if( ALWAYS(pExpr->x.pList!=0) ){
76938 /* Case 2: expr IN (exprlist)
76939 **
@@ -76948,12 +77159,13 @@
76948 int r1, r2, r3;
76949
76950 if( !affinity ){
76951 affinity = SQLITE_AFF_NONE;
76952 }
76953 keyInfo.aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
76954 keyInfo.aSortOrder = &sortOrder;
 
76955
76956 /* Loop through each expression in <exprlist>. */
76957 r1 = sqlite3GetTempReg(pParse);
76958 r2 = sqlite3GetTempReg(pParse);
76959 sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
@@ -76988,12 +77200,12 @@
76988 }
76989 }
76990 sqlite3ReleaseTempReg(pParse, r1);
76991 sqlite3ReleaseTempReg(pParse, r2);
76992 }
76993 if( !isRowid ){
76994 sqlite3VdbeChangeP4(v, addr, (void *)&keyInfo, P4_KEYINFO);
76995 }
76996 break;
76997 }
76998
76999 case TK_EXISTS:
@@ -77549,19 +77761,24 @@
77549 break;
77550 }
77551 /* Otherwise, fall thru into the TK_COLUMN case */
77552 }
77553 case TK_COLUMN: {
77554 if( pExpr->iTable<0 ){
77555 /* This only happens when coding check constraints */
77556 assert( pParse->ckBase>0 );
77557 inReg = pExpr->iColumn + pParse->ckBase;
77558 }else{
77559 inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
77560 pExpr->iColumn, pExpr->iTable, target,
77561 pExpr->op2);
77562 }
 
 
 
 
 
77563 break;
77564 }
77565 case TK_INTEGER: {
77566 codeInteger(pParse, pExpr, 0, target);
77567 break;
@@ -78980,10 +79197,16 @@
78980 ** Do a deep comparison of two expression trees. Return 0 if the two
78981 ** expressions are completely identical. Return 1 if they differ only
78982 ** by a COLLATE operator at the top level. Return 2 if there are differences
78983 ** other than the top-level COLLATE operator.
78984 **
 
 
 
 
 
 
78985 ** Sometimes this routine will return 2 even if the two expressions
78986 ** really are equivalent. If we cannot prove that the expressions are
78987 ** identical, we return 2 just to be safe. So if this routine
78988 ** returns 2, then you do not really know for certain if the two
78989 ** expressions are the same. But if you get a 0 or 1 return, then you
@@ -78990,33 +79213,36 @@
78990 ** can be sure the expressions are the same. In the places where
78991 ** this routine is used, it does not hurt to get an extra 2 - that
78992 ** just might result in some slightly slower code. But returning
78993 ** an incorrect 0 or 1 could lead to a malfunction.
78994 */
78995 SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB){
78996 if( pA==0||pB==0 ){
78997 return pB==pA ? 0 : 2;
78998 }
78999 assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
79000 assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
79001 if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
79002 return 2;
79003 }
79004 if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
79005 if( pA->op!=pB->op ){
79006 if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB)<2 ){
79007 return 1;
79008 }
79009 if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft)<2 ){
79010 return 1;
79011 }
79012 return 2;
79013 }
79014 if( sqlite3ExprCompare(pA->pLeft, pB->pLeft) ) return 2;
79015 if( sqlite3ExprCompare(pA->pRight, pB->pRight) ) return 2;
79016 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList) ) return 2;
79017 if( pA->iTable!=pB->iTable || pA->iColumn!=pB->iColumn ) return 2;
 
 
 
79018 if( ExprHasProperty(pA, EP_IntValue) ){
79019 if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
79020 return 2;
79021 }
79022 }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
@@ -79030,28 +79256,70 @@
79030
79031 /*
79032 ** Compare two ExprList objects. Return 0 if they are identical and
79033 ** non-zero if they differ in any way.
79034 **
 
 
 
79035 ** This routine might return non-zero for equivalent ExprLists. The
79036 ** only consequence will be disabled optimizations. But this routine
79037 ** must never return 0 if the two ExprList objects are different, or
79038 ** a malfunction will result.
79039 **
79040 ** Two NULL pointers are considered to be the same. But a NULL pointer
79041 ** always differs from a non-NULL pointer.
79042 */
79043 SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB){
79044 int i;
79045 if( pA==0 && pB==0 ) return 0;
79046 if( pA==0 || pB==0 ) return 1;
79047 if( pA->nExpr!=pB->nExpr ) return 1;
79048 for(i=0; i<pA->nExpr; i++){
79049 Expr *pExprA = pA->a[i].pExpr;
79050 Expr *pExprB = pB->a[i].pExpr;
79051 if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
79052 if( sqlite3ExprCompare(pExprA, pExprB) ) return 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79053 }
79054 return 0;
79055 }
79056
79057 /*
@@ -79232,11 +79500,11 @@
79232 /* Check to see if pExpr is a duplicate of another aggregate
79233 ** function that is already in the pAggInfo structure
79234 */
79235 struct AggInfo_func *pItem = pAggInfo->aFunc;
79236 for(i=0; i<pAggInfo->nFunc; i++, pItem++){
79237 if( sqlite3ExprCompare(pItem->pExpr, pExpr)==0 ){
79238 break;
79239 }
79240 }
79241 if( i>=pAggInfo->nFunc ){
79242 /* pExpr is original. Make a new entry in pAggInfo->aFunc[]
@@ -80649,10 +80917,11 @@
80649 int i; /* Loop counter */
80650 int topOfLoop; /* The top of the loop */
80651 int endOfLoop; /* The end of the loop */
80652 int jZeroRows = -1; /* Jump from here if number of rows is zero */
80653 int iDb; /* Index of database containing pTab */
 
80654 int regTabname = iMem++; /* Register containing table name */
80655 int regIdxname = iMem++; /* Register containing index name */
80656 int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
80657 #ifdef SQLITE_ENABLE_STAT3
80658 int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
@@ -80708,10 +80977,11 @@
80708 KeyInfo *pKey;
80709 int addrIfNot = 0; /* address of OP_IfNot */
80710 int *aChngAddr; /* Array of jump instruction addresses */
80711
80712 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
 
80713 VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
80714 nCol = pIdx->nColumn;
80715 aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
80716 if( aChngAddr==0 ) continue;
80717 pKey = sqlite3IndexKeyinfo(pParse, pIdx);
@@ -80867,48 +81137,45 @@
80867 ** If K==0 then no entry is made into the sqlite_stat1 table.
80868 ** If K>0 then it is always the case the D>0 so division by zero
80869 ** is never possible.
80870 */
80871 sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
80872 if( jZeroRows<0 ){
80873 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
80874 }
80875 for(i=0; i<nCol; i++){
80876 sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
80877 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
80878 sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
80879 sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
80880 sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
80881 sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
80882 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
80883 }
 
80884 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
80885 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
80886 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
80887 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
 
80888 }
80889
80890 /* If the table has no indices, create a single sqlite_stat1 entry
80891 ** containing NULL as the index name and the row count as the content.
80892 */
80893 if( pTab->pIndex==0 ){
80894 sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
80895 VdbeComment((v, "%s", pTab->zName));
80896 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
80897 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
80898 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
80899 }else{
80900 sqlite3VdbeJumpHere(v, jZeroRows);
80901 jZeroRows = sqlite3VdbeAddOp0(v, OP_Goto);
80902 }
80903 sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
80904 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
80905 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
80906 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
80907 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
80908 if( pParse->nMem<regRec ) pParse->nMem = regRec;
80909 sqlite3VdbeJumpHere(v, jZeroRows);
80910 }
80911
80912
80913 /*
80914 ** Generate code that will cause the most recent index analysis to
@@ -81087,12 +81354,14 @@
81087 v = 0;
81088 while( (c=z[0])>='0' && c<='9' ){
81089 v = v*10 + c - '0';
81090 z++;
81091 }
81092 if( i==0 ) pTable->nRowEst = v;
81093 if( pIndex==0 ) break;
 
 
81094 pIndex->aiRowEst[i] = v;
81095 if( *z==' ' ) z++;
81096 if( strcmp(z, "unordered")==0 ){
81097 pIndex->bUnordered = 1;
81098 break;
@@ -82528,10 +82797,11 @@
82528 */
82529 static void freeIndex(sqlite3 *db, Index *p){
82530 #ifndef SQLITE_OMIT_ANALYZE
82531 sqlite3DeleteIndexSamples(db, p);
82532 #endif
 
82533 sqlite3DbFree(db, p->zColAff);
82534 sqlite3DbFree(db, p);
82535 }
82536
82537 /*
@@ -83371,11 +83641,12 @@
83371 sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
83372 "INTEGER PRIMARY KEY");
83373 #endif
83374 }else{
83375 Index *p;
83376 p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0);
 
83377 if( p ){
83378 p->autoIndex = 2;
83379 }
83380 pList = 0;
83381 }
@@ -83666,30 +83937,11 @@
83666
83667 #ifndef SQLITE_OMIT_CHECK
83668 /* Resolve names in all CHECK constraint expressions.
83669 */
83670 if( p->pCheck ){
83671 SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
83672 NameContext sNC; /* Name context for pParse->pNewTable */
83673 ExprList *pList; /* List of all CHECK constraints */
83674 int i; /* Loop counter */
83675
83676 memset(&sNC, 0, sizeof(sNC));
83677 memset(&sSrc, 0, sizeof(sSrc));
83678 sSrc.nSrc = 1;
83679 sSrc.a[0].zName = p->zName;
83680 sSrc.a[0].pTab = p;
83681 sSrc.a[0].iCursor = -1;
83682 sNC.pParse = pParse;
83683 sNC.pSrcList = &sSrc;
83684 sNC.ncFlags = NC_IsCheck;
83685 pList = p->pCheck;
83686 for(i=0; i<pList->nExpr; i++){
83687 if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
83688 return;
83689 }
83690 }
83691 }
83692 #endif /* !defined(SQLITE_OMIT_CHECK) */
83693
83694 /* If the db->init.busy is 1 it means we are reading the SQL off the
83695 ** "sqlite_master" or "sqlite_temp_master" table on the disk.
@@ -84537,10 +84789,11 @@
84537 int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
84538 int iSorter; /* Cursor opened by OpenSorter (if in use) */
84539 int addr1; /* Address of top of loop */
84540 int addr2; /* Address to jump to for next iteration */
84541 int tnum; /* Root page of index */
 
84542 Vdbe *v; /* Generate code into this virtual machine */
84543 KeyInfo *pKey; /* KeyInfo for index */
84544 int regRecord; /* Register holding assemblied index record */
84545 sqlite3 *db = pParse->db; /* The database connection */
84546 int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
@@ -84576,12 +84829,13 @@
84576 ** records into the sorter. */
84577 sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
84578 addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
84579 regRecord = sqlite3GetTempReg(pParse);
84580
84581 sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1);
84582 sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
 
84583 sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
84584 sqlite3VdbeJumpHere(v, addr1);
84585 addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
84586 if( pIndex->onError!=OE_None ){
84587 int j2 = sqlite3VdbeCurrentAddr(v) + 3;
@@ -84628,11 +84882,11 @@
84628 Token *pName2, /* Second part of index name. May be NULL */
84629 SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
84630 ExprList *pList, /* A list of columns to be indexed */
84631 int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
84632 Token *pStart, /* The CREATE token that begins this statement */
84633 Token *pEnd, /* The ")" that closes the CREATE INDEX statement */
84634 int sortOrder, /* Sort order of primary key when pList==NULL */
84635 int ifNotExist /* Omit error if index already exists */
84636 ){
84637 Index *pRet = 0; /* Pointer to return */
84638 Table *pTab = 0; /* Table to be indexed */
@@ -84650,11 +84904,10 @@
84650 struct ExprList_item *pListItem; /* For looping over pList */
84651 int nCol;
84652 int nExtra = 0;
84653 char *zExtra;
84654
84655 assert( pStart==0 || pEnd!=0 ); /* pEnd must be non-NULL if pStart is */
84656 assert( pParse->nErr==0 ); /* Never called with prior errors */
84657 if( db->mallocFailed || IN_DECLARE_VTAB ){
84658 goto exit_create_index;
84659 }
84660 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -84696,11 +84949,16 @@
84696 assert(0);
84697 }
84698 pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
84699 assert( db->mallocFailed==0 || pTab==0 );
84700 if( pTab==0 ) goto exit_create_index;
84701 assert( db->aDb[iDb].pSchema==pTab->pSchema );
 
 
 
 
 
84702 }else{
84703 assert( pName==0 );
84704 assert( pStart==0 );
84705 pTab = pParse->pNewTable;
84706 if( !pTab ) goto exit_create_index;
@@ -84845,10 +85103,15 @@
84845 pIndex->nColumn = pList->nExpr;
84846 pIndex->onError = (u8)onError;
84847 pIndex->uniqNotNull = onError==OE_Abort;
84848 pIndex->autoIndex = (u8)(pName==0);
84849 pIndex->pSchema = db->aDb[iDb].pSchema;
 
 
 
 
 
84850 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
84851
84852 /* Check to see if we should honor DESC requests on index columns
84853 */
84854 if( pDb->pSchema->file_format>=4 ){
@@ -85000,11 +85263,11 @@
85000 ** If pTblName==0 it means this index is generated as a primary key
85001 ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
85002 ** has just been created, it contains no data and the index initialization
85003 ** step can be skipped.
85004 */
85005 else{ /* if( db->init.busy==0 ) */
85006 Vdbe *v;
85007 char *zStmt;
85008 int iMem = ++pParse->nMem;
85009
85010 v = sqlite3GetVdbe(pParse);
@@ -85018,16 +85281,15 @@
85018
85019 /* Gather the complete text of the CREATE INDEX statement into
85020 ** the zStmt variable
85021 */
85022 if( pStart ){
85023 assert( pEnd!=0 );
 
85024 /* A named index with an explicit CREATE INDEX statement */
85025 zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
85026 onError==OE_None ? "" : " UNIQUE",
85027 (int)(pEnd->z - pName->z) + 1,
85028 pName->z);
85029 }else{
85030 /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
85031 /* zStmt = sqlite3MPrintf(""); */
85032 zStmt = 0;
85033 }
@@ -85079,14 +85341,12 @@
85079 pIndex = 0;
85080 }
85081
85082 /* Clean up before exiting */
85083 exit_create_index:
85084 if( pIndex ){
85085 sqlite3DbFree(db, pIndex->zColAff);
85086 sqlite3DbFree(db, pIndex);
85087 }
85088 sqlite3ExprListDelete(db, pList);
85089 sqlite3SrcListDelete(db, pTblName);
85090 sqlite3DbFree(db, zName);
85091 return pRet;
85092 }
@@ -85960,29 +86220,24 @@
85960 ** the error.
85961 */
85962 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
85963 int i;
85964 int nCol = pIdx->nColumn;
85965 int nBytes = sizeof(KeyInfo) + (nCol-1)*sizeof(CollSeq*) + nCol;
85966 sqlite3 *db = pParse->db;
85967 KeyInfo *pKey = (KeyInfo *)sqlite3DbMallocZero(db, nBytes);
85968
85969 if( pKey ){
85970 pKey->db = pParse->db;
85971 pKey->aSortOrder = (u8 *)&(pKey->aColl[nCol]);
85972 assert( &pKey->aSortOrder[nCol]==&(((u8 *)pKey)[nBytes]) );
85973 for(i=0; i<nCol; i++){
85974 char *zColl = pIdx->azColl[i];
85975 assert( zColl );
85976 pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
85977 pKey->aSortOrder[i] = pIdx->aSortOrder[i];
85978 }
85979 pKey->nField = (u16)nCol;
85980 }
85981
85982 if( pParse->nErr ){
85983 sqlite3DbFree(db, pKey);
85984 pKey = 0;
85985 }
85986 return pKey;
85987 }
85988
@@ -87058,15 +87313,18 @@
87058 int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
87059 ){
87060 int i;
87061 Index *pIdx;
87062 int r1;
 
 
87063
87064 for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
87065 if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
87066 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0);
87067 sqlite3VdbeAddOp3(pParse->pVdbe, OP_IdxDelete, iCur+i, r1,pIdx->nColumn+1);
 
87068 }
87069 }
87070
87071 /*
87072 ** Generate code that will assemble an index key and put it in register
@@ -87076,24 +87334,42 @@
87076 **
87077 ** Return a register number which is the first in a block of
87078 ** registers that holds the elements of the index key. The
87079 ** block of registers has already been deallocated by the time
87080 ** this routine returns.
 
 
 
 
 
 
 
87081 */
87082 SQLITE_PRIVATE int sqlite3GenerateIndexKey(
87083 Parse *pParse, /* Parsing context */
87084 Index *pIdx, /* The index for which to generate a key */
87085 int iCur, /* Cursor number for the pIdx->pTable table */
87086 int regOut, /* Write the new index key to this register */
87087 int doMakeRec /* Run the OP_MakeRecord instruction if true */
 
87088 ){
87089 Vdbe *v = pParse->pVdbe;
87090 int j;
87091 Table *pTab = pIdx->pTable;
87092 int regBase;
87093 int nCol;
87094
 
 
 
 
 
 
 
 
 
 
87095 nCol = pIdx->nColumn;
87096 regBase = sqlite3GetTempRange(pParse, nCol+1);
87097 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
87098 for(j=0; j<nCol; j++){
87099 int idx = pIdx->aiColumn[j];
@@ -89262,11 +89538,14 @@
89262 sqlite3ReleaseTempReg(pParse, regRec);
89263 sqlite3ReleaseTempRange(pParse, regTemp, nCol);
89264 }
89265 }
89266
89267 if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
 
 
 
89268 /* Special case: If this is an INSERT statement that will insert exactly
89269 ** one row into the table, raise a constraint immediately instead of
89270 ** incrementing a counter. This is necessary as the VM code is being
89271 ** generated for will not open a statement transaction. */
89272 assert( nIncr==1 );
@@ -89653,11 +89932,13 @@
89653 for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
89654 Index *pIdx = 0; /* Foreign key index for pFKey */
89655 SrcList *pSrc;
89656 int *aiCol = 0;
89657
89658 if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){
 
 
89659 assert( regOld==0 && regNew!=0 );
89660 /* Inserting a single row into a parent table cannot cause an immediate
89661 ** foreign key violation. So do nothing in this case. */
89662 continue;
89663 }
@@ -91448,12 +91729,22 @@
91448 ** Add the new records to the indices as we go.
91449 */
91450 for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
91451 int regIdx;
91452 int regR;
 
91453
91454 if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
 
 
 
 
 
 
 
 
 
91455
91456 /* Create a key for accessing the index entry */
91457 regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
91458 for(i=0; i<pIdx->nColumn; i++){
91459 int idx = pIdx->aiColumn[i];
@@ -91470,10 +91761,11 @@
91470
91471 /* Find out what action to take in case there is an indexing conflict */
91472 onError = pIdx->onError;
91473 if( onError==OE_None ){
91474 sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
 
91475 continue; /* pIdx is not a UNIQUE index */
91476 }
91477 if( overrideError!=OE_Default ){
91478 onError = overrideError;
91479 }else if( onError==OE_Default ){
@@ -91539,10 +91831,11 @@
91539 seenReplace = 1;
91540 break;
91541 }
91542 }
91543 sqlite3VdbeJumpHere(v, j3);
 
91544 sqlite3ReleaseTempReg(pParse, regR);
91545 }
91546
91547 if( pbMayReplace ){
91548 *pbMayReplace = seenReplace;
@@ -91568,22 +91861,23 @@
91568 int appendBias, /* True if this is likely to be an append */
91569 int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
91570 ){
91571 int i;
91572 Vdbe *v;
91573 int nIdx;
91574 Index *pIdx;
91575 u8 pik_flags;
91576 int regData;
91577 int regRec;
91578
91579 v = sqlite3GetVdbe(pParse);
91580 assert( v!=0 );
91581 assert( pTab->pSelect==0 ); /* This table is not a VIEW */
91582 for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){}
91583 for(i=nIdx-1; i>=0; i--){
91584 if( aRegIdx[i]==0 ) continue;
 
 
 
91585 sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
91586 if( useSeekResult ){
91587 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
91588 }
91589 }
@@ -91681,10 +91975,11 @@
91681 **
91682 ** * The index is over the same set of columns
91683 ** * The same DESC and ASC markings occurs on all columns
91684 ** * The same onError processing (OE_Abort, OE_Ignore, etc)
91685 ** * The same collating sequence on each column
 
91686 */
91687 static int xferCompatibleIndex(Index *pDest, Index *pSrc){
91688 int i;
91689 assert( pDest && pSrc );
91690 assert( pDest->pTable!=pSrc->pTable );
@@ -91702,10 +91997,13 @@
91702 return 0; /* Different sort orders */
91703 }
91704 if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
91705 return 0; /* Different collating sequences */
91706 }
 
 
 
91707 }
91708
91709 /* If no test above fails then the indices must be compatible */
91710 return 1;
91711 }
@@ -91858,11 +92156,11 @@
91858 if( pSrcIdx==0 ){
91859 return 0; /* pDestIdx has no corresponding index in pSrc */
91860 }
91861 }
91862 #ifndef SQLITE_OMIT_CHECK
91863 if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck, pDest->pCheck) ){
91864 return 0; /* Tables have different CHECK constraints. Ticket #2252 */
91865 }
91866 #endif
91867 #ifndef SQLITE_OMIT_FOREIGN_KEY
91868 /* Disallow the transfer optimization if the destination table constains
@@ -92615,15 +92913,18 @@
92615 #ifndef SQLITE_CORE
92616 /* This case when the file really is being compiled as a loadable
92617 ** extension */
92618 # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
92619 # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
 
 
92620 #else
92621 /* This case when the file is being statically linked into the
92622 ** application */
92623 # define SQLITE_EXTENSION_INIT1 /*no-op*/
92624 # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
 
92625 #endif
92626
92627 #endif /* _SQLITE3EXT_H_ */
92628
92629 /************** End of sqlite3ext.h ******************************************/
@@ -93275,10 +93576,39 @@
93275 sqlite3_mutex_leave(mutex);
93276 assert( (rc&0xff)==rc );
93277 return rc;
93278 }
93279 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93280
93281 /*
93282 ** Reset the automatic extension loading mechanism.
93283 */
93284 SQLITE_API void sqlite3_reset_auto_extension(void){
@@ -93516,10 +93846,11 @@
93516 { "empty_result_callbacks", SQLITE_NullCallback },
93517 { "legacy_file_format", SQLITE_LegacyFileFmt },
93518 { "fullfsync", SQLITE_FullFSync },
93519 { "checkpoint_fullfsync", SQLITE_CkptFullFSync },
93520 { "reverse_unordered_selects", SQLITE_ReverseOrder },
 
93521 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
93522 { "automatic_index", SQLITE_AutoIndex },
93523 #endif
93524 #ifdef SQLITE_DEBUG
93525 { "sql_trace", SQLITE_SqlTrace },
@@ -93536,16 +93867,17 @@
93536 { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
93537
93538 /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
93539 ** flag if there are any active statements. */
93540 { "read_uncommitted", SQLITE_ReadUncommitted },
93541 { "recursive_triggers", SQLITE_RecTriggers },
93542
93543 /* This flag may only be set if both foreign-key and trigger support
93544 ** are present in the build. */
93545 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
93546 { "foreign_keys", SQLITE_ForeignKeys },
 
93547 #endif
93548 };
93549 int i;
93550 const struct sPragmaType *p;
93551 for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
@@ -93567,10 +93899,11 @@
93567
93568 if( sqlite3GetBoolean(zRight, 0) ){
93569 db->flags |= mask;
93570 }else{
93571 db->flags &= ~mask;
 
93572 }
93573
93574 /* Many of the flag-pragmas modify the code generated by the SQL
93575 ** compiler (eg. count_changes). So add an opcode to expire all
93576 ** compiled SQL statements after modifying a pragma value.
@@ -94736,13 +95069,11 @@
94736 cnt++;
94737 }
94738 }
94739
94740 /* Make sure sufficient number of registers have been allocated */
94741 if( pParse->nMem < cnt+4 ){
94742 pParse->nMem = cnt+4;
94743 }
94744
94745 /* Do the b-tree integrity checks */
94746 sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
94747 sqlite3VdbeChangeP5(v, (u8)i);
94748 addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
@@ -94763,16 +95094,19 @@
94763
94764 if( pTab->pIndex==0 ) continue;
94765 addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
94766 sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
94767 sqlite3VdbeJumpHere(v, addr);
 
94768 sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
94769 sqlite3VdbeAddOp2(v, OP_Integer, 0, 2); /* reg(2) will count entries */
94770 loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0);
94771 sqlite3VdbeAddOp2(v, OP_AddImm, 2, 1); /* increment entry count */
 
 
94772 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
94773 int jmp2;
94774 int r1;
94775 static const VdbeOpList idxErr[] = {
94776 { OP_AddImm, 1, -1, 0},
94777 { OP_String8, 0, 3, 0}, /* 1 */
94778 { OP_Rowid, 1, 4, 0},
@@ -94783,47 +95117,38 @@
94783 { OP_Concat, 6, 3, 3},
94784 { OP_ResultRow, 3, 1, 0},
94785 { OP_IfPos, 1, 0, 0}, /* 9 */
94786 { OP_Halt, 0, 0, 0},
94787 };
94788 r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0);
 
94789 jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
94790 addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
94791 sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
94792 sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
94793 sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
94794 sqlite3VdbeJumpHere(v, addr+9);
94795 sqlite3VdbeJumpHere(v, jmp2);
 
94796 }
94797 sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop+1);
94798 sqlite3VdbeJumpHere(v, loopTop);
 
 
 
94799 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
94800 static const VdbeOpList cntIdx[] = {
94801 { OP_Integer, 0, 3, 0},
94802 { OP_Rewind, 0, 0, 0}, /* 1 */
94803 { OP_AddImm, 3, 1, 0},
94804 { OP_Next, 0, 0, 0}, /* 3 */
94805 { OP_Eq, 2, 0, 3}, /* 4 */
94806 { OP_AddImm, 1, -1, 0},
94807 { OP_String8, 0, 2, 0}, /* 6 */
94808 { OP_String8, 0, 3, 0}, /* 7 */
94809 { OP_Concat, 3, 2, 2},
94810 { OP_ResultRow, 2, 1, 0},
94811 };
94812 addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1);
94813 sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
94814 sqlite3VdbeJumpHere(v, addr);
94815 addr = sqlite3VdbeAddOpList(v, ArraySize(cntIdx), cntIdx);
94816 sqlite3VdbeChangeP1(v, addr+1, j+2);
94817 sqlite3VdbeChangeP2(v, addr+1, addr+4);
94818 sqlite3VdbeChangeP1(v, addr+3, j+2);
94819 sqlite3VdbeChangeP2(v, addr+3, addr+2);
94820 sqlite3VdbeJumpHere(v, addr+4);
94821 sqlite3VdbeChangeP4(v, addr+6,
94822 "wrong # of entries in index ", P4_STATIC);
94823 sqlite3VdbeChangeP4(v, addr+7, pIdx->zName, P4_TRANSIENT);
94824 }
94825 }
94826 }
94827 addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
94828 sqlite3VdbeChangeP2(v, addr, -mxErr);
94829 sqlite3VdbeJumpHere(v, addr+1);
@@ -95979,10 +96304,16 @@
95979
95980 assert( ppStmt );
95981 *ppStmt = 0;
95982 if( !sqlite3SafetyCheckOk(db) ){
95983 return SQLITE_MISUSE_BKPT;
 
 
 
 
 
 
95984 }
95985 sqlite3_mutex_enter(db->mutex);
95986 zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
95987 if( zSql8 ){
95988 rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
@@ -96840,10 +97171,29 @@
96840 */
96841 if( pOrderBy==0 && p->iLimit ){
96842 sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
96843 }
96844 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96845
96846 /*
96847 ** Given an expression list, generate a KeyInfo structure that records
96848 ** the collating sequence for each expression in that expression list.
96849 **
@@ -96857,29 +97207,23 @@
96857 ** function is responsible for seeing that this structure is eventually
96858 ** freed. Add the KeyInfo structure to the P4 field of an opcode using
96859 ** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
96860 */
96861 static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
96862 sqlite3 *db = pParse->db;
96863 int nExpr;
96864 KeyInfo *pInfo;
96865 struct ExprList_item *pItem;
 
96866 int i;
96867
96868 nExpr = pList->nExpr;
96869 pInfo = sqlite3DbMallocZero(db, sizeof(*pInfo) + nExpr*(sizeof(CollSeq*)+1) );
96870 if( pInfo ){
96871 pInfo->aSortOrder = (u8*)&pInfo->aColl[nExpr];
96872 pInfo->nField = (u16)nExpr;
96873 pInfo->enc = ENC(db);
96874 pInfo->db = db;
96875 for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
96876 CollSeq *pColl;
96877 pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
96878 if( !pColl ){
96879 pColl = db->pDfltColl;
96880 }
96881 pInfo->aColl[i] = pColl;
96882 pInfo->aSortOrder[i] = pItem->sortOrder;
96883 }
96884 }
96885 return pInfo;
@@ -97981,27 +98325,21 @@
97981 CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
97982 int nCol; /* Number of columns in result set */
97983
97984 assert( p->pRightmost==p );
97985 nCol = p->pEList->nExpr;
97986 pKeyInfo = sqlite3DbMallocZero(db,
97987 sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
97988 if( !pKeyInfo ){
97989 rc = SQLITE_NOMEM;
97990 goto multi_select_end;
97991 }
97992
97993 pKeyInfo->enc = ENC(db);
97994 pKeyInfo->nField = (u16)nCol;
97995
97996 for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
97997 *apColl = multiSelectCollSeq(pParse, p, i);
97998 if( 0==*apColl ){
97999 *apColl = db->pDfltColl;
98000 }
98001 }
98002 pKeyInfo->aSortOrder = (u8*)apColl;
98003
98004 for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
98005 for(i=0; i<2; i++){
98006 int addr = pLoop->addrOpenEphm[i];
98007 if( addr<0 ){
@@ -98366,16 +98704,12 @@
98366 struct ExprList_item *pItem;
98367 for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
98368 assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
98369 aPermute[i] = pItem->iOrderByCol - 1;
98370 }
98371 pKeyMerge =
98372 sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
98373 if( pKeyMerge ){
98374 pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
98375 pKeyMerge->nField = (u16)nOrderBy;
98376 pKeyMerge->enc = ENC(db);
98377 for(i=0; i<nOrderBy; i++){
98378 CollSeq *pColl;
98379 Expr *pTerm = pOrderBy->a[i].pExpr;
98380 if( pTerm->flags & EP_Collate ){
98381 pColl = sqlite3ExprCollSeq(pParse, pTerm);
@@ -98408,16 +98742,12 @@
98408 int nExpr = p->pEList->nExpr;
98409 assert( nOrderBy>=nExpr || db->mallocFailed );
98410 regPrev = pParse->nMem+1;
98411 pParse->nMem += nExpr+1;
98412 sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
98413 pKeyDup = sqlite3DbMallocZero(db,
98414 sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
98415 if( pKeyDup ){
98416 pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
98417 pKeyDup->nField = (u16)nExpr;
98418 pKeyDup->enc = ENC(db);
98419 for(i=0; i<nExpr; i++){
98420 pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
98421 pKeyDup->aSortOrder[i] = 0;
98422 }
98423 }
@@ -99679,14 +100009,16 @@
99679 ** and/or pParse->db->mallocFailed.
99680 */
99681 static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
99682 Walker w;
99683 memset(&w, 0, sizeof(w));
99684 w.xSelectCallback = convertCompoundSelectToSubquery;
99685 w.xExprCallback = exprWalkNoop;
99686 w.pParse = pParse;
99687 sqlite3WalkSelect(&w, pSelect);
 
 
 
99688 w.xSelectCallback = selectExpander;
99689 sqlite3WalkSelect(&w, pSelect);
99690 }
99691
99692
@@ -100216,11 +100548,11 @@
100216 ** will cause elements to come out in the correct order. This is
100217 ** an optimization - the correct answer should result regardless.
100218 ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
100219 ** to disable this optimization for testing purposes.
100220 */
100221 if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy)==0
100222 && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
100223 pOrderBy = 0;
100224 }
100225
100226 /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
@@ -100237,11 +100569,11 @@
100237 ** used for both the ORDER BY and DISTINCT processing. As originally
100238 ** written the query must use a temp-table for at least one of the ORDER
100239 ** BY and DISTINCT, and an index or separate temp-table for the other.
100240 */
100241 if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
100242 && sqlite3ExprListCompare(pOrderBy, p->pEList)==0
100243 ){
100244 p->selFlags &= ~SF_Distinct;
100245 p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
100246 pGroupBy = p->pGroupBy;
100247 pOrderBy = 0;
@@ -102464,11 +102796,11 @@
102464 aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
102465 if( aRegIdx==0 ) goto update_cleanup;
102466 }
102467 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
102468 int reg;
102469 if( hasFK || chngRowid ){
102470 reg = ++pParse->nMem;
102471 }else{
102472 reg = 0;
102473 for(i=0; i<pIdx->nColumn; i++){
102474 if( aXRef[pIdx->aiColumn[i]]>=0 ){
@@ -104070,12 +104402,12 @@
104070 int (*x)(sqlite3_vtab *);
104071 sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
104072 if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
104073 rc = x(pVtab);
104074 sqlite3DbFree(db, *pzErrmsg);
104075 *pzErrmsg = sqlite3DbStrDup(db, pVtab->zErrMsg);
104076 sqlite3_free(pVtab->zErrMsg);
104077 }
104078 }
104079 db->aVTrans = aVTrans;
104080 return rc;
104081 }
@@ -104391,10 +104723,12 @@
104391 typedef struct WhereLoop WhereLoop;
104392 typedef struct WherePath WherePath;
104393 typedef struct WhereTerm WhereTerm;
104394 typedef struct WhereLoopBuilder WhereLoopBuilder;
104395 typedef struct WhereScan WhereScan;
 
 
104396
104397 /*
104398 ** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The
104399 ** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
104400 ** (Virtual tables can return a larger cost, but let's assume they do not.)
@@ -104497,10 +104831,31 @@
104497 u16 nLSlot; /* Number of slots allocated for aLTerm[] */
104498 WhereTerm **aLTerm; /* WhereTerms used */
104499 WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
104500 WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */
104501 };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104502
104503 /* Forward declaration of methods */
104504 static int whereLoopResize(sqlite3*, WhereLoop*, int);
104505
104506 /*
@@ -104712,11 +105067,11 @@
104712 struct WhereLoopBuilder {
104713 WhereInfo *pWInfo; /* Information about this WHERE */
104714 WhereClause *pWC; /* WHERE clause terms */
104715 ExprList *pOrderBy; /* ORDER BY clause */
104716 WhereLoop *pNew; /* Template WhereLoop */
104717 WhereLoop *pBest; /* If non-NULL, store single best loop here */
104718 };
104719
104720 /*
104721 ** The WHERE clause processing routine has two halves. The
104722 ** first part does the start of the WHERE loop and the second
@@ -104854,10 +105209,58 @@
104854 ** UPDATE or DELETE might change subsequent WHERE clause results.
104855 */
104856 SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo){
104857 return pWInfo->okOnePass;
104858 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104859
104860 /*
104861 ** Initialize a preallocated WhereClause structure.
104862 */
104863 static void whereClauseInit(
@@ -104933,11 +105336,11 @@
104933 ** the pWC->a[] array.
104934 */
104935 static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
104936 WhereTerm *pTerm;
104937 int idx;
104938 testcase( wtFlags & TERM_VIRTUAL ); /* EV: R-00211-15100 */
104939 if( pWC->nTerm>=pWC->nSlot ){
104940 WhereTerm *pOld = pWC->a;
104941 sqlite3 *db = pWC->pWInfo->pParse->db;
104942 pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
104943 if( pWC->a==0 ){
@@ -105078,17 +105481,10 @@
105078
105079 /*
105080 ** Return TRUE if the given operator is one of the operators that is
105081 ** allowed for an indexable WHERE clause term. The allowed operators are
105082 ** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
105083 **
105084 ** IMPLEMENTATION-OF: R-59926-26393 To be usable by an index a term must be
105085 ** of one of the following forms: column = expression column > expression
105086 ** column >= expression column < expression column <= expression
105087 ** expression = column expression > column expression >= column
105088 ** expression < column expression <= column column IN
105089 ** (expression-list) column IN (subquery) column IS NULL
105090 */
105091 static int allowedOp(int op){
105092 assert( TK_GT>TK_EQ && TK_GT<TK_GE );
105093 assert( TK_LT>TK_EQ && TK_LT<TK_GE );
105094 assert( TK_LE>TK_EQ && TK_LE<TK_GE );
@@ -105403,11 +105799,11 @@
105403 op = pRight->op2;
105404 }
105405 if( op==TK_VARIABLE ){
105406 Vdbe *pReprepare = pParse->pReprepare;
105407 int iCol = pRight->iColumn;
105408 pVal = sqlite3VdbeGetValue(pReprepare, iCol, SQLITE_AFF_NONE);
105409 if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
105410 z = (char *)sqlite3_value_text(pVal);
105411 }
105412 sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
105413 assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
@@ -105758,12 +106154,10 @@
105758 }
105759
105760 /* At this point, okToChngToIN is true if original pTerm satisfies
105761 ** case 1. In that case, construct a new virtual term that is
105762 ** pTerm converted into an IN operator.
105763 **
105764 ** EV: R-00211-15100
105765 */
105766 if( okToChngToIN ){
105767 Expr *pDup; /* A transient duplicate expression */
105768 ExprList *pList = 0; /* The RHS of the IN operator */
105769 Expr *pLeft = 0; /* The LHS of the IN operator */
@@ -106001,13 +106395,11 @@
106001 ** wildcard. But if we increment '@', that will push it into the
106002 ** alphabetic range where case conversions will mess up the
106003 ** inequality. To avoid this, make sure to also run the full
106004 ** LIKE on all candidate expressions by clearing the isComplete flag
106005 */
106006 if( c=='A'-1 ) isComplete = 0; /* EV: R-64339-08207 */
106007
106008
106009 c = sqlite3UpperToLower[c];
106010 }
106011 *pC = c + 1;
106012 }
106013 sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
@@ -106510,11 +106902,11 @@
106510 VdbeComment((v, "for %s", pTable->zName));
106511
106512 /* Fill the automatic index with content */
106513 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
106514 regRecord = sqlite3GetTempReg(pParse);
106515 sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1);
106516 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
106517 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
106518 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
106519 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
106520 sqlite3VdbeJumpHere(v, addrTop);
@@ -106867,11 +107259,11 @@
106867 if( pExpr->op==TK_VARIABLE
106868 || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
106869 ){
106870 int iVar = pExpr->iColumn;
106871 sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
106872 *pp = sqlite3VdbeGetValue(pParse->pReprepare, iVar, aff);
106873 return SQLITE_OK;
106874 }
106875 return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
106876 }
106877 #endif
@@ -107093,13 +107485,10 @@
107093 **
107094 ** The t2.z='ok' is disabled in the in (2) because it originates
107095 ** in the ON clause. The term is disabled in (3) because it is not part
107096 ** of a LEFT OUTER JOIN. In (1), the term is not disabled.
107097 **
107098 ** IMPLEMENTATION-OF: R-24597-58655 No tests are done for terms that are
107099 ** completely satisfied by indices.
107100 **
107101 ** Disabling a term causes that term to not be tested in the inner loop
107102 ** of the join. Disabling is an optimization. When terms are satisfied
107103 ** by indices, we disable them to prevent redundant tests in the inner
107104 ** loop. We would get the correct results if nothing were ever disabled,
107105 ** but joins might run a little slower. The trick is to disable as much
@@ -107325,11 +107714,11 @@
107325 pTerm = pLoop->aLTerm[j];
107326 assert( pTerm!=0 );
107327 /* The following true for indices with redundant columns.
107328 ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
107329 testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
107330 testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107331 r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
107332 if( r1!=regBase+j ){
107333 if( nReg==1 ){
107334 sqlite3ReleaseTempReg(pParse, regBase);
107335 regBase = r1;
@@ -107525,10 +107914,11 @@
107525 WhereLevel *pLevel; /* The where level to be coded */
107526 WhereLoop *pLoop; /* The WhereLoop object being coded */
107527 WhereClause *pWC; /* Decomposition of the entire WHERE clause */
107528 WhereTerm *pTerm; /* A WHERE clause term */
107529 Parse *pParse; /* Parsing context */
 
107530 Vdbe *v; /* The prepared stmt under constructions */
107531 struct SrcList_item *pTabItem; /* FROM clause term being coded */
107532 int addrBrk; /* Jump here to break out of the loop */
107533 int addrCont; /* Jump here to continue with next cycle */
107534 int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
@@ -107536,10 +107926,11 @@
107536 Bitmask newNotReady; /* Return value */
107537
107538 pParse = pWInfo->pParse;
107539 v = pParse->pVdbe;
107540 pWC = &pWInfo->sWC;
 
107541 pLevel = &pWInfo->a[iLevel];
107542 pLoop = pLevel->pWLoop;
107543 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
107544 iCur = pTabItem->iCursor;
107545 bRev = (pWInfo->revMask>>iLevel)&1;
@@ -107634,11 +108025,11 @@
107634 iReleaseReg = sqlite3GetTempReg(pParse);
107635 pTerm = pLoop->aLTerm[0];
107636 assert( pTerm!=0 );
107637 assert( pTerm->pExpr!=0 );
107638 assert( omitTable==0 );
107639 testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107640 iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
107641 addrNxt = pLevel->addrNxt;
107642 sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
107643 sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
107644 sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
@@ -107682,11 +108073,11 @@
107682 assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
107683 assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
107684 assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
107685
107686 assert( (pStart->wtFlags & TERM_VNULL)==0 );
107687 testcase( pStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107688 pX = pStart->pExpr;
107689 assert( pX!=0 );
107690 testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
107691 r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
107692 sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
@@ -107701,11 +108092,11 @@
107701 Expr *pX;
107702 pX = pEnd->pExpr;
107703 assert( pX!=0 );
107704 assert( (pEnd->wtFlags & TERM_VNULL)==0 );
107705 testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
107706 testcase( pEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107707 memEndValue = ++pParse->nMem;
107708 sqlite3ExprCode(pParse, pX->pRight, memEndValue);
107709 if( pX->op==TK_LT || pX->op==TK_GT ){
107710 testOp = bRev ? OP_Le : OP_Ge;
107711 }else{
@@ -107826,11 +108217,11 @@
107826 /* Generate code to evaluate all constraint terms using == or IN
107827 ** and store the values of those terms in an array of registers
107828 ** starting at regBase.
107829 */
107830 regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
107831 zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
107832 addrNxt = pLevel->addrNxt;
107833
107834 /* If we are doing a reverse order scan on an ascending index, or
107835 ** a forward order scan on a descending index, interchange the
107836 ** start and end terms (pRangeStart and pRangeEnd).
@@ -107867,11 +108258,11 @@
107867 if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
107868 zStartAff[nEq] = SQLITE_AFF_NONE;
107869 }
107870 }
107871 nConstraint++;
107872 testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107873 }else if( isMinQuery ){
107874 sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
107875 nConstraint++;
107876 startEq = 0;
107877 start_constraints = 1;
@@ -107909,14 +108300,14 @@
107909 zEndAff[nEq] = SQLITE_AFF_NONE;
107910 }
107911 }
107912 codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
107913 nConstraint++;
107914 testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); /* EV: R-30575-11662 */
107915 }
107916 sqlite3DbFree(pParse->db, zStartAff);
107917 sqlite3DbFree(pParse->db, zEndAff);
107918
107919 /* Top of the loop body */
107920 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
107921
107922 /* Check if the index cursor is past the end of the range. */
@@ -108039,11 +108430,11 @@
108039 */
108040 if( pWInfo->nLevel>1 ){
108041 int nNotReady; /* The number of notReady tables */
108042 struct SrcList_item *origSrc; /* Original list of tables */
108043 nNotReady = pWInfo->nLevel - iLevel - 1;
108044 pOrTab = sqlite3StackAllocRaw(pParse->db,
108045 sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
108046 if( pOrTab==0 ) return notReady;
108047 pOrTab->nAlloc = (u8)(nNotReady + 1);
108048 pOrTab->nSrc = pOrTab->nAlloc;
108049 memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
@@ -108089,15 +108480,16 @@
108089 */
108090 if( pWC->nTerm>1 ){
108091 int iTerm;
108092 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
108093 Expr *pExpr = pWC->a[iTerm].pExpr;
 
108094 if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
108095 if( pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_ORINFO) ) continue;
108096 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
108097 pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
108098 pAndExpr = sqlite3ExprAnd(pParse->db, pAndExpr, pExpr);
108099 }
108100 if( pAndExpr ){
108101 pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
108102 }
108103 }
@@ -108113,11 +108505,11 @@
108113 }
108114 /* Loop through table entries that match term pOrTerm. */
108115 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
108116 WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
108117 WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
108118 assert( pSubWInfo || pParse->nErr || pParse->db->mallocFailed );
108119 if( pSubWInfo ){
108120 WhereLoop *pSubLoop;
108121 explainOneScan(
108122 pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
108123 );
@@ -108168,17 +108560,17 @@
108168 }
108169 pLevel->u.pCovidx = pCov;
108170 if( pCov ) pLevel->iIdxCur = iCovCur;
108171 if( pAndExpr ){
108172 pAndExpr->pLeft = 0;
108173 sqlite3ExprDelete(pParse->db, pAndExpr);
108174 }
108175 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
108176 sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
108177 sqlite3VdbeResolveLabel(v, iLoopBody);
108178
108179 if( pWInfo->nLevel>1 ) sqlite3StackFree(pParse->db, pOrTab);
108180 if( !untestedTerms ) disableTerm(pLevel, pTerm);
108181 }else
108182 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
108183
108184 {
@@ -108195,18 +108587,14 @@
108195 }
108196 newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
108197
108198 /* Insert code to test every subexpression that can be completely
108199 ** computed using the current set of tables.
108200 **
108201 ** IMPLEMENTATION-OF: R-49525-50935 Terms that cannot be satisfied through
108202 ** the use of indices become tests that are evaluated against each row of
108203 ** the relevant input tables.
108204 */
108205 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
108206 Expr *pE;
108207 testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
108208 testcase( pTerm->wtFlags & TERM_CODED );
108209 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108210 if( (pTerm->prereqAll & newNotReady)!=0 ){
108211 testcase( pWInfo->untestedTerms==0
108212 && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
@@ -108229,13 +108617,12 @@
108229 ** and we are coding the t1 loop and the t2 loop has not yet coded,
108230 ** then we cannot use the "t1.a=t2.b" constraint, but we can code
108231 ** the implied "t1.a=123" constraint.
108232 */
108233 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
108234 Expr *pE;
108235 WhereTerm *pAlt;
108236 Expr sEq;
108237 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108238 if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
108239 if( pTerm->leftCursor!=iCur ) continue;
108240 if( pLevel->iLeftJoin ) continue;
108241 pE = pTerm->pExpr;
@@ -108245,13 +108632,17 @@
108245 if( pAlt==0 ) continue;
108246 if( pAlt->wtFlags & (TERM_CODED) ) continue;
108247 testcase( pAlt->eOperator & WO_EQ );
108248 testcase( pAlt->eOperator & WO_IN );
108249 VdbeNoopComment((v, "begin transitive constraint"));
108250 sEq = *pAlt->pExpr;
108251 sEq.pLeft = pE->pLeft;
108252 sqlite3ExprIfFalse(pParse, &sEq, addrCont, SQLITE_JUMPIFNULL);
 
 
 
 
108253 }
108254
108255 /* For a LEFT OUTER JOIN, generate code that will record the fact that
108256 ** at least one row of the right table has matched the left table.
108257 */
@@ -108259,11 +108650,11 @@
108259 pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
108260 sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
108261 VdbeComment((v, "record LEFT JOIN hit"));
108262 sqlite3ExprCacheClear(pParse);
108263 for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
108264 testcase( pTerm->wtFlags & TERM_VIRTUAL ); /* IMP: R-30575-11662 */
108265 testcase( pTerm->wtFlags & TERM_CODED );
108266 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108267 if( (pTerm->prereqAll & newNotReady)!=0 ){
108268 assert( pWInfo->untestedTerms );
108269 continue;
@@ -108418,16 +108809,16 @@
108418 ** is better and has fewer dependencies. Or the template will be ignored
108419 ** and no insert will occur if an existing WhereLoop is faster and has
108420 ** fewer dependencies than the template. Otherwise a new WhereLoop is
108421 ** added based on the template.
108422 **
108423 ** If pBuilder->pBest is not NULL then we only care about the very
108424 ** best template and that template should be stored in pBuilder->pBest.
108425 ** If pBuilder->pBest is NULL then a list of the best templates are stored
108426 ** in pBuilder->pWInfo->pLoops.
108427 **
108428 ** When accumulating multiple loops (when pBuilder->pBest is NULL) we
108429 ** still might overwrite similar loops with the new template if the
108430 ** template is better. Loops may be overwritten if the following
108431 ** conditions are met:
108432 **
108433 ** (1) They have the same iTab.
@@ -108440,34 +108831,26 @@
108440 static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
108441 WhereLoop **ppPrev, *p, *pNext = 0;
108442 WhereInfo *pWInfo = pBuilder->pWInfo;
108443 sqlite3 *db = pWInfo->pParse->db;
108444
108445 /* If pBuilder->pBest is defined, then only keep track of the single
108446 ** best WhereLoop. pBuilder->pBest->maskSelf==0 indicates that no
108447 ** prior WhereLoops have been evaluated and that the current pTemplate
108448 ** is therefore the first and hence the best and should be retained.
108449 */
108450 if( (p = pBuilder->pBest)!=0 ){
108451 if( p->maskSelf!=0 ){
108452 WhereCost rCost = whereCostAdd(p->rRun,p->rSetup);
108453 WhereCost rTemplate = whereCostAdd(pTemplate->rRun,pTemplate->rSetup);
108454 if( rCost < rTemplate ){
108455 testcase( rCost==rTemplate-1 );
108456 goto whereLoopInsert_noop;
108457 }
108458 if( rCost==rTemplate && (p->prereq & pTemplate->prereq)==p->prereq ){
108459 goto whereLoopInsert_noop;
108460 }
108461 }
108462 #if WHERETRACE_ENABLED
108463 if( sqlite3WhereTrace & 0x8 ){
108464 sqlite3DebugPrintf(p->maskSelf==0 ? "ins-init: " : "ins-best: ");
108465 whereLoopPrint(pTemplate, pWInfo->pTabList);
108466 }
108467 #endif
108468 whereLoopXfer(db, p, pTemplate);
108469 return SQLITE_OK;
108470 }
108471
108472 /* Search for an existing WhereLoop to overwrite, or which takes
108473 ** priority over pTemplate.
@@ -108557,11 +108940,11 @@
108557
108558 /* Jump here if the insert is a no-op */
108559 whereLoopInsert_noop:
108560 #if WHERETRACE_ENABLED
108561 if( sqlite3WhereTrace & 0x8 ){
108562 sqlite3DebugPrintf(pBuilder->pBest ? "ins-skip: " : "ins-noop: ");
108563 whereLoopPrint(pTemplate, pWInfo->pTabList);
108564 }
108565 #endif
108566 return SQLITE_OK;
108567 }
@@ -108708,11 +109091,12 @@
108708 rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
108709 }else if( (pTerm->eOperator & WO_IN)
108710 && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
108711 rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
108712 }
108713 if( rc==SQLITE_OK ) pNew->nOut = whereCost(nOut);
 
108714 }
108715 #endif
108716 if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
108717 /* Each row involves a step of the index, then a binary search of
108718 ** the main table */
@@ -108780,10 +109164,21 @@
108780 if( x<BMS-1 ) m |= MASKBIT(x);
108781 }
108782 return m;
108783 }
108784
 
 
 
 
 
 
 
 
 
 
 
108785
108786 /*
108787 ** Add all WhereLoop objects for a single table of the join where the table
108788 ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
108789 ** a b-tree table, not a virtual table.
@@ -108803,15 +109198,17 @@
108803 int rc = SQLITE_OK; /* Return code */
108804 int iSortIdx = 1; /* Index number */
108805 int b; /* A boolean value */
108806 WhereCost rSize; /* number of rows in the table */
108807 WhereCost rLogSize; /* Logarithm of the number of rows in the table */
 
108808
108809 pNew = pBuilder->pNew;
108810 pWInfo = pBuilder->pWInfo;
108811 pTabList = pWInfo->pTabList;
108812 pSrc = pTabList->a + pNew->iTab;
 
108813 assert( !IsVirtual(pSrc->pTab) );
108814
108815 if( pSrc->pIndex ){
108816 /* An INDEXED BY clause specifies a particular index to use */
108817 pProbe = pSrc->pIndex;
@@ -108839,19 +109236,18 @@
108839 }
108840 rSize = whereCost(pSrc->pTab->nRowEst);
108841 rLogSize = estLog(rSize);
108842
108843 /* Automatic indexes */
108844 if( !pBuilder->pBest
108845 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
108846 && pSrc->pIndex==0
108847 && !pSrc->viaCoroutine
108848 && !pSrc->notIndexed
108849 && !pSrc->isCorrelated
108850 ){
108851 /* Generate auto-index WhereLoops */
108852 WhereClause *pWC = pBuilder->pWC;
108853 WhereTerm *pTerm;
108854 WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
108855 for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
108856 if( pTerm->prereqRight & pNew->maskSelf ) continue;
108857 if( termCanDriveIndex(pTerm, pSrc, 0) ){
@@ -108877,10 +109273,14 @@
108877 }
108878
108879 /* Loop over all indices
108880 */
108881 for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
 
 
 
 
108882 pNew->u.btree.nEq = 0;
108883 pNew->nLTerm = 0;
108884 pNew->iSortIdx = 0;
108885 pNew->rSetup = 0;
108886 pNew->prereq = mExtra;
@@ -109125,11 +109525,11 @@
109125 WhereTerm *pTerm, *pWCEnd;
109126 int rc = SQLITE_OK;
109127 int iCur;
109128 WhereClause tempWC;
109129 WhereLoopBuilder sSubBuild;
109130 WhereLoop sBest;
109131 struct SrcList_item *pItem;
109132
109133 pWC = pBuilder->pWC;
109134 if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
109135 pWCEnd = pWC->a + pWC->nTerm;
@@ -109140,20 +109540,18 @@
109140 && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
109141 ){
109142 WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
109143 WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
109144 WhereTerm *pOrTerm;
109145 WhereCost rTotal = 0;
109146 WhereCost nRow = 0;
109147 Bitmask prereq = mExtra;
109148
109149 whereLoopInit(&sBest);
109150 pItem = pWInfo->pTabList->a + pNew->iTab;
109151 iCur = pItem->iCursor;
109152 sSubBuild = *pBuilder;
109153 sSubBuild.pOrderBy = 0;
109154 sSubBuild.pBest = &sBest;
109155
109156 for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
109157 if( (pOrTerm->eOperator & WO_AND)!=0 ){
109158 sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
109159 }else if( pOrTerm->leftCursor==iCur ){
@@ -109164,43 +109562,52 @@
109164 tempWC.a = pOrTerm;
109165 sSubBuild.pWC = &tempWC;
109166 }else{
109167 continue;
109168 }
109169 sBest.maskSelf = 0;
109170 sBest.rSetup = 0;
109171 sBest.rRun = 0;
109172 #ifndef SQLITE_OMIT_VIRTUALTABLE
109173 if( IsVirtual(pItem->pTab) ){
109174 rc = whereLoopAddVirtual(&sSubBuild);
 
109175 }else
109176 #endif
109177 {
109178 rc = whereLoopAddBtree(&sSubBuild, mExtra);
109179 }
109180 /* sBest.maskSelf is always zero if an error occurs */
109181 assert( rc==SQLITE_OK || sBest.maskSelf==0 );
109182 if( sBest.maskSelf==0 ) break;
109183 assert( sBest.rSetup==0 );
109184 rTotal = whereCostAdd(rTotal, sBest.rRun);
109185 nRow = whereCostAdd(nRow, sBest.nOut);
109186 prereq |= sBest.prereq;
109187 }
109188 assert( pNew->nLSlot>=1 );
109189 if( sBest.maskSelf ){
109190 pNew->nLTerm = 1;
109191 pNew->aLTerm[0] = pTerm;
109192 pNew->wsFlags = WHERE_MULTI_OR;
109193 pNew->rSetup = 0;
 
 
 
 
 
 
 
 
 
 
 
 
109194 /* TUNING: Multiple by 3.5 for the secondary table lookup */
109195 pNew->rRun = rTotal + 18; assert( 18==whereCost(7)-whereCost(2) );
109196 pNew->nOut = nRow;
109197 pNew->prereq = prereq;
109198 memset(&pNew->u, 0, sizeof(pNew->u));
109199 rc = whereLoopInsert(pBuilder, pNew);
109200 }
109201 whereLoopClear(pWInfo->pParse->db, &sBest);
109202 }
109203 }
109204 return rc;
109205 }
109206
@@ -109810,11 +110217,11 @@
109810 pLoop->u.btree.nEq = 1;
109811 /* TUNING: Cost of a rowid lookup is 10 */
109812 pLoop->rRun = 33; /* 33==whereCost(10) */
109813 }else{
109814 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
109815 if( pIdx->onError==OE_None ) continue;
109816 for(j=0; j<pIdx->nColumn; j++){
109817 pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
109818 if( pTerm==0 ) break;
109819 whereLoopResize(pWInfo->pParse->db, pLoop, j);
109820 pLoop->aLTerm[j] = pTerm;
@@ -110003,11 +110410,12 @@
110003 pWInfo->wctrlFlags = wctrlFlags;
110004 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
110005 pMaskSet = &pWInfo->sMaskSet;
110006 sWLB.pWInfo = pWInfo;
110007 sWLB.pWC = &pWInfo->sWC;
110008 sWLB.pNew = (WhereLoop*)&pWInfo->a[nTabList];
 
110009 whereLoopInit(sWLB.pNew);
110010 #ifdef SQLITE_DEBUG
110011 sWLB.pNew->cId = '*';
110012 #endif
110013
@@ -110015,11 +110423,11 @@
110015 ** subexpression is separated by an AND operator.
110016 */
110017 initMaskSet(pMaskSet);
110018 whereClauseInit(&pWInfo->sWC, pWInfo);
110019 sqlite3ExprCodeConstants(pParse, pWhere);
110020 whereSplit(&pWInfo->sWC, pWhere, TK_AND); /* IMP: R-15842-53296 */
110021 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110022
110023 /* Special case: a WHERE clause that is constant. Evaluate the
110024 ** expression and either jump over all of the code or fall thru.
110025 */
@@ -110649,11 +111057,11 @@
110649 #endif
110650 #define sqlite3ParserARG_SDECL Parse *pParse;
110651 #define sqlite3ParserARG_PDECL ,Parse *pParse
110652 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
110653 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
110654 #define YYNSTATE 627
110655 #define YYNRULE 327
110656 #define YYFALLBACK 1
110657 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
110658 #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
110659 #define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
@@ -110722,167 +111130,167 @@
110722 ** shifting non-terminals after a reduce.
110723 ** yy_default[] Default action for each state.
110724 */
110725 #define YY_ACTTAB_COUNT (1564)
110726 static const YYACTIONTYPE yy_action[] = {
110727 /* 0 */ 309, 955, 184, 417, 2, 171, 624, 594, 56, 56,
110728 /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
110729 /* 20 */ 52, 52, 51, 233, 620, 619, 298, 620, 619, 234,
110730 /* 30 */ 587, 581, 56, 56, 56, 56, 19, 54, 54, 54,
110731 /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 605, 57,
110732 /* 50 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110733 /* 60 */ 56, 56, 541, 54, 54, 54, 54, 53, 53, 52,
110734 /* 70 */ 52, 52, 51, 233, 309, 594, 325, 196, 195, 194,
110735 /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110736 /* 90 */ 51, 233, 617, 616, 165, 617, 616, 380, 377, 376,
110737 /* 100 */ 407, 532, 576, 576, 587, 581, 303, 422, 375, 59,
110738 /* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
110739 /* 120 */ 574, 545, 65, 57, 58, 48, 579, 578, 580, 580,
110740 /* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
110741 /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 223,
110742 /* 150 */ 539, 420, 170, 176, 138, 280, 383, 275, 382, 168,
110743 /* 160 */ 489, 551, 409, 668, 620, 619, 271, 438, 409, 438,
110744 /* 170 */ 550, 604, 67, 482, 507, 618, 599, 412, 587, 581,
110745 /* 180 */ 600, 483, 618, 412, 618, 598, 91, 439, 440, 439,
110746 /* 190 */ 335, 598, 73, 669, 222, 266, 480, 57, 58, 48,
110747 /* 200 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
110748 /* 210 */ 670, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110749 /* 220 */ 51, 233, 309, 279, 232, 231, 1, 132, 200, 385,
110750 /* 230 */ 620, 619, 617, 616, 278, 435, 289, 563, 175, 262,
110751 /* 240 */ 409, 264, 437, 497, 436, 166, 441, 568, 336, 568,
110752 /* 250 */ 201, 537, 587, 581, 599, 412, 165, 594, 600, 380,
110753 /* 260 */ 377, 376, 597, 598, 92, 523, 618, 569, 569, 592,
110754 /* 270 */ 375, 57, 58, 48, 579, 578, 580, 580, 55, 55,
110755 /* 280 */ 56, 56, 56, 56, 597, 54, 54, 54, 54, 53,
110756 /* 290 */ 53, 52, 52, 52, 51, 233, 309, 463, 617, 616,
110757 /* 300 */ 590, 590, 590, 174, 272, 396, 409, 272, 409, 548,
110758 /* 310 */ 397, 620, 619, 68, 326, 620, 619, 620, 619, 618,
110759 /* 320 */ 546, 412, 618, 412, 471, 594, 587, 581, 472, 598,
110760 /* 330 */ 92, 598, 92, 52, 52, 52, 51, 233, 513, 512,
110761 /* 340 */ 206, 322, 363, 464, 221, 57, 58, 48, 579, 578,
110762 /* 350 */ 580, 580, 55, 55, 56, 56, 56, 56, 529, 54,
110763 /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
110764 /* 370 */ 309, 396, 409, 396, 597, 372, 386, 530, 347, 617,
110765 /* 380 */ 616, 575, 202, 617, 616, 617, 616, 412, 620, 619,
110766 /* 390 */ 145, 255, 346, 254, 577, 598, 74, 351, 45, 489,
110767 /* 400 */ 587, 581, 235, 189, 464, 544, 167, 296, 187, 469,
110768 /* 410 */ 479, 67, 62, 39, 618, 546, 597, 345, 573, 57,
110769 /* 420 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110770 /* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
110771 /* 440 */ 52, 52, 51, 233, 309, 562, 558, 407, 528, 576,
110772 /* 450 */ 576, 344, 255, 346, 254, 182, 617, 616, 503, 504,
110773 /* 460 */ 314, 409, 557, 235, 166, 271, 409, 352, 564, 181,
110774 /* 470 */ 407, 546, 576, 576, 587, 581, 412, 537, 556, 561,
110775 /* 480 */ 517, 412, 618, 249, 598, 16, 7, 36, 467, 598,
110776 /* 490 */ 92, 516, 618, 57, 58, 48, 579, 578, 580, 580,
110777 /* 500 */ 55, 55, 56, 56, 56, 56, 541, 54, 54, 54,
110778 /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 327,
110779 /* 520 */ 572, 571, 525, 558, 560, 394, 871, 246, 409, 248,
110780 /* 530 */ 171, 392, 594, 219, 407, 409, 576, 576, 502, 557,
110781 /* 540 */ 364, 145, 510, 412, 407, 229, 576, 576, 587, 581,
110782 /* 550 */ 412, 598, 92, 381, 269, 556, 166, 400, 598, 69,
110783 /* 560 */ 501, 419, 945, 199, 945, 198, 546, 57, 58, 48,
110784 /* 570 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
110785 /* 580 */ 568, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110786 /* 590 */ 51, 233, 309, 317, 419, 944, 508, 944, 308, 597,
110787 /* 600 */ 594, 565, 490, 212, 173, 247, 423, 615, 614, 613,
110788 /* 610 */ 323, 197, 143, 405, 572, 571, 489, 66, 50, 47,
110789 /* 620 */ 146, 594, 587, 581, 232, 231, 559, 427, 67, 555,
110790 /* 630 */ 15, 618, 186, 543, 303, 421, 35, 206, 432, 423,
110791 /* 640 */ 552, 57, 58, 48, 579, 578, 580, 580, 55, 55,
110792 /* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
110793 /* 660 */ 53, 52, 52, 52, 51, 233, 309, 569, 569, 260,
110794 /* 670 */ 268, 597, 12, 373, 568, 166, 409, 313, 409, 420,
110795 /* 680 */ 409, 473, 473, 365, 618, 50, 47, 146, 597, 594,
110796 /* 690 */ 468, 412, 166, 412, 351, 412, 587, 581, 32, 598,
110797 /* 700 */ 94, 598, 97, 598, 95, 627, 625, 329, 142, 50,
110798 /* 710 */ 47, 146, 333, 349, 358, 57, 58, 48, 579, 578,
110799 /* 720 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
110800 /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
110801 /* 740 */ 309, 409, 388, 412, 409, 22, 565, 404, 212, 362,
110802 /* 750 */ 389, 598, 104, 359, 409, 156, 412, 409, 603, 412,
110803 /* 760 */ 537, 331, 569, 569, 598, 103, 493, 598, 105, 412,
110804 /* 770 */ 587, 581, 412, 260, 549, 618, 11, 598, 106, 521,
110805 /* 780 */ 598, 133, 169, 457, 456, 170, 35, 601, 618, 57,
110806 /* 790 */ 58, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110807 /* 800 */ 56, 56, 409, 54, 54, 54, 54, 53, 53, 52,
110808 /* 810 */ 52, 52, 51, 233, 309, 409, 259, 412, 409, 50,
110809 /* 820 */ 47, 146, 357, 318, 355, 598, 134, 527, 352, 337,
110810 /* 830 */ 412, 409, 356, 412, 357, 409, 357, 618, 598, 98,
110811 /* 840 */ 129, 598, 102, 618, 587, 581, 412, 21, 235, 618,
110812 /* 850 */ 412, 618, 211, 143, 598, 101, 30, 167, 598, 93,
110813 /* 860 */ 350, 535, 203, 57, 58, 48, 579, 578, 580, 580,
110814 /* 870 */ 55, 55, 56, 56, 56, 56, 409, 54, 54, 54,
110815 /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 309, 409,
110816 /* 890 */ 526, 412, 409, 425, 215, 305, 597, 551, 141, 598,
110817 /* 900 */ 100, 40, 409, 38, 412, 409, 550, 412, 409, 228,
110818 /* 910 */ 220, 314, 598, 77, 500, 598, 96, 412, 587, 581,
110819 /* 920 */ 412, 338, 253, 412, 218, 598, 137, 379, 598, 136,
110820 /* 930 */ 28, 598, 135, 270, 715, 210, 481, 57, 58, 48,
110821 /* 940 */ 579, 578, 580, 580, 55, 55, 56, 56, 56, 56,
110822 /* 950 */ 409, 54, 54, 54, 54, 53, 53, 52, 52, 52,
110823 /* 960 */ 51, 233, 309, 409, 272, 412, 409, 315, 147, 597,
110824 /* 970 */ 272, 626, 2, 598, 76, 209, 409, 127, 412, 618,
110825 /* 980 */ 126, 412, 409, 621, 235, 618, 598, 90, 374, 598,
110826 /* 990 */ 89, 412, 587, 581, 27, 260, 350, 412, 618, 598,
110827 /* 1000 */ 75, 321, 541, 541, 125, 598, 88, 320, 278, 597,
110828 /* 1010 */ 618, 57, 46, 48, 579, 578, 580, 580, 55, 55,
110829 /* 1020 */ 56, 56, 56, 56, 409, 54, 54, 54, 54, 53,
110830 /* 1030 */ 53, 52, 52, 52, 51, 233, 309, 409, 450, 412,
110831 /* 1040 */ 164, 284, 282, 272, 609, 424, 304, 598, 87, 370,
110832 /* 1050 */ 409, 477, 412, 409, 608, 409, 607, 602, 618, 618,
110833 /* 1060 */ 598, 99, 586, 585, 122, 412, 587, 581, 412, 618,
110834 /* 1070 */ 412, 618, 618, 598, 86, 366, 598, 17, 598, 85,
110835 /* 1080 */ 319, 185, 519, 518, 583, 582, 58, 48, 579, 578,
110836 /* 1090 */ 580, 580, 55, 55, 56, 56, 56, 56, 409, 54,
110837 /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
110838 /* 1110 */ 309, 584, 409, 412, 409, 260, 260, 260, 408, 591,
110839 /* 1120 */ 474, 598, 84, 170, 409, 466, 518, 412, 121, 412,
110840 /* 1130 */ 618, 618, 618, 618, 618, 598, 83, 598, 72, 412,
110841 /* 1140 */ 587, 581, 51, 233, 625, 329, 470, 598, 71, 257,
110842 /* 1150 */ 159, 120, 14, 462, 157, 158, 117, 260, 448, 447,
110843 /* 1160 */ 446, 48, 579, 578, 580, 580, 55, 55, 56, 56,
110844 /* 1170 */ 56, 56, 618, 54, 54, 54, 54, 53, 53, 52,
110845 /* 1180 */ 52, 52, 51, 233, 44, 403, 260, 3, 409, 459,
110846 /* 1190 */ 260, 413, 619, 118, 398, 10, 25, 24, 554, 348,
110847 /* 1200 */ 217, 618, 406, 412, 409, 618, 4, 44, 403, 618,
110848 /* 1210 */ 3, 598, 82, 618, 413, 619, 455, 542, 115, 412,
110849 /* 1220 */ 538, 401, 536, 274, 506, 406, 251, 598, 81, 216,
110850 /* 1230 */ 273, 563, 618, 243, 453, 618, 154, 618, 618, 618,
110851 /* 1240 */ 449, 416, 623, 110, 401, 618, 409, 236, 64, 123,
110852 /* 1250 */ 487, 41, 42, 531, 563, 204, 409, 267, 43, 411,
110853 /* 1260 */ 410, 412, 265, 592, 108, 618, 107, 434, 332, 598,
110854 /* 1270 */ 80, 412, 618, 263, 41, 42, 443, 618, 409, 598,
110855 /* 1280 */ 70, 43, 411, 410, 433, 261, 592, 149, 618, 597,
110856 /* 1290 */ 256, 237, 188, 412, 590, 590, 590, 589, 588, 13,
110857 /* 1300 */ 618, 598, 18, 328, 235, 618, 44, 403, 360, 3,
110858 /* 1310 */ 418, 461, 339, 413, 619, 227, 124, 590, 590, 590,
110859 /* 1320 */ 589, 588, 13, 618, 406, 409, 618, 409, 139, 34,
110860 /* 1330 */ 403, 387, 3, 148, 622, 312, 413, 619, 311, 330,
110861 /* 1340 */ 412, 460, 412, 401, 180, 353, 412, 406, 598, 79,
110862 /* 1350 */ 598, 78, 250, 563, 598, 9, 618, 612, 611, 610,
110863 /* 1360 */ 618, 8, 452, 442, 242, 415, 401, 618, 239, 235,
110864 /* 1370 */ 179, 238, 428, 41, 42, 288, 563, 618, 618, 618,
110865 /* 1380 */ 43, 411, 410, 618, 144, 592, 618, 618, 177, 61,
110866 /* 1390 */ 618, 596, 391, 620, 619, 287, 41, 42, 414, 618,
110867 /* 1400 */ 293, 30, 393, 43, 411, 410, 292, 618, 592, 31,
110868 /* 1410 */ 618, 395, 291, 60, 230, 37, 590, 590, 590, 589,
110869 /* 1420 */ 588, 13, 214, 553, 183, 290, 172, 301, 300, 299,
110870 /* 1430 */ 178, 297, 595, 563, 451, 29, 285, 390, 540, 590,
110871 /* 1440 */ 590, 590, 589, 588, 13, 283, 520, 534, 150, 533,
110872 /* 1450 */ 241, 281, 384, 192, 191, 324, 515, 514, 276, 240,
110873 /* 1460 */ 510, 523, 307, 511, 128, 592, 509, 225, 226, 486,
110874 /* 1470 */ 485, 224, 152, 491, 464, 306, 484, 163, 153, 371,
110875 /* 1480 */ 478, 151, 162, 258, 369, 161, 367, 208, 475, 476,
110876 /* 1490 */ 26, 160, 465, 140, 361, 131, 590, 590, 590, 116,
110877 /* 1500 */ 119, 454, 343, 155, 114, 342, 113, 112, 445, 111,
110878 /* 1510 */ 130, 109, 431, 316, 426, 430, 23, 429, 20, 606,
110879 /* 1520 */ 190, 507, 255, 341, 244, 63, 294, 593, 310, 570,
110880 /* 1530 */ 277, 402, 354, 235, 567, 496, 495, 492, 494, 302,
110881 /* 1540 */ 458, 378, 286, 245, 566, 5, 252, 547, 193, 444,
110882 /* 1550 */ 233, 340, 207, 524, 368, 505, 334, 522, 499, 399,
110883 /* 1560 */ 295, 498, 956, 488,
110884 };
110885 static const YYCODETYPE yy_lookahead[] = {
110886 /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
110887 /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
110888 /* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
@@ -111030,21 +111438,21 @@
111030 /* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
111031 /* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
111032 /* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
111033 /* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
111034 /* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
111035 /* 1490 */ 135, 156, 189, 68, 157, 218, 129, 130, 131, 22,
111036 /* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
111037 /* 1510 */ 218, 189, 40, 157, 38, 157, 240, 157, 240, 153,
111038 /* 1520 */ 196, 181, 105, 106, 107, 243, 198, 166, 111, 230,
111039 /* 1530 */ 176, 226, 239, 116, 230, 176, 166, 166, 176, 148,
111040 /* 1540 */ 199, 177, 209, 209, 166, 196, 239, 208, 185, 199,
111041 /* 1550 */ 92, 209, 233, 173, 234, 182, 139, 173, 182, 191,
111042 /* 1560 */ 195, 182, 250, 186,
111043 };
111044 #define YY_SHIFT_USE_DFLT (-70)
111045 #define YY_SHIFT_COUNT (416)
111046 #define YY_SHIFT_MIN (-69)
111047 #define YY_SHIFT_MAX (1487)
111048 static const short yy_shift_ofst[] = {
111049 /* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
111050 /* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
@@ -111057,44 +111465,44 @@
111057 /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
111058 /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
111059 /* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
111060 /* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111061 /* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
111062 /* 130 */ 732, 868, 231, 1051, 1458, -70, -70, -70, 1367, 57,
111063 /* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
111064 /* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111065 /* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111066 /* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111067 /* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
111068 /* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
111069 /* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
111070 /* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
111071 /* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
111072 /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1476, 1308, 1308,
111073 /* 240 */ 1472, 1472, 1308, 1477, 1425, 1275, 1487, 1487, 1487, 1487,
111074 /* 250 */ 1308, 1461, 1275, 1477, 1425, 1425, 1308, 1461, 1355, 1441,
111075 /* 260 */ 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348, 1348,
111076 /* 270 */ 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408, 1348,
111077 /* 280 */ 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308, 1280,
111078 /* 290 */ 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346, 1338,
111079 /* 300 */ 1338, 1338, 1338, -70, -70, -70, -70, -70, -70, 1013,
111080 /* 310 */ 467, 612, 84, 179, -28, 870, 410, 761, 760, 667,
111081 /* 320 */ 650, 531, 220, 361, 331, 125, 127, 97, 1306, 1300,
111082 /* 330 */ 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174, 1139,
111083 /* 340 */ 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184, 1174,
111084 /* 350 */ 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152, 1147,
111085 /* 360 */ 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960, 1057,
111086 /* 370 */ 1031, 1030, 899, 938, 982, 936, 972, 958, 910, 955,
111087 /* 380 */ 875, 885, 908, 857, 859, 867, 804, 590, 834, 747,
111088 /* 390 */ 818, 513, 611, 741, 673, 637, 611, 606, 603, 579,
111089 /* 400 */ 501, 541, 468, 386, 445, 395, 376, 281, 185, 120,
111090 /* 410 */ 92, 75, 45, 114, 25, 11, 5,
111091 };
111092 #define YY_REDUCE_USE_DFLT (-169)
111093 #define YY_REDUCE_COUNT (308)
111094 #define YY_REDUCE_MIN (-168)
111095 #define YY_REDUCE_MAX (1391)
111096 static const short yy_reduce_ofst[] = {
111097 /* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
111098 /* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
111099 /* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
111100 /* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
@@ -111111,87 +111519,87 @@
111111 /* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
111112 /* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
111113 /* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
111114 /* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
111115 /* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
111116 /* 190 */ -168, 1384, 1380, 1377, 1379, 1376, 1373, 1339, 1365, 1368,
111117 /* 200 */ 1365, 1365, 1365, 1365, 1365, 1365, 1365, 1320, 1319, 1365,
111118 /* 210 */ 1365, 1339, 1378, 1349, 1391, 1350, 1342, 1334, 1307, 1341,
111119 /* 220 */ 1293, 1364, 1363, 1371, 1362, 1370, 1359, 1340, 1354, 1333,
111120 /* 230 */ 1305, 1304, 1299, 1361, 1328, 1324, 1366, 1282, 1360, 1358,
111121 /* 240 */ 1278, 1276, 1356, 1292, 1322, 1309, 1317, 1315, 1314, 1312,
111122 /* 250 */ 1345, 1347, 1302, 1277, 1311, 1303, 1337, 1335, 1252, 1248,
111123 /* 260 */ 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301, 1295,
111124 /* 270 */ 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274, 1281,
111125 /* 280 */ 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266, 1189,
111126 /* 290 */ 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219, 1216,
111127 /* 300 */ 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
111128 };
111129 static const YYACTIONTYPE yy_default[] = {
111130 /* 0 */ 632, 866, 954, 954, 866, 866, 954, 954, 954, 756,
111131 /* 10 */ 954, 954, 954, 864, 954, 954, 784, 784, 928, 954,
111132 /* 20 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111133 /* 30 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111134 /* 40 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111135 /* 50 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111136 /* 60 */ 954, 954, 954, 954, 954, 954, 954, 671, 760, 790,
111137 /* 70 */ 954, 954, 954, 954, 954, 954, 954, 954, 927, 929,
111138 /* 80 */ 798, 797, 907, 771, 795, 788, 792, 867, 860, 861,
111139 /* 90 */ 859, 863, 868, 954, 791, 827, 844, 826, 838, 843,
111140 /* 100 */ 850, 842, 839, 829, 828, 830, 831, 954, 954, 954,
111141 /* 110 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111142 /* 120 */ 954, 954, 954, 658, 725, 954, 954, 954, 954, 954,
111143 /* 130 */ 954, 954, 954, 832, 833, 847, 846, 845, 954, 663,
111144 /* 140 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111145 /* 150 */ 934, 932, 954, 879, 954, 954, 954, 954, 954, 954,
111146 /* 160 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111147 /* 170 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111148 /* 180 */ 638, 756, 756, 756, 632, 954, 954, 954, 946, 760,
111149 /* 190 */ 750, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111150 /* 200 */ 954, 954, 954, 800, 739, 917, 919, 954, 900, 737,
111151 /* 210 */ 660, 758, 673, 748, 640, 794, 773, 773, 912, 794,
111152 /* 220 */ 912, 696, 719, 954, 784, 954, 784, 693, 784, 773,
111153 /* 230 */ 862, 954, 954, 954, 757, 748, 954, 939, 764, 764,
111154 /* 240 */ 931, 931, 764, 806, 729, 794, 736, 736, 736, 736,
111155 /* 250 */ 764, 655, 794, 806, 729, 729, 764, 655, 906, 904,
111156 /* 260 */ 764, 764, 655, 764, 655, 764, 655, 872, 727, 727,
111157 /* 270 */ 727, 711, 876, 876, 872, 727, 696, 727, 711, 727,
111158 /* 280 */ 727, 777, 772, 777, 772, 777, 772, 764, 764, 954,
111159 /* 290 */ 789, 778, 787, 785, 794, 954, 714, 648, 648, 637,
111160 /* 300 */ 637, 637, 637, 951, 951, 946, 698, 698, 681, 954,
111161 /* 310 */ 954, 954, 954, 954, 954, 954, 881, 954, 954, 954,
111162 /* 320 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 633,
111163 /* 330 */ 941, 954, 954, 938, 954, 954, 954, 954, 799, 954,
111164 /* 340 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 916,
111165 /* 350 */ 954, 954, 954, 954, 954, 954, 954, 910, 954, 954,
111166 /* 360 */ 954, 954, 954, 954, 903, 902, 954, 954, 954, 954,
111167 /* 370 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111168 /* 380 */ 954, 954, 954, 954, 954, 954, 954, 954, 954, 954,
111169 /* 390 */ 954, 954, 786, 954, 779, 954, 865, 954, 954, 954,
111170 /* 400 */ 954, 954, 954, 954, 954, 954, 954, 742, 815, 954,
111171 /* 410 */ 814, 818, 813, 665, 954, 646, 954, 629, 634, 950,
111172 /* 420 */ 953, 952, 949, 948, 947, 942, 940, 937, 936, 935,
111173 /* 430 */ 933, 930, 926, 885, 883, 890, 889, 888, 887, 886,
111174 /* 440 */ 884, 882, 880, 801, 796, 793, 925, 878, 738, 735,
111175 /* 450 */ 734, 654, 943, 909, 918, 805, 804, 807, 915, 914,
111176 /* 460 */ 913, 911, 908, 895, 803, 802, 730, 870, 869, 657,
111177 /* 470 */ 899, 898, 897, 901, 905, 896, 766, 656, 653, 662,
111178 /* 480 */ 717, 718, 726, 724, 723, 722, 721, 720, 716, 664,
111179 /* 490 */ 672, 710, 695, 694, 875, 877, 874, 873, 703, 702,
111180 /* 500 */ 708, 707, 706, 705, 704, 701, 700, 699, 692, 691,
111181 /* 510 */ 697, 690, 713, 712, 709, 689, 733, 732, 731, 728,
111182 /* 520 */ 688, 687, 686, 818, 685, 684, 824, 823, 811, 854,
111183 /* 530 */ 753, 752, 751, 763, 762, 775, 774, 809, 808, 776,
111184 /* 540 */ 761, 755, 754, 770, 769, 768, 767, 759, 749, 781,
111185 /* 550 */ 783, 782, 780, 856, 765, 853, 924, 923, 922, 921,
111186 /* 560 */ 920, 858, 857, 825, 822, 676, 677, 893, 892, 894,
111187 /* 570 */ 891, 679, 678, 675, 674, 855, 744, 743, 851, 848,
111188 /* 580 */ 840, 836, 852, 849, 841, 837, 835, 834, 820, 819,
111189 /* 590 */ 817, 816, 812, 821, 667, 745, 741, 740, 810, 747,
111190 /* 600 */ 746, 683, 682, 680, 661, 659, 652, 650, 649, 651,
111191 /* 610 */ 647, 645, 644, 643, 642, 641, 670, 669, 668, 666,
111192 /* 620 */ 665, 639, 636, 635, 631, 630, 628,
111193 };
111194
111195 /* The next table maps tokens into fallback tokens. If a construct
111196 ** like the following:
111197 **
@@ -111659,11 +112067,11 @@
111659 /* 237 */ "case_operand ::=",
111660 /* 238 */ "exprlist ::= nexprlist",
111661 /* 239 */ "exprlist ::=",
111662 /* 240 */ "nexprlist ::= nexprlist COMMA expr",
111663 /* 241 */ "nexprlist ::= expr",
111664 /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP",
111665 /* 243 */ "uniqueflag ::= UNIQUE",
111666 /* 244 */ "uniqueflag ::=",
111667 /* 245 */ "idxlist_opt ::=",
111668 /* 246 */ "idxlist_opt ::= LP idxlist RP",
111669 /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
@@ -112378,11 +112786,11 @@
112378 { 224, 0 },
112379 { 220, 1 },
112380 { 220, 0 },
112381 { 215, 3 },
112382 { 215, 1 },
112383 { 147, 11 },
112384 { 227, 1 },
112385 { 227, 0 },
112386 { 178, 0 },
112387 { 178, 3 },
112388 { 187, 5 },
@@ -112820,10 +113228,11 @@
112820 case 114: /* select ::= select multiselect_op oneselect */
112821 {
112822 if( yymsp[0].minor.yy159 ){
112823 yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
112824 yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
 
112825 }else{
112826 sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
112827 }
112828 yygotominor.yy159 = yymsp[0].minor.yy159;
112829 }
@@ -113382,15 +113791,15 @@
113382 {yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
113383 break;
113384 case 241: /* nexprlist ::= expr */
113385 {yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
113386 break;
113387 case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
113388 {
113389 sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0,
113390 sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy442, yymsp[-9].minor.yy392,
113391 &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy392);
113392 }
113393 break;
113394 case 243: /* uniqueflag ::= UNIQUE */
113395 case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
113396 {yygotominor.yy392 = OE_Abort;}
@@ -114312,11 +114721,10 @@
114312 *tokenType = TK_SPACE;
114313 return i;
114314 }
114315 case '-': {
114316 if( z[1]=='-' ){
114317 /* IMP: R-50417-27976 -- syntax diagram for comments */
114318 for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
114319 *tokenType = TK_SPACE; /* IMP: R-22934-25134 */
114320 return i;
114321 }
114322 *tokenType = TK_MINUS;
@@ -114345,11 +114753,10 @@
114345 case '/': {
114346 if( z[1]!='*' || z[2]==0 ){
114347 *tokenType = TK_SLASH;
114348 return 1;
114349 }
114350 /* IMP: R-50417-27976 -- syntax diagram for comments */
114351 for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
114352 if( c ) i++;
114353 *tokenType = TK_SPACE; /* IMP: R-22934-25134 */
114354 return i;
114355 }
@@ -116127,10 +116534,12 @@
116127 }
116128 sqlite3BtreeLeaveAll(db);
116129
116130 /* Any deferred constraint violations have now been resolved. */
116131 db->nDeferredCons = 0;
 
 
116132
116133 /* If one has been configured, invoke the rollback-hook callback */
116134 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
116135 db->xRollbackCallback(db->pRollbackArg);
116136 }
@@ -116188,10 +116597,11 @@
116188 case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break;
116189 case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break;
116190 case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
116191 case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
116192 case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
 
116193 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
116194 case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
116195 case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
116196 case SQLITE_FULL: zName = "SQLITE_FULL"; break;
116197 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
@@ -116388,11 +116798,11 @@
116388 void *pArg
116389 ){
116390 sqlite3_mutex_enter(db->mutex);
116391 if( nOps>0 ){
116392 db->xProgress = xProgress;
116393 db->nProgressOps = nOps;
116394 db->pProgressArg = pArg;
116395 }else{
116396 db->xProgress = 0;
116397 db->nProgressOps = 0;
116398 db->pProgressArg = 0;
@@ -117543,11 +117953,11 @@
117543 db->autoCommit = 1;
117544 db->nextAutovac = -1;
117545 db->szMmap = sqlite3GlobalConfig.szMmap;
117546 db->nextPagesize = 0;
117547 db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
117548 #if !defined(SQLITE_DEAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
117549 | SQLITE_AutoIndex
117550 #endif
117551 #if SQLITE_DEFAULT_FILE_FORMAT<4
117552 | SQLITE_LegacyFileFmt
117553 #endif
@@ -119087,11 +119497,11 @@
119087
119088 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
119089
119090 /* If not building as part of the core, include sqlite3ext.h. */
119091 #ifndef SQLITE_CORE
119092 SQLITE_API extern const sqlite3_api_routines *sqlite3_api;
119093 #endif
119094
119095 /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
119096 /************** Begin file fts3_tokenizer.h **********************************/
119097 /*
@@ -124995,11 +125405,14 @@
124995
124996 #if !SQLITE_CORE
124997 /*
124998 ** Initialize API pointer table, if required.
124999 */
125000 SQLITE_API int sqlite3_extension_init(
 
 
 
125001 sqlite3 *db,
125002 char **pzErrMsg,
125003 const sqlite3_api_routines *pApi
125004 ){
125005 SQLITE_EXTENSION_INIT2(pApi)
@@ -128013,11 +128426,11 @@
128013 }
128014
128015
128016 #ifdef SQLITE_TEST
128017
128018 /* #include <tcl.h> */
128019 /* #include <string.h> */
128020
128021 /*
128022 ** Implementation of a special SQL scalar function for testing tokenizers
128023 ** designed to be used in concert with the Tcl testing framework. This
@@ -140042,11 +140455,14 @@
140042 (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
140043 );
140044 }
140045
140046 #if !SQLITE_CORE
140047 SQLITE_API int sqlite3_extension_init(
 
 
 
140048 sqlite3 *db,
140049 char **pzErrMsg,
140050 const sqlite3_api_routines *pApi
140051 ){
140052 SQLITE_EXTENSION_INIT2(pApi)
@@ -140544,11 +140960,14 @@
140544
140545 return rc;
140546 }
140547
140548 #if !SQLITE_CORE
140549 SQLITE_API int sqlite3_extension_init(
 
 
 
140550 sqlite3 *db,
140551 char **pzErrMsg,
140552 const sqlite3_api_routines *pApi
140553 ){
140554 SQLITE_EXTENSION_INIT2(pApi)
140555
--- src/sqlite3.c
+++ src/sqlite3.c
@@ -399,13 +399,10 @@
399 ** On Windows, if the SQLITE_WIN32_MALLOC_VALIDATE macro is defined and the
400 ** assert() macro is enabled, each call into the Win32 native heap subsystem
401 ** will cause HeapValidate to be called. If heap validation should fail, an
402 ** assertion will be triggered.
403 **
 
 
 
404 ** If none of the above are defined, then set SQLITE_SYSTEM_MALLOC as
405 ** the default.
406 */
407 #if defined(SQLITE_SYSTEM_MALLOC) \
408 + defined(SQLITE_WIN32_MALLOC) \
@@ -439,24 +436,17 @@
436 */
437 #if !defined(_XOPEN_SOURCE) && !defined(__DARWIN__) && !defined(__APPLE__)
438 # define _XOPEN_SOURCE 600
439 #endif
440
 
 
 
 
 
 
 
441 /*
442 ** NDEBUG and SQLITE_DEBUG are opposites. It should always be true that
443 ** defined(NDEBUG)==!defined(SQLITE_DEBUG). If this is not currently true,
444 ** make it true by defining or undefining NDEBUG.
445 **
446 ** Setting NDEBUG makes the code smaller and faster by disabling the
447 ** assert() statements in the code. So we want the default action
448 ** to be for NDEBUG to be set and NDEBUG to be undefined only if SQLITE_DEBUG
449 ** is set. Thus NDEBUG becomes an opt-in rather than an opt-out
450 ** feature.
451 */
452 #if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
@@ -522,11 +512,11 @@
512 ** hint of unplanned behavior.
513 **
514 ** In other words, ALWAYS and NEVER are added for defensive code.
515 **
516 ** When doing coverage testing ALWAYS and NEVER are hard-coded to
517 ** be true and false so that the unreachable code they specify will
518 ** not be counted as untested code.
519 */
520 #if defined(SQLITE_COVERAGE_TEST)
521 # define ALWAYS(X) (1)
522 # define NEVER(X) (0)
@@ -546,20 +536,16 @@
536 #define IS_BIG_INT(X) (((X)&~(i64)0xffffffff)!=0)
537
538 /*
539 ** The macro unlikely() is a hint that surrounds a boolean
540 ** expression that is usually false. Macro likely() surrounds
541 ** a boolean expression that is usually true. These hints could,
542 ** in theory, be used by the compiler to generate better code, but
543 ** currently they are just comments for human readers.
544 */
545 #define likely(X) (X)
546 #define unlikely(X) (X)
 
 
 
 
 
547
548 /************** Include sqlite3.h in the middle of sqliteInt.h ***************/
549 /************** Begin file sqlite3.h *****************************************/
550 /*
551 ** 2001 September 15
@@ -670,11 +656,11 @@
656 ** [sqlite3_libversion_number()], [sqlite3_sourceid()],
657 ** [sqlite_version()] and [sqlite_source_id()].
658 */
659 #define SQLITE_VERSION "3.8.0"
660 #define SQLITE_VERSION_NUMBER 3008000
661 #define SQLITE_SOURCE_ID "2013-08-06 07:45:08 924f7e4d7a8fa2fe9100836663f3733b6e1a9084"
662
663 /*
664 ** CAPI3REF: Run-Time Library Version Numbers
665 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
666 **
@@ -1039,10 +1025,11 @@
1025 #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
1026 #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
1027 #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
1028 #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
1029 #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
1030 #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
1031 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
1032 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
1033 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
1034 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
1035 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -3120,13 +3107,14 @@
3107 ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
3108 ** database connection D. An example use for this
3109 ** interface is to keep a GUI updated during a large query.
3110 **
3111 ** ^The parameter P is passed through as the only parameter to the
3112 ** callback function X. ^The parameter N is the approximate number of
3113 ** [virtual machine instructions] that are evaluated between successive
3114 ** invocations of the callback X. ^If N is less than one then the progress
3115 ** handler is disabled.
3116 **
3117 ** ^Only a single progress handler may be defined at one time per
3118 ** [database connection]; setting a new progress handler cancels the
3119 ** old one. ^Setting parameter X to NULL disables the progress handler.
3120 ** ^The progress handler is also disabled by setting N to a value less
@@ -4742,45 +4730,53 @@
4730 SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
4731
4732 /*
4733 ** CAPI3REF: Function Auxiliary Data
4734 **
4735 ** These functions may be used by (non-aggregate) SQL functions to
4736 ** associate metadata with argument values. If the same value is passed to
4737 ** multiple invocations of the same SQL function during query execution, under
4738 ** some circumstances the associated metadata may be preserved. An example
4739 ** of where this might be useful is in a regular-expression matching
4740 ** function. The compiled version of the regular expression can be stored as
4741 ** metadata associated with the pattern string.
4742 ** Then as long as the pattern string remains the same,
4743 ** the compiled regular expression can be reused on multiple
4744 ** invocations of the same function.
4745 **
4746 ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
4747 ** associated by the sqlite3_set_auxdata() function with the Nth argument
4748 ** value to the application-defined function. ^If there is no metadata
4749 ** associated with the function argument, this sqlite3_get_auxdata() interface
4750 ** returns a NULL pointer.
4751 **
4752 ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
4753 ** argument of the application-defined function. ^Subsequent
4754 ** calls to sqlite3_get_auxdata(C,N) return P from the most recent
4755 ** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
4756 ** NULL if the metadata has been discarded.
4757 ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
4758 ** SQLite will invoke the destructor function X with parameter P exactly
4759 ** once, when the metadata is discarded.
4760 ** SQLite is free to discard the metadata at any time, including: <ul>
4761 ** <li> when the corresponding function parameter changes, or
4762 ** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
4763 ** SQL statement, or
4764 ** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
4765 ** <li> during the original sqlite3_set_auxdata() call when a memory
4766 ** allocation error occurs. </ul>)^
4767 **
4768 ** Note the last bullet in particular. The destructor X in
4769 ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
4770 ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
4771 ** should be called near the end of the function implementation and the
4772 ** function implementation should not make any use of P after
4773 ** sqlite3_set_auxdata() has been called.
4774 **
4775 ** ^(In practice, metadata is preserved between function calls for
4776 ** function parameters that are compile-time constants, including literal
4777 ** values and [parameters] and expressions composed from the same.)^
4778 **
4779 ** These routines must be called from the same thread in which
4780 ** the SQL function is running.
4781 */
4782 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
@@ -5689,14 +5685,27 @@
5685 **
5686 ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
5687 ** on the list of automatic extensions is a harmless no-op. ^No entry point
5688 ** will be called more than once for each database connection that is opened.
5689 **
5690 ** See also: [sqlite3_reset_auto_extension()]
5691 ** and [sqlite3_cancel_auto_extension()]
5692 */
5693 SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
5694
5695 /*
5696 ** CAPI3REF: Cancel Automatic Extension Loading
5697 **
5698 ** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
5699 ** initialization routine X that was registered using a prior call to
5700 ** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
5701 ** routine returns 1 if initialization routine X was successfully
5702 ** unregistered and it returns 0 if X was not on the list of initialization
5703 ** routines.
5704 */
5705 SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
5706
5707 /*
5708 ** CAPI3REF: Reset Automatic Extension Loading
5709 **
5710 ** ^This interface disables all automatic extensions previously
5711 ** registered using [sqlite3_auto_extension()].
@@ -6805,10 +6814,16 @@
6814 ** transaction rollback or database recovery operations are not included.
6815 ** If an IO or other error occurs while writing a page to disk, the effect
6816 ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
6817 ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
6818 ** </dd>
6819 **
6820 ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
6821 ** <dd>This parameter returns zero for the current value if and only if
6822 ** all foreign key constraints (deferred or immediate) have been
6823 ** resolved.)^ ^The highwater mark is always 0.
6824 ** </dd>
6825 ** </dl>
6826 */
6827 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
6828 #define SQLITE_DBSTATUS_CACHE_USED 1
6829 #define SQLITE_DBSTATUS_SCHEMA_USED 2
@@ -6817,11 +6832,12 @@
6832 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
6833 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6834 #define SQLITE_DBSTATUS_CACHE_HIT 7
6835 #define SQLITE_DBSTATUS_CACHE_MISS 8
6836 #define SQLITE_DBSTATUS_CACHE_WRITE 9
6837 #define SQLITE_DBSTATUS_DEFERRED_FKS 10
6838 #define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
6839
6840
6841 /*
6842 ** CAPI3REF: Prepared Statement Status
6843 **
@@ -8795,11 +8811,10 @@
8811
8812 /*
8813 ** The names of the following types declared in vdbeInt.h are required
8814 ** for the VdbeOp definition.
8815 */
 
8816 typedef struct Mem Mem;
8817 typedef struct SubProgram SubProgram;
8818
8819 /*
8820 ** A single instruction of the virtual machine has an opcode
@@ -8819,11 +8834,10 @@
8834 void *p; /* Generic pointer */
8835 char *z; /* Pointer to data for string (char array) types */
8836 i64 *pI64; /* Used when p4type is P4_INT64 */
8837 double *pReal; /* Used when p4type is P4_REAL */
8838 FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */
 
8839 CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */
8840 Mem *pMem; /* Used when p4type is P4_MEM */
8841 VTable *pVtab; /* Used when p4type is P4_VTAB */
8842 KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */
8843 int *ai; /* Used when p4type is P4_INTARRAY */
@@ -8873,11 +8887,10 @@
8887 #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */
8888 #define P4_STATIC (-2) /* Pointer to a static string */
8889 #define P4_COLLSEQ (-4) /* P4 is a pointer to a CollSeq structure */
8890 #define P4_FUNCDEF (-5) /* P4 is a pointer to a FuncDef structure */
8891 #define P4_KEYINFO (-6) /* P4 is a pointer to a KeyInfo structure */
 
8892 #define P4_MEM (-8) /* P4 is a pointer to a Mem* structure */
8893 #define P4_TRANSIENT 0 /* P4 is a pointer to a transient string */
8894 #define P4_VTAB (-10) /* P4 is a pointer to an sqlite3_vtab structure */
8895 #define P4_MPRINTF (-11) /* P4 is a string obtained from sqlite3_mprintf() */
8896 #define P4_REAL (-12) /* P4 is a 64-bit floating point value */
@@ -8930,155 +8943,155 @@
8943 */
8944 /************** Include opcodes.h in the middle of vdbe.h ********************/
8945 /************** Begin file opcodes.h *****************************************/
8946 /* Automatically generated. Do not edit */
8947 /* See the mkopcodeh.awk script for details */
8948 #define OP_Function 1
8949 #define OP_Savepoint 2
8950 #define OP_AutoCommit 3
8951 #define OP_Transaction 4
8952 #define OP_SorterNext 5
8953 #define OP_Prev 6
8954 #define OP_Next 7
8955 #define OP_AggStep 8
8956 #define OP_Checkpoint 9
8957 #define OP_JournalMode 10
8958 #define OP_Vacuum 11
8959 #define OP_VFilter 12
8960 #define OP_VUpdate 13
8961 #define OP_Goto 14
8962 #define OP_Gosub 15
8963 #define OP_Return 16
8964 #define OP_Yield 17
8965 #define OP_HaltIfNull 18
8966 #define OP_Not 19 /* same as TK_NOT */
8967 #define OP_Halt 20
8968 #define OP_Integer 21
8969 #define OP_Int64 22
8970 #define OP_String 23
8971 #define OP_Null 24
8972 #define OP_Blob 25
8973 #define OP_Variable 26
8974 #define OP_Move 27
8975 #define OP_Copy 28
8976 #define OP_SCopy 29
8977 #define OP_ResultRow 30
8978 #define OP_CollSeq 31
8979 #define OP_AddImm 32
8980 #define OP_MustBeInt 33
8981 #define OP_RealAffinity 34
8982 #define OP_Permutation 35
8983 #define OP_Compare 36
8984 #define OP_Jump 37
8985 #define OP_Once 38
8986 #define OP_If 39
8987 #define OP_IfNot 40
8988 #define OP_Column 41
8989 #define OP_Affinity 42
8990 #define OP_MakeRecord 43
8991 #define OP_Count 44
8992 #define OP_ReadCookie 45
8993 #define OP_SetCookie 46
8994 #define OP_VerifyCookie 47
8995 #define OP_OpenRead 48
8996 #define OP_OpenWrite 49
8997 #define OP_OpenAutoindex 50
8998 #define OP_OpenEphemeral 51
8999 #define OP_SorterOpen 52
9000 #define OP_OpenPseudo 53
9001 #define OP_Close 54
9002 #define OP_SeekLt 55
9003 #define OP_SeekLe 56
9004 #define OP_SeekGe 57
9005 #define OP_SeekGt 58
9006 #define OP_Seek 59
9007 #define OP_NotFound 60
9008 #define OP_Found 61
9009 #define OP_IsUnique 62
9010 #define OP_NotExists 63
9011 #define OP_Sequence 64
9012 #define OP_NewRowid 65
9013 #define OP_Insert 66
9014 #define OP_InsertInt 67
9015 #define OP_Or 68 /* same as TK_OR */
9016 #define OP_And 69 /* same as TK_AND */
9017 #define OP_Delete 70
9018 #define OP_ResetCount 71
9019 #define OP_SorterCompare 72
9020 #define OP_IsNull 73 /* same as TK_ISNULL */
9021 #define OP_NotNull 74 /* same as TK_NOTNULL */
9022 #define OP_Ne 75 /* same as TK_NE */
9023 #define OP_Eq 76 /* same as TK_EQ */
9024 #define OP_Gt 77 /* same as TK_GT */
9025 #define OP_Le 78 /* same as TK_LE */
9026 #define OP_Lt 79 /* same as TK_LT */
9027 #define OP_Ge 80 /* same as TK_GE */
9028 #define OP_SorterData 81
9029 #define OP_BitAnd 82 /* same as TK_BITAND */
9030 #define OP_BitOr 83 /* same as TK_BITOR */
9031 #define OP_ShiftLeft 84 /* same as TK_LSHIFT */
9032 #define OP_ShiftRight 85 /* same as TK_RSHIFT */
9033 #define OP_Add 86 /* same as TK_PLUS */
9034 #define OP_Subtract 87 /* same as TK_MINUS */
9035 #define OP_Multiply 88 /* same as TK_STAR */
9036 #define OP_Divide 89 /* same as TK_SLASH */
9037 #define OP_Remainder 90 /* same as TK_REM */
9038 #define OP_Concat 91 /* same as TK_CONCAT */
9039 #define OP_RowKey 92
9040 #define OP_BitNot 93 /* same as TK_BITNOT */
9041 #define OP_String8 94 /* same as TK_STRING */
9042 #define OP_RowData 95
9043 #define OP_Rowid 96
9044 #define OP_NullRow 97
9045 #define OP_Last 98
9046 #define OP_SorterSort 99
9047 #define OP_Sort 100
9048 #define OP_Rewind 101
9049 #define OP_SorterInsert 102
9050 #define OP_IdxInsert 103
9051 #define OP_IdxDelete 104
9052 #define OP_IdxRowid 105
9053 #define OP_IdxLT 106
9054 #define OP_IdxGE 107
9055 #define OP_Destroy 108
9056 #define OP_Clear 109
9057 #define OP_CreateIndex 110
9058 #define OP_CreateTable 111
9059 #define OP_ParseSchema 112
9060 #define OP_LoadAnalysis 113
9061 #define OP_DropTable 114
9062 #define OP_DropIndex 115
9063 #define OP_DropTrigger 116
9064 #define OP_IntegrityCk 117
9065 #define OP_RowSetAdd 118
9066 #define OP_RowSetRead 119
9067 #define OP_RowSetTest 120
9068 #define OP_Program 121
9069 #define OP_Param 122
9070 #define OP_FkCounter 123
9071 #define OP_FkIfZero 124
9072 #define OP_MemMax 125
9073 #define OP_IfPos 126
9074 #define OP_IfNeg 127
9075 #define OP_IfZero 128
9076 #define OP_AggFinal 129
9077 #define OP_Real 130 /* same as TK_FLOAT */
9078 #define OP_IncrVacuum 131
9079 #define OP_Expire 132
9080 #define OP_TableLock 133
9081 #define OP_VBegin 134
9082 #define OP_VCreate 135
9083 #define OP_VDestroy 136
9084 #define OP_VOpen 137
9085 #define OP_VColumn 138
9086 #define OP_VNext 139
9087 #define OP_VRename 140
9088 #define OP_ToText 141 /* same as TK_TO_TEXT */
9089 #define OP_ToBlob 142 /* same as TK_TO_BLOB */
9090 #define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/
9091 #define OP_ToInt 144 /* same as TK_TO_INT */
9092 #define OP_ToReal 145 /* same as TK_TO_REAL */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9093 #define OP_Pagecount 146
9094 #define OP_MaxPgcnt 147
9095 #define OP_Trace 148
9096 #define OP_Noop 149
9097 #define OP_Explain 150
@@ -9094,28 +9107,28 @@
9107 #define OPFLG_IN2 0x0008 /* in2: P2 is an input */
9108 #define OPFLG_IN3 0x0010 /* in3: P3 is an input */
9109 #define OPFLG_OUT2 0x0020 /* out2: P2 is an output */
9110 #define OPFLG_OUT3 0x0040 /* out3: P3 is an output */
9111 #define OPFLG_INITIALIZER {\
9112 /* 0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,\
9113 /* 8 */ 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x01,\
9114 /* 16 */ 0x04, 0x04, 0x10, 0x24, 0x00, 0x02, 0x02, 0x02,\
9115 /* 24 */ 0x02, 0x02, 0x02, 0x00, 0x00, 0x24, 0x00, 0x00,\
9116 /* 32 */ 0x04, 0x05, 0x04, 0x00, 0x00, 0x01, 0x01, 0x05,\
9117 /* 40 */ 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00,\
9118 /* 48 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,\
9119 /* 56 */ 0x11, 0x11, 0x11, 0x08, 0x11, 0x11, 0x11, 0x11,\
9120 /* 64 */ 0x02, 0x02, 0x00, 0x00, 0x4c, 0x4c, 0x00, 0x00,\
9121 /* 72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
9122 /* 80 */ 0x15, 0x00, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,\
9123 /* 88 */ 0x4c, 0x4c, 0x4c, 0x4c, 0x00, 0x24, 0x02, 0x00,\
9124 /* 96 */ 0x02, 0x00, 0x01, 0x01, 0x01, 0x01, 0x08, 0x08,\
9125 /* 104 */ 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x02, 0x02,\
9126 /* 112 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x45,\
9127 /* 120 */ 0x15, 0x01, 0x02, 0x00, 0x01, 0x08, 0x05, 0x05,\
9128 /* 128 */ 0x05, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,\
9129 /* 136 */ 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x04, 0x04,\
9130 /* 144 */ 0x04, 0x04, 0x02, 0x02, 0x00, 0x00, 0x00,}
9131
9132 /************** End of opcodes.h *********************************************/
9133 /************** Continuing where we left off in vdbe.h ***********************/
9134
@@ -9161,11 +9174,11 @@
9174 SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*);
9175 SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*);
9176 SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int);
9177 SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*);
9178 SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
9179 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
9180 SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int);
9181 #ifndef SQLITE_OMIT_TRACE
9182 SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*);
9183 #endif
9184
@@ -10117,11 +10130,11 @@
10130 void *pAuthArg; /* 1st argument to the access auth function */
10131 #endif
10132 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
10133 int (*xProgress)(void *); /* The progress callback */
10134 void *pProgressArg; /* Argument to the progress callback */
10135 unsigned nProgressOps; /* Number of opcodes for progress callback */
10136 #endif
10137 #ifndef SQLITE_OMIT_VIRTUALTABLE
10138 int nVTrans; /* Allocated size of aVTrans */
10139 Hash aModule; /* populated by sqlite3_create_module() */
10140 VtabCtx *pVtabCtx; /* Context for active vtab connect/create */
@@ -10135,10 +10148,11 @@
10148 Savepoint *pSavepoint; /* List of active savepoints */
10149 int busyTimeout; /* Busy handler timeout, in msec */
10150 int nSavepoint; /* Number of non-transaction savepoints */
10151 int nStatement; /* Number of nested statement-transactions */
10152 i64 nDeferredCons; /* Net deferred constraints this transaction. */
10153 i64 nDeferredImmCons; /* Net deferred immediate constraints */
10154 int *pnBytesFreed; /* If not NULL, increment this in DbFree() */
10155
10156 #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
10157 /* The following variables are all protected by the STATIC_MASTER
10158 ** mutex, not by sqlite3.mutex. They are used by code in notify.c.
@@ -10190,10 +10204,13 @@
10204 #define SQLITE_ForeignKeys 0x00040000 /* Enforce foreign key constraints */
10205 #define SQLITE_AutoIndex 0x00080000 /* Enable automatic indexes */
10206 #define SQLITE_PreferBuiltin 0x00100000 /* Preference to built-in funcs */
10207 #define SQLITE_LoadExtension 0x00200000 /* Enable load_extension */
10208 #define SQLITE_EnableTrigger 0x00400000 /* True to enable triggers */
10209 #define SQLITE_DeferFKs 0x00800000 /* Defer all FK constraints */
10210 #define SQLITE_QueryOnly 0x01000000 /* Disable database changes */
10211
10212
10213 /*
10214 ** Bits of the sqlite3.dbOptFlags field that are used by the
10215 ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
10216 ** selectively disable various optimizations.
@@ -10336,10 +10353,11 @@
10353 ** OP_Savepoint instruction.
10354 */
10355 struct Savepoint {
10356 char *zName; /* Savepoint name (nul-terminated) */
10357 i64 nDeferredCons; /* Number of deferred fk violations */
10358 i64 nDeferredImmCons; /* Number of deferred imm fk. */
10359 Savepoint *pNext; /* Parent savepoint (if any) */
10360 };
10361
10362 /*
10363 ** The following are used as the second parameter to sqlite3Savepoint(),
@@ -10654,16 +10672,20 @@
10672
10673 /*
10674 ** An instance of the following structure is passed as the first
10675 ** argument to sqlite3VdbeKeyCompare and is used to control the
10676 ** comparison of the two index keys.
10677 **
10678 ** Note that aSortOrder[] and aColl[] have nField+1 slots. There
10679 ** are nField slots for the columns of an index then one extra slot
10680 ** for the rowid at the end.
10681 */
10682 struct KeyInfo {
10683 sqlite3 *db; /* The database connection */
10684 u8 enc; /* Text encoding - one of the SQLITE_UTF* values */
10685 u16 nField; /* Maximum index for aColl[] and aSortOrder[] */
10686 u8 *aSortOrder; /* Sort order for each column. */
10687 CollSeq *aColl[1]; /* Collating sequence for each term of the key */
10688 };
10689
10690 /*
10691 ** An instance of the following structure holds information about a
@@ -10728,10 +10750,11 @@
10750 char *zColAff; /* String defining the affinity of each column */
10751 Index *pNext; /* The next index associated with the same table */
10752 Schema *pSchema; /* Schema containing this index */
10753 u8 *aSortOrder; /* for each column: True==DESC, False==ASC */
10754 char **azColl; /* Array of collation sequence names for index */
10755 Expr *pPartIdxWhere; /* WHERE clause for partial indices */
10756 int tnum; /* DB Page containing root of this index */
10757 u16 nColumn; /* Number of columns in table used by this index */
10758 u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
10759 unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */
10760 unsigned bUnordered:1; /* Use this index for == or IN queries only */
@@ -11208,10 +11231,11 @@
11231 #define NC_HasAgg 0x02 /* One or more aggregate functions seen */
11232 #define NC_IsCheck 0x04 /* True if resolving names in a CHECK constraint */
11233 #define NC_InAggFunc 0x08 /* True if analyzing arguments to an agg func */
11234 #define NC_AsMaybe 0x10 /* Resolve to AS terms of the result set only
11235 ** if no other resolution is available */
11236 #define NC_PartIdx 0x20 /* True if resolving a partial index WHERE */
11237
11238 /*
11239 ** An instance of the following structure contains all information
11240 ** needed to generate code for a single SELECT statement.
11241 **
@@ -11262,10 +11286,11 @@
11286 #define SF_HasTypeInfo 0x0020 /* FROM subqueries have Table metadata */
11287 #define SF_UseSorter 0x0040 /* Sort using a sorter */
11288 #define SF_Values 0x0080 /* Synthesized from VALUES clause */
11289 #define SF_Materialize 0x0100 /* Force materialization of views */
11290 #define SF_NestedFrom 0x0200 /* Part of a parenthesized FROM clause */
11291 #define SF_MaybeConvert 0x0400 /* Need convertCompoundSelectToSubquery() */
11292
11293
11294 /*
11295 ** The results of a select can be distributed in several ways. The
11296 ** "SRT" prefix means "SELECT Result Type".
@@ -11383,19 +11408,21 @@
11408 u8 nTempInUse; /* Number of aTempReg[] currently checked out */
11409 u8 nColCache; /* Number of entries in aColCache[] */
11410 u8 iColCache; /* Next entry in aColCache[] to replace */
11411 u8 isMultiWrite; /* True if statement may modify/insert multiple rows */
11412 u8 mayAbort; /* True if statement may throw an ABORT exception */
11413 u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
11414 int aTempReg[8]; /* Holding area for temporary registers */
11415 int nRangeReg; /* Size of the temporary register block */
11416 int iRangeReg; /* First register in temporary register block */
11417 int nErr; /* Number of errors seen */
11418 int nTab; /* Number of previously allocated VDBE cursors */
11419 int nMem; /* Number of memory cells used so far */
11420 int nSet; /* Number of sets used so far */
11421 int nOnce; /* Number of OP_Once instructions so far */
11422 int ckBase; /* Base register of data during check constraints */
11423 int iPartIdxTab; /* Table corresponding to a partial index */
11424 int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
11425 int iCacheCnt; /* Counter used to generate aColCache[].lru values */
11426 struct yColCache {
11427 int iTable; /* Table cursor number */
11428 int iColumn; /* Table column number */
@@ -11973,11 +12000,11 @@
12000 SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*);
12001 SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*);
12002 SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*);
12003 SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*);
12004 SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
12005 Expr*, int, int);
12006 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
12007 SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*);
12008 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
12009 Expr*,ExprList*,u16,Expr*,Expr*);
12010 SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*);
@@ -12021,12 +12048,13 @@
12048 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
12049 SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
12050 SQLITE_PRIVATE void sqlite3Vacuum(Parse*);
12051 SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*);
12052 SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*);
12053 SQLITE_PRIVATE int sqlite3ExprCompare(Expr*, Expr*, int);
12054 SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int);
12055 SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr*, Expr*, int);
12056 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
12057 SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
12058 SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
12059 SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*);
12060 SQLITE_PRIVATE void sqlite3PrngSaveState(void);
@@ -12049,11 +12077,11 @@
12077 SQLITE_PRIVATE void sqlite3ExprCodeIsNullJump(Vdbe*, const Expr*, int, int);
12078 SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
12079 SQLITE_PRIVATE int sqlite3IsRowid(const char*);
12080 SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int);
12081 SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*);
12082 SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
12083 SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int,
12084 int*,int,int,int,int,int*);
12085 SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int);
12086 SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int);
12087 SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int);
@@ -12252,10 +12280,11 @@
12280 SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *, Expr *, int, int);
12281 SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*);
12282 SQLITE_PRIVATE int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
12283 SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*);
12284 SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
12285 SQLITE_PRIVATE void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
12286 SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
12287 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
12288 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
12289 SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
12290 SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
@@ -12271,10 +12300,11 @@
12300 SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
12301 SQLITE_PRIVATE void sqlite3MinimumFileFormat(Parse*, int, int);
12302 SQLITE_PRIVATE void sqlite3SchemaClear(void *);
12303 SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
12304 SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
12305 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int);
12306 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *, Index *);
12307 SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *,
12308 void (*)(sqlite3_context*,int,sqlite3_value **),
12309 void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*),
12310 FuncDestructor *pDestructor
@@ -13223,10 +13253,13 @@
13253 typedef struct VdbeSorter VdbeSorter;
13254
13255 /* Opaque type used by the explainer */
13256 typedef struct Explain Explain;
13257
13258 /* Elements of the linked list at Vdbe.pAuxData */
13259 typedef struct AuxData AuxData;
13260
13261 /*
13262 ** A cursor is a pointer into a single BTree within a database file.
13263 ** The cursor can seek to a BTree entry with a particular key, or
13264 ** loop over all entries of the Btree. You can also insert new BTree
13265 ** entries or retrieve the key or data from the entry that the cursor
@@ -13409,27 +13442,23 @@
13442 */
13443 #ifdef SQLITE_DEBUG
13444 #define memIsValid(M) ((M)->flags & MEM_Invalid)==0
13445 #endif
13446
13447 /*
13448 ** Each auxilliary data pointer stored by a user defined function
13449 ** implementation calling sqlite3_set_auxdata() is stored in an instance
13450 ** of this structure. All such structures associated with a single VM
13451 ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed
13452 ** when the VM is halted (if not before).
 
 
 
13453 */
13454 struct AuxData {
13455 int iOp; /* Instruction number of OP_Function opcode */
13456 int iArg; /* Index of function argument. */
13457 void *pAux; /* Aux data pointer */
13458 void (*xDelete)(void *); /* Destructor for the aux data */
13459 AuxData *pNext; /* Next element in list */
 
13460 };
13461
13462 /*
13463 ** The "context" argument for a installable function. A pointer to an
13464 ** instance of this structure is the first argument to the routines used
@@ -13443,16 +13472,17 @@
13472 ** This structure is defined inside of vdbeInt.h because it uses substructures
13473 ** (Mem) which are only defined there.
13474 */
13475 struct sqlite3_context {
13476 FuncDef *pFunc; /* Pointer to function information. MUST BE FIRST */
 
13477 Mem s; /* The return value is stored here */
13478 Mem *pMem; /* Memory cell used to store aggregate context */
13479 CollSeq *pColl; /* Collating sequence */
13480 int isError; /* Error code returned by the function. */
13481 int skipFlag; /* Skip skip accumulator loading if true */
13482 int iOp; /* Instruction number of OP_Function */
13483 Vdbe *pVdbe; /* The VM that owns this context */
13484 };
13485
13486 /*
13487 ** An Explain object accumulates indented output which is helpful
13488 ** in describing recursive data structures.
@@ -13530,10 +13560,11 @@
13560 #ifndef SQLITE_OMIT_TRACE
13561 i64 startTime; /* Time when query started - used for profiling */
13562 #endif
13563 i64 nFkConstraint; /* Number of imm. FK constraints this VM */
13564 i64 nStmtDefCons; /* Number of def. constraints when stmt started */
13565 i64 nStmtDefImmCons; /* Number of def. imm constraints when stmt started */
13566 char *zSql; /* Text of the SQL statement that generated this */
13567 void *pFree; /* Free this when deleting the vdbe */
13568 #ifdef SQLITE_DEBUG
13569 FILE *trace; /* Write an execution trace here, if not NULL */
13570 #endif
@@ -13546,10 +13577,11 @@
13577 int nFrame; /* Number of frames in pFrame list */
13578 u32 expmask; /* Binding to these vars invalidates VM */
13579 SubProgram *pProgram; /* Linked list of all sub-programs used by VM */
13580 int nOnceFlag; /* Size of array aOnceFlag[] */
13581 u8 *aOnceFlag; /* Flags for OP_Once */
13582 AuxData *pAuxData; /* Linked list of auxdata allocations */
13583 };
13584
13585 /*
13586 ** The following are allowed values for Vdbe.magic
13587 */
@@ -13569,11 +13601,11 @@
13601 #endif
13602 SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32);
13603 SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem*, int);
13604 SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, int, Mem*, int);
13605 SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
13606 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe*, int, int);
13607
13608 int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
13609 SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*);
13610 SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *);
13611 SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
@@ -13889,10 +13921,20 @@
13921 }
13922 *pHighwater = 0;
13923 *pCurrent = nRet;
13924 break;
13925 }
13926
13927 /* Set *pCurrent to non-zero if there are unresolved deferred foreign
13928 ** key constraints. Set *pCurrent to zero if all foreign key constraints
13929 ** have been satisfied. The *pHighwater is always set to zero.
13930 */
13931 case SQLITE_DBSTATUS_DEFERRED_FKS: {
13932 *pHighwater = 0;
13933 *pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
13934 break;
13935 }
13936
13937 default: {
13938 rc = SQLITE_ERROR;
13939 }
13940 }
@@ -22658,91 +22700,91 @@
22700 /* Automatically generated. Do not edit */
22701 /* See the mkopcodec.awk script for details. */
22702 #if !defined(SQLITE_OMIT_EXPLAIN) || !defined(NDEBUG) || defined(VDBE_PROFILE) || defined(SQLITE_DEBUG)
22703 SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
22704 static const char *const azName[] = { "?",
22705 /* 1 */ "Function",
22706 /* 2 */ "Savepoint",
22707 /* 3 */ "AutoCommit",
22708 /* 4 */ "Transaction",
22709 /* 5 */ "SorterNext",
22710 /* 6 */ "Prev",
22711 /* 7 */ "Next",
22712 /* 8 */ "AggStep",
22713 /* 9 */ "Checkpoint",
22714 /* 10 */ "JournalMode",
22715 /* 11 */ "Vacuum",
22716 /* 12 */ "VFilter",
22717 /* 13 */ "VUpdate",
22718 /* 14 */ "Goto",
22719 /* 15 */ "Gosub",
22720 /* 16 */ "Return",
22721 /* 17 */ "Yield",
22722 /* 18 */ "HaltIfNull",
22723 /* 19 */ "Not",
22724 /* 20 */ "Halt",
22725 /* 21 */ "Integer",
22726 /* 22 */ "Int64",
22727 /* 23 */ "String",
22728 /* 24 */ "Null",
22729 /* 25 */ "Blob",
22730 /* 26 */ "Variable",
22731 /* 27 */ "Move",
22732 /* 28 */ "Copy",
22733 /* 29 */ "SCopy",
22734 /* 30 */ "ResultRow",
22735 /* 31 */ "CollSeq",
22736 /* 32 */ "AddImm",
22737 /* 33 */ "MustBeInt",
22738 /* 34 */ "RealAffinity",
22739 /* 35 */ "Permutation",
22740 /* 36 */ "Compare",
22741 /* 37 */ "Jump",
22742 /* 38 */ "Once",
22743 /* 39 */ "If",
22744 /* 40 */ "IfNot",
22745 /* 41 */ "Column",
22746 /* 42 */ "Affinity",
22747 /* 43 */ "MakeRecord",
22748 /* 44 */ "Count",
22749 /* 45 */ "ReadCookie",
22750 /* 46 */ "SetCookie",
22751 /* 47 */ "VerifyCookie",
22752 /* 48 */ "OpenRead",
22753 /* 49 */ "OpenWrite",
22754 /* 50 */ "OpenAutoindex",
22755 /* 51 */ "OpenEphemeral",
22756 /* 52 */ "SorterOpen",
22757 /* 53 */ "OpenPseudo",
22758 /* 54 */ "Close",
22759 /* 55 */ "SeekLt",
22760 /* 56 */ "SeekLe",
22761 /* 57 */ "SeekGe",
22762 /* 58 */ "SeekGt",
22763 /* 59 */ "Seek",
22764 /* 60 */ "NotFound",
22765 /* 61 */ "Found",
22766 /* 62 */ "IsUnique",
22767 /* 63 */ "NotExists",
22768 /* 64 */ "Sequence",
22769 /* 65 */ "NewRowid",
22770 /* 66 */ "Insert",
22771 /* 67 */ "InsertInt",
22772 /* 68 */ "Or",
22773 /* 69 */ "And",
22774 /* 70 */ "Delete",
22775 /* 71 */ "ResetCount",
22776 /* 72 */ "SorterCompare",
22777 /* 73 */ "IsNull",
22778 /* 74 */ "NotNull",
22779 /* 75 */ "Ne",
22780 /* 76 */ "Eq",
22781 /* 77 */ "Gt",
22782 /* 78 */ "Le",
22783 /* 79 */ "Lt",
22784 /* 80 */ "Ge",
22785 /* 81 */ "SorterData",
22786 /* 82 */ "BitAnd",
22787 /* 83 */ "BitOr",
22788 /* 84 */ "ShiftLeft",
22789 /* 85 */ "ShiftRight",
22790 /* 86 */ "Add",
@@ -22749,59 +22791,59 @@
22791 /* 87 */ "Subtract",
22792 /* 88 */ "Multiply",
22793 /* 89 */ "Divide",
22794 /* 90 */ "Remainder",
22795 /* 91 */ "Concat",
22796 /* 92 */ "RowKey",
22797 /* 93 */ "BitNot",
22798 /* 94 */ "String8",
22799 /* 95 */ "RowData",
22800 /* 96 */ "Rowid",
22801 /* 97 */ "NullRow",
22802 /* 98 */ "Last",
22803 /* 99 */ "SorterSort",
22804 /* 100 */ "Sort",
22805 /* 101 */ "Rewind",
22806 /* 102 */ "SorterInsert",
22807 /* 103 */ "IdxInsert",
22808 /* 104 */ "IdxDelete",
22809 /* 105 */ "IdxRowid",
22810 /* 106 */ "IdxLT",
22811 /* 107 */ "IdxGE",
22812 /* 108 */ "Destroy",
22813 /* 109 */ "Clear",
22814 /* 110 */ "CreateIndex",
22815 /* 111 */ "CreateTable",
22816 /* 112 */ "ParseSchema",
22817 /* 113 */ "LoadAnalysis",
22818 /* 114 */ "DropTable",
22819 /* 115 */ "DropIndex",
22820 /* 116 */ "DropTrigger",
22821 /* 117 */ "IntegrityCk",
22822 /* 118 */ "RowSetAdd",
22823 /* 119 */ "RowSetRead",
22824 /* 120 */ "RowSetTest",
22825 /* 121 */ "Program",
22826 /* 122 */ "Param",
22827 /* 123 */ "FkCounter",
22828 /* 124 */ "FkIfZero",
22829 /* 125 */ "MemMax",
22830 /* 126 */ "IfPos",
22831 /* 127 */ "IfNeg",
22832 /* 128 */ "IfZero",
22833 /* 129 */ "AggFinal",
22834 /* 130 */ "Real",
22835 /* 131 */ "IncrVacuum",
22836 /* 132 */ "Expire",
22837 /* 133 */ "TableLock",
22838 /* 134 */ "VBegin",
22839 /* 135 */ "VCreate",
22840 /* 136 */ "VDestroy",
22841 /* 137 */ "VOpen",
22842 /* 138 */ "VColumn",
22843 /* 139 */ "VNext",
22844 /* 140 */ "VRename",
22845 /* 141 */ "ToText",
22846 /* 142 */ "ToBlob",
22847 /* 143 */ "ToNumeric",
22848 /* 144 */ "ToInt",
22849 /* 145 */ "ToReal",
@@ -30454,10 +30496,11 @@
30496 */
30497 #if SQLITE_OS_WIN /* This file is used for Windows only */
30498
30499 #ifdef __CYGWIN__
30500 # include <sys/cygwin.h>
30501 /* # include <errno.h> */
30502 #endif
30503
30504 /*
30505 ** Include code that is common to all os_*.c files
30506 */
@@ -30874,10 +30917,11 @@
30917 * zero for the default behavior.
30918 */
30919 #ifndef SQLITE_WIN32_HEAP_FLAGS
30920 # define SQLITE_WIN32_HEAP_FLAGS (0)
30921 #endif
30922
30923
30924 /*
30925 ** The winMemData structure stores information required by the Win32-specific
30926 ** sqlite3_mem_methods implementation.
30927 */
@@ -34339,14 +34383,14 @@
34383 OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n",
34384 osGetCurrentProcessId(), pFd));
34385 return SQLITE_OK;
34386 }
34387 assert( (nMap % winSysInfo.dwPageSize)==0 );
 
 
 
34388 assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff );
34389 #if SQLITE_OS_WINRT
34390 pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap);
34391 #else
34392 pNew = osMapViewOfFile(pFd->hMap, flags, 0, 0, (SIZE_T)nMap);
34393 #endif
34394 if( pNew==NULL ){
34395 osCloseHandle(pFd->hMap);
34396 pFd->hMap = NULL;
@@ -34511,10 +34555,19 @@
34555 #endif
34556 /* caller will handle out of memory */
34557 return zConverted;
34558 }
34559
34560 /*
34561 ** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is
34562 ** in characters, so we allocate 3 bytes per character assuming worst-case
34563 ** 3-bytes-per-character UTF8.
34564 */
34565 #ifndef SQLITE_WIN32_MAX_PATH
34566 # define SQLITE_WIN32_MAX_PATH (MAX_PATH*3)
34567 #endif
34568
34569 /*
34570 ** Create a temporary file name in zBuf. zBuf must be big enough to
34571 ** hold at pVfs->mxPathname characters.
34572 */
34573 static int getTempname(int nBuf, char *zBuf){
@@ -34522,53 +34575,74 @@
34575 "abcdefghijklmnopqrstuvwxyz"
34576 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
34577 "0123456789";
34578 size_t i, j;
34579 int nTempPath;
34580 char zTempPath[SQLITE_WIN32_MAX_PATH+2];
34581
34582 /* It's odd to simulate an io-error here, but really this is just
34583 ** using the io-error infrastructure to test that SQLite handles this
34584 ** function failing.
34585 */
34586 SimulateIOError( return SQLITE_IOERR );
34587
 
 
34588 if( sqlite3_temp_directory ){
34589 sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s",
34590 sqlite3_temp_directory);
34591 }
34592 #if !SQLITE_OS_WINRT
34593 else if( isNT() ){
34594 char *zMulti;
34595 WCHAR zWidePath[MAX_PATH];
34596 if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){
34597 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
34598 return SQLITE_IOERR_GETTEMPPATH;
34599 }
34600 zMulti = unicodeToUtf8(zWidePath);
34601 if( zMulti ){
34602 sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti);
34603 sqlite3_free(zMulti);
34604 }else{
34605 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
34606 return SQLITE_IOERR_NOMEM;
34607 }
34608 }
34609 #ifdef SQLITE_WIN32_HAS_ANSI
34610 else{
34611 char *zUtf8;
34612 char zMbcsPath[SQLITE_WIN32_MAX_PATH];
34613 if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){
34614 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n"));
34615 return SQLITE_IOERR_GETTEMPPATH;
34616 }
34617 zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath);
34618 if( zUtf8 ){
34619 sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8);
34620 sqlite3_free(zUtf8);
34621 }else{
34622 OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
34623 return SQLITE_IOERR_NOMEM;
34624 }
34625 }
34626 #else
34627 else{
34628 /*
34629 ** Compiled without ANSI support and the current operating system
34630 ** is not Windows NT; therefore, just zero the temporary buffer.
34631 */
34632 memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
34633 }
34634 #endif /* SQLITE_WIN32_HAS_ANSI */
34635 #else
34636 else{
34637 /*
34638 ** Compiled for WinRT and the sqlite3_temp_directory is not set;
34639 ** therefore, just zero the temporary buffer.
34640 */
34641 memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2);
34642 }
34643 #endif /* !SQLITE_OS_WINRT */
34644
34645 /* Check that the output buffer is large enough for the temporary file
34646 ** name. If it is not, return SQLITE_ERROR.
34647 */
34648 nTempPath = sqlite3Strlen30(zTempPath);
@@ -34650,11 +34724,11 @@
34724 int cnt = 0;
34725
34726 /* If argument zPath is a NULL pointer, this function is required to open
34727 ** a temporary file. Use this buffer to store the file name in.
34728 */
34729 char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */
34730
34731 int rc = SQLITE_OK; /* Function Return Code */
34732 #if !defined(NDEBUG) || SQLITE_OS_WINCE
34733 int eType = flags&0xFFFFFF00; /* Type of file to open */
34734 #endif
@@ -34716,12 +34790,11 @@
34790 /* If the second argument to this function is NULL, generate a
34791 ** temporary file name to use
34792 */
34793 if( !zUtf8Name ){
34794 assert(isDelete && !isOpenJournal);
34795 rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname);
 
34796 if( rc!=SQLITE_OK ){
34797 OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc)));
34798 return rc;
34799 }
34800 zUtf8Name = zTmpname;
@@ -35148,27 +35221,34 @@
35221 ){
35222
35223 #if defined(__CYGWIN__)
35224 SimulateIOError( return SQLITE_ERROR );
35225 UNUSED_PARAMETER(nFull);
35226 assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH );
35227 assert( nFull>=pVfs->mxPathname );
35228 if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){
35229 /*
35230 ** NOTE: We are dealing with a relative path name and the data
35231 ** directory has been set. Therefore, use it as the basis
35232 ** for converting the relative path name to an absolute
35233 ** one by prepending the data directory and a slash.
35234 */
35235 char zOut[SQLITE_WIN32_MAX_PATH+1];
35236 if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
35237 SQLITE_WIN32_MAX_PATH+1)<0 ){
35238 winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
35239 zRelative);
35240 return SQLITE_CANTOPEN_FULLPATH;
35241 }
35242 sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
35243 sqlite3_data_directory, zOut);
35244 }else{
35245 if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
35246 winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path",
35247 zRelative);
35248 return SQLITE_CANTOPEN_FULLPATH;
35249 }
35250 }
35251 return SQLITE_OK;
35252 #endif
35253
35254 #if (SQLITE_OS_WINCE || SQLITE_OS_WINRT) && !defined(__CYGWIN__)
@@ -35506,11 +35586,11 @@
35586 */
35587 SQLITE_API int sqlite3_os_init(void){
35588 static sqlite3_vfs winVfs = {
35589 3, /* iVersion */
35590 sizeof(winFile), /* szOsFile */
35591 SQLITE_WIN32_MAX_PATH, /* mxPathname */
35592 0, /* pNext */
35593 "win32", /* zName */
35594 0, /* pAppData */
35595 winOpen, /* xOpen */
35596 winDelete, /* xDelete */
@@ -60131,12 +60211,12 @@
60211 ** a prior call to sqlite3VdbeMakeLabel().
60212 */
60213 SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){
60214 int j = -1-x;
60215 assert( p->magic==VDBE_MAGIC_INIT );
60216 assert( j<p->nLabel );
60217 if( j>=0 && p->aLabel ){
60218 p->aLabel[j] = p->nOp;
60219 }
60220 }
60221
60222 /*
@@ -60288,44 +60368,64 @@
60368 p->readOnly = 1;
60369 p->bIsReader = 0;
60370 for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
60371 u8 opcode = pOp->opcode;
60372
60373 /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
60374 ** cases from this switch! */
60375 switch( opcode ){
60376 case OP_Function:
60377 case OP_AggStep: {
60378 if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
60379 break;
60380 }
60381 case OP_Transaction: {
60382 if( pOp->p2!=0 ) p->readOnly = 0;
60383 /* fall thru */
60384 }
60385 case OP_AutoCommit:
60386 case OP_Savepoint: {
60387 p->bIsReader = 1;
60388 break;
60389 }
60390 #ifndef SQLITE_OMIT_WAL
60391 case OP_Checkpoint:
60392 #endif
60393 case OP_Vacuum:
60394 case OP_JournalMode: {
60395 p->readOnly = 0;
60396 p->bIsReader = 1;
60397 break;
60398 }
60399 #ifndef SQLITE_OMIT_VIRTUALTABLE
60400 case OP_VUpdate: {
60401 if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
60402 break;
60403 }
60404 case OP_VFilter: {
60405 int n;
60406 assert( p->nOp - i >= 3 );
60407 assert( pOp[-1].opcode==OP_Integer );
60408 n = pOp[-1].p1;
60409 if( n>nMaxArgs ) nMaxArgs = n;
60410 break;
60411 }
60412 #endif
60413 case OP_Next:
60414 case OP_SorterNext: {
60415 pOp->p4.xAdvance = sqlite3BtreeNext;
60416 pOp->p4type = P4_ADVANCE;
60417 break;
60418 }
60419 case OP_Prev: {
60420 pOp->p4.xAdvance = sqlite3BtreePrevious;
60421 pOp->p4type = P4_ADVANCE;
60422 break;
60423 }
60424 }
60425
60426 pOp->opflags = sqlite3OpcodeProperty[opcode];
60427 if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
60428 assert( -1-pOp->p2<p->nLabel );
60429 pOp->p2 = aLabel[-1-pOp->p2];
60430 }
60431 }
@@ -60456,12 +60556,11 @@
60556 /*
60557 ** Change the P2 operand of instruction addr so that it points to
60558 ** the address of the next instruction to be coded.
60559 */
60560 SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){
60561 if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
 
60562 }
60563
60564
60565 /*
60566 ** If the input FuncDef structure is ephemeral, then free it. If
@@ -60493,17 +60592,10 @@
60592 }
60593 case P4_MPRINTF: {
60594 if( db->pnBytesFreed==0 ) sqlite3_free(p4);
60595 break;
60596 }
 
 
 
 
 
 
 
60597 case P4_FUNCDEF: {
60598 freeEphemeralFunction(db, (FuncDef*)p4);
60599 break;
60600 }
60601 case P4_MEM: {
@@ -60618,24 +60710,17 @@
60710 pOp->p4type = P4_INT32;
60711 }else if( zP4==0 ){
60712 pOp->p4.p = 0;
60713 pOp->p4type = P4_NOTUSED;
60714 }else if( n==P4_KEYINFO ){
60715 KeyInfo *pOrig, *pNew;
60716
60717 pOrig = (KeyInfo*)zP4;
60718 pOp->p4.pKeyInfo = pNew = sqlite3KeyInfoAlloc(db, pOrig->nField);
60719 if( pNew ){
60720 memcpy(pNew->aColl, pOrig->aColl, pOrig->nField*sizeof(pNew->aColl[0]));
60721 memcpy(pNew->aSortOrder, pOrig->aSortOrder, pOrig->nField);
 
 
 
 
 
 
 
60722 pOp->p4type = P4_KEYINFO;
60723 }else{
60724 p->db->mallocFailed = 1;
60725 pOp->p4type = P4_NOTUSED;
60726 }
@@ -61529,10 +61614,14 @@
61614 while( p->pDelFrame ){
61615 VdbeFrame *pDel = p->pDelFrame;
61616 p->pDelFrame = pDel->pParent;
61617 sqlite3VdbeFrameDelete(pDel);
61618 }
61619
61620 /* Delete any auxdata allocations made by the VM */
61621 sqlite3VdbeDeleteAuxData(p, -1, 0);
61622 assert( p->pAuxData==0 );
61623 }
61624
61625 /*
61626 ** Clean up the VM after execution.
61627 **
@@ -61946,10 +62035,11 @@
62035 /* If the statement transaction is being rolled back, also restore the
62036 ** database handles deferred constraint counter to the value it had when
62037 ** the statement transaction was opened. */
62038 if( eOp==SAVEPOINT_ROLLBACK ){
62039 db->nDeferredCons = p->nStmtDefCons;
62040 db->nDeferredImmCons = p->nStmtDefImmCons;
62041 }
62042 }
62043 return rc;
62044 }
62045
@@ -61964,11 +62054,13 @@
62054 ** and write an error message to it. Then return SQLITE_ERROR.
62055 */
62056 #ifndef SQLITE_OMIT_FOREIGN_KEY
62057 SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){
62058 sqlite3 *db = p->db;
62059 if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0)
62060 || (!deferred && p->nFkConstraint>0)
62061 ){
62062 p->rc = SQLITE_CONSTRAINT_FOREIGNKEY;
62063 p->errorAction = OE_Abort;
62064 sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed");
62065 return SQLITE_ERROR;
62066 }
@@ -62097,10 +62189,12 @@
62189 }else if( rc!=SQLITE_OK ){
62190 p->rc = rc;
62191 sqlite3RollbackAll(db, SQLITE_OK);
62192 }else{
62193 db->nDeferredCons = 0;
62194 db->nDeferredImmCons = 0;
62195 db->flags &= ~SQLITE_DeferFKs;
62196 sqlite3CommitInternalChanges(db);
62197 }
62198 }else{
62199 sqlite3RollbackAll(db, SQLITE_OK);
62200 }
@@ -62322,24 +62416,39 @@
62416 sqlite3VdbeDelete(p);
62417 return rc;
62418 }
62419
62420 /*
62421 ** If parameter iOp is less than zero, then invoke the destructor for
62422 ** all auxiliary data pointers currently cached by the VM passed as
62423 ** the first argument.
62424 **
62425 ** Or, if iOp is greater than or equal to zero, then the destructor is
62426 ** only invoked for those auxiliary data pointers created by the user
62427 ** function invoked by the OP_Function opcode at instruction iOp of
62428 ** VM pVdbe, and only then if:
62429 **
62430 ** * the associated function parameter is the 32nd or later (counting
62431 ** from left to right), or
62432 **
62433 ** * the corresponding bit in argument mask is clear (where the first
62434 ** function parameter corrsponds to bit 0 etc.).
62435 */
62436 SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(Vdbe *pVdbe, int iOp, int mask){
62437 AuxData **pp = &pVdbe->pAuxData;
62438 while( *pp ){
62439 AuxData *pAux = *pp;
62440 if( (iOp<0)
62441 || (pAux->iOp==iOp && (pAux->iArg>31 || !(mask & ((u32)1<<pAux->iArg))))
62442 ){
62443 if( pAux->xDelete ){
62444 pAux->xDelete(pAux->pAux);
62445 }
62446 *pp = pAux->pNext;
62447 sqlite3DbFree(pVdbe->db, pAux);
62448 }else{
62449 pp= &pAux->pNext;
62450 }
62451 }
62452 }
62453
62454 /*
@@ -62854,15 +62963,14 @@
62963 */
62964 SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
62965 int nKey1, const void *pKey1, /* Left key */
62966 UnpackedRecord *pPKey2 /* Right key */
62967 ){
62968 u32 d1; /* Offset into aKey[] of next data element */
62969 u32 idx1; /* Offset into aKey[] of next header element */
62970 u32 szHdr1; /* Number of bytes in header */
62971 int i = 0;
 
62972 int rc = 0;
62973 const unsigned char *aKey1 = (const unsigned char *)pKey1;
62974 KeyInfo *pKeyInfo;
62975 Mem mem1;
62976
@@ -62881,32 +62989,42 @@
62989 */
62990 /* mem1.u.i = 0; // not needed, here to silence compiler warning */
62991
62992 idx1 = getVarint32(aKey1, szHdr1);
62993 d1 = szHdr1;
62994 assert( pKeyInfo->nField+1>=pPKey2->nField );
62995 assert( pKeyInfo->aSortOrder!=0 );
62996 while( idx1<szHdr1 && i<pPKey2->nField ){
62997 u32 serial_type1;
62998
62999 /* Read the serial types for the next element in each key. */
63000 idx1 += getVarint32( aKey1+idx1, serial_type1 );
63001
63002 /* Verify that there is enough key space remaining to avoid
63003 ** a buffer overread. The "d1+serial_type1+2" subexpression will
63004 ** always be greater than or equal to the amount of required key space.
63005 ** Use that approximation to avoid the more expensive call to
63006 ** sqlite3VdbeSerialTypeLen() in the common case.
63007 */
63008 if( d1+serial_type1+2>(u32)nKey1
63009 && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1
63010 ){
63011 break;
63012 }
63013
63014 /* Extract the values to be compared.
63015 */
63016 d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
63017
63018 /* Do the comparison
63019 */
63020 rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
 
63021 if( rc!=0 ){
63022 assert( mem1.zMalloc==0 ); /* See comment below */
63023
63024 /* Invert the result if we are using DESC sort order. */
63025 if( pKeyInfo->aSortOrder[i] ){
63026 rc = -rc;
63027 }
63028
63029 /* If the PREFIX_SEARCH flag is set and all fields except the final
63030 ** rowid field were equal, then clear the PREFIX_SEARCH flag and set
@@ -63117,11 +63235,11 @@
63235 ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_*
63236 ** constants) to the value before returning it.
63237 **
63238 ** The returned value must be freed by the caller using sqlite3ValueFree().
63239 */
63240 SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){
63241 assert( iVar>0 );
63242 if( v ){
63243 Mem *pMem = &v->aVar[iVar-1];
63244 if( 0==(pMem->flags & MEM_Null) ){
63245 sqlite3_value *pRet = sqlite3ValueNew(v->db);
@@ -63536,11 +63654,13 @@
63654 */
63655 if( db->nVdbeActive==0 ){
63656 db->u1.isInterrupted = 0;
63657 }
63658
63659 assert( db->nVdbeWrite>0 || db->autoCommit==0
63660 || (db->nDeferredCons==0 && db->nDeferredImmCons==0)
63661 );
63662
63663 #ifndef SQLITE_OMIT_TRACE
63664 if( db->xProfile && !db->init.busy ){
63665 sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime);
63666 }
@@ -63732,18 +63852,18 @@
63852 /*
63853 ** Return the auxilary data pointer, if any, for the iArg'th argument to
63854 ** the user-function defined by pCtx.
63855 */
63856 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){
63857 AuxData *pAuxData;
63858
63859 assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
63860 for(pAuxData=pCtx->pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
63861 if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
 
63862 }
63863
63864 return (pAuxData ? pAuxData->pAux : 0);
63865 }
63866
63867 /*
63868 ** Set the auxilary data pointer and delete function, for the iArg'th
63869 ** argument to the user-function defined by pCtx. Any previous value is
@@ -63753,33 +63873,30 @@
63873 sqlite3_context *pCtx,
63874 int iArg,
63875 void *pAux,
63876 void (*xDelete)(void*)
63877 ){
63878 AuxData *pAuxData;
63879 Vdbe *pVdbe = pCtx->pVdbe;
 
63880
63881 assert( sqlite3_mutex_held(pCtx->s.db->mutex) );
63882 if( iArg<0 ) goto failed;
63883
63884 for(pAuxData=pVdbe->pAuxData; pAuxData; pAuxData=pAuxData->pNext){
63885 if( pAuxData->iOp==pCtx->iOp && pAuxData->iArg==iArg ) break;
63886 }
63887 if( pAuxData==0 ){
63888 pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
63889 if( !pAuxData ) goto failed;
63890 pAuxData->iOp = pCtx->iOp;
63891 pAuxData->iArg = iArg;
63892 pAuxData->pNext = pVdbe->pAuxData;
63893 pVdbe->pAuxData = pAuxData;
63894 }else if( pAuxData->xDelete ){
 
 
 
63895 pAuxData->xDelete(pAuxData->pAux);
63896 }
63897
63898 pAuxData->pAux = pAux;
63899 pAuxData->xDelete = xDelete;
63900 return;
63901
63902 failed:
@@ -65384,16 +65501,15 @@
65501 Op *pOp; /* Current operation */
65502 int rc = SQLITE_OK; /* Value to return */
65503 sqlite3 *db = p->db; /* The database */
65504 u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
65505 u8 encoding = ENC(db); /* The database encoding */
 
 
 
 
65506 int iCompare = 0; /* Result of last OP_Compare operation */
65507 unsigned nVmStep = 0; /* Number of virtual machine steps */
65508 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65509 unsigned nProgressLimit = 0;/* Invoke xProgress() when nVmStep reaches this */
65510 #endif
65511 Mem *aMem = p->aMem; /* Copy of p->aMem */
65512 Mem *pIn1 = 0; /* 1st input operand */
65513 Mem *pIn2 = 0; /* 2nd input operand */
65514 Mem *pIn3 = 0; /* 3rd input operand */
65515 Mem *pOut = 0; /* Output operand */
@@ -65848,11 +65964,19 @@
65964 p->pResultSet = 0;
65965 db->busyHandler.nBusy = 0;
65966 CHECK_FOR_INTERRUPT;
65967 sqlite3VdbeIOTraceSql(p);
65968 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
65969 if( db->xProgress ){
65970 assert( 0 < db->nProgressOps );
65971 nProgressLimit = (unsigned)p->aCounter[SQLITE_STMTSTATUS_VM_STEP-1];
65972 if( nProgressLimit==0 ){
65973 nProgressLimit = db->nProgressOps;
65974 }else{
65975 nProgressLimit %= (unsigned)db->nProgressOps;
65976 }
65977 }
65978 #endif
65979 #ifdef SQLITE_DEBUG
65980 sqlite3BeginBenignMalloc();
65981 if( p->pc==0 && (p->db->flags & SQLITE_VdbeListing)!=0 ){
65982 int i;
@@ -65895,31 +66019,10 @@
66019 sqlite3_interrupt_count--;
66020 if( sqlite3_interrupt_count==0 ){
66021 sqlite3_interrupt(db);
66022 }
66023 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66024 #endif
66025
66026 /* On any opcode with the "out2-prerelease" tag, free any
66027 ** external allocations out of mem[p2] and set mem[p2] to be
66028 ** an undefined integer. Opcodes will either fill in the integer
@@ -66010,12 +66113,44 @@
66113 ** The next instruction executed will be
66114 ** the one at index P2 from the beginning of
66115 ** the program.
66116 */
66117 case OP_Goto: { /* jump */
 
66118 pc = pOp->p2 - 1;
66119
66120 /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev,
66121 ** OP_VNext, OP_RowSetNext, or OP_SorterNext) all jump here upon
66122 ** completion. Check to see if sqlite3_interrupt() has been called
66123 ** or if the progress callback needs to be invoked.
66124 **
66125 ** This code uses unstructured "goto" statements and does not look clean.
66126 ** But that is not due to sloppy coding habits. The code is written this
66127 ** way for performance, to avoid having to run the interrupt and progress
66128 ** checks on every opcode. This helps sqlite3_step() to run about 1.5%
66129 ** faster according to "valgrind --tool=cachegrind" */
66130 check_for_interrupt:
66131 CHECK_FOR_INTERRUPT;
66132 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
66133 /* Call the progress callback if it is configured and the required number
66134 ** of VDBE ops have been executed (either since this invocation of
66135 ** sqlite3VdbeExec() or since last time the progress callback was called).
66136 ** If the progress callback returns non-zero, exit the virtual machine with
66137 ** a return code SQLITE_ABORT.
66138 */
66139 if( db->xProgress!=0 && nVmStep>=nProgressLimit ){
66140 int prc;
66141 prc = db->xProgress(db->pProgressArg);
66142 if( prc!=0 ){
66143 rc = SQLITE_INTERRUPT;
66144 goto vdbe_error_halt;
66145 }
66146 if( db->xProgress!=0 ){
66147 nProgressLimit = nVmStep + db->nProgressOps - (nVmStep%db->nProgressOps);
66148 }
66149 }
66150 #endif
66151
66152 break;
66153 }
66154
66155 /* Opcode: Gosub P1 P2 * * *
66156 **
@@ -66132,11 +66267,11 @@
66267 assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR );
66268 if( rc==SQLITE_BUSY ){
66269 p->rc = rc = SQLITE_BUSY;
66270 }else{
66271 assert( rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT );
66272 assert( rc==SQLITE_OK || db->nDeferredCons>0 || db->nDeferredImmCons>0 );
66273 rc = p->rc ? SQLITE_ERROR : SQLITE_DONE;
66274 }
66275 goto vdbe_return;
66276 }
66277
@@ -66694,23 +66829,18 @@
66829 Deephemeralize(u.ai.pArg);
66830 sqlite3VdbeMemStoreType(u.ai.pArg);
66831 REGISTER_TRACE(pOp->p2+u.ai.i, u.ai.pArg);
66832 }
66833
66834 assert( pOp->p4type==P4_FUNCDEF );
66835 u.ai.ctx.pFunc = pOp->p4.pFunc;
 
 
 
 
 
 
 
66836 u.ai.ctx.s.flags = MEM_Null;
66837 u.ai.ctx.s.db = db;
66838 u.ai.ctx.s.xDel = 0;
66839 u.ai.ctx.s.zMalloc = 0;
66840 u.ai.ctx.iOp = pc;
66841 u.ai.ctx.pVdbe = p;
66842
66843 /* The output cell may already have a buffer allocated. Move
66844 ** the pointer to u.ai.ctx.s so in case the user-function can use
66845 ** the already allocated buffer instead of allocating a new one.
66846 */
@@ -66729,15 +66859,11 @@
66859 lastRowid = db->lastRowid;
66860
66861 /* If any auxiliary data functions have been called by this user function,
66862 ** immediately call the destructor for any non-static values.
66863 */
66864 sqlite3VdbeDeleteAuxData(p, pc, pOp->p1);
 
 
 
 
66865
66866 if( db->mallocFailed ){
66867 /* Even though a malloc() has failed, the implementation of the
66868 ** user function may have called an sqlite3_result_XXX() function
66869 ** to return a value. The following call releases any resources
@@ -68028,10 +68154,11 @@
68154
68155 /* Link the new savepoint into the database handle's list. */
68156 u.as.pNew->pNext = db->pSavepoint;
68157 db->pSavepoint = u.as.pNew;
68158 u.as.pNew->nDeferredCons = db->nDeferredCons;
68159 u.as.pNew->nDeferredImmCons = db->nDeferredImmCons;
68160 }
68161 }
68162 }else{
68163 u.as.iSavepoint = 0;
68164
@@ -68115,10 +68242,11 @@
68242 if( !isTransaction ){
68243 db->nSavepoint--;
68244 }
68245 }else{
68246 db->nDeferredCons = u.as.pSavepoint->nDeferredCons;
68247 db->nDeferredImmCons = u.as.pSavepoint->nDeferredImmCons;
68248 }
68249
68250 if( !isTransaction ){
68251 rc = sqlite3VtabSavepoint(db, u.as.p1, u.as.iSavepoint);
68252 if( rc!=SQLITE_OK ) goto abort_due_to_error;
@@ -68244,10 +68372,14 @@
68372
68373 assert( p->bIsReader );
68374 assert( p->readOnly==0 || pOp->p2==0 );
68375 assert( pOp->p1>=0 && pOp->p1<db->nDb );
68376 assert( (p->btreeMask & (((yDbMask)1)<<pOp->p1))!=0 );
68377 if( pOp->p2 && (db->flags & SQLITE_QueryOnly)!=0 ){
68378 rc = SQLITE_READONLY;
68379 goto abort_due_to_error;
68380 }
68381 u.au.pBt = db->aDb[pOp->p1].pBt;
68382
68383 if( u.au.pBt ){
68384 rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2);
68385 if( rc==SQLITE_BUSY ){
@@ -68276,10 +68408,11 @@
68408
68409 /* Store the current value of the database handles deferred constraint
68410 ** counter. If the statement transaction needs to be rolled back,
68411 ** the value of this counter needs to be restored too. */
68412 p->nStmtDefCons = db->nDeferredCons;
68413 p->nStmtDefImmCons = db->nDeferredImmCons;
68414 }
68415 }
68416 break;
68417 }
68418
@@ -69851,11 +69984,10 @@
69984 #if 0 /* local variables moved into u.br */
69985 VdbeCursor *pC;
69986 int res;
69987 #endif /* local variables moved into u.br */
69988
 
69989 assert( pOp->p1>=0 && pOp->p1<p->nCursor );
69990 assert( pOp->p5<=ArraySize(p->aCounter) );
69991 u.br.pC = p->apCsr[pOp->p1];
69992 if( u.br.pC==0 ){
69993 break; /* See ticket #2273 */
@@ -69880,11 +70012,11 @@
70012 #ifdef SQLITE_TEST
70013 sqlite3_search_count++;
70014 #endif
70015 }
70016 u.br.pC->rowidIsValid = 0;
70017 goto check_for_interrupt;
70018 }
70019
70020 /* Opcode: IdxInsert P1 P2 P3 * P5
70021 **
70022 ** Register P2 holds an SQL index key made using the
@@ -70426,11 +70558,11 @@
70558 */
70559 case OP_RowSetRead: { /* jump, in1, out3 */
70560 #if 0 /* local variables moved into u.cb */
70561 i64 val;
70562 #endif /* local variables moved into u.cb */
70563
70564 pIn1 = &aMem[pOp->p1];
70565 if( (pIn1->flags & MEM_RowSet)==0
70566 || sqlite3RowSetNext(pIn1->u.pRowSet, &u.cb.val)==0
70567 ){
70568 /* The boolean index is empty */
@@ -70438,11 +70570,11 @@
70570 pc = pOp->p2 - 1;
70571 }else{
70572 /* A value was pulled from the index */
70573 sqlite3VdbeMemSetInt64(&aMem[pOp->p3], u.cb.val);
70574 }
70575 goto check_for_interrupt;
70576 }
70577
70578 /* Opcode: RowSetTest P1 P2 P3 P4
70579 **
70580 ** Register P3 is assumed to hold a 64-bit integer value. If register P1
@@ -70658,11 +70790,13 @@
70790 ** If P1 is non-zero, the database constraint counter is incremented
70791 ** (deferred foreign key constraints). Otherwise, if P1 is zero, the
70792 ** statement counter is incremented (immediate foreign key constraints).
70793 */
70794 case OP_FkCounter: {
70795 if( db->flags & SQLITE_DeferFKs ){
70796 db->nDeferredImmCons += pOp->p2;
70797 }else if( pOp->p1 ){
70798 db->nDeferredCons += pOp->p2;
70799 }else{
70800 p->nFkConstraint += pOp->p2;
70801 }
70802 break;
@@ -70679,13 +70813,13 @@
70813 ** zero, the jump is taken if the statement constraint-counter is zero
70814 ** (immediate foreign key constraint violations).
70815 */
70816 case OP_FkIfZero: { /* jump */
70817 if( pOp->p1 ){
70818 if( db->nDeferredCons==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
70819 }else{
70820 if( p->nFkConstraint==0 && db->nDeferredImmCons==0 ) pc = pOp->p2-1;
70821 }
70822 break;
70823 }
70824 #endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */
70825
@@ -71367,11 +71501,11 @@
71501
71502 if( !u.cp.res ){
71503 /* If there is data, jump to P2 */
71504 pc = pOp->p2 - 1;
71505 }
71506 goto check_for_interrupt;
71507 }
71508 #endif /* SQLITE_OMIT_VIRTUALTABLE */
71509
71510 #ifndef SQLITE_OMIT_VIRTUALTABLE
71511 /* Opcode: VRename P1 * * P4 *
@@ -74092,15 +74226,24 @@
74226 /* Translate the schema name in zDb into a pointer to the corresponding
74227 ** schema. If not found, pSchema will remain NULL and nothing will match
74228 ** resulting in an appropriate error message toward the end of this routine
74229 */
74230 if( zDb ){
74231 testcase( pNC->ncFlags & NC_PartIdx );
74232 testcase( pNC->ncFlags & NC_IsCheck );
74233 if( (pNC->ncFlags & (NC_PartIdx|NC_IsCheck))!=0 ){
74234 /* Silently ignore database qualifiers inside CHECK constraints and partial
74235 ** indices. Do not raise errors because that might break legacy and
74236 ** because it does not hurt anything to just ignore the database name. */
74237 zDb = 0;
74238 }else{
74239 for(i=0; i<db->nDb; i++){
74240 assert( db->aDb[i].zName );
74241 if( sqlite3StrICmp(db->aDb[i].zName,zDb)==0 ){
74242 pSchema = db->aDb[i].pSchema;
74243 break;
74244 }
74245 }
74246 }
74247 }
74248
74249 /* Start at the inner-most context and move outward until a match is found */
@@ -74373,10 +74516,43 @@
74516 }
74517 ExprSetProperty(p, EP_Resolved);
74518 }
74519 return p;
74520 }
74521
74522 /*
74523 ** Report an error that an expression is not valid for a partial index WHERE
74524 ** clause.
74525 */
74526 static void notValidPartIdxWhere(
74527 Parse *pParse, /* Leave error message here */
74528 NameContext *pNC, /* The name context */
74529 const char *zMsg /* Type of error */
74530 ){
74531 if( (pNC->ncFlags & NC_PartIdx)!=0 ){
74532 sqlite3ErrorMsg(pParse, "%s prohibited in partial index WHERE clauses",
74533 zMsg);
74534 }
74535 }
74536
74537 #ifndef SQLITE_OMIT_CHECK
74538 /*
74539 ** Report an error that an expression is not valid for a CHECK constraint.
74540 */
74541 static void notValidCheckConstraint(
74542 Parse *pParse, /* Leave error message here */
74543 NameContext *pNC, /* The name context */
74544 const char *zMsg /* Type of error */
74545 ){
74546 if( (pNC->ncFlags & NC_IsCheck)!=0 ){
74547 sqlite3ErrorMsg(pParse,"%s prohibited in CHECK constraints", zMsg);
74548 }
74549 }
74550 #else
74551 # define notValidCheckConstraint(P,N,M)
74552 #endif
74553
74554
74555 /*
74556 ** This routine is callback for sqlite3WalkExpr().
74557 **
74558 ** Resolve symbolic names into TK_COLUMN operators for the current
@@ -74473,10 +74649,11 @@
74649 FuncDef *pDef; /* Information about the function */
74650 u8 enc = ENC(pParse->db); /* The database encoding */
74651
74652 testcase( pExpr->op==TK_CONST_FUNC );
74653 assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
74654 notValidPartIdxWhere(pParse, pNC, "functions");
74655 zId = pExpr->u.zToken;
74656 nId = sqlite3Strlen30(zId);
74657 pDef = sqlite3FindFunction(pParse->db, zId, nId, n, enc, 0);
74658 if( pDef==0 ){
74659 pDef = sqlite3FindFunction(pParse->db, zId, nId, -2, enc, 0);
@@ -74538,31 +74715,25 @@
74715 #endif
74716 case TK_IN: {
74717 testcase( pExpr->op==TK_IN );
74718 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
74719 int nRef = pNC->nRef;
74720 notValidCheckConstraint(pParse, pNC, "subqueries");
74721 notValidPartIdxWhere(pParse, pNC, "subqueries");
 
 
 
74722 sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
74723 assert( pNC->nRef>=nRef );
74724 if( nRef!=pNC->nRef ){
74725 ExprSetProperty(pExpr, EP_VarSelect);
74726 }
74727 }
74728 break;
74729 }
 
74730 case TK_VARIABLE: {
74731 notValidCheckConstraint(pParse, pNC, "parameters");
74732 notValidPartIdxWhere(pParse, pNC, "parameters");
 
74733 break;
74734 }
 
74735 }
74736 return (pParse->nErr || pParse->db->mallocFailed) ? WRC_Abort : WRC_Continue;
74737 }
74738
74739 /*
@@ -74649,11 +74820,11 @@
74820 /* Try to match the ORDER BY expression against an expression
74821 ** in the result set. Return an 1-based index of the matching
74822 ** result-set entry.
74823 */
74824 for(i=0; i<pEList->nExpr; i++){
74825 if( sqlite3ExprCompare(pEList->a[i].pExpr, pE, -1)<2 ){
74826 return i+1;
74827 }
74828 }
74829
74830 /* If no match, return 0. */
@@ -74877,11 +75048,11 @@
75048 pItem->iOrderByCol = 0;
75049 if( sqlite3ResolveExprNames(pNC, pE) ){
75050 return 1;
75051 }
75052 for(j=0; j<pSelect->pEList->nExpr; j++){
75053 if( sqlite3ExprCompare(pE, pSelect->pEList->a[j].pExpr, -1)==0 ){
75054 pItem->iOrderByCol = j+1;
75055 }
75056 }
75057 }
75058 return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
@@ -75183,10 +75354,52 @@
75354 w.xSelectCallback = resolveSelectStep;
75355 w.pParse = pParse;
75356 w.u.pNC = pOuterNC;
75357 sqlite3WalkSelect(&w, p);
75358 }
75359
75360 /*
75361 ** Resolve names in expressions that can only reference a single table:
75362 **
75363 ** * CHECK constraints
75364 ** * WHERE clauses on partial indices
75365 **
75366 ** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
75367 ** is set to -1 and the Expr.iColumn value is set to the column number.
75368 **
75369 ** Any errors cause an error message to be set in pParse.
75370 */
75371 SQLITE_PRIVATE void sqlite3ResolveSelfReference(
75372 Parse *pParse, /* Parsing context */
75373 Table *pTab, /* The table being referenced */
75374 int type, /* NC_IsCheck or NC_PartIdx */
75375 Expr *pExpr, /* Expression to resolve. May be NULL. */
75376 ExprList *pList /* Expression list to resolve. May be NUL. */
75377 ){
75378 SrcList sSrc; /* Fake SrcList for pParse->pNewTable */
75379 NameContext sNC; /* Name context for pParse->pNewTable */
75380 int i; /* Loop counter */
75381
75382 assert( type==NC_IsCheck || type==NC_PartIdx );
75383 memset(&sNC, 0, sizeof(sNC));
75384 memset(&sSrc, 0, sizeof(sSrc));
75385 sSrc.nSrc = 1;
75386 sSrc.a[0].zName = pTab->zName;
75387 sSrc.a[0].pTab = pTab;
75388 sSrc.a[0].iCursor = -1;
75389 sNC.pParse = pParse;
75390 sNC.pSrcList = &sSrc;
75391 sNC.ncFlags = type;
75392 if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
75393 if( pList ){
75394 for(i=0; i<pList->nExpr; i++){
75395 if( sqlite3ResolveExprNames(&sNC, pList->a[i].pExpr) ){
75396 return;
75397 }
75398 }
75399 }
75400 }
75401
75402 /************** End of resolve.c *********************************************/
75403 /************** Begin file expr.c ********************************************/
75404 /*
75405 ** 2001 September 15
@@ -76879,14 +77092,13 @@
77092 #endif
77093
77094 switch( pExpr->op ){
77095 case TK_IN: {
77096 char affinity; /* Affinity of the LHS of the IN */
 
 
77097 int addr; /* Address of OP_OpenEphemeral instruction */
77098 Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
77099 KeyInfo *pKeyInfo = 0; /* Key information */
77100
77101 if( rMayHaveNull ){
77102 sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
77103 }
77104
@@ -76906,13 +77118,11 @@
77118 ** is used.
77119 */
77120 pExpr->iTable = pParse->nTab++;
77121 addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, !isRowid);
77122 if( rMayHaveNull==0 ) sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
77123 pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, 1);
 
 
77124
77125 if( ExprHasProperty(pExpr, EP_xIsSelect) ){
77126 /* Case 1: expr IN (SELECT ...)
77127 **
77128 ** Generate code to write the results of the select into the temporary
@@ -76925,15 +77135,16 @@
77135 sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
77136 dest.affSdst = (u8)affinity;
77137 assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
77138 pExpr->x.pSelect->iLimit = 0;
77139 if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){
77140 sqlite3DbFree(pParse->db, pKeyInfo);
77141 return 0;
77142 }
77143 pEList = pExpr->x.pSelect->pEList;
77144 if( pKeyInfo && ALWAYS(pEList!=0 && pEList->nExpr>0) ){
77145 pKeyInfo->aColl[0] = sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft,
77146 pEList->a[0].pExpr);
77147 }
77148 }else if( ALWAYS(pExpr->x.pList!=0) ){
77149 /* Case 2: expr IN (exprlist)
77150 **
@@ -76948,12 +77159,13 @@
77159 int r1, r2, r3;
77160
77161 if( !affinity ){
77162 affinity = SQLITE_AFF_NONE;
77163 }
77164 if( pKeyInfo ){
77165 pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
77166 }
77167
77168 /* Loop through each expression in <exprlist>. */
77169 r1 = sqlite3GetTempReg(pParse);
77170 r2 = sqlite3GetTempReg(pParse);
77171 sqlite3VdbeAddOp2(v, OP_Null, 0, r2);
@@ -76988,12 +77200,12 @@
77200 }
77201 }
77202 sqlite3ReleaseTempReg(pParse, r1);
77203 sqlite3ReleaseTempReg(pParse, r2);
77204 }
77205 if( pKeyInfo ){
77206 sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO_HANDOFF);
77207 }
77208 break;
77209 }
77210
77211 case TK_EXISTS:
@@ -77549,19 +77761,24 @@
77761 break;
77762 }
77763 /* Otherwise, fall thru into the TK_COLUMN case */
77764 }
77765 case TK_COLUMN: {
77766 int iTab = pExpr->iTable;
77767 if( iTab<0 ){
77768 if( pParse->ckBase>0 ){
77769 /* Generating CHECK constraints or inserting into partial index */
77770 inReg = pExpr->iColumn + pParse->ckBase;
77771 break;
77772 }else{
77773 /* Deleting from a partial index */
77774 iTab = pParse->iPartIdxTab;
77775 }
77776 }
77777 inReg = sqlite3ExprCodeGetColumn(pParse, pExpr->pTab,
77778 pExpr->iColumn, iTab, target,
77779 pExpr->op2);
77780 break;
77781 }
77782 case TK_INTEGER: {
77783 codeInteger(pParse, pExpr, 0, target);
77784 break;
@@ -78980,10 +79197,16 @@
79197 ** Do a deep comparison of two expression trees. Return 0 if the two
79198 ** expressions are completely identical. Return 1 if they differ only
79199 ** by a COLLATE operator at the top level. Return 2 if there are differences
79200 ** other than the top-level COLLATE operator.
79201 **
79202 ** If any subelement of pB has Expr.iTable==(-1) then it is allowed
79203 ** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
79204 **
79205 ** The pA side might be using TK_REGISTER. If that is the case and pB is
79206 ** not using TK_REGISTER but is otherwise equivalent, then still return 0.
79207 **
79208 ** Sometimes this routine will return 2 even if the two expressions
79209 ** really are equivalent. If we cannot prove that the expressions are
79210 ** identical, we return 2 just to be safe. So if this routine
79211 ** returns 2, then you do not really know for certain if the two
79212 ** expressions are the same. But if you get a 0 or 1 return, then you
@@ -78990,33 +79213,36 @@
79213 ** can be sure the expressions are the same. In the places where
79214 ** this routine is used, it does not hurt to get an extra 2 - that
79215 ** just might result in some slightly slower code. But returning
79216 ** an incorrect 0 or 1 could lead to a malfunction.
79217 */
79218 SQLITE_PRIVATE int sqlite3ExprCompare(Expr *pA, Expr *pB, int iTab){
79219 if( pA==0||pB==0 ){
79220 return pB==pA ? 0 : 2;
79221 }
79222 assert( !ExprHasAnyProperty(pA, EP_TokenOnly|EP_Reduced) );
79223 assert( !ExprHasAnyProperty(pB, EP_TokenOnly|EP_Reduced) );
79224 if( ExprHasProperty(pA, EP_xIsSelect) || ExprHasProperty(pB, EP_xIsSelect) ){
79225 return 2;
79226 }
79227 if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
79228 if( pA->op!=pB->op && (pA->op!=TK_REGISTER || pA->op2!=pB->op) ){
79229 if( pA->op==TK_COLLATE && sqlite3ExprCompare(pA->pLeft, pB, iTab)<2 ){
79230 return 1;
79231 }
79232 if( pB->op==TK_COLLATE && sqlite3ExprCompare(pA, pB->pLeft, iTab)<2 ){
79233 return 1;
79234 }
79235 return 2;
79236 }
79237 if( sqlite3ExprCompare(pA->pLeft, pB->pLeft, iTab) ) return 2;
79238 if( sqlite3ExprCompare(pA->pRight, pB->pRight, iTab) ) return 2;
79239 if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
79240 if( pA->iColumn!=pB->iColumn ) return 2;
79241 if( pA->iTable!=pB->iTable
79242 && pA->op!=TK_REGISTER
79243 && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
79244 if( ExprHasProperty(pA, EP_IntValue) ){
79245 if( !ExprHasProperty(pB, EP_IntValue) || pA->u.iValue!=pB->u.iValue ){
79246 return 2;
79247 }
79248 }else if( pA->op!=TK_COLUMN && ALWAYS(pA->op!=TK_AGG_COLUMN) && pA->u.zToken){
@@ -79030,28 +79256,70 @@
79256
79257 /*
79258 ** Compare two ExprList objects. Return 0 if they are identical and
79259 ** non-zero if they differ in any way.
79260 **
79261 ** If any subelement of pB has Expr.iTable==(-1) then it is allowed
79262 ** to compare equal to an equivalent element in pA with Expr.iTable==iTab.
79263 **
79264 ** This routine might return non-zero for equivalent ExprLists. The
79265 ** only consequence will be disabled optimizations. But this routine
79266 ** must never return 0 if the two ExprList objects are different, or
79267 ** a malfunction will result.
79268 **
79269 ** Two NULL pointers are considered to be the same. But a NULL pointer
79270 ** always differs from a non-NULL pointer.
79271 */
79272 SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
79273 int i;
79274 if( pA==0 && pB==0 ) return 0;
79275 if( pA==0 || pB==0 ) return 1;
79276 if( pA->nExpr!=pB->nExpr ) return 1;
79277 for(i=0; i<pA->nExpr; i++){
79278 Expr *pExprA = pA->a[i].pExpr;
79279 Expr *pExprB = pB->a[i].pExpr;
79280 if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1;
79281 if( sqlite3ExprCompare(pExprA, pExprB, iTab) ) return 1;
79282 }
79283 return 0;
79284 }
79285
79286 /*
79287 ** Return true if we can prove the pE2 will always be true if pE1 is
79288 ** true. Return false if we cannot complete the proof or if pE2 might
79289 ** be false. Examples:
79290 **
79291 ** pE1: x==5 pE2: x==5 Result: true
79292 ** pE1: x>0 pE2: x==5 Result: false
79293 ** pE1: x=21 pE2: x=21 OR y=43 Result: true
79294 ** pE1: x!=123 pE2: x IS NOT NULL Result: true
79295 ** pE1: x!=?1 pE2: x IS NOT NULL Result: true
79296 ** pE1: x IS NULL pE2: x IS NOT NULL Result: false
79297 ** pE1: x IS ?2 pE2: x IS NOT NULL Reuslt: false
79298 **
79299 ** When comparing TK_COLUMN nodes between pE1 and pE2, if pE2 has
79300 ** Expr.iTable<0 then assume a table number given by iTab.
79301 **
79302 ** When in doubt, return false. Returning true might give a performance
79303 ** improvement. Returning false might cause a performance reduction, but
79304 ** it will always give the correct answer and is hence always safe.
79305 */
79306 SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Expr *pE1, Expr *pE2, int iTab){
79307 if( sqlite3ExprCompare(pE1, pE2, iTab)==0 ){
79308 return 1;
79309 }
79310 if( pE2->op==TK_OR
79311 && (sqlite3ExprImpliesExpr(pE1, pE2->pLeft, iTab)
79312 || sqlite3ExprImpliesExpr(pE1, pE2->pRight, iTab) )
79313 ){
79314 return 1;
79315 }
79316 if( pE2->op==TK_NOTNULL
79317 && sqlite3ExprCompare(pE1->pLeft, pE2->pLeft, iTab)==0
79318 && (pE1->op!=TK_ISNULL && pE1->op!=TK_IS)
79319 ){
79320 return 1;
79321 }
79322 return 0;
79323 }
79324
79325 /*
@@ -79232,11 +79500,11 @@
79500 /* Check to see if pExpr is a duplicate of another aggregate
79501 ** function that is already in the pAggInfo structure
79502 */
79503 struct AggInfo_func *pItem = pAggInfo->aFunc;
79504 for(i=0; i<pAggInfo->nFunc; i++, pItem++){
79505 if( sqlite3ExprCompare(pItem->pExpr, pExpr, -1)==0 ){
79506 break;
79507 }
79508 }
79509 if( i>=pAggInfo->nFunc ){
79510 /* pExpr is original. Make a new entry in pAggInfo->aFunc[]
@@ -80649,10 +80917,11 @@
80917 int i; /* Loop counter */
80918 int topOfLoop; /* The top of the loop */
80919 int endOfLoop; /* The end of the loop */
80920 int jZeroRows = -1; /* Jump from here if number of rows is zero */
80921 int iDb; /* Index of database containing pTab */
80922 u8 needTableCnt = 1; /* True to count the table */
80923 int regTabname = iMem++; /* Register containing table name */
80924 int regIdxname = iMem++; /* Register containing index name */
80925 int regStat1 = iMem++; /* The stat column of sqlite_stat1 */
80926 #ifdef SQLITE_ENABLE_STAT3
80927 int regNumEq = regStat1; /* Number of instances. Same as regStat1 */
@@ -80708,10 +80977,11 @@
80977 KeyInfo *pKey;
80978 int addrIfNot = 0; /* address of OP_IfNot */
80979 int *aChngAddr; /* Array of jump instruction addresses */
80980
80981 if( pOnlyIdx && pOnlyIdx!=pIdx ) continue;
80982 if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0;
80983 VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName));
80984 nCol = pIdx->nColumn;
80985 aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol);
80986 if( aChngAddr==0 ) continue;
80987 pKey = sqlite3IndexKeyinfo(pParse, pIdx);
@@ -80867,48 +81137,45 @@
81137 ** If K==0 then no entry is made into the sqlite_stat1 table.
81138 ** If K>0 then it is always the case the D>0 so division by zero
81139 ** is never possible.
81140 */
81141 sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1);
81142 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem);
 
 
81143 for(i=0; i<nCol; i++){
81144 sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0);
81145 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
81146 sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp);
81147 sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1);
81148 sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp);
81149 sqlite3VdbeAddOp1(v, OP_ToInt, regTemp);
81150 sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1);
81151 }
81152 if( pIdx->pPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows);
81153 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
81154 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
81155 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
81156 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
81157 if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows);
81158 }
81159
81160 /* Create a single sqlite_stat1 entry containing NULL as the index
81161 ** name and the row count as the content.
81162 */
81163 if( pOnlyIdx==0 && needTableCnt ){
81164 sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb);
81165 VdbeComment((v, "%s", pTab->zName));
81166 sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1);
81167 sqlite3VdbeAddOp1(v, OP_Close, iIdxCur);
81168 jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1);
81169 sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
81170 sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0);
81171 sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
81172 sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid);
81173 sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
81174 sqlite3VdbeJumpHere(v, jZeroRows);
81175 }
81176 if( pParse->nMem<regRec ) pParse->nMem = regRec;
 
 
 
81177 }
81178
81179
81180 /*
81181 ** Generate code that will cause the most recent index analysis to
@@ -81087,12 +81354,14 @@
81354 v = 0;
81355 while( (c=z[0])>='0' && c<='9' ){
81356 v = v*10 + c - '0';
81357 z++;
81358 }
81359 if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){
81360 if( v>0 ) pTable->nRowEst = v;
81361 if( pIndex==0 ) break;
81362 }
81363 pIndex->aiRowEst[i] = v;
81364 if( *z==' ' ) z++;
81365 if( strcmp(z, "unordered")==0 ){
81366 pIndex->bUnordered = 1;
81367 break;
@@ -82528,10 +82797,11 @@
82797 */
82798 static void freeIndex(sqlite3 *db, Index *p){
82799 #ifndef SQLITE_OMIT_ANALYZE
82800 sqlite3DeleteIndexSamples(db, p);
82801 #endif
82802 sqlite3ExprDelete(db, p->pPartIdxWhere);
82803 sqlite3DbFree(db, p->zColAff);
82804 sqlite3DbFree(db, p);
82805 }
82806
82807 /*
@@ -83371,11 +83641,12 @@
83641 sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an "
83642 "INTEGER PRIMARY KEY");
83643 #endif
83644 }else{
83645 Index *p;
83646 p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0,
83647 0, sortOrder, 0);
83648 if( p ){
83649 p->autoIndex = 2;
83650 }
83651 pList = 0;
83652 }
@@ -83666,30 +83937,11 @@
83937
83938 #ifndef SQLITE_OMIT_CHECK
83939 /* Resolve names in all CHECK constraint expressions.
83940 */
83941 if( p->pCheck ){
83942 sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83943 }
83944 #endif /* !defined(SQLITE_OMIT_CHECK) */
83945
83946 /* If the db->init.busy is 1 it means we are reading the SQL off the
83947 ** "sqlite_master" or "sqlite_temp_master" table on the disk.
@@ -84537,10 +84789,11 @@
84789 int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */
84790 int iSorter; /* Cursor opened by OpenSorter (if in use) */
84791 int addr1; /* Address of top of loop */
84792 int addr2; /* Address to jump to for next iteration */
84793 int tnum; /* Root page of index */
84794 int iPartIdxLabel; /* Jump to this label to skip a row */
84795 Vdbe *v; /* Generate code into this virtual machine */
84796 KeyInfo *pKey; /* KeyInfo for index */
84797 int regRecord; /* Register holding assemblied index record */
84798 sqlite3 *db = pParse->db; /* The database connection */
84799 int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema);
@@ -84576,12 +84829,13 @@
84829 ** records into the sorter. */
84830 sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead);
84831 addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
84832 regRecord = sqlite3GetTempReg(pParse);
84833
84834 sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 1, &iPartIdxLabel);
84835 sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
84836 sqlite3VdbeResolveLabel(v, iPartIdxLabel);
84837 sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
84838 sqlite3VdbeJumpHere(v, addr1);
84839 addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0);
84840 if( pIndex->onError!=OE_None ){
84841 int j2 = sqlite3VdbeCurrentAddr(v) + 3;
@@ -84628,11 +84882,11 @@
84882 Token *pName2, /* Second part of index name. May be NULL */
84883 SrcList *pTblName, /* Table to index. Use pParse->pNewTable if 0 */
84884 ExprList *pList, /* A list of columns to be indexed */
84885 int onError, /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */
84886 Token *pStart, /* The CREATE token that begins this statement */
84887 Expr *pPIWhere, /* WHERE clause for partial indices */
84888 int sortOrder, /* Sort order of primary key when pList==NULL */
84889 int ifNotExist /* Omit error if index already exists */
84890 ){
84891 Index *pRet = 0; /* Pointer to return */
84892 Table *pTab = 0; /* Table to be indexed */
@@ -84650,11 +84904,10 @@
84904 struct ExprList_item *pListItem; /* For looping over pList */
84905 int nCol;
84906 int nExtra = 0;
84907 char *zExtra;
84908
 
84909 assert( pParse->nErr==0 ); /* Never called with prior errors */
84910 if( db->mallocFailed || IN_DECLARE_VTAB ){
84911 goto exit_create_index;
84912 }
84913 if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){
@@ -84696,11 +84949,16 @@
84949 assert(0);
84950 }
84951 pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]);
84952 assert( db->mallocFailed==0 || pTab==0 );
84953 if( pTab==0 ) goto exit_create_index;
84954 if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){
84955 sqlite3ErrorMsg(pParse,
84956 "cannot create a TEMP index on non-TEMP table \"%s\"",
84957 pTab->zName);
84958 goto exit_create_index;
84959 }
84960 }else{
84961 assert( pName==0 );
84962 assert( pStart==0 );
84963 pTab = pParse->pNewTable;
84964 if( !pTab ) goto exit_create_index;
@@ -84845,10 +85103,15 @@
85103 pIndex->nColumn = pList->nExpr;
85104 pIndex->onError = (u8)onError;
85105 pIndex->uniqNotNull = onError==OE_Abort;
85106 pIndex->autoIndex = (u8)(pName==0);
85107 pIndex->pSchema = db->aDb[iDb].pSchema;
85108 if( pPIWhere ){
85109 sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0);
85110 pIndex->pPartIdxWhere = pPIWhere;
85111 pPIWhere = 0;
85112 }
85113 assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
85114
85115 /* Check to see if we should honor DESC requests on index columns
85116 */
85117 if( pDb->pSchema->file_format>=4 ){
@@ -85000,11 +85263,11 @@
85263 ** If pTblName==0 it means this index is generated as a primary key
85264 ** or UNIQUE constraint of a CREATE TABLE statement. Since the table
85265 ** has just been created, it contains no data and the index initialization
85266 ** step can be skipped.
85267 */
85268 else if( pParse->nErr==0 ){
85269 Vdbe *v;
85270 char *zStmt;
85271 int iMem = ++pParse->nMem;
85272
85273 v = sqlite3GetVdbe(pParse);
@@ -85018,16 +85281,15 @@
85281
85282 /* Gather the complete text of the CREATE INDEX statement into
85283 ** the zStmt variable
85284 */
85285 if( pStart ){
85286 int n = (pParse->sLastToken.z - pName->z) + pParse->sLastToken.n;
85287 if( pName->z[n-1]==';' ) n--;
85288 /* A named index with an explicit CREATE INDEX statement */
85289 zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s",
85290 onError==OE_None ? "" : " UNIQUE", n, pName->z);
 
 
85291 }else{
85292 /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */
85293 /* zStmt = sqlite3MPrintf(""); */
85294 zStmt = 0;
85295 }
@@ -85079,14 +85341,12 @@
85341 pIndex = 0;
85342 }
85343
85344 /* Clean up before exiting */
85345 exit_create_index:
85346 if( pIndex ) freeIndex(db, pIndex);
85347 sqlite3ExprDelete(db, pPIWhere);
 
 
85348 sqlite3ExprListDelete(db, pList);
85349 sqlite3SrcListDelete(db, pTblName);
85350 sqlite3DbFree(db, zName);
85351 return pRet;
85352 }
@@ -85960,29 +86220,24 @@
86220 ** the error.
86221 */
86222 SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){
86223 int i;
86224 int nCol = pIdx->nColumn;
86225 KeyInfo *pKey;
86226
86227 pKey = sqlite3KeyInfoAlloc(pParse->db, nCol);
86228 if( pKey ){
 
 
 
 
86229 for(i=0; i<nCol; i++){
86230 char *zColl = pIdx->azColl[i];
86231 assert( zColl );
86232 pKey->aColl[i] = sqlite3LocateCollSeq(pParse, zColl);
86233 pKey->aSortOrder[i] = pIdx->aSortOrder[i];
86234 }
 
86235 }
86236
86237 if( pParse->nErr ){
86238 sqlite3DbFree(pParse->db, pKey);
86239 pKey = 0;
86240 }
86241 return pKey;
86242 }
86243
@@ -87058,15 +87313,18 @@
87313 int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
87314 ){
87315 int i;
87316 Index *pIdx;
87317 int r1;
87318 int iPartIdxLabel;
87319 Vdbe *v = pParse->pVdbe;
87320
87321 for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){
87322 if( aRegIdx!=0 && aRegIdx[i-1]==0 ) continue;
87323 r1 = sqlite3GenerateIndexKey(pParse, pIdx, iCur, 0, 0, &iPartIdxLabel);
87324 sqlite3VdbeAddOp3(v, OP_IdxDelete, iCur+i, r1, pIdx->nColumn+1);
87325 sqlite3VdbeResolveLabel(v, iPartIdxLabel);
87326 }
87327 }
87328
87329 /*
87330 ** Generate code that will assemble an index key and put it in register
@@ -87076,24 +87334,42 @@
87334 **
87335 ** Return a register number which is the first in a block of
87336 ** registers that holds the elements of the index key. The
87337 ** block of registers has already been deallocated by the time
87338 ** this routine returns.
87339 **
87340 ** If *piPartIdxLabel is not NULL, fill it in with a label and jump
87341 ** to that label if pIdx is a partial index that should be skipped.
87342 ** A partial index should be skipped if its WHERE clause evaluates
87343 ** to false or null. If pIdx is not a partial index, *piPartIdxLabel
87344 ** will be set to zero which is an empty label that is ignored by
87345 ** sqlite3VdbeResolveLabel().
87346 */
87347 SQLITE_PRIVATE int sqlite3GenerateIndexKey(
87348 Parse *pParse, /* Parsing context */
87349 Index *pIdx, /* The index for which to generate a key */
87350 int iCur, /* Cursor number for the pIdx->pTable table */
87351 int regOut, /* Write the new index key to this register */
87352 int doMakeRec, /* Run the OP_MakeRecord instruction if true */
87353 int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
87354 ){
87355 Vdbe *v = pParse->pVdbe;
87356 int j;
87357 Table *pTab = pIdx->pTable;
87358 int regBase;
87359 int nCol;
87360
87361 if( piPartIdxLabel ){
87362 if( pIdx->pPartIdxWhere ){
87363 *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
87364 pParse->iPartIdxTab = iCur;
87365 sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel,
87366 SQLITE_JUMPIFNULL);
87367 }else{
87368 *piPartIdxLabel = 0;
87369 }
87370 }
87371 nCol = pIdx->nColumn;
87372 regBase = sqlite3GetTempRange(pParse, nCol+1);
87373 sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regBase+nCol);
87374 for(j=0; j<nCol; j++){
87375 int idx = pIdx->aiColumn[j];
@@ -89262,11 +89538,14 @@
89538 sqlite3ReleaseTempReg(pParse, regRec);
89539 sqlite3ReleaseTempRange(pParse, regTemp, nCol);
89540 }
89541 }
89542
89543 if( !pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs)
89544 && !pParse->pToplevel
89545 && !pParse->isMultiWrite
89546 ){
89547 /* Special case: If this is an INSERT statement that will insert exactly
89548 ** one row into the table, raise a constraint immediately instead of
89549 ** incrementing a counter. This is necessary as the VM code is being
89550 ** generated for will not open a statement transaction. */
89551 assert( nIncr==1 );
@@ -89653,11 +89932,13 @@
89932 for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){
89933 Index *pIdx = 0; /* Foreign key index for pFKey */
89934 SrcList *pSrc;
89935 int *aiCol = 0;
89936
89937 if( !pFKey->isDeferred && !(db->flags & SQLITE_DeferFKs)
89938 && !pParse->pToplevel && !pParse->isMultiWrite
89939 ){
89940 assert( regOld==0 && regNew!=0 );
89941 /* Inserting a single row into a parent table cannot cause an immediate
89942 ** foreign key violation. So do nothing in this case. */
89943 continue;
89944 }
@@ -91448,12 +91729,22 @@
91729 ** Add the new records to the indices as we go.
91730 */
91731 for(iCur=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, iCur++){
91732 int regIdx;
91733 int regR;
91734 int addrSkipRow = 0;
91735
91736 if( aRegIdx[iCur]==0 ) continue; /* Skip unused indices */
91737
91738 if( pIdx->pPartIdxWhere ){
91739 sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[iCur]);
91740 addrSkipRow = sqlite3VdbeMakeLabel(v);
91741 pParse->ckBase = regData;
91742 sqlite3ExprIfFalse(pParse, pIdx->pPartIdxWhere, addrSkipRow,
91743 SQLITE_JUMPIFNULL);
91744 pParse->ckBase = 0;
91745 }
91746
91747 /* Create a key for accessing the index entry */
91748 regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn+1);
91749 for(i=0; i<pIdx->nColumn; i++){
91750 int idx = pIdx->aiColumn[i];
@@ -91470,10 +91761,11 @@
91761
91762 /* Find out what action to take in case there is an indexing conflict */
91763 onError = pIdx->onError;
91764 if( onError==OE_None ){
91765 sqlite3ReleaseTempRange(pParse, regIdx, pIdx->nColumn+1);
91766 sqlite3VdbeResolveLabel(v, addrSkipRow);
91767 continue; /* pIdx is not a UNIQUE index */
91768 }
91769 if( overrideError!=OE_Default ){
91770 onError = overrideError;
91771 }else if( onError==OE_Default ){
@@ -91539,10 +91831,11 @@
91831 seenReplace = 1;
91832 break;
91833 }
91834 }
91835 sqlite3VdbeJumpHere(v, j3);
91836 sqlite3VdbeResolveLabel(v, addrSkipRow);
91837 sqlite3ReleaseTempReg(pParse, regR);
91838 }
91839
91840 if( pbMayReplace ){
91841 *pbMayReplace = seenReplace;
@@ -91568,22 +91861,23 @@
91861 int appendBias, /* True if this is likely to be an append */
91862 int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */
91863 ){
91864 int i;
91865 Vdbe *v;
 
91866 Index *pIdx;
91867 u8 pik_flags;
91868 int regData;
91869 int regRec;
91870
91871 v = sqlite3GetVdbe(pParse);
91872 assert( v!=0 );
91873 assert( pTab->pSelect==0 ); /* This table is not a VIEW */
91874 for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
 
91875 if( aRegIdx[i]==0 ) continue;
91876 if( pIdx->pPartIdxWhere ){
91877 sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2);
91878 }
91879 sqlite3VdbeAddOp2(v, OP_IdxInsert, baseCur+i+1, aRegIdx[i]);
91880 if( useSeekResult ){
91881 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
91882 }
91883 }
@@ -91681,10 +91975,11 @@
91975 **
91976 ** * The index is over the same set of columns
91977 ** * The same DESC and ASC markings occurs on all columns
91978 ** * The same onError processing (OE_Abort, OE_Ignore, etc)
91979 ** * The same collating sequence on each column
91980 ** * The index has the exact same WHERE clause
91981 */
91982 static int xferCompatibleIndex(Index *pDest, Index *pSrc){
91983 int i;
91984 assert( pDest && pSrc );
91985 assert( pDest->pTable!=pSrc->pTable );
@@ -91702,10 +91997,13 @@
91997 return 0; /* Different sort orders */
91998 }
91999 if( !xferCompatibleCollation(pSrc->azColl[i],pDest->azColl[i]) ){
92000 return 0; /* Different collating sequences */
92001 }
92002 }
92003 if( sqlite3ExprCompare(pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){
92004 return 0; /* Different WHERE clauses */
92005 }
92006
92007 /* If no test above fails then the indices must be compatible */
92008 return 1;
92009 }
@@ -91858,11 +92156,11 @@
92156 if( pSrcIdx==0 ){
92157 return 0; /* pDestIdx has no corresponding index in pSrc */
92158 }
92159 }
92160 #ifndef SQLITE_OMIT_CHECK
92161 if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
92162 return 0; /* Tables have different CHECK constraints. Ticket #2252 */
92163 }
92164 #endif
92165 #ifndef SQLITE_OMIT_FOREIGN_KEY
92166 /* Disallow the transfer optimization if the destination table constains
@@ -92615,15 +92913,18 @@
92913 #ifndef SQLITE_CORE
92914 /* This case when the file really is being compiled as a loadable
92915 ** extension */
92916 # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0;
92917 # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v;
92918 # define SQLITE_EXTENSION_INIT3 \
92919 extern const sqlite3_api_routines *sqlite3_api;
92920 #else
92921 /* This case when the file is being statically linked into the
92922 ** application */
92923 # define SQLITE_EXTENSION_INIT1 /*no-op*/
92924 # define SQLITE_EXTENSION_INIT2(v) (void)v; /* unused parameter */
92925 # define SQLITE_EXTENSION_INIT3 /*no-op*/
92926 #endif
92927
92928 #endif /* _SQLITE3EXT_H_ */
92929
92930 /************** End of sqlite3ext.h ******************************************/
@@ -93275,10 +93576,39 @@
93576 sqlite3_mutex_leave(mutex);
93577 assert( (rc&0xff)==rc );
93578 return rc;
93579 }
93580 }
93581
93582 /*
93583 ** Cancel a prior call to sqlite3_auto_extension. Remove xInit from the
93584 ** set of routines that is invoked for each new database connection, if it
93585 ** is currently on the list. If xInit is not on the list, then this
93586 ** routine is a no-op.
93587 **
93588 ** Return 1 if xInit was found on the list and removed. Return 0 if xInit
93589 ** was not on the list.
93590 */
93591 SQLITE_API int sqlite3_cancel_auto_extension(void (*xInit)(void)){
93592 #if SQLITE_THREADSAFE
93593 sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
93594 #endif
93595 int i;
93596 int n = 0;
93597 wsdAutoextInit;
93598 sqlite3_mutex_enter(mutex);
93599 for(i=wsdAutoext.nExt-1; i>=0; i--){
93600 if( wsdAutoext.aExt[i]==xInit ){
93601 wsdAutoext.nExt--;
93602 wsdAutoext.aExt[i] = wsdAutoext.aExt[wsdAutoext.nExt];
93603 n++;
93604 break;
93605 }
93606 }
93607 sqlite3_mutex_leave(mutex);
93608 return n;
93609 }
93610
93611 /*
93612 ** Reset the automatic extension loading mechanism.
93613 */
93614 SQLITE_API void sqlite3_reset_auto_extension(void){
@@ -93516,10 +93846,11 @@
93846 { "empty_result_callbacks", SQLITE_NullCallback },
93847 { "legacy_file_format", SQLITE_LegacyFileFmt },
93848 { "fullfsync", SQLITE_FullFSync },
93849 { "checkpoint_fullfsync", SQLITE_CkptFullFSync },
93850 { "reverse_unordered_selects", SQLITE_ReverseOrder },
93851 { "query_only", SQLITE_QueryOnly },
93852 #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
93853 { "automatic_index", SQLITE_AutoIndex },
93854 #endif
93855 #ifdef SQLITE_DEBUG
93856 { "sql_trace", SQLITE_SqlTrace },
@@ -93536,16 +93867,17 @@
93867 { "writable_schema", SQLITE_WriteSchema|SQLITE_RecoveryMode },
93868
93869 /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted
93870 ** flag if there are any active statements. */
93871 { "read_uncommitted", SQLITE_ReadUncommitted },
93872 { "recursive_triggers", SQLITE_RecTriggers },
93873
93874 /* This flag may only be set if both foreign-key and trigger support
93875 ** are present in the build. */
93876 #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
93877 { "foreign_keys", SQLITE_ForeignKeys },
93878 { "defer_foreign_keys", SQLITE_DeferFKs },
93879 #endif
93880 };
93881 int i;
93882 const struct sPragmaType *p;
93883 for(i=0, p=aPragma; i<ArraySize(aPragma); i++, p++){
@@ -93567,10 +93899,11 @@
93899
93900 if( sqlite3GetBoolean(zRight, 0) ){
93901 db->flags |= mask;
93902 }else{
93903 db->flags &= ~mask;
93904 if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0;
93905 }
93906
93907 /* Many of the flag-pragmas modify the code generated by the SQL
93908 ** compiler (eg. count_changes). So add an opcode to expire all
93909 ** compiled SQL statements after modifying a pragma value.
@@ -94736,13 +95069,11 @@
95069 cnt++;
95070 }
95071 }
95072
95073 /* Make sure sufficient number of registers have been allocated */
95074 pParse->nMem = MAX( pParse->nMem, cnt+7 );
 
 
95075
95076 /* Do the b-tree integrity checks */
95077 sqlite3VdbeAddOp3(v, OP_IntegrityCk, 2, cnt, 1);
95078 sqlite3VdbeChangeP5(v, (u8)i);
95079 addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2);
@@ -94763,16 +95094,19 @@
95094
95095 if( pTab->pIndex==0 ) continue;
95096 addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Stop if out of errors */
95097 sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
95098 sqlite3VdbeJumpHere(v, addr);
95099 sqlite3ExprCacheClear(pParse);
95100 sqlite3OpenTableAndIndices(pParse, pTab, 1, OP_OpenRead);
95101 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
95102 sqlite3VdbeAddOp2(v, OP_Integer, 0, 7+j); /* index entries counter */
95103 }
95104 pParse->nMem = MAX(pParse->nMem, 7+j);
95105 loopTop = sqlite3VdbeAddOp2(v, OP_Rewind, 1, 0) + 1;
95106 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
95107 int jmp2, jmp3;
95108 int r1;
95109 static const VdbeOpList idxErr[] = {
95110 { OP_AddImm, 1, -1, 0},
95111 { OP_String8, 0, 3, 0}, /* 1 */
95112 { OP_Rowid, 1, 4, 0},
@@ -94783,47 +95117,38 @@
95117 { OP_Concat, 6, 3, 3},
95118 { OP_ResultRow, 3, 1, 0},
95119 { OP_IfPos, 1, 0, 0}, /* 9 */
95120 { OP_Halt, 0, 0, 0},
95121 };
95122 r1 = sqlite3GenerateIndexKey(pParse, pIdx, 1, 3, 0, &jmp3);
95123 sqlite3VdbeAddOp2(v, OP_AddImm, 7+j, 1); /* increment entry count */
95124 jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, j+2, 0, r1, pIdx->nColumn+1);
95125 addr = sqlite3VdbeAddOpList(v, ArraySize(idxErr), idxErr);
95126 sqlite3VdbeChangeP4(v, addr+1, "rowid ", P4_STATIC);
95127 sqlite3VdbeChangeP4(v, addr+3, " missing from index ", P4_STATIC);
95128 sqlite3VdbeChangeP4(v, addr+4, pIdx->zName, P4_TRANSIENT);
95129 sqlite3VdbeJumpHere(v, addr+9);
95130 sqlite3VdbeJumpHere(v, jmp2);
95131 sqlite3VdbeResolveLabel(v, jmp3);
95132 }
95133 sqlite3VdbeAddOp2(v, OP_Next, 1, loopTop);
95134 sqlite3VdbeJumpHere(v, loopTop-1);
95135 #ifndef SQLITE_OMIT_BTREECOUNT
95136 sqlite3VdbeAddOp4(v, OP_String8, 0, 2, 0,
95137 "wrong # of entries in index ", P4_STATIC);
95138 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
95139 addr = sqlite3VdbeCurrentAddr(v);
95140 sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr+2);
 
 
 
 
 
 
 
 
 
 
 
95141 sqlite3VdbeAddOp2(v, OP_Halt, 0, 0);
95142 sqlite3VdbeAddOp2(v, OP_Count, j+2, 3);
95143 sqlite3VdbeAddOp3(v, OP_Eq, 7+j, addr+8, 3);
95144 sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1);
95145 sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pIdx->zName, P4_TRANSIENT);
95146 sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
95147 sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
95148 }
95149 #endif /* SQLITE_OMIT_BTREECOUNT */
 
 
 
95150 }
95151 }
95152 addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode);
95153 sqlite3VdbeChangeP2(v, addr, -mxErr);
95154 sqlite3VdbeJumpHere(v, addr+1);
@@ -95979,10 +96304,16 @@
96304
96305 assert( ppStmt );
96306 *ppStmt = 0;
96307 if( !sqlite3SafetyCheckOk(db) ){
96308 return SQLITE_MISUSE_BKPT;
96309 }
96310 if( nBytes>=0 ){
96311 int sz;
96312 const char *z = (const char*)zSql;
96313 for(sz=0; sz<nBytes && (z[sz]!=0 || z[sz+1]!=0); sz += 2){}
96314 nBytes = sz;
96315 }
96316 sqlite3_mutex_enter(db->mutex);
96317 zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE);
96318 if( zSql8 ){
96319 rc = sqlite3LockAndPrepare(db, zSql8, -1, saveSqlFlag, 0, ppStmt, &zTail8);
@@ -96840,10 +97171,29 @@
97171 */
97172 if( pOrderBy==0 && p->iLimit ){
97173 sqlite3VdbeAddOp3(v, OP_IfZero, p->iLimit, iBreak, -1);
97174 }
97175 }
97176
97177 /*
97178 ** Allocate a KeyInfo object sufficient for an index of N columns.
97179 **
97180 ** Actually, always allocate one extra column for the rowid at the end
97181 ** of the index. So the KeyInfo returned will have space sufficient for
97182 ** N+1 columns.
97183 */
97184 SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N){
97185 KeyInfo *p = sqlite3DbMallocZero(db,
97186 sizeof(KeyInfo) + (N+1)*(sizeof(CollSeq*)+1));
97187 if( p ){
97188 p->aSortOrder = (u8*)&p->aColl[N+1];
97189 p->nField = (u16)N;
97190 p->enc = ENC(db);
97191 p->db = db;
97192 }
97193 return p;
97194 }
97195
97196 /*
97197 ** Given an expression list, generate a KeyInfo structure that records
97198 ** the collating sequence for each expression in that expression list.
97199 **
@@ -96857,29 +97207,23 @@
97207 ** function is responsible for seeing that this structure is eventually
97208 ** freed. Add the KeyInfo structure to the P4 field of an opcode using
97209 ** P4_KEYINFO_HANDOFF is the usual way of dealing with this.
97210 */
97211 static KeyInfo *keyInfoFromExprList(Parse *pParse, ExprList *pList){
 
97212 int nExpr;
97213 KeyInfo *pInfo;
97214 struct ExprList_item *pItem;
97215 sqlite3 *db = pParse->db;
97216 int i;
97217
97218 nExpr = pList->nExpr;
97219 pInfo = sqlite3KeyInfoAlloc(db, nExpr);
97220 if( pInfo ){
 
 
 
 
97221 for(i=0, pItem=pList->a; i<nExpr; i++, pItem++){
97222 CollSeq *pColl;
97223 pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr);
97224 if( !pColl ) pColl = db->pDfltColl;
 
 
97225 pInfo->aColl[i] = pColl;
97226 pInfo->aSortOrder[i] = pItem->sortOrder;
97227 }
97228 }
97229 return pInfo;
@@ -97981,27 +98325,21 @@
98325 CollSeq **apColl; /* For looping through pKeyInfo->aColl[] */
98326 int nCol; /* Number of columns in result set */
98327
98328 assert( p->pRightmost==p );
98329 nCol = p->pEList->nExpr;
98330 pKeyInfo = sqlite3KeyInfoAlloc(db, nCol);
 
98331 if( !pKeyInfo ){
98332 rc = SQLITE_NOMEM;
98333 goto multi_select_end;
98334 }
 
 
 
 
98335 for(i=0, apColl=pKeyInfo->aColl; i<nCol; i++, apColl++){
98336 *apColl = multiSelectCollSeq(pParse, p, i);
98337 if( 0==*apColl ){
98338 *apColl = db->pDfltColl;
98339 }
98340 }
 
98341
98342 for(pLoop=p; pLoop; pLoop=pLoop->pPrior){
98343 for(i=0; i<2; i++){
98344 int addr = pLoop->addrOpenEphm[i];
98345 if( addr<0 ){
@@ -98366,16 +98704,12 @@
98704 struct ExprList_item *pItem;
98705 for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
98706 assert( pItem->iOrderByCol>0 && pItem->iOrderByCol<=p->pEList->nExpr );
98707 aPermute[i] = pItem->iOrderByCol - 1;
98708 }
98709 pKeyMerge = sqlite3KeyInfoAlloc(db, nOrderBy);
 
98710 if( pKeyMerge ){
 
 
 
98711 for(i=0; i<nOrderBy; i++){
98712 CollSeq *pColl;
98713 Expr *pTerm = pOrderBy->a[i].pExpr;
98714 if( pTerm->flags & EP_Collate ){
98715 pColl = sqlite3ExprCollSeq(pParse, pTerm);
@@ -98408,16 +98742,12 @@
98742 int nExpr = p->pEList->nExpr;
98743 assert( nOrderBy>=nExpr || db->mallocFailed );
98744 regPrev = pParse->nMem+1;
98745 pParse->nMem += nExpr+1;
98746 sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
98747 pKeyDup = sqlite3KeyInfoAlloc(db, nExpr);
 
98748 if( pKeyDup ){
 
 
 
98749 for(i=0; i<nExpr; i++){
98750 pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
98751 pKeyDup->aSortOrder[i] = 0;
98752 }
98753 }
@@ -99679,14 +100009,16 @@
100009 ** and/or pParse->db->mallocFailed.
100010 */
100011 static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){
100012 Walker w;
100013 memset(&w, 0, sizeof(w));
 
100014 w.xExprCallback = exprWalkNoop;
100015 w.pParse = pParse;
100016 if( pParse->hasCompound ){
100017 w.xSelectCallback = convertCompoundSelectToSubquery;
100018 sqlite3WalkSelect(&w, pSelect);
100019 }
100020 w.xSelectCallback = selectExpander;
100021 sqlite3WalkSelect(&w, pSelect);
100022 }
100023
100024
@@ -100216,11 +100548,11 @@
100548 ** will cause elements to come out in the correct order. This is
100549 ** an optimization - the correct answer should result regardless.
100550 ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER
100551 ** to disable this optimization for testing purposes.
100552 */
100553 if( sqlite3ExprListCompare(p->pGroupBy, pOrderBy, -1)==0
100554 && OptimizationEnabled(db, SQLITE_GroupByOrder) ){
100555 pOrderBy = 0;
100556 }
100557
100558 /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and
@@ -100237,11 +100569,11 @@
100569 ** used for both the ORDER BY and DISTINCT processing. As originally
100570 ** written the query must use a temp-table for at least one of the ORDER
100571 ** BY and DISTINCT, and an index or separate temp-table for the other.
100572 */
100573 if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct
100574 && sqlite3ExprListCompare(pOrderBy, p->pEList, -1)==0
100575 ){
100576 p->selFlags &= ~SF_Distinct;
100577 p->pGroupBy = sqlite3ExprListDup(db, p->pEList, 0);
100578 pGroupBy = p->pGroupBy;
100579 pOrderBy = 0;
@@ -102464,11 +102796,11 @@
102796 aRegIdx = sqlite3DbMallocRaw(db, sizeof(Index*) * nIdx );
102797 if( aRegIdx==0 ) goto update_cleanup;
102798 }
102799 for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
102800 int reg;
102801 if( hasFK || chngRowid || pIdx->pPartIdxWhere ){
102802 reg = ++pParse->nMem;
102803 }else{
102804 reg = 0;
102805 for(i=0; i<pIdx->nColumn; i++){
102806 if( aXRef[pIdx->aiColumn[i]]>=0 ){
@@ -104070,12 +104402,12 @@
104402 int (*x)(sqlite3_vtab *);
104403 sqlite3_vtab *pVtab = aVTrans[i]->pVtab;
104404 if( pVtab && (x = pVtab->pModule->xSync)!=0 ){
104405 rc = x(pVtab);
104406 sqlite3DbFree(db, *pzErrmsg);
104407 *pzErrmsg = pVtab->zErrMsg;
104408 pVtab->zErrMsg = 0;
104409 }
104410 }
104411 db->aVTrans = aVTrans;
104412 return rc;
104413 }
@@ -104391,10 +104723,12 @@
104723 typedef struct WhereLoop WhereLoop;
104724 typedef struct WherePath WherePath;
104725 typedef struct WhereTerm WhereTerm;
104726 typedef struct WhereLoopBuilder WhereLoopBuilder;
104727 typedef struct WhereScan WhereScan;
104728 typedef struct WhereOrCost WhereOrCost;
104729 typedef struct WhereOrSet WhereOrSet;
104730
104731 /*
104732 ** Cost X is tracked as 10*log2(X) stored in a 16-bit integer. The
104733 ** maximum cost for ordinary tables is 64*(2**63) which becomes 6900.
104734 ** (Virtual tables can return a larger cost, but let's assume they do not.)
@@ -104497,10 +104831,31 @@
104831 u16 nLSlot; /* Number of slots allocated for aLTerm[] */
104832 WhereTerm **aLTerm; /* WhereTerms used */
104833 WhereLoop *pNextLoop; /* Next WhereLoop object in the WhereClause */
104834 WhereTerm *aLTermSpace[4]; /* Initial aLTerm[] space */
104835 };
104836
104837 /* This object holds the prerequisites and the cost of running a
104838 ** subquery on one operand of an OR operator in the WHERE clause.
104839 ** See WhereOrSet for additional information
104840 */
104841 struct WhereOrCost {
104842 Bitmask prereq; /* Prerequisites */
104843 WhereCost rRun; /* Cost of running this subquery */
104844 WhereCost nOut; /* Number of outputs for this subquery */
104845 };
104846
104847 /* The WhereOrSet object holds a set of possible WhereOrCosts that
104848 ** correspond to the subquery(s) of OR-clause processing. At most
104849 ** favorable N_OR_COST elements are retained.
104850 */
104851 #define N_OR_COST 3
104852 struct WhereOrSet {
104853 u16 n; /* Number of valid a[] entries */
104854 WhereOrCost a[N_OR_COST]; /* Set of best costs */
104855 };
104856
104857
104858 /* Forward declaration of methods */
104859 static int whereLoopResize(sqlite3*, WhereLoop*, int);
104860
104861 /*
@@ -104712,11 +105067,11 @@
105067 struct WhereLoopBuilder {
105068 WhereInfo *pWInfo; /* Information about this WHERE */
105069 WhereClause *pWC; /* WHERE clause terms */
105070 ExprList *pOrderBy; /* ORDER BY clause */
105071 WhereLoop *pNew; /* Template WhereLoop */
105072 WhereOrSet *pOrSet; /* Record best loops here, if not NULL */
105073 };
105074
105075 /*
105076 ** The WHERE clause processing routine has two halves. The
105077 ** first part does the start of the WHERE loop and the second
@@ -104854,10 +105209,58 @@
105209 ** UPDATE or DELETE might change subsequent WHERE clause results.
105210 */
105211 SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo){
105212 return pWInfo->okOnePass;
105213 }
105214
105215 /*
105216 ** Move the content of pSrc into pDest
105217 */
105218 static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
105219 pDest->n = pSrc->n;
105220 memcpy(pDest->a, pSrc->a, pDest->n*sizeof(pDest->a[0]));
105221 }
105222
105223 /*
105224 ** Try to insert a new prerequisite/cost entry into the WhereOrSet pSet.
105225 **
105226 ** The new entry might overwrite an existing entry, or it might be
105227 ** appended, or it might be discarded. Do whatever is the right thing
105228 ** so that pSet keeps the N_OR_COST best entries seen so far.
105229 */
105230 static int whereOrInsert(
105231 WhereOrSet *pSet, /* The WhereOrSet to be updated */
105232 Bitmask prereq, /* Prerequisites of the new entry */
105233 WhereCost rRun, /* Run-cost of the new entry */
105234 WhereCost nOut /* Number of outputs for the new entry */
105235 ){
105236 u16 i;
105237 WhereOrCost *p;
105238 for(i=pSet->n, p=pSet->a; i>0; i--, p++){
105239 if( rRun<=p->rRun && (prereq & p->prereq)==prereq ){
105240 goto whereOrInsert_done;
105241 }
105242 if( p->rRun<=rRun && (p->prereq & prereq)==p->prereq ){
105243 return 0;
105244 }
105245 }
105246 if( pSet->n<N_OR_COST ){
105247 p = &pSet->a[pSet->n++];
105248 p->nOut = nOut;
105249 }else{
105250 p = pSet->a;
105251 for(i=1; i<pSet->n; i++){
105252 if( p->rRun>pSet->a[i].rRun ) p = pSet->a + i;
105253 }
105254 if( p->rRun<=rRun ) return 0;
105255 }
105256 whereOrInsert_done:
105257 p->prereq = prereq;
105258 p->rRun = rRun;
105259 if( p->nOut>nOut ) p->nOut = nOut;
105260 return 1;
105261 }
105262
105263 /*
105264 ** Initialize a preallocated WhereClause structure.
105265 */
105266 static void whereClauseInit(
@@ -104933,11 +105336,11 @@
105336 ** the pWC->a[] array.
105337 */
105338 static int whereClauseInsert(WhereClause *pWC, Expr *p, u8 wtFlags){
105339 WhereTerm *pTerm;
105340 int idx;
105341 testcase( wtFlags & TERM_VIRTUAL );
105342 if( pWC->nTerm>=pWC->nSlot ){
105343 WhereTerm *pOld = pWC->a;
105344 sqlite3 *db = pWC->pWInfo->pParse->db;
105345 pWC->a = sqlite3DbMallocRaw(db, sizeof(pWC->a[0])*pWC->nSlot*2 );
105346 if( pWC->a==0 ){
@@ -105078,17 +105481,10 @@
105481
105482 /*
105483 ** Return TRUE if the given operator is one of the operators that is
105484 ** allowed for an indexable WHERE clause term. The allowed operators are
105485 ** "=", "<", ">", "<=", ">=", "IN", and "IS NULL"
 
 
 
 
 
 
 
105486 */
105487 static int allowedOp(int op){
105488 assert( TK_GT>TK_EQ && TK_GT<TK_GE );
105489 assert( TK_LT>TK_EQ && TK_LT<TK_GE );
105490 assert( TK_LE>TK_EQ && TK_LE<TK_GE );
@@ -105403,11 +105799,11 @@
105799 op = pRight->op2;
105800 }
105801 if( op==TK_VARIABLE ){
105802 Vdbe *pReprepare = pParse->pReprepare;
105803 int iCol = pRight->iColumn;
105804 pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_NONE);
105805 if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){
105806 z = (char *)sqlite3_value_text(pVal);
105807 }
105808 sqlite3VdbeSetVarmask(pParse->pVdbe, iCol);
105809 assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER );
@@ -105758,12 +106154,10 @@
106154 }
106155
106156 /* At this point, okToChngToIN is true if original pTerm satisfies
106157 ** case 1. In that case, construct a new virtual term that is
106158 ** pTerm converted into an IN operator.
 
 
106159 */
106160 if( okToChngToIN ){
106161 Expr *pDup; /* A transient duplicate expression */
106162 ExprList *pList = 0; /* The RHS of the IN operator */
106163 Expr *pLeft = 0; /* The LHS of the IN operator */
@@ -106001,13 +106395,11 @@
106395 ** wildcard. But if we increment '@', that will push it into the
106396 ** alphabetic range where case conversions will mess up the
106397 ** inequality. To avoid this, make sure to also run the full
106398 ** LIKE on all candidate expressions by clearing the isComplete flag
106399 */
106400 if( c=='A'-1 ) isComplete = 0;
 
 
106401 c = sqlite3UpperToLower[c];
106402 }
106403 *pC = c + 1;
106404 }
106405 sCollSeqName.z = noCase ? "NOCASE" : "BINARY";
@@ -106510,11 +106902,11 @@
106902 VdbeComment((v, "for %s", pTable->zName));
106903
106904 /* Fill the automatic index with content */
106905 addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
106906 regRecord = sqlite3GetTempReg(pParse);
106907 sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 1, 0);
106908 sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
106909 sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
106910 sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
106911 sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
106912 sqlite3VdbeJumpHere(v, addrTop);
@@ -106867,11 +107259,11 @@
107259 if( pExpr->op==TK_VARIABLE
107260 || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE)
107261 ){
107262 int iVar = pExpr->iColumn;
107263 sqlite3VdbeSetVarmask(pParse->pVdbe, iVar);
107264 *pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff);
107265 return SQLITE_OK;
107266 }
107267 return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp);
107268 }
107269 #endif
@@ -107093,13 +107485,10 @@
107485 **
107486 ** The t2.z='ok' is disabled in the in (2) because it originates
107487 ** in the ON clause. The term is disabled in (3) because it is not part
107488 ** of a LEFT OUTER JOIN. In (1), the term is not disabled.
107489 **
 
 
 
107490 ** Disabling a term causes that term to not be tested in the inner loop
107491 ** of the join. Disabling is an optimization. When terms are satisfied
107492 ** by indices, we disable them to prevent redundant tests in the inner
107493 ** loop. We would get the correct results if nothing were ever disabled,
107494 ** but joins might run a little slower. The trick is to disable as much
@@ -107325,11 +107714,11 @@
107714 pTerm = pLoop->aLTerm[j];
107715 assert( pTerm!=0 );
107716 /* The following true for indices with redundant columns.
107717 ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */
107718 testcase( (pTerm->wtFlags & TERM_CODED)!=0 );
107719 testcase( pTerm->wtFlags & TERM_VIRTUAL );
107720 r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j);
107721 if( r1!=regBase+j ){
107722 if( nReg==1 ){
107723 sqlite3ReleaseTempReg(pParse, regBase);
107724 regBase = r1;
@@ -107525,10 +107914,11 @@
107914 WhereLevel *pLevel; /* The where level to be coded */
107915 WhereLoop *pLoop; /* The WhereLoop object being coded */
107916 WhereClause *pWC; /* Decomposition of the entire WHERE clause */
107917 WhereTerm *pTerm; /* A WHERE clause term */
107918 Parse *pParse; /* Parsing context */
107919 sqlite3 *db; /* Database connection */
107920 Vdbe *v; /* The prepared stmt under constructions */
107921 struct SrcList_item *pTabItem; /* FROM clause term being coded */
107922 int addrBrk; /* Jump here to break out of the loop */
107923 int addrCont; /* Jump here to continue with next cycle */
107924 int iRowidReg = 0; /* Rowid is stored in this register, if not zero */
@@ -107536,10 +107926,11 @@
107926 Bitmask newNotReady; /* Return value */
107927
107928 pParse = pWInfo->pParse;
107929 v = pParse->pVdbe;
107930 pWC = &pWInfo->sWC;
107931 db = pParse->db;
107932 pLevel = &pWInfo->a[iLevel];
107933 pLoop = pLevel->pWLoop;
107934 pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
107935 iCur = pTabItem->iCursor;
107936 bRev = (pWInfo->revMask>>iLevel)&1;
@@ -107634,11 +108025,11 @@
108025 iReleaseReg = sqlite3GetTempReg(pParse);
108026 pTerm = pLoop->aLTerm[0];
108027 assert( pTerm!=0 );
108028 assert( pTerm->pExpr!=0 );
108029 assert( omitTable==0 );
108030 testcase( pTerm->wtFlags & TERM_VIRTUAL );
108031 iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
108032 addrNxt = pLevel->addrNxt;
108033 sqlite3VdbeAddOp2(v, OP_MustBeInt, iRowidReg, addrNxt);
108034 sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addrNxt, iRowidReg);
108035 sqlite3ExprCacheAffinityChange(pParse, iRowidReg, 1);
@@ -107682,11 +108073,11 @@
108073 assert( TK_LE==TK_GT+1 ); /* Make sure the ordering.. */
108074 assert( TK_LT==TK_GT+2 ); /* ... of the TK_xx values... */
108075 assert( TK_GE==TK_GT+3 ); /* ... is correcct. */
108076
108077 assert( (pStart->wtFlags & TERM_VNULL)==0 );
108078 testcase( pStart->wtFlags & TERM_VIRTUAL );
108079 pX = pStart->pExpr;
108080 assert( pX!=0 );
108081 testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
108082 r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
108083 sqlite3VdbeAddOp3(v, aMoveOp[pX->op-TK_GT], iCur, addrBrk, r1);
@@ -107701,11 +108092,11 @@
108092 Expr *pX;
108093 pX = pEnd->pExpr;
108094 assert( pX!=0 );
108095 assert( (pEnd->wtFlags & TERM_VNULL)==0 );
108096 testcase( pEnd->leftCursor!=iCur ); /* Transitive constraints */
108097 testcase( pEnd->wtFlags & TERM_VIRTUAL );
108098 memEndValue = ++pParse->nMem;
108099 sqlite3ExprCode(pParse, pX->pRight, memEndValue);
108100 if( pX->op==TK_LT || pX->op==TK_GT ){
108101 testOp = bRev ? OP_Le : OP_Ge;
108102 }else{
@@ -107826,11 +108217,11 @@
108217 /* Generate code to evaluate all constraint terms using == or IN
108218 ** and store the values of those terms in an array of registers
108219 ** starting at regBase.
108220 */
108221 regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff);
108222 zEndAff = sqlite3DbStrDup(db, zStartAff);
108223 addrNxt = pLevel->addrNxt;
108224
108225 /* If we are doing a reverse order scan on an ascending index, or
108226 ** a forward order scan on a descending index, interchange the
108227 ** start and end terms (pRangeStart and pRangeEnd).
@@ -107867,11 +108258,11 @@
108258 if( sqlite3ExprNeedsNoAffinityChange(pRight, zStartAff[nEq]) ){
108259 zStartAff[nEq] = SQLITE_AFF_NONE;
108260 }
108261 }
108262 nConstraint++;
108263 testcase( pRangeStart->wtFlags & TERM_VIRTUAL );
108264 }else if( isMinQuery ){
108265 sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq);
108266 nConstraint++;
108267 startEq = 0;
108268 start_constraints = 1;
@@ -107909,14 +108300,14 @@
108300 zEndAff[nEq] = SQLITE_AFF_NONE;
108301 }
108302 }
108303 codeApplyAffinity(pParse, regBase, nEq+1, zEndAff);
108304 nConstraint++;
108305 testcase( pRangeEnd->wtFlags & TERM_VIRTUAL );
108306 }
108307 sqlite3DbFree(db, zStartAff);
108308 sqlite3DbFree(db, zEndAff);
108309
108310 /* Top of the loop body */
108311 pLevel->p2 = sqlite3VdbeCurrentAddr(v);
108312
108313 /* Check if the index cursor is past the end of the range. */
@@ -108039,11 +108430,11 @@
108430 */
108431 if( pWInfo->nLevel>1 ){
108432 int nNotReady; /* The number of notReady tables */
108433 struct SrcList_item *origSrc; /* Original list of tables */
108434 nNotReady = pWInfo->nLevel - iLevel - 1;
108435 pOrTab = sqlite3StackAllocRaw(db,
108436 sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0]));
108437 if( pOrTab==0 ) return notReady;
108438 pOrTab->nAlloc = (u8)(nNotReady + 1);
108439 pOrTab->nSrc = pOrTab->nAlloc;
108440 memcpy(pOrTab->a, pTabItem, sizeof(*pTabItem));
@@ -108089,15 +108480,16 @@
108480 */
108481 if( pWC->nTerm>1 ){
108482 int iTerm;
108483 for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
108484 Expr *pExpr = pWC->a[iTerm].pExpr;
108485 if( &pWC->a[iTerm] == pTerm ) continue;
108486 if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
108487 if( pWC->a[iTerm].wtFlags & (TERM_ORINFO) ) continue;
108488 if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
108489 pExpr = sqlite3ExprDup(db, pExpr, 0);
108490 pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
108491 }
108492 if( pAndExpr ){
108493 pAndExpr = sqlite3PExpr(pParse, TK_AND, 0, pAndExpr, 0);
108494 }
108495 }
@@ -108113,11 +108505,11 @@
108505 }
108506 /* Loop through table entries that match term pOrTerm. */
108507 pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
108508 WHERE_OMIT_OPEN_CLOSE | WHERE_AND_ONLY |
108509 WHERE_FORCE_TABLE | WHERE_ONETABLE_ONLY, iCovCur);
108510 assert( pSubWInfo || pParse->nErr || db->mallocFailed );
108511 if( pSubWInfo ){
108512 WhereLoop *pSubLoop;
108513 explainOneScan(
108514 pParse, pOrTab, &pSubWInfo->a[0], iLevel, pLevel->iFrom, 0
108515 );
@@ -108168,17 +108560,17 @@
108560 }
108561 pLevel->u.pCovidx = pCov;
108562 if( pCov ) pLevel->iIdxCur = iCovCur;
108563 if( pAndExpr ){
108564 pAndExpr->pLeft = 0;
108565 sqlite3ExprDelete(db, pAndExpr);
108566 }
108567 sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
108568 sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
108569 sqlite3VdbeResolveLabel(v, iLoopBody);
108570
108571 if( pWInfo->nLevel>1 ) sqlite3StackFree(db, pOrTab);
108572 if( !untestedTerms ) disableTerm(pLevel, pTerm);
108573 }else
108574 #endif /* SQLITE_OMIT_OR_OPTIMIZATION */
108575
108576 {
@@ -108195,18 +108587,14 @@
108587 }
108588 newNotReady = notReady & ~getMask(&pWInfo->sMaskSet, iCur);
108589
108590 /* Insert code to test every subexpression that can be completely
108591 ** computed using the current set of tables.
 
 
 
 
108592 */
108593 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
108594 Expr *pE;
108595 testcase( pTerm->wtFlags & TERM_VIRTUAL );
108596 testcase( pTerm->wtFlags & TERM_CODED );
108597 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108598 if( (pTerm->prereqAll & newNotReady)!=0 ){
108599 testcase( pWInfo->untestedTerms==0
108600 && (pWInfo->wctrlFlags & WHERE_ONETABLE_ONLY)!=0 );
@@ -108229,13 +108617,12 @@
108617 ** and we are coding the t1 loop and the t2 loop has not yet coded,
108618 ** then we cannot use the "t1.a=t2.b" constraint, but we can code
108619 ** the implied "t1.a=123" constraint.
108620 */
108621 for(pTerm=pWC->a, j=pWC->nTerm; j>0; j--, pTerm++){
108622 Expr *pE, *pEAlt;
108623 WhereTerm *pAlt;
 
108624 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108625 if( pTerm->eOperator!=(WO_EQUIV|WO_EQ) ) continue;
108626 if( pTerm->leftCursor!=iCur ) continue;
108627 if( pLevel->iLeftJoin ) continue;
108628 pE = pTerm->pExpr;
@@ -108245,13 +108632,17 @@
108632 if( pAlt==0 ) continue;
108633 if( pAlt->wtFlags & (TERM_CODED) ) continue;
108634 testcase( pAlt->eOperator & WO_EQ );
108635 testcase( pAlt->eOperator & WO_IN );
108636 VdbeNoopComment((v, "begin transitive constraint"));
108637 pEAlt = sqlite3StackAllocRaw(db, sizeof(*pEAlt));
108638 if( pEAlt ){
108639 *pEAlt = *pAlt->pExpr;
108640 pEAlt->pLeft = pE->pLeft;
108641 sqlite3ExprIfFalse(pParse, pEAlt, addrCont, SQLITE_JUMPIFNULL);
108642 sqlite3StackFree(db, pEAlt);
108643 }
108644 }
108645
108646 /* For a LEFT OUTER JOIN, generate code that will record the fact that
108647 ** at least one row of the right table has matched the left table.
108648 */
@@ -108259,11 +108650,11 @@
108650 pLevel->addrFirst = sqlite3VdbeCurrentAddr(v);
108651 sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin);
108652 VdbeComment((v, "record LEFT JOIN hit"));
108653 sqlite3ExprCacheClear(pParse);
108654 for(pTerm=pWC->a, j=0; j<pWC->nTerm; j++, pTerm++){
108655 testcase( pTerm->wtFlags & TERM_VIRTUAL );
108656 testcase( pTerm->wtFlags & TERM_CODED );
108657 if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue;
108658 if( (pTerm->prereqAll & newNotReady)!=0 ){
108659 assert( pWInfo->untestedTerms );
108660 continue;
@@ -108418,16 +108809,16 @@
108809 ** is better and has fewer dependencies. Or the template will be ignored
108810 ** and no insert will occur if an existing WhereLoop is faster and has
108811 ** fewer dependencies than the template. Otherwise a new WhereLoop is
108812 ** added based on the template.
108813 **
108814 ** If pBuilder->pOrSet is not NULL then we only care about only the
108815 ** prerequisites and rRun and nOut costs of the N best loops. That
108816 ** information is gathered in the pBuilder->pOrSet object. This special
108817 ** processing mode is used only for OR clause processing.
108818 **
108819 ** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we
108820 ** still might overwrite similar loops with the new template if the
108821 ** template is better. Loops may be overwritten if the following
108822 ** conditions are met:
108823 **
108824 ** (1) They have the same iTab.
@@ -108440,34 +108831,26 @@
108831 static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){
108832 WhereLoop **ppPrev, *p, *pNext = 0;
108833 WhereInfo *pWInfo = pBuilder->pWInfo;
108834 sqlite3 *db = pWInfo->pParse->db;
108835
108836 /* If pBuilder->pOrSet is defined, then only keep track of the costs
108837 ** and prereqs.
 
 
108838 */
108839 if( pBuilder->pOrSet!=0 ){
108840 #if WHERETRACE_ENABLED
108841 u16 n = pBuilder->pOrSet->n;
108842 int x =
108843 #endif
108844 whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun,
108845 pTemplate->nOut);
 
 
 
 
 
108846 #if WHERETRACE_ENABLED
108847 if( sqlite3WhereTrace & 0x8 ){
108848 sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n);
108849 whereLoopPrint(pTemplate, pWInfo->pTabList);
108850 }
108851 #endif
 
108852 return SQLITE_OK;
108853 }
108854
108855 /* Search for an existing WhereLoop to overwrite, or which takes
108856 ** priority over pTemplate.
@@ -108557,11 +108940,11 @@
108940
108941 /* Jump here if the insert is a no-op */
108942 whereLoopInsert_noop:
108943 #if WHERETRACE_ENABLED
108944 if( sqlite3WhereTrace & 0x8 ){
108945 sqlite3DebugPrintf("ins-noop: ");
108946 whereLoopPrint(pTemplate, pWInfo->pTabList);
108947 }
108948 #endif
108949 return SQLITE_OK;
108950 }
@@ -108708,11 +109091,12 @@
109091 rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut);
109092 }else if( (pTerm->eOperator & WO_IN)
109093 && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){
109094 rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut);
109095 }
109096 assert( nOut==0 || rc==SQLITE_OK );
109097 if( nOut ) pNew->nOut = whereCost(nOut);
109098 }
109099 #endif
109100 if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){
109101 /* Each row involves a step of the index, then a binary search of
109102 ** the main table */
@@ -108780,10 +109164,21 @@
109164 if( x<BMS-1 ) m |= MASKBIT(x);
109165 }
109166 return m;
109167 }
109168
109169 /* Check to see if a partial index with pPartIndexWhere can be used
109170 ** in the current query. Return true if it can be and false if not.
109171 */
109172 static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){
109173 int i;
109174 WhereTerm *pTerm;
109175 for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
109176 if( sqlite3ExprImpliesExpr(pTerm->pExpr, pWhere, iTab) ) return 1;
109177 }
109178 return 0;
109179 }
109180
109181 /*
109182 ** Add all WhereLoop objects for a single table of the join where the table
109183 ** is idenfied by pBuilder->pNew->iTab. That table is guaranteed to be
109184 ** a b-tree table, not a virtual table.
@@ -108803,15 +109198,17 @@
109198 int rc = SQLITE_OK; /* Return code */
109199 int iSortIdx = 1; /* Index number */
109200 int b; /* A boolean value */
109201 WhereCost rSize; /* number of rows in the table */
109202 WhereCost rLogSize; /* Logarithm of the number of rows in the table */
109203 WhereClause *pWC; /* The parsed WHERE clause */
109204
109205 pNew = pBuilder->pNew;
109206 pWInfo = pBuilder->pWInfo;
109207 pTabList = pWInfo->pTabList;
109208 pSrc = pTabList->a + pNew->iTab;
109209 pWC = pBuilder->pWC;
109210 assert( !IsVirtual(pSrc->pTab) );
109211
109212 if( pSrc->pIndex ){
109213 /* An INDEXED BY clause specifies a particular index to use */
109214 pProbe = pSrc->pIndex;
@@ -108839,19 +109236,18 @@
109236 }
109237 rSize = whereCost(pSrc->pTab->nRowEst);
109238 rLogSize = estLog(rSize);
109239
109240 /* Automatic indexes */
109241 if( !pBuilder->pOrSet
109242 && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
109243 && pSrc->pIndex==0
109244 && !pSrc->viaCoroutine
109245 && !pSrc->notIndexed
109246 && !pSrc->isCorrelated
109247 ){
109248 /* Generate auto-index WhereLoops */
 
109249 WhereTerm *pTerm;
109250 WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
109251 for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
109252 if( pTerm->prereqRight & pNew->maskSelf ) continue;
109253 if( termCanDriveIndex(pTerm, pSrc, 0) ){
@@ -108877,10 +109273,14 @@
109273 }
109274
109275 /* Loop over all indices
109276 */
109277 for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
109278 if( pProbe->pPartIdxWhere!=0
109279 && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
109280 continue; /* Partial index inappropriate for this query */
109281 }
109282 pNew->u.btree.nEq = 0;
109283 pNew->nLTerm = 0;
109284 pNew->iSortIdx = 0;
109285 pNew->rSetup = 0;
109286 pNew->prereq = mExtra;
@@ -109125,11 +109525,11 @@
109525 WhereTerm *pTerm, *pWCEnd;
109526 int rc = SQLITE_OK;
109527 int iCur;
109528 WhereClause tempWC;
109529 WhereLoopBuilder sSubBuild;
109530 WhereOrSet sSum, sCur, sPrev;
109531 struct SrcList_item *pItem;
109532
109533 pWC = pBuilder->pWC;
109534 if( pWInfo->wctrlFlags & WHERE_AND_ONLY ) return SQLITE_OK;
109535 pWCEnd = pWC->a + pWC->nTerm;
@@ -109140,20 +109540,18 @@
109540 && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0
109541 ){
109542 WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc;
109543 WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm];
109544 WhereTerm *pOrTerm;
109545 int once = 1;
109546 int i, j;
 
109547
 
109548 pItem = pWInfo->pTabList->a + pNew->iTab;
109549 iCur = pItem->iCursor;
109550 sSubBuild = *pBuilder;
109551 sSubBuild.pOrderBy = 0;
109552 sSubBuild.pOrSet = &sCur;
109553
109554 for(pOrTerm=pOrWC->a; pOrTerm<pOrWCEnd; pOrTerm++){
109555 if( (pOrTerm->eOperator & WO_AND)!=0 ){
109556 sSubBuild.pWC = &pOrTerm->u.pAndInfo->wc;
109557 }else if( pOrTerm->leftCursor==iCur ){
@@ -109164,43 +109562,52 @@
109562 tempWC.a = pOrTerm;
109563 sSubBuild.pWC = &tempWC;
109564 }else{
109565 continue;
109566 }
109567 sCur.n = 0;
 
 
109568 #ifndef SQLITE_OMIT_VIRTUALTABLE
109569 if( IsVirtual(pItem->pTab) ){
109570 rc = whereLoopAddVirtual(&sSubBuild);
109571 for(i=0; i<sCur.n; i++) sCur.a[i].prereq |= mExtra;
109572 }else
109573 #endif
109574 {
109575 rc = whereLoopAddBtree(&sSubBuild, mExtra);
109576 }
109577 assert( rc==SQLITE_OK || sCur.n==0 );
109578 if( sCur.n==0 ){
109579 sSum.n = 0;
109580 break;
109581 }else if( once ){
109582 whereOrMove(&sSum, &sCur);
109583 once = 0;
109584 }else{
109585 whereOrMove(&sPrev, &sSum);
109586 sSum.n = 0;
109587 for(i=0; i<sPrev.n; i++){
109588 for(j=0; j<sCur.n; j++){
109589 whereOrInsert(&sSum, sPrev.a[i].prereq | sCur.a[j].prereq,
109590 whereCostAdd(sPrev.a[i].rRun, sCur.a[j].rRun),
109591 whereCostAdd(sPrev.a[i].nOut, sCur.a[j].nOut));
109592 }
109593 }
109594 }
109595 }
109596 pNew->nLTerm = 1;
109597 pNew->aLTerm[0] = pTerm;
109598 pNew->wsFlags = WHERE_MULTI_OR;
109599 pNew->rSetup = 0;
109600 pNew->iSortIdx = 0;
109601 memset(&pNew->u, 0, sizeof(pNew->u));
109602 for(i=0; rc==SQLITE_OK && i<sSum.n; i++){
109603 /* TUNING: Multiple by 3.5 for the secondary table lookup */
109604 pNew->rRun = sSum.a[i].rRun + 18;
109605 pNew->nOut = sSum.a[i].nOut;
109606 pNew->prereq = sSum.a[i].prereq;
 
109607 rc = whereLoopInsert(pBuilder, pNew);
109608 }
 
109609 }
109610 }
109611 return rc;
109612 }
109613
@@ -109810,11 +110217,11 @@
110217 pLoop->u.btree.nEq = 1;
110218 /* TUNING: Cost of a rowid lookup is 10 */
110219 pLoop->rRun = 33; /* 33==whereCost(10) */
110220 }else{
110221 for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
110222 if( pIdx->onError==OE_None || pIdx->pPartIdxWhere!=0 ) continue;
110223 for(j=0; j<pIdx->nColumn; j++){
110224 pTerm = findTerm(pWC, iCur, pIdx->aiColumn[j], 0, WO_EQ, pIdx);
110225 if( pTerm==0 ) break;
110226 whereLoopResize(pWInfo->pParse->db, pLoop, j);
110227 pLoop->aLTerm[j] = pTerm;
@@ -110003,11 +110410,12 @@
110410 pWInfo->wctrlFlags = wctrlFlags;
110411 pWInfo->savedNQueryLoop = pParse->nQueryLoop;
110412 pMaskSet = &pWInfo->sMaskSet;
110413 sWLB.pWInfo = pWInfo;
110414 sWLB.pWC = &pWInfo->sWC;
110415 sWLB.pNew = (WhereLoop*)(((char*)pWInfo)+nByteWInfo);
110416 assert( EIGHT_BYTE_ALIGNMENT(sWLB.pNew) );
110417 whereLoopInit(sWLB.pNew);
110418 #ifdef SQLITE_DEBUG
110419 sWLB.pNew->cId = '*';
110420 #endif
110421
@@ -110015,11 +110423,11 @@
110423 ** subexpression is separated by an AND operator.
110424 */
110425 initMaskSet(pMaskSet);
110426 whereClauseInit(&pWInfo->sWC, pWInfo);
110427 sqlite3ExprCodeConstants(pParse, pWhere);
110428 whereSplit(&pWInfo->sWC, pWhere, TK_AND);
110429 sqlite3CodeVerifySchema(pParse, -1); /* Insert the cookie verifier Goto */
110430
110431 /* Special case: a WHERE clause that is constant. Evaluate the
110432 ** expression and either jump over all of the code or fall thru.
110433 */
@@ -110649,11 +111057,11 @@
111057 #endif
111058 #define sqlite3ParserARG_SDECL Parse *pParse;
111059 #define sqlite3ParserARG_PDECL ,Parse *pParse
111060 #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse
111061 #define sqlite3ParserARG_STORE yypParser->pParse = pParse
111062 #define YYNSTATE 628
111063 #define YYNRULE 327
111064 #define YYFALLBACK 1
111065 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
111066 #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
111067 #define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
@@ -110722,167 +111130,167 @@
111130 ** shifting non-terminals after a reduce.
111131 ** yy_default[] Default action for each state.
111132 */
111133 #define YY_ACTTAB_COUNT (1564)
111134 static const YYACTIONTYPE yy_action[] = {
111135 /* 0 */ 310, 956, 184, 418, 2, 171, 625, 595, 56, 56,
111136 /* 10 */ 56, 56, 49, 54, 54, 54, 54, 53, 53, 52,
111137 /* 20 */ 52, 52, 51, 233, 621, 620, 299, 621, 620, 234,
111138 /* 30 */ 588, 582, 56, 56, 56, 56, 19, 54, 54, 54,
111139 /* 40 */ 54, 53, 53, 52, 52, 52, 51, 233, 606, 57,
111140 /* 50 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111141 /* 60 */ 56, 56, 542, 54, 54, 54, 54, 53, 53, 52,
111142 /* 70 */ 52, 52, 51, 233, 310, 595, 326, 196, 195, 194,
111143 /* 80 */ 33, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111144 /* 90 */ 51, 233, 618, 617, 165, 618, 617, 381, 378, 377,
111145 /* 100 */ 408, 533, 577, 577, 588, 582, 304, 423, 376, 59,
111146 /* 110 */ 53, 53, 52, 52, 52, 51, 233, 50, 47, 146,
111147 /* 120 */ 575, 546, 65, 57, 58, 48, 580, 579, 581, 581,
111148 /* 130 */ 55, 55, 56, 56, 56, 56, 213, 54, 54, 54,
111149 /* 140 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 223,
111150 /* 150 */ 540, 421, 170, 176, 138, 281, 384, 276, 383, 168,
111151 /* 160 */ 490, 552, 410, 669, 621, 620, 272, 439, 410, 439,
111152 /* 170 */ 551, 605, 67, 483, 508, 619, 600, 413, 588, 582,
111153 /* 180 */ 601, 484, 619, 413, 619, 599, 91, 440, 441, 440,
111154 /* 190 */ 336, 599, 73, 670, 222, 267, 481, 57, 58, 48,
111155 /* 200 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
111156 /* 210 */ 671, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111157 /* 220 */ 51, 233, 310, 280, 232, 231, 1, 132, 200, 386,
111158 /* 230 */ 621, 620, 618, 617, 279, 436, 290, 564, 175, 263,
111159 /* 240 */ 410, 265, 438, 498, 437, 166, 442, 569, 337, 569,
111160 /* 250 */ 201, 538, 588, 582, 600, 413, 165, 595, 601, 381,
111161 /* 260 */ 378, 377, 598, 599, 92, 524, 619, 570, 570, 593,
111162 /* 270 */ 376, 57, 58, 48, 580, 579, 581, 581, 55, 55,
111163 /* 280 */ 56, 56, 56, 56, 598, 54, 54, 54, 54, 53,
111164 /* 290 */ 53, 52, 52, 52, 51, 233, 310, 464, 618, 617,
111165 /* 300 */ 591, 591, 591, 174, 273, 397, 410, 273, 410, 549,
111166 /* 310 */ 398, 621, 620, 68, 327, 621, 620, 621, 620, 619,
111167 /* 320 */ 547, 413, 619, 413, 472, 595, 588, 582, 473, 599,
111168 /* 330 */ 92, 599, 92, 52, 52, 52, 51, 233, 514, 513,
111169 /* 340 */ 206, 323, 364, 465, 221, 57, 58, 48, 580, 579,
111170 /* 350 */ 581, 581, 55, 55, 56, 56, 56, 56, 530, 54,
111171 /* 360 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
111172 /* 370 */ 310, 397, 410, 397, 598, 373, 387, 531, 348, 618,
111173 /* 380 */ 617, 576, 202, 618, 617, 618, 617, 413, 621, 620,
111174 /* 390 */ 145, 255, 347, 254, 578, 599, 74, 352, 45, 490,
111175 /* 400 */ 588, 582, 235, 189, 465, 545, 167, 297, 187, 470,
111176 /* 410 */ 480, 67, 62, 39, 619, 547, 598, 346, 574, 57,
111177 /* 420 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111178 /* 430 */ 56, 56, 6, 54, 54, 54, 54, 53, 53, 52,
111179 /* 440 */ 52, 52, 51, 233, 310, 563, 559, 408, 529, 577,
111180 /* 450 */ 577, 345, 255, 347, 254, 182, 618, 617, 504, 505,
111181 /* 460 */ 315, 410, 558, 235, 166, 272, 410, 353, 565, 181,
111182 /* 470 */ 408, 547, 577, 577, 588, 582, 413, 538, 557, 562,
111183 /* 480 */ 518, 413, 619, 249, 599, 16, 7, 36, 468, 599,
111184 /* 490 */ 92, 517, 619, 57, 58, 48, 580, 579, 581, 581,
111185 /* 500 */ 55, 55, 56, 56, 56, 56, 542, 54, 54, 54,
111186 /* 510 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 328,
111187 /* 520 */ 573, 572, 526, 559, 561, 395, 872, 246, 410, 248,
111188 /* 530 */ 171, 393, 595, 219, 408, 410, 577, 577, 503, 558,
111189 /* 540 */ 365, 145, 511, 413, 408, 229, 577, 577, 588, 582,
111190 /* 550 */ 413, 599, 92, 382, 270, 557, 166, 401, 599, 69,
111191 /* 560 */ 502, 420, 946, 199, 946, 198, 547, 57, 58, 48,
111192 /* 570 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
111193 /* 580 */ 569, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111194 /* 590 */ 51, 233, 310, 318, 420, 945, 509, 945, 309, 598,
111195 /* 600 */ 595, 566, 491, 212, 173, 247, 424, 616, 615, 614,
111196 /* 610 */ 324, 197, 143, 406, 573, 572, 490, 66, 50, 47,
111197 /* 620 */ 146, 595, 588, 582, 232, 231, 560, 428, 67, 556,
111198 /* 630 */ 15, 619, 186, 544, 304, 422, 35, 206, 433, 424,
111199 /* 640 */ 553, 57, 58, 48, 580, 579, 581, 581, 55, 55,
111200 /* 650 */ 56, 56, 56, 56, 205, 54, 54, 54, 54, 53,
111201 /* 660 */ 53, 52, 52, 52, 51, 233, 310, 570, 570, 261,
111202 /* 670 */ 269, 598, 12, 374, 569, 166, 410, 314, 410, 421,
111203 /* 680 */ 410, 474, 474, 366, 619, 50, 47, 146, 598, 595,
111204 /* 690 */ 256, 413, 166, 413, 352, 413, 588, 582, 32, 599,
111205 /* 700 */ 94, 599, 97, 599, 95, 628, 626, 330, 142, 50,
111206 /* 710 */ 47, 146, 334, 350, 359, 57, 58, 48, 580, 579,
111207 /* 720 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
111208 /* 730 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
111209 /* 740 */ 310, 410, 389, 413, 410, 22, 566, 405, 212, 363,
111210 /* 750 */ 390, 599, 104, 360, 410, 156, 413, 410, 604, 413,
111211 /* 760 */ 538, 332, 570, 570, 599, 103, 494, 599, 105, 413,
111212 /* 770 */ 588, 582, 413, 261, 550, 619, 11, 599, 106, 522,
111213 /* 780 */ 599, 133, 169, 458, 457, 170, 35, 602, 619, 57,
111214 /* 790 */ 58, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111215 /* 800 */ 56, 56, 410, 54, 54, 54, 54, 53, 53, 52,
111216 /* 810 */ 52, 52, 51, 233, 310, 410, 260, 413, 410, 50,
111217 /* 820 */ 47, 146, 358, 319, 356, 599, 134, 528, 353, 338,
111218 /* 830 */ 413, 410, 357, 413, 358, 410, 358, 619, 599, 98,
111219 /* 840 */ 129, 599, 102, 619, 588, 582, 413, 21, 235, 619,
111220 /* 850 */ 413, 619, 211, 143, 599, 101, 30, 167, 599, 93,
111221 /* 860 */ 351, 536, 203, 57, 58, 48, 580, 579, 581, 581,
111222 /* 870 */ 55, 55, 56, 56, 56, 56, 410, 54, 54, 54,
111223 /* 880 */ 54, 53, 53, 52, 52, 52, 51, 233, 310, 410,
111224 /* 890 */ 527, 413, 410, 426, 215, 306, 598, 552, 141, 599,
111225 /* 900 */ 100, 40, 410, 38, 413, 410, 551, 413, 410, 228,
111226 /* 910 */ 220, 315, 599, 77, 501, 599, 96, 413, 588, 582,
111227 /* 920 */ 413, 339, 253, 413, 218, 599, 137, 380, 599, 136,
111228 /* 930 */ 28, 599, 135, 271, 716, 210, 482, 57, 58, 48,
111229 /* 940 */ 580, 579, 581, 581, 55, 55, 56, 56, 56, 56,
111230 /* 950 */ 410, 54, 54, 54, 54, 53, 53, 52, 52, 52,
111231 /* 960 */ 51, 233, 310, 410, 273, 413, 410, 316, 147, 598,
111232 /* 970 */ 273, 627, 2, 599, 76, 209, 410, 127, 413, 619,
111233 /* 980 */ 126, 413, 410, 622, 235, 619, 599, 90, 375, 599,
111234 /* 990 */ 89, 413, 588, 582, 27, 261, 351, 413, 619, 599,
111235 /* 1000 */ 75, 322, 542, 542, 125, 599, 88, 321, 279, 598,
111236 /* 1010 */ 619, 57, 46, 48, 580, 579, 581, 581, 55, 55,
111237 /* 1020 */ 56, 56, 56, 56, 410, 54, 54, 54, 54, 53,
111238 /* 1030 */ 53, 52, 52, 52, 51, 233, 310, 410, 451, 413,
111239 /* 1040 */ 164, 285, 283, 273, 610, 425, 305, 599, 87, 371,
111240 /* 1050 */ 410, 478, 413, 410, 609, 410, 608, 603, 619, 619,
111241 /* 1060 */ 599, 99, 587, 586, 122, 413, 588, 582, 413, 619,
111242 /* 1070 */ 413, 619, 619, 599, 86, 367, 599, 17, 599, 85,
111243 /* 1080 */ 320, 185, 520, 519, 584, 583, 58, 48, 580, 579,
111244 /* 1090 */ 581, 581, 55, 55, 56, 56, 56, 56, 410, 54,
111245 /* 1100 */ 54, 54, 54, 53, 53, 52, 52, 52, 51, 233,
111246 /* 1110 */ 310, 585, 410, 413, 410, 261, 261, 261, 409, 592,
111247 /* 1120 */ 475, 599, 84, 170, 410, 467, 519, 413, 121, 413,
111248 /* 1130 */ 619, 619, 619, 619, 619, 599, 83, 599, 72, 413,
111249 /* 1140 */ 588, 582, 51, 233, 626, 330, 471, 599, 71, 258,
111250 /* 1150 */ 159, 120, 14, 463, 157, 158, 117, 261, 449, 448,
111251 /* 1160 */ 447, 48, 580, 579, 581, 581, 55, 55, 56, 56,
111252 /* 1170 */ 56, 56, 619, 54, 54, 54, 54, 53, 53, 52,
111253 /* 1180 */ 52, 52, 51, 233, 44, 404, 261, 3, 410, 460,
111254 /* 1190 */ 261, 414, 620, 118, 399, 10, 25, 24, 555, 349,
111255 /* 1200 */ 217, 619, 407, 413, 410, 619, 4, 44, 404, 619,
111256 /* 1210 */ 3, 599, 82, 619, 414, 620, 456, 543, 115, 413,
111257 /* 1220 */ 539, 402, 537, 275, 507, 407, 251, 599, 81, 216,
111258 /* 1230 */ 274, 564, 619, 243, 454, 619, 154, 619, 619, 619,
111259 /* 1240 */ 450, 417, 624, 110, 402, 619, 410, 236, 64, 123,
111260 /* 1250 */ 488, 41, 42, 532, 564, 204, 410, 268, 43, 412,
111261 /* 1260 */ 411, 413, 266, 593, 108, 619, 107, 435, 333, 599,
111262 /* 1270 */ 80, 413, 619, 264, 41, 42, 444, 619, 410, 599,
111263 /* 1280 */ 70, 43, 412, 411, 434, 262, 593, 149, 619, 598,
111264 /* 1290 */ 257, 237, 188, 413, 591, 591, 591, 590, 589, 13,
111265 /* 1300 */ 619, 599, 18, 329, 235, 619, 44, 404, 361, 3,
111266 /* 1310 */ 419, 462, 340, 414, 620, 227, 124, 591, 591, 591,
111267 /* 1320 */ 590, 589, 13, 619, 407, 410, 619, 410, 139, 34,
111268 /* 1330 */ 404, 388, 3, 148, 623, 313, 414, 620, 312, 331,
111269 /* 1340 */ 413, 461, 413, 402, 180, 354, 413, 407, 599, 79,
111270 /* 1350 */ 599, 78, 250, 564, 599, 9, 619, 613, 612, 611,
111271 /* 1360 */ 619, 8, 453, 443, 242, 416, 402, 619, 239, 235,
111272 /* 1370 */ 179, 238, 429, 41, 42, 289, 564, 619, 619, 619,
111273 /* 1380 */ 43, 412, 411, 619, 144, 593, 619, 619, 177, 61,
111274 /* 1390 */ 619, 597, 392, 621, 620, 288, 41, 42, 415, 619,
111275 /* 1400 */ 294, 30, 394, 43, 412, 411, 293, 619, 593, 31,
111276 /* 1410 */ 619, 396, 292, 60, 230, 37, 591, 591, 591, 590,
111277 /* 1420 */ 589, 13, 214, 554, 183, 291, 172, 302, 301, 300,
111278 /* 1430 */ 178, 298, 596, 564, 452, 29, 286, 391, 541, 591,
111279 /* 1440 */ 591, 591, 590, 589, 13, 284, 521, 535, 150, 534,
111280 /* 1450 */ 241, 282, 385, 192, 191, 325, 516, 515, 277, 240,
111281 /* 1460 */ 511, 524, 308, 512, 128, 593, 510, 225, 226, 487,
111282 /* 1470 */ 486, 224, 152, 492, 465, 307, 485, 163, 153, 372,
111283 /* 1480 */ 479, 151, 162, 259, 370, 161, 368, 208, 476, 477,
111284 /* 1490 */ 26, 160, 469, 466, 362, 140, 591, 591, 591, 116,
111285 /* 1500 */ 119, 455, 344, 155, 114, 343, 113, 112, 446, 111,
111286 /* 1510 */ 131, 109, 432, 317, 130, 431, 23, 20, 430, 427,
111287 /* 1520 */ 190, 63, 255, 342, 244, 607, 295, 287, 311, 594,
111288 /* 1530 */ 278, 508, 496, 235, 493, 571, 497, 568, 495, 403,
111289 /* 1540 */ 459, 379, 355, 245, 193, 303, 567, 296, 341, 5,
111290 /* 1550 */ 445, 548, 506, 207, 525, 500, 335, 489, 252, 369,
111291 /* 1560 */ 400, 499, 523, 233,
111292 };
111293 static const YYCODETYPE yy_lookahead[] = {
111294 /* 0 */ 19, 142, 143, 144, 145, 24, 1, 26, 77, 78,
111295 /* 10 */ 79, 80, 81, 82, 83, 84, 85, 86, 87, 88,
111296 /* 20 */ 89, 90, 91, 92, 26, 27, 15, 26, 27, 197,
@@ -111030,21 +111438,21 @@
111438 /* 1440 */ 130, 131, 132, 133, 134, 210, 175, 211, 31, 211,
111439 /* 1450 */ 33, 210, 104, 86, 87, 47, 175, 183, 175, 42,
111440 /* 1460 */ 103, 94, 178, 177, 22, 98, 175, 92, 228, 175,
111441 /* 1470 */ 175, 228, 55, 183, 57, 178, 175, 156, 61, 18,
111442 /* 1480 */ 157, 64, 156, 235, 157, 156, 45, 157, 236, 157,
111443 /* 1490 */ 135, 156, 199, 189, 157, 68, 129, 130, 131, 22,
111444 /* 1500 */ 189, 199, 157, 156, 192, 18, 192, 192, 199, 192,
111445 /* 1510 */ 218, 189, 40, 157, 218, 157, 240, 240, 157, 38,
111446 /* 1520 */ 196, 243, 105, 106, 107, 153, 198, 209, 111, 166,
111447 /* 1530 */ 176, 181, 166, 116, 166, 230, 176, 230, 176, 226,
111448 /* 1540 */ 199, 177, 239, 209, 185, 148, 166, 195, 209, 196,
111449 /* 1550 */ 199, 208, 182, 233, 173, 182, 139, 186, 239, 234,
111450 /* 1560 */ 191, 182, 173, 92,
111451 };
111452 #define YY_SHIFT_USE_DFLT (-70)
111453 #define YY_SHIFT_COUNT (417)
111454 #define YY_SHIFT_MIN (-69)
111455 #define YY_SHIFT_MAX (1487)
111456 static const short yy_shift_ofst[] = {
111457 /* 0 */ 1143, 1188, 1417, 1188, 1287, 1287, 138, 138, -2, -19,
111458 /* 10 */ 1287, 1287, 1287, 1287, 347, 362, 129, 129, 795, 1165,
@@ -111057,44 +111465,44 @@
111465 /* 80 */ 869, 869, 869, 869, 869, 869, 869, 869, 869, 869,
111466 /* 90 */ 869, 869, 869, 943, 869, 1017, 1091, 1091, -69, -45,
111467 /* 100 */ -45, -45, -45, -45, -1, 24, 245, 362, 362, 362,
111468 /* 110 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111469 /* 120 */ 362, 362, 362, 388, 356, 362, 362, 362, 362, 362,
111470 /* 130 */ 732, 868, 231, 1051, 1471, -70, -70, -70, 1367, 57,
111471 /* 140 */ 434, 434, 289, 291, 285, 1, 204, 572, 539, 362,
111472 /* 150 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111473 /* 160 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111474 /* 170 */ 362, 362, 362, 362, 362, 362, 362, 362, 362, 362,
111475 /* 180 */ 362, 506, 506, 506, 705, 1253, 1253, 1253, -70, -70,
111476 /* 190 */ -70, 171, 171, 160, 502, 502, 502, 446, 432, 511,
111477 /* 200 */ 422, 358, 335, -12, -12, -12, -12, 576, 294, -12,
111478 /* 210 */ -12, 295, 595, 141, 600, 730, 723, 723, 805, 730,
111479 /* 220 */ 805, 439, 911, 231, 865, 231, 865, 807, 865, 723,
111480 /* 230 */ 766, 633, 633, 231, 284, 63, 608, 1481, 1308, 1308,
111481 /* 240 */ 1472, 1472, 1308, 1477, 1427, 1275, 1487, 1487, 1487, 1487,
111482 /* 250 */ 1308, 1461, 1275, 1477, 1427, 1427, 1275, 1308, 1461, 1355,
111483 /* 260 */ 1441, 1308, 1308, 1461, 1308, 1461, 1308, 1461, 1442, 1348,
111484 /* 270 */ 1348, 1348, 1408, 1375, 1375, 1442, 1348, 1357, 1348, 1408,
111485 /* 280 */ 1348, 1348, 1316, 1331, 1316, 1331, 1316, 1331, 1308, 1308,
111486 /* 290 */ 1280, 1288, 1289, 1285, 1279, 1275, 1253, 1336, 1346, 1346,
111487 /* 300 */ 1338, 1338, 1338, 1338, -70, -70, -70, -70, -70, -70,
111488 /* 310 */ 1013, 467, 612, 84, 179, -28, 870, 410, 761, 760,
111489 /* 320 */ 667, 650, 531, 220, 361, 331, 125, 127, 97, 1306,
111490 /* 330 */ 1300, 1270, 1151, 1272, 1203, 1232, 1261, 1244, 1148, 1174,
111491 /* 340 */ 1139, 1156, 1124, 1220, 1115, 1210, 1233, 1099, 1193, 1184,
111492 /* 350 */ 1174, 1173, 1029, 1121, 1120, 1085, 1162, 1119, 1037, 1152,
111493 /* 360 */ 1147, 1129, 1046, 1011, 1093, 1098, 1075, 1061, 1032, 960,
111494 /* 370 */ 1057, 1031, 1030, 899, 938, 982, 936, 972, 958, 910,
111495 /* 380 */ 955, 875, 885, 908, 857, 859, 867, 804, 590, 834,
111496 /* 390 */ 747, 818, 513, 611, 741, 673, 637, 611, 606, 603,
111497 /* 400 */ 579, 501, 541, 468, 386, 445, 395, 376, 281, 185,
111498 /* 410 */ 120, 92, 75, 45, 114, 25, 11, 5,
111499 };
111500 #define YY_REDUCE_USE_DFLT (-169)
111501 #define YY_REDUCE_COUNT (309)
111502 #define YY_REDUCE_MIN (-168)
111503 #define YY_REDUCE_MAX (1397)
111504 static const short yy_reduce_ofst[] = {
111505 /* 0 */ -141, 90, 1095, 222, 158, 156, 19, 17, 10, -104,
111506 /* 10 */ 378, 316, 311, 12, 180, 249, 598, 464, 397, 1181,
111507 /* 20 */ 1177, 1175, 1128, 1106, 1096, 1054, 1038, 974, 964, 962,
111508 /* 30 */ 948, 905, 903, 900, 887, 874, 832, 826, 816, 813,
@@ -111111,87 +111519,87 @@
111519 /* 140 */ 935, 892, 968, 1245, 1242, 1234, 1225, 798, 798, 1222,
111520 /* 150 */ 1221, 1218, 1214, 1213, 1212, 1202, 1195, 1191, 1161, 1158,
111521 /* 160 */ 1140, 1135, 1123, 1112, 1107, 1100, 1080, 1074, 1073, 1072,
111522 /* 170 */ 1070, 1067, 1048, 1044, 969, 968, 907, 906, 904, 894,
111523 /* 180 */ 833, 837, 836, 340, 827, 815, 775, 68, 722, 646,
111524 /* 190 */ -168, 1389, 1381, 1371, 1379, 1373, 1370, 1343, 1352, 1369,
111525 /* 200 */ 1352, 1352, 1352, 1352, 1352, 1352, 1352, 1325, 1320, 1352,
111526 /* 210 */ 1352, 1343, 1380, 1353, 1397, 1351, 1339, 1334, 1319, 1341,
111527 /* 220 */ 1303, 1364, 1359, 1368, 1362, 1366, 1360, 1350, 1354, 1318,
111528 /* 230 */ 1313, 1307, 1305, 1363, 1328, 1324, 1372, 1278, 1361, 1358,
111529 /* 240 */ 1277, 1276, 1356, 1296, 1322, 1309, 1317, 1315, 1314, 1312,
111530 /* 250 */ 1345, 1347, 1302, 1292, 1311, 1304, 1293, 1337, 1335, 1252,
111531 /* 260 */ 1248, 1332, 1330, 1329, 1327, 1326, 1323, 1321, 1297, 1301,
111532 /* 270 */ 1295, 1294, 1290, 1243, 1240, 1284, 1291, 1286, 1283, 1274,
111533 /* 280 */ 1281, 1271, 1238, 1241, 1236, 1235, 1227, 1226, 1267, 1266,
111534 /* 290 */ 1189, 1229, 1223, 1211, 1206, 1201, 1197, 1239, 1237, 1219,
111535 /* 300 */ 1216, 1209, 1208, 1185, 1089, 1086, 1087, 1137, 1136, 1164,
111536 };
111537 static const YYACTIONTYPE yy_default[] = {
111538 /* 0 */ 633, 867, 955, 955, 867, 867, 955, 955, 955, 757,
111539 /* 10 */ 955, 955, 955, 865, 955, 955, 785, 785, 929, 955,
111540 /* 20 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111541 /* 30 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111542 /* 40 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111543 /* 50 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111544 /* 60 */ 955, 955, 955, 955, 955, 955, 955, 672, 761, 791,
111545 /* 70 */ 955, 955, 955, 955, 955, 955, 955, 955, 928, 930,
111546 /* 80 */ 799, 798, 908, 772, 796, 789, 793, 868, 861, 862,
111547 /* 90 */ 860, 864, 869, 955, 792, 828, 845, 827, 839, 844,
111548 /* 100 */ 851, 843, 840, 830, 829, 831, 832, 955, 955, 955,
111549 /* 110 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111550 /* 120 */ 955, 955, 955, 659, 726, 955, 955, 955, 955, 955,
111551 /* 130 */ 955, 955, 955, 833, 834, 848, 847, 846, 955, 664,
111552 /* 140 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111553 /* 150 */ 935, 933, 955, 880, 955, 955, 955, 955, 955, 955,
111554 /* 160 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111555 /* 170 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111556 /* 180 */ 639, 757, 757, 757, 633, 955, 955, 955, 947, 761,
111557 /* 190 */ 751, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111558 /* 200 */ 955, 955, 955, 801, 740, 918, 920, 955, 901, 738,
111559 /* 210 */ 661, 759, 674, 749, 641, 795, 774, 774, 913, 795,
111560 /* 220 */ 913, 697, 720, 955, 785, 955, 785, 694, 785, 774,
111561 /* 230 */ 863, 955, 955, 955, 758, 749, 955, 940, 765, 765,
111562 /* 240 */ 932, 932, 765, 807, 730, 795, 737, 737, 737, 737,
111563 /* 250 */ 765, 656, 795, 807, 730, 730, 795, 765, 656, 907,
111564 /* 260 */ 905, 765, 765, 656, 765, 656, 765, 656, 873, 728,
111565 /* 270 */ 728, 728, 712, 877, 877, 873, 728, 697, 728, 712,
111566 /* 280 */ 728, 728, 778, 773, 778, 773, 778, 773, 765, 765,
111567 /* 290 */ 955, 790, 779, 788, 786, 795, 955, 715, 649, 649,
111568 /* 300 */ 638, 638, 638, 638, 952, 952, 947, 699, 699, 682,
111569 /* 310 */ 955, 955, 955, 955, 955, 955, 955, 882, 955, 955,
111570 /* 320 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111571 /* 330 */ 634, 942, 955, 955, 939, 955, 955, 955, 955, 800,
111572 /* 340 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111573 /* 350 */ 917, 955, 955, 955, 955, 955, 955, 955, 911, 955,
111574 /* 360 */ 955, 955, 955, 955, 955, 904, 903, 955, 955, 955,
111575 /* 370 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111576 /* 380 */ 955, 955, 955, 955, 955, 955, 955, 955, 955, 955,
111577 /* 390 */ 955, 955, 955, 787, 955, 780, 955, 866, 955, 955,
111578 /* 400 */ 955, 955, 955, 955, 955, 955, 955, 955, 743, 816,
111579 /* 410 */ 955, 815, 819, 814, 666, 955, 647, 955, 630, 635,
111580 /* 420 */ 951, 954, 953, 950, 949, 948, 943, 941, 938, 937,
111581 /* 430 */ 936, 934, 931, 927, 886, 884, 891, 890, 889, 888,
111582 /* 440 */ 887, 885, 883, 881, 802, 797, 794, 926, 879, 739,
111583 /* 450 */ 736, 735, 655, 944, 910, 919, 806, 805, 808, 916,
111584 /* 460 */ 915, 914, 912, 909, 896, 804, 803, 731, 871, 870,
111585 /* 470 */ 658, 900, 899, 898, 902, 906, 897, 767, 657, 654,
111586 /* 480 */ 663, 718, 719, 727, 725, 724, 723, 722, 721, 717,
111587 /* 490 */ 665, 673, 711, 696, 695, 876, 878, 875, 874, 704,
111588 /* 500 */ 703, 709, 708, 707, 706, 705, 702, 701, 700, 693,
111589 /* 510 */ 692, 698, 691, 714, 713, 710, 690, 734, 733, 732,
111590 /* 520 */ 729, 689, 688, 687, 819, 686, 685, 825, 824, 812,
111591 /* 530 */ 855, 754, 753, 752, 764, 763, 776, 775, 810, 809,
111592 /* 540 */ 777, 762, 756, 755, 771, 770, 769, 768, 760, 750,
111593 /* 550 */ 782, 784, 783, 781, 857, 766, 854, 925, 924, 923,
111594 /* 560 */ 922, 921, 859, 858, 826, 823, 677, 678, 894, 893,
111595 /* 570 */ 895, 892, 680, 679, 676, 675, 856, 745, 744, 852,
111596 /* 580 */ 849, 841, 837, 853, 850, 842, 838, 836, 835, 821,
111597 /* 590 */ 820, 818, 817, 813, 822, 668, 746, 742, 741, 811,
111598 /* 600 */ 748, 747, 684, 683, 681, 662, 660, 653, 651, 650,
111599 /* 610 */ 652, 648, 646, 645, 644, 643, 642, 671, 670, 669,
111600 /* 620 */ 667, 666, 640, 637, 636, 632, 631, 629,
111601 };
111602
111603 /* The next table maps tokens into fallback tokens. If a construct
111604 ** like the following:
111605 **
@@ -111659,11 +112067,11 @@
112067 /* 237 */ "case_operand ::=",
112068 /* 238 */ "exprlist ::= nexprlist",
112069 /* 239 */ "exprlist ::=",
112070 /* 240 */ "nexprlist ::= nexprlist COMMA expr",
112071 /* 241 */ "nexprlist ::= expr",
112072 /* 242 */ "cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt",
112073 /* 243 */ "uniqueflag ::= UNIQUE",
112074 /* 244 */ "uniqueflag ::=",
112075 /* 245 */ "idxlist_opt ::=",
112076 /* 246 */ "idxlist_opt ::= LP idxlist RP",
112077 /* 247 */ "idxlist ::= idxlist COMMA nm collate sortorder",
@@ -112378,11 +112786,11 @@
112786 { 224, 0 },
112787 { 220, 1 },
112788 { 220, 0 },
112789 { 215, 3 },
112790 { 215, 1 },
112791 { 147, 12 },
112792 { 227, 1 },
112793 { 227, 0 },
112794 { 178, 0 },
112795 { 178, 3 },
112796 { 187, 5 },
@@ -112820,10 +113228,11 @@
113228 case 114: /* select ::= select multiselect_op oneselect */
113229 {
113230 if( yymsp[0].minor.yy159 ){
113231 yymsp[0].minor.yy159->op = (u8)yymsp[-1].minor.yy392;
113232 yymsp[0].minor.yy159->pPrior = yymsp[-2].minor.yy159;
113233 if( yymsp[-1].minor.yy392!=TK_ALL ) pParse->hasCompound = 1;
113234 }else{
113235 sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy159);
113236 }
113237 yygotominor.yy159 = yymsp[0].minor.yy159;
113238 }
@@ -113382,15 +113791,15 @@
113791 {yygotominor.yy442 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy442,yymsp[0].minor.yy342.pExpr);}
113792 break;
113793 case 241: /* nexprlist ::= expr */
113794 {yygotominor.yy442 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy342.pExpr);}
113795 break;
113796 case 242: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP where_opt */
113797 {
113798 sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0,
113799 sqlite3SrcListAppend(pParse->db,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy442, yymsp[-10].minor.yy392,
113800 &yymsp[-11].minor.yy0, yymsp[0].minor.yy122, SQLITE_SO_ASC, yymsp[-8].minor.yy392);
113801 }
113802 break;
113803 case 243: /* uniqueflag ::= UNIQUE */
113804 case 296: /* raisetype ::= ABORT */ yytestcase(yyruleno==296);
113805 {yygotominor.yy392 = OE_Abort;}
@@ -114312,11 +114721,10 @@
114721 *tokenType = TK_SPACE;
114722 return i;
114723 }
114724 case '-': {
114725 if( z[1]=='-' ){
 
114726 for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
114727 *tokenType = TK_SPACE; /* IMP: R-22934-25134 */
114728 return i;
114729 }
114730 *tokenType = TK_MINUS;
@@ -114345,11 +114753,10 @@
114753 case '/': {
114754 if( z[1]!='*' || z[2]==0 ){
114755 *tokenType = TK_SLASH;
114756 return 1;
114757 }
 
114758 for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
114759 if( c ) i++;
114760 *tokenType = TK_SPACE; /* IMP: R-22934-25134 */
114761 return i;
114762 }
@@ -116127,10 +116534,12 @@
116534 }
116535 sqlite3BtreeLeaveAll(db);
116536
116537 /* Any deferred constraint violations have now been resolved. */
116538 db->nDeferredCons = 0;
116539 db->nDeferredImmCons = 0;
116540 db->flags &= ~SQLITE_DeferFKs;
116541
116542 /* If one has been configured, invoke the rollback-hook callback */
116543 if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){
116544 db->xRollbackCallback(db->pRollbackArg);
116545 }
@@ -116188,10 +116597,11 @@
116597 case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break;
116598 case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break;
116599 case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break;
116600 case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break;
116601 case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break;
116602 case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break;
116603 case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break;
116604 case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break;
116605 case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break;
116606 case SQLITE_FULL: zName = "SQLITE_FULL"; break;
116607 case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break;
@@ -116388,11 +116798,11 @@
116798 void *pArg
116799 ){
116800 sqlite3_mutex_enter(db->mutex);
116801 if( nOps>0 ){
116802 db->xProgress = xProgress;
116803 db->nProgressOps = (unsigned)nOps;
116804 db->pProgressArg = pArg;
116805 }else{
116806 db->xProgress = 0;
116807 db->nProgressOps = 0;
116808 db->pProgressArg = 0;
@@ -117543,11 +117953,11 @@
117953 db->autoCommit = 1;
117954 db->nextAutovac = -1;
117955 db->szMmap = sqlite3GlobalConfig.szMmap;
117956 db->nextPagesize = 0;
117957 db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger
117958 #if !defined(SQLITE_DEFAULT_AUTOMATIC_INDEX) || SQLITE_DEFAULT_AUTOMATIC_INDEX
117959 | SQLITE_AutoIndex
117960 #endif
117961 #if SQLITE_DEFAULT_FILE_FORMAT<4
117962 | SQLITE_LegacyFileFmt
117963 #endif
@@ -119087,11 +119497,11 @@
119497
119498 #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
119499
119500 /* If not building as part of the core, include sqlite3ext.h. */
119501 #ifndef SQLITE_CORE
119502 SQLITE_EXTENSION_INIT3
119503 #endif
119504
119505 /************** Include fts3_tokenizer.h in the middle of fts3Int.h **********/
119506 /************** Begin file fts3_tokenizer.h **********************************/
119507 /*
@@ -124995,11 +125405,14 @@
125405
125406 #if !SQLITE_CORE
125407 /*
125408 ** Initialize API pointer table, if required.
125409 */
125410 #ifdef _WIN32
125411 __declspec(dllexport)
125412 #endif
125413 SQLITE_API int sqlite3_fts3_init(
125414 sqlite3 *db,
125415 char **pzErrMsg,
125416 const sqlite3_api_routines *pApi
125417 ){
125418 SQLITE_EXTENSION_INIT2(pApi)
@@ -128013,11 +128426,11 @@
128426 }
128427
128428
128429 #ifdef SQLITE_TEST
128430
128431 #include <tcl.h>
128432 /* #include <string.h> */
128433
128434 /*
128435 ** Implementation of a special SQL scalar function for testing tokenizers
128436 ** designed to be used in concert with the Tcl testing framework. This
@@ -140042,11 +140455,14 @@
140455 (void *)pGeomCtx, geomCallback, 0, 0, doSqlite3Free
140456 );
140457 }
140458
140459 #if !SQLITE_CORE
140460 #ifdef _WIN32
140461 __declspec(dllexport)
140462 #endif
140463 SQLITE_API int sqlite3_rtree_init(
140464 sqlite3 *db,
140465 char **pzErrMsg,
140466 const sqlite3_api_routines *pApi
140467 ){
140468 SQLITE_EXTENSION_INIT2(pApi)
@@ -140544,11 +140960,14 @@
140960
140961 return rc;
140962 }
140963
140964 #if !SQLITE_CORE
140965 #ifdef _WIN32
140966 __declspec(dllexport)
140967 #endif
140968 SQLITE_API int sqlite3_icu_init(
140969 sqlite3 *db,
140970 char **pzErrMsg,
140971 const sqlite3_api_routines *pApi
140972 ){
140973 SQLITE_EXTENSION_INIT2(pApi)
140974
+63 -33
--- 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.8.0"
111111
#define SQLITE_VERSION_NUMBER 3008000
112
-#define SQLITE_SOURCE_ID "2013-07-09 03:04:32 52a49cbc1621094b2fe2b021209b768d29e0426b"
112
+#define SQLITE_SOURCE_ID "2013-08-06 07:45:08 924f7e4d7a8fa2fe9100836663f3733b6e1a9084"
113113
114114
/*
115115
** CAPI3REF: Run-Time Library Version Numbers
116116
** KEYWORDS: sqlite3_version, sqlite3_sourceid
117117
**
@@ -476,10 +476,11 @@
476476
#define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
477477
#define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
478478
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
479479
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
480480
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
481
+#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
481482
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
482483
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
483484
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
484485
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
485486
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -2557,13 +2558,14 @@
25572558
** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
25582559
** database connection D. An example use for this
25592560
** interface is to keep a GUI updated during a large query.
25602561
**
25612562
** ^The parameter P is passed through as the only parameter to the
2562
-** callback function X. ^The parameter N is the number of
2563
+** callback function X. ^The parameter N is the approximate number of
25632564
** [virtual machine instructions] that are evaluated between successive
2564
-** invocations of the callback X.
2565
+** invocations of the callback X. ^If N is less than one then the progress
2566
+** handler is disabled.
25652567
**
25662568
** ^Only a single progress handler may be defined at one time per
25672569
** [database connection]; setting a new progress handler cancels the
25682570
** old one. ^Setting parameter X to NULL disables the progress handler.
25692571
** ^The progress handler is also disabled by setting N to a value less
@@ -4179,45 +4181,53 @@
41794181
SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
41804182
41814183
/*
41824184
** CAPI3REF: Function Auxiliary Data
41834185
**
4184
-** The following two functions may be used by scalar SQL functions to
4186
+** These functions may be used by (non-aggregate) SQL functions to
41854187
** associate metadata with argument values. If the same value is passed to
41864188
** multiple invocations of the same SQL function during query execution, under
4187
-** some circumstances the associated metadata may be preserved. This may
4188
-** be used, for example, to add a regular-expression matching scalar
4189
-** function. The compiled version of the regular expression is stored as
4190
-** metadata associated with the SQL value passed as the regular expression
4191
-** pattern. The compiled regular expression can be reused on multiple
4192
-** invocations of the same function so that the original pattern string
4193
-** does not need to be recompiled on each invocation.
4189
+** some circumstances the associated metadata may be preserved. An example
4190
+** of where this might be useful is in a regular-expression matching
4191
+** function. The compiled version of the regular expression can be stored as
4192
+** metadata associated with the pattern string.
4193
+** Then as long as the pattern string remains the same,
4194
+** the compiled regular expression can be reused on multiple
4195
+** invocations of the same function.
41944196
**
41954197
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
41964198
** associated by the sqlite3_set_auxdata() function with the Nth argument
4197
-** value to the application-defined function. ^If no metadata has been ever
4198
-** been set for the Nth argument of the function, or if the corresponding
4199
-** function parameter has changed since the meta-data was set,
4200
-** then sqlite3_get_auxdata() returns a NULL pointer.
4201
-**
4202
-** ^The sqlite3_set_auxdata() interface saves the metadata
4203
-** pointed to by its 3rd parameter as the metadata for the N-th
4204
-** argument of the application-defined function. Subsequent
4205
-** calls to sqlite3_get_auxdata() might return this data, if it has
4206
-** not been destroyed.
4207
-** ^If it is not NULL, SQLite will invoke the destructor
4208
-** function given by the 4th parameter to sqlite3_set_auxdata() on
4209
-** the metadata when the corresponding function parameter changes
4210
-** or when the SQL statement completes, whichever comes first.
4211
-**
4212
-** SQLite is free to call the destructor and drop metadata on any
4213
-** parameter of any function at any time. ^The only guarantee is that
4214
-** the destructor will be called before the metadata is dropped.
4199
+** value to the application-defined function. ^If there is no metadata
4200
+** associated with the function argument, this sqlite3_get_auxdata() interface
4201
+** returns a NULL pointer.
4202
+**
4203
+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
4204
+** argument of the application-defined function. ^Subsequent
4205
+** calls to sqlite3_get_auxdata(C,N) return P from the most recent
4206
+** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
4207
+** NULL if the metadata has been discarded.
4208
+** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
4209
+** SQLite will invoke the destructor function X with parameter P exactly
4210
+** once, when the metadata is discarded.
4211
+** SQLite is free to discard the metadata at any time, including: <ul>
4212
+** <li> when the corresponding function parameter changes, or
4213
+** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
4214
+** SQL statement, or
4215
+** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
4216
+** <li> during the original sqlite3_set_auxdata() call when a memory
4217
+** allocation error occurs. </ul>)^
4218
+**
4219
+** Note the last bullet in particular. The destructor X in
4220
+** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
4221
+** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
4222
+** should be called near the end of the function implementation and the
4223
+** function implementation should not make any use of P after
4224
+** sqlite3_set_auxdata() has been called.
42154225
**
42164226
** ^(In practice, metadata is preserved between function calls for
4217
-** expressions that are constant at compile time. This includes literal
4218
-** values and [parameters].)^
4227
+** function parameters that are compile-time constants, including literal
4228
+** values and [parameters] and expressions composed from the same.)^
42194229
**
42204230
** These routines must be called from the same thread in which
42214231
** the SQL function is running.
42224232
*/
42234233
SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
@@ -5126,14 +5136,27 @@
51265136
**
51275137
** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
51285138
** on the list of automatic extensions is a harmless no-op. ^No entry point
51295139
** will be called more than once for each database connection that is opened.
51305140
**
5131
-** See also: [sqlite3_reset_auto_extension()].
5141
+** See also: [sqlite3_reset_auto_extension()]
5142
+** and [sqlite3_cancel_auto_extension()]
51325143
*/
51335144
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
51345145
5146
+/*
5147
+** CAPI3REF: Cancel Automatic Extension Loading
5148
+**
5149
+** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
5150
+** initialization routine X that was registered using a prior call to
5151
+** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
5152
+** routine returns 1 if initialization routine X was successfully
5153
+** unregistered and it returns 0 if X was not on the list of initialization
5154
+** routines.
5155
+*/
5156
+SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
5157
+
51355158
/*
51365159
** CAPI3REF: Reset Automatic Extension Loading
51375160
**
51385161
** ^This interface disables all automatic extensions previously
51395162
** registered using [sqlite3_auto_extension()].
@@ -6242,10 +6265,16 @@
62426265
** transaction rollback or database recovery operations are not included.
62436266
** If an IO or other error occurs while writing a page to disk, the effect
62446267
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
62456268
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
62466269
** </dd>
6270
+**
6271
+** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
6272
+** <dd>This parameter returns zero for the current value if and only if
6273
+** all foreign key constraints (deferred or immediate) have been
6274
+** resolved.)^ ^The highwater mark is always 0.
6275
+** </dd>
62476276
** </dl>
62486277
*/
62496278
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
62506279
#define SQLITE_DBSTATUS_CACHE_USED 1
62516280
#define SQLITE_DBSTATUS_SCHEMA_USED 2
@@ -6254,11 +6283,12 @@
62546283
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
62556284
#define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
62566285
#define SQLITE_DBSTATUS_CACHE_HIT 7
62576286
#define SQLITE_DBSTATUS_CACHE_MISS 8
62586287
#define SQLITE_DBSTATUS_CACHE_WRITE 9
6259
-#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
6288
+#define SQLITE_DBSTATUS_DEFERRED_FKS 10
6289
+#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
62606290
62616291
62626292
/*
62636293
** CAPI3REF: Prepared Statement Status
62646294
**
62656295
--- 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.8.0"
111 #define SQLITE_VERSION_NUMBER 3008000
112 #define SQLITE_SOURCE_ID "2013-07-09 03:04:32 52a49cbc1621094b2fe2b021209b768d29e0426b"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -476,10 +476,11 @@
476 #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
477 #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
478 #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
479 #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
480 #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
 
481 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
482 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
483 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
484 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
485 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -2557,13 +2558,14 @@
2557 ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
2558 ** database connection D. An example use for this
2559 ** interface is to keep a GUI updated during a large query.
2560 **
2561 ** ^The parameter P is passed through as the only parameter to the
2562 ** callback function X. ^The parameter N is the number of
2563 ** [virtual machine instructions] that are evaluated between successive
2564 ** invocations of the callback X.
 
2565 **
2566 ** ^Only a single progress handler may be defined at one time per
2567 ** [database connection]; setting a new progress handler cancels the
2568 ** old one. ^Setting parameter X to NULL disables the progress handler.
2569 ** ^The progress handler is also disabled by setting N to a value less
@@ -4179,45 +4181,53 @@
4179 SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
4180
4181 /*
4182 ** CAPI3REF: Function Auxiliary Data
4183 **
4184 ** The following two functions may be used by scalar SQL functions to
4185 ** associate metadata with argument values. If the same value is passed to
4186 ** multiple invocations of the same SQL function during query execution, under
4187 ** some circumstances the associated metadata may be preserved. This may
4188 ** be used, for example, to add a regular-expression matching scalar
4189 ** function. The compiled version of the regular expression is stored as
4190 ** metadata associated with the SQL value passed as the regular expression
4191 ** pattern. The compiled regular expression can be reused on multiple
4192 ** invocations of the same function so that the original pattern string
4193 ** does not need to be recompiled on each invocation.
4194 **
4195 ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
4196 ** associated by the sqlite3_set_auxdata() function with the Nth argument
4197 ** value to the application-defined function. ^If no metadata has been ever
4198 ** been set for the Nth argument of the function, or if the corresponding
4199 ** function parameter has changed since the meta-data was set,
4200 ** then sqlite3_get_auxdata() returns a NULL pointer.
4201 **
4202 ** ^The sqlite3_set_auxdata() interface saves the metadata
4203 ** pointed to by its 3rd parameter as the metadata for the N-th
4204 ** argument of the application-defined function. Subsequent
4205 ** calls to sqlite3_get_auxdata() might return this data, if it has
4206 ** not been destroyed.
4207 ** ^If it is not NULL, SQLite will invoke the destructor
4208 ** function given by the 4th parameter to sqlite3_set_auxdata() on
4209 ** the metadata when the corresponding function parameter changes
4210 ** or when the SQL statement completes, whichever comes first.
4211 **
4212 ** SQLite is free to call the destructor and drop metadata on any
4213 ** parameter of any function at any time. ^The only guarantee is that
4214 ** the destructor will be called before the metadata is dropped.
 
 
 
 
 
 
 
 
4215 **
4216 ** ^(In practice, metadata is preserved between function calls for
4217 ** expressions that are constant at compile time. This includes literal
4218 ** values and [parameters].)^
4219 **
4220 ** These routines must be called from the same thread in which
4221 ** the SQL function is running.
4222 */
4223 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
@@ -5126,14 +5136,27 @@
5126 **
5127 ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
5128 ** on the list of automatic extensions is a harmless no-op. ^No entry point
5129 ** will be called more than once for each database connection that is opened.
5130 **
5131 ** See also: [sqlite3_reset_auto_extension()].
 
5132 */
5133 SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
5134
 
 
 
 
 
 
 
 
 
 
 
 
5135 /*
5136 ** CAPI3REF: Reset Automatic Extension Loading
5137 **
5138 ** ^This interface disables all automatic extensions previously
5139 ** registered using [sqlite3_auto_extension()].
@@ -6242,10 +6265,16 @@
6242 ** transaction rollback or database recovery operations are not included.
6243 ** If an IO or other error occurs while writing a page to disk, the effect
6244 ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
6245 ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
6246 ** </dd>
 
 
 
 
 
 
6247 ** </dl>
6248 */
6249 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
6250 #define SQLITE_DBSTATUS_CACHE_USED 1
6251 #define SQLITE_DBSTATUS_SCHEMA_USED 2
@@ -6254,11 +6283,12 @@
6254 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
6255 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6256 #define SQLITE_DBSTATUS_CACHE_HIT 7
6257 #define SQLITE_DBSTATUS_CACHE_MISS 8
6258 #define SQLITE_DBSTATUS_CACHE_WRITE 9
6259 #define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
 
6260
6261
6262 /*
6263 ** CAPI3REF: Prepared Statement Status
6264 **
6265
--- 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.8.0"
111 #define SQLITE_VERSION_NUMBER 3008000
112 #define SQLITE_SOURCE_ID "2013-08-06 07:45:08 924f7e4d7a8fa2fe9100836663f3733b6e1a9084"
113
114 /*
115 ** CAPI3REF: Run-Time Library Version Numbers
116 ** KEYWORDS: sqlite3_version, sqlite3_sourceid
117 **
@@ -476,10 +476,11 @@
476 #define SQLITE_IOERR_SHMLOCK (SQLITE_IOERR | (20<<8))
477 #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8))
478 #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
479 #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
480 #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
481 #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
482 #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
483 #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
484 #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
485 #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
486 #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
@@ -2557,13 +2558,14 @@
2558 ** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for
2559 ** database connection D. An example use for this
2560 ** interface is to keep a GUI updated during a large query.
2561 **
2562 ** ^The parameter P is passed through as the only parameter to the
2563 ** callback function X. ^The parameter N is the approximate number of
2564 ** [virtual machine instructions] that are evaluated between successive
2565 ** invocations of the callback X. ^If N is less than one then the progress
2566 ** handler is disabled.
2567 **
2568 ** ^Only a single progress handler may be defined at one time per
2569 ** [database connection]; setting a new progress handler cancels the
2570 ** old one. ^Setting parameter X to NULL disables the progress handler.
2571 ** ^The progress handler is also disabled by setting N to a value less
@@ -4179,45 +4181,53 @@
4181 SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
4182
4183 /*
4184 ** CAPI3REF: Function Auxiliary Data
4185 **
4186 ** These functions may be used by (non-aggregate) SQL functions to
4187 ** associate metadata with argument values. If the same value is passed to
4188 ** multiple invocations of the same SQL function during query execution, under
4189 ** some circumstances the associated metadata may be preserved. An example
4190 ** of where this might be useful is in a regular-expression matching
4191 ** function. The compiled version of the regular expression can be stored as
4192 ** metadata associated with the pattern string.
4193 ** Then as long as the pattern string remains the same,
4194 ** the compiled regular expression can be reused on multiple
4195 ** invocations of the same function.
4196 **
4197 ** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
4198 ** associated by the sqlite3_set_auxdata() function with the Nth argument
4199 ** value to the application-defined function. ^If there is no metadata
4200 ** associated with the function argument, this sqlite3_get_auxdata() interface
4201 ** returns a NULL pointer.
4202 **
4203 ** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
4204 ** argument of the application-defined function. ^Subsequent
4205 ** calls to sqlite3_get_auxdata(C,N) return P from the most recent
4206 ** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
4207 ** NULL if the metadata has been discarded.
4208 ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
4209 ** SQLite will invoke the destructor function X with parameter P exactly
4210 ** once, when the metadata is discarded.
4211 ** SQLite is free to discard the metadata at any time, including: <ul>
4212 ** <li> when the corresponding function parameter changes, or
4213 ** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
4214 ** SQL statement, or
4215 ** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
4216 ** <li> during the original sqlite3_set_auxdata() call when a memory
4217 ** allocation error occurs. </ul>)^
4218 **
4219 ** Note the last bullet in particular. The destructor X in
4220 ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
4221 ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
4222 ** should be called near the end of the function implementation and the
4223 ** function implementation should not make any use of P after
4224 ** sqlite3_set_auxdata() has been called.
4225 **
4226 ** ^(In practice, metadata is preserved between function calls for
4227 ** function parameters that are compile-time constants, including literal
4228 ** values and [parameters] and expressions composed from the same.)^
4229 **
4230 ** These routines must be called from the same thread in which
4231 ** the SQL function is running.
4232 */
4233 SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N);
@@ -5126,14 +5136,27 @@
5136 **
5137 ** ^Calling sqlite3_auto_extension(X) with an entry point X that is already
5138 ** on the list of automatic extensions is a harmless no-op. ^No entry point
5139 ** will be called more than once for each database connection that is opened.
5140 **
5141 ** See also: [sqlite3_reset_auto_extension()]
5142 ** and [sqlite3_cancel_auto_extension()]
5143 */
5144 SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
5145
5146 /*
5147 ** CAPI3REF: Cancel Automatic Extension Loading
5148 **
5149 ** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
5150 ** initialization routine X that was registered using a prior call to
5151 ** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
5152 ** routine returns 1 if initialization routine X was successfully
5153 ** unregistered and it returns 0 if X was not on the list of initialization
5154 ** routines.
5155 */
5156 SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
5157
5158 /*
5159 ** CAPI3REF: Reset Automatic Extension Loading
5160 **
5161 ** ^This interface disables all automatic extensions previously
5162 ** registered using [sqlite3_auto_extension()].
@@ -6242,10 +6265,16 @@
6265 ** transaction rollback or database recovery operations are not included.
6266 ** If an IO or other error occurs while writing a page to disk, the effect
6267 ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
6268 ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
6269 ** </dd>
6270 **
6271 ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
6272 ** <dd>This parameter returns zero for the current value if and only if
6273 ** all foreign key constraints (deferred or immediate) have been
6274 ** resolved.)^ ^The highwater mark is always 0.
6275 ** </dd>
6276 ** </dl>
6277 */
6278 #define SQLITE_DBSTATUS_LOOKASIDE_USED 0
6279 #define SQLITE_DBSTATUS_CACHE_USED 1
6280 #define SQLITE_DBSTATUS_SCHEMA_USED 2
@@ -6254,11 +6283,12 @@
6283 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5
6284 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6
6285 #define SQLITE_DBSTATUS_CACHE_HIT 7
6286 #define SQLITE_DBSTATUS_CACHE_MISS 8
6287 #define SQLITE_DBSTATUS_CACHE_WRITE 9
6288 #define SQLITE_DBSTATUS_DEFERRED_FKS 10
6289 #define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
6290
6291
6292 /*
6293 ** CAPI3REF: Prepared Statement Status
6294 **
6295
+59 -10
--- src/style.c
+++ src/style.c
@@ -462,11 +462,11 @@
462462
;
463463
464464
/*
465465
** The default Cascading Style Sheet.
466466
** It's assembled by different strings for each class.
467
-** The default css conatains all definitions.
467
+** The default css contains all definitions.
468468
** The style sheet, send to the client only contains the ones,
469469
** not defined in the user defined css.
470470
*/
471471
const char zDefaultCSS[] =
472472
@ /* General settings for the entire page */
@@ -656,10 +656,15 @@
656656
},
657657
{ "td.timelineTableCell",
658658
"the format for the timeline data cells",
659659
@ vertical-align: top;
660660
@ text-align: left;
661
+ },
662
+ { "tr.timelineCurrent td.timelineTableCell",
663
+ "the format for the timeline data cell of the current checkout",
664
+ @ padding: .1em .2em;
665
+ @ border: 1px dashed #446979;
661666
},
662667
{ "span.timelineLeaf",
663668
"the format for the timeline leaf marks",
664669
@ font-weight: bold;
665670
},
@@ -965,20 +970,43 @@
965970
{ "ul.filelist",
966971
"List of files in a timeline",
967972
@ margin-top: 3px;
968973
@ line-height: 100%;
969974
},
970
- { "div.sbsdiff",
971
- "side-by-side diff display",
972
- @ font-family: monospace;
975
+ { "table.sbsdiffcols",
976
+ "side-by-side diff display (column-based)",
977
+ @ border-spacing: 0;
973978
@ font-size: xx-small;
974
- @ white-space: pre;
979
+ },
980
+ { "table.sbsdiffcols td",
981
+ "sbs diff table cell",
982
+ @ padding: 0;
983
+ @ vertical-align: top;
984
+ },
985
+ { "table.sbsdiffcols pre",
986
+ "sbs diff pre block",
987
+ @ margin: 0;
988
+ @ padding: 0;
989
+ @ border: 0;
990
+ @ font-size: inherit;
991
+ @ background: inherit;
992
+ @ color: inherit;
993
+ },
994
+ { "div.difflncol",
995
+ "diff line number column",
996
+ @ padding-right: 1em;
997
+ @ text-align: right;
998
+ @ color: #a0a0a0;
999
+ },
1000
+ { "div.difftxtcol",
1001
+ "diff text column",
1002
+ @ width: 45em;
1003
+ @ overflow-x: auto;
9751004
},
976
- { "div.udiff",
977
- "context diff display",
978
- @ font-family: monospace;
979
- @ white-space: pre;
1005
+ { "div.diffmkrcol",
1006
+ "diff marker column",
1007
+ @ padding: 0 1em;
9801008
},
9811009
{ "span.diffchng",
9821010
"changes in a diff",
9831011
@ background-color: #c0c0ff;
9841012
},
@@ -990,10 +1018,12 @@
9901018
"deleted in a diff",
9911019
@ background-color: #ffc8c8;
9921020
},
9931021
{ "span.diffhr",
9941022
"suppressed lines in a diff",
1023
+ @ display: inline-block;
1024
+ @ margin: .5em 0 1em;
9951025
@ color: #0000ff;
9961026
},
9971027
{ "span.diffln",
9981028
"line numbers in a diff",
9991029
@ color: #a0a0a0;
@@ -1033,10 +1063,23 @@
10331063
@ padding: 0.1em 1em 0.1em 1em;
10341064
},
10351065
{ ".statistics-report-row-year",
10361066
"",
10371067
@ text-align: left;
1068
+ },
1069
+ { ".statistics-report-graph-line",
1070
+ "for the /stats_report views",
1071
+ @ background-color: #446979;
1072
+ },
1073
+ { ".statistics-report-week-number-label",
1074
+ "for the /stats_report views",
1075
+ @ text-align: right;
1076
+ @ font-size: 0.8em;
1077
+ },
1078
+ { ".statistics-report-week-of-year-list",
1079
+ "for the /stats_report views",
1080
+ @ font-size: 0.8em;
10381081
},
10391082
{ "tr.row0",
10401083
"even table row color",
10411084
@ /* use default */
10421085
},
@@ -1136,12 +1179,18 @@
11361179
@ g.userUid = %d(g.userUid)<br />
11371180
@ g.zLogin = %h(g.zLogin)<br />
11381181
@ capabilities = %s(zCap)<br />
11391182
@ <hr>
11401183
P("HTTP_USER_AGENT");
1141
- cgi_print_all(atoi(PD("showall","0")));
1184
+ cgi_print_all(showAll);
1185
+ if( showAll && blob_size(&g.httpHeader)>0 ){
1186
+ @ <hr>
1187
+ @ <pre>
1188
+ @ %h(blob_str(&g.httpHeader))
1189
+ @ </pre>
1190
+ }
11421191
if( g.perm.Setup ){
11431192
const char *zRedir = P("redirect");
11441193
if( zRedir ) cgi_redirect(zRedir);
11451194
}
11461195
style_footer();
11471196
}
11481197
--- src/style.c
+++ src/style.c
@@ -462,11 +462,11 @@
462 ;
463
464 /*
465 ** The default Cascading Style Sheet.
466 ** It's assembled by different strings for each class.
467 ** The default css conatains all definitions.
468 ** The style sheet, send to the client only contains the ones,
469 ** not defined in the user defined css.
470 */
471 const char zDefaultCSS[] =
472 @ /* General settings for the entire page */
@@ -656,10 +656,15 @@
656 },
657 { "td.timelineTableCell",
658 "the format for the timeline data cells",
659 @ vertical-align: top;
660 @ text-align: left;
 
 
 
 
 
661 },
662 { "span.timelineLeaf",
663 "the format for the timeline leaf marks",
664 @ font-weight: bold;
665 },
@@ -965,20 +970,43 @@
965 { "ul.filelist",
966 "List of files in a timeline",
967 @ margin-top: 3px;
968 @ line-height: 100%;
969 },
970 { "div.sbsdiff",
971 "side-by-side diff display",
972 @ font-family: monospace;
973 @ font-size: xx-small;
974 @ white-space: pre;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
975 },
976 { "div.udiff",
977 "context diff display",
978 @ font-family: monospace;
979 @ white-space: pre;
980 },
981 { "span.diffchng",
982 "changes in a diff",
983 @ background-color: #c0c0ff;
984 },
@@ -990,10 +1018,12 @@
990 "deleted in a diff",
991 @ background-color: #ffc8c8;
992 },
993 { "span.diffhr",
994 "suppressed lines in a diff",
 
 
995 @ color: #0000ff;
996 },
997 { "span.diffln",
998 "line numbers in a diff",
999 @ color: #a0a0a0;
@@ -1033,10 +1063,23 @@
1033 @ padding: 0.1em 1em 0.1em 1em;
1034 },
1035 { ".statistics-report-row-year",
1036 "",
1037 @ text-align: left;
 
 
 
 
 
 
 
 
 
 
 
 
 
1038 },
1039 { "tr.row0",
1040 "even table row color",
1041 @ /* use default */
1042 },
@@ -1136,12 +1179,18 @@
1136 @ g.userUid = %d(g.userUid)<br />
1137 @ g.zLogin = %h(g.zLogin)<br />
1138 @ capabilities = %s(zCap)<br />
1139 @ <hr>
1140 P("HTTP_USER_AGENT");
1141 cgi_print_all(atoi(PD("showall","0")));
 
 
 
 
 
 
1142 if( g.perm.Setup ){
1143 const char *zRedir = P("redirect");
1144 if( zRedir ) cgi_redirect(zRedir);
1145 }
1146 style_footer();
1147 }
1148
--- src/style.c
+++ src/style.c
@@ -462,11 +462,11 @@
462 ;
463
464 /*
465 ** The default Cascading Style Sheet.
466 ** It's assembled by different strings for each class.
467 ** The default css contains all definitions.
468 ** The style sheet, send to the client only contains the ones,
469 ** not defined in the user defined css.
470 */
471 const char zDefaultCSS[] =
472 @ /* General settings for the entire page */
@@ -656,10 +656,15 @@
656 },
657 { "td.timelineTableCell",
658 "the format for the timeline data cells",
659 @ vertical-align: top;
660 @ text-align: left;
661 },
662 { "tr.timelineCurrent td.timelineTableCell",
663 "the format for the timeline data cell of the current checkout",
664 @ padding: .1em .2em;
665 @ border: 1px dashed #446979;
666 },
667 { "span.timelineLeaf",
668 "the format for the timeline leaf marks",
669 @ font-weight: bold;
670 },
@@ -965,20 +970,43 @@
970 { "ul.filelist",
971 "List of files in a timeline",
972 @ margin-top: 3px;
973 @ line-height: 100%;
974 },
975 { "table.sbsdiffcols",
976 "side-by-side diff display (column-based)",
977 @ border-spacing: 0;
978 @ font-size: xx-small;
979 },
980 { "table.sbsdiffcols td",
981 "sbs diff table cell",
982 @ padding: 0;
983 @ vertical-align: top;
984 },
985 { "table.sbsdiffcols pre",
986 "sbs diff pre block",
987 @ margin: 0;
988 @ padding: 0;
989 @ border: 0;
990 @ font-size: inherit;
991 @ background: inherit;
992 @ color: inherit;
993 },
994 { "div.difflncol",
995 "diff line number column",
996 @ padding-right: 1em;
997 @ text-align: right;
998 @ color: #a0a0a0;
999 },
1000 { "div.difftxtcol",
1001 "diff text column",
1002 @ width: 45em;
1003 @ overflow-x: auto;
1004 },
1005 { "div.diffmkrcol",
1006 "diff marker column",
1007 @ padding: 0 1em;
 
1008 },
1009 { "span.diffchng",
1010 "changes in a diff",
1011 @ background-color: #c0c0ff;
1012 },
@@ -990,10 +1018,12 @@
1018 "deleted in a diff",
1019 @ background-color: #ffc8c8;
1020 },
1021 { "span.diffhr",
1022 "suppressed lines in a diff",
1023 @ display: inline-block;
1024 @ margin: .5em 0 1em;
1025 @ color: #0000ff;
1026 },
1027 { "span.diffln",
1028 "line numbers in a diff",
1029 @ color: #a0a0a0;
@@ -1033,10 +1063,23 @@
1063 @ padding: 0.1em 1em 0.1em 1em;
1064 },
1065 { ".statistics-report-row-year",
1066 "",
1067 @ text-align: left;
1068 },
1069 { ".statistics-report-graph-line",
1070 "for the /stats_report views",
1071 @ background-color: #446979;
1072 },
1073 { ".statistics-report-week-number-label",
1074 "for the /stats_report views",
1075 @ text-align: right;
1076 @ font-size: 0.8em;
1077 },
1078 { ".statistics-report-week-of-year-list",
1079 "for the /stats_report views",
1080 @ font-size: 0.8em;
1081 },
1082 { "tr.row0",
1083 "even table row color",
1084 @ /* use default */
1085 },
@@ -1136,12 +1179,18 @@
1179 @ g.userUid = %d(g.userUid)<br />
1180 @ g.zLogin = %h(g.zLogin)<br />
1181 @ capabilities = %s(zCap)<br />
1182 @ <hr>
1183 P("HTTP_USER_AGENT");
1184 cgi_print_all(showAll);
1185 if( showAll && blob_size(&g.httpHeader)>0 ){
1186 @ <hr>
1187 @ <pre>
1188 @ %h(blob_str(&g.httpHeader))
1189 @ </pre>
1190 }
1191 if( g.perm.Setup ){
1192 const char *zRedir = P("redirect");
1193 if( zRedir ) cgi_redirect(zRedir);
1194 }
1195 style_footer();
1196 }
1197
+6
--- src/sync.c
+++ src/sync.c
@@ -93,10 +93,16 @@
9393
if( find_option("private",0,0)!=0 ){
9494
*pSyncFlags |= SYNC_PRIVATE;
9595
}
9696
if( find_option("verbose","v",0)!=0 ){
9797
*pSyncFlags |= SYNC_VERBOSE;
98
+ }
99
+ /* The --verily option to sync, push, and pull forces extra igot cards
100
+ ** to be exchanged. This can overcome malfunctions in the sync protocol.
101
+ */
102
+ if( find_option("verily",0,0)!=0 ){
103
+ *pSyncFlags |= SYNC_RESYNC;
98104
}
99105
url_proxy_options();
100106
db_find_and_open_repository(0, 0);
101107
db_open_config(0);
102108
if( g.argc==2 ){
103109
--- src/sync.c
+++ src/sync.c
@@ -93,10 +93,16 @@
93 if( find_option("private",0,0)!=0 ){
94 *pSyncFlags |= SYNC_PRIVATE;
95 }
96 if( find_option("verbose","v",0)!=0 ){
97 *pSyncFlags |= SYNC_VERBOSE;
 
 
 
 
 
 
98 }
99 url_proxy_options();
100 db_find_and_open_repository(0, 0);
101 db_open_config(0);
102 if( g.argc==2 ){
103
--- src/sync.c
+++ src/sync.c
@@ -93,10 +93,16 @@
93 if( find_option("private",0,0)!=0 ){
94 *pSyncFlags |= SYNC_PRIVATE;
95 }
96 if( find_option("verbose","v",0)!=0 ){
97 *pSyncFlags |= SYNC_VERBOSE;
98 }
99 /* The --verily option to sync, push, and pull forces extra igot cards
100 ** to be exchanged. This can overcome malfunctions in the sync protocol.
101 */
102 if( find_option("verily",0,0)!=0 ){
103 *pSyncFlags |= SYNC_RESYNC;
104 }
105 url_proxy_options();
106 db_find_and_open_repository(0, 0);
107 db_open_config(0);
108 if( g.argc==2 ){
109
+19 -5
--- src/tag.c
+++ src/tag.c
@@ -348,14 +348,15 @@
348348
** %fossil tag cancel ?--raw? TAGNAME CHECK-IN
349349
**
350350
** Remove the tag TAGNAME from CHECK-IN, and also remove
351351
** the propagation of the tag to any descendants.
352352
**
353
-** %fossil tag find ?--raw? ?-t|--type TYPE? TAGNAME
353
+** %fossil tag find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME
354354
**
355355
** List all objects that use TAGNAME. TYPE can be "ci" for
356
-** checkins or "e" for events.
356
+** checkins or "e" for events. The limit option limits the number
357
+** of results to the given value.
357358
**
358359
** %fossil tag list ?--raw? ?CHECK-IN?
359360
**
360361
** List all tags, or if CHECK-IN is supplied, list
361362
** all tags and their values for CHECK-IN.
@@ -387,10 +388,12 @@
387388
void tag_cmd(void){
388389
int n;
389390
int fRaw = find_option("raw","",0)!=0;
390391
int fPropagate = find_option("propagate","",0)!=0;
391392
const char *zPrefix = fRaw ? "" : "sym-";
393
+ char const * zFindLimit = find_option("limit","n",1);
394
+ int const nFindLimit = zFindLimit ? atoi(zFindLimit) : 0;
392395
393396
db_find_and_open_repository(0, 0);
394397
if( g.argc<3 ){
395398
goto tag_cmd_usage;
396399
}
@@ -428,40 +431,51 @@
428431
}else
429432
430433
if( strncmp(g.argv[2],"find",n)==0 ){
431434
Stmt q;
432435
const char *zType = find_option("type","t",1);
436
+ Blob sql = empty_blob;
433437
if( zType==0 || zType[0]==0 ) zType = "*";
434438
if( g.argc!=4 ){
435
- usage("find ?--raw? ?-t|--type TYPE? TAGNAME");
439
+ usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
436440
}
437441
if( fRaw ){
438
- db_prepare(&q,
442
+ blob_appendf(&sql,
439443
"SELECT blob.uuid FROM tagxref, blob"
440444
" WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
441445
" AND tagxref.tagtype>0"
442446
" AND blob.rid=tagxref.rid",
443447
g.argv[3]
444448
);
449
+ if(nFindLimit>0){
450
+ blob_appendf(&sql, " LIMIT %d", nFindLimit);
451
+ }
452
+ db_prepare(&q, "%s", blob_str(&sql));
453
+ blob_reset(&sql);
445454
while( db_step(&q)==SQLITE_ROW ){
446455
fossil_print("%s\n", db_column_text(&q, 0));
447456
}
448457
db_finalize(&q);
449458
}else{
450459
int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
451460
g.argv[3]);
452461
if( tagid>0 ){
453
- db_prepare(&q,
462
+ blob_appendf(&sql,
454463
"%s"
455464
" AND event.type GLOB '%q'"
456465
" AND blob.rid IN ("
457466
" SELECT rid FROM tagxref"
458467
" WHERE tagtype>0 AND tagid=%d"
459468
")"
460469
" ORDER BY event.mtime DESC",
461470
timeline_query_for_tty(), zType, tagid
462471
);
472
+ if(nFindLimit>0){
473
+ blob_appendf(&sql, " LIMIT %d", nFindLimit);
474
+ }
475
+ db_prepare(&q, "%s", blob_str(&sql));
476
+ blob_reset(&sql);
463477
print_timeline(&q, 2000, 0);
464478
db_finalize(&q);
465479
}
466480
}
467481
}else
468482
--- src/tag.c
+++ src/tag.c
@@ -348,14 +348,15 @@
348 ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN
349 **
350 ** Remove the tag TAGNAME from CHECK-IN, and also remove
351 ** the propagation of the tag to any descendants.
352 **
353 ** %fossil tag find ?--raw? ?-t|--type TYPE? TAGNAME
354 **
355 ** List all objects that use TAGNAME. TYPE can be "ci" for
356 ** checkins or "e" for events.
 
357 **
358 ** %fossil tag list ?--raw? ?CHECK-IN?
359 **
360 ** List all tags, or if CHECK-IN is supplied, list
361 ** all tags and their values for CHECK-IN.
@@ -387,10 +388,12 @@
387 void tag_cmd(void){
388 int n;
389 int fRaw = find_option("raw","",0)!=0;
390 int fPropagate = find_option("propagate","",0)!=0;
391 const char *zPrefix = fRaw ? "" : "sym-";
 
 
392
393 db_find_and_open_repository(0, 0);
394 if( g.argc<3 ){
395 goto tag_cmd_usage;
396 }
@@ -428,40 +431,51 @@
428 }else
429
430 if( strncmp(g.argv[2],"find",n)==0 ){
431 Stmt q;
432 const char *zType = find_option("type","t",1);
 
433 if( zType==0 || zType[0]==0 ) zType = "*";
434 if( g.argc!=4 ){
435 usage("find ?--raw? ?-t|--type TYPE? TAGNAME");
436 }
437 if( fRaw ){
438 db_prepare(&q,
439 "SELECT blob.uuid FROM tagxref, blob"
440 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
441 " AND tagxref.tagtype>0"
442 " AND blob.rid=tagxref.rid",
443 g.argv[3]
444 );
 
 
 
 
 
445 while( db_step(&q)==SQLITE_ROW ){
446 fossil_print("%s\n", db_column_text(&q, 0));
447 }
448 db_finalize(&q);
449 }else{
450 int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
451 g.argv[3]);
452 if( tagid>0 ){
453 db_prepare(&q,
454 "%s"
455 " AND event.type GLOB '%q'"
456 " AND blob.rid IN ("
457 " SELECT rid FROM tagxref"
458 " WHERE tagtype>0 AND tagid=%d"
459 ")"
460 " ORDER BY event.mtime DESC",
461 timeline_query_for_tty(), zType, tagid
462 );
 
 
 
 
 
463 print_timeline(&q, 2000, 0);
464 db_finalize(&q);
465 }
466 }
467 }else
468
--- src/tag.c
+++ src/tag.c
@@ -348,14 +348,15 @@
348 ** %fossil tag cancel ?--raw? TAGNAME CHECK-IN
349 **
350 ** Remove the tag TAGNAME from CHECK-IN, and also remove
351 ** the propagation of the tag to any descendants.
352 **
353 ** %fossil tag find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME
354 **
355 ** List all objects that use TAGNAME. TYPE can be "ci" for
356 ** checkins or "e" for events. The limit option limits the number
357 ** of results to the given value.
358 **
359 ** %fossil tag list ?--raw? ?CHECK-IN?
360 **
361 ** List all tags, or if CHECK-IN is supplied, list
362 ** all tags and their values for CHECK-IN.
@@ -387,10 +388,12 @@
388 void tag_cmd(void){
389 int n;
390 int fRaw = find_option("raw","",0)!=0;
391 int fPropagate = find_option("propagate","",0)!=0;
392 const char *zPrefix = fRaw ? "" : "sym-";
393 char const * zFindLimit = find_option("limit","n",1);
394 int const nFindLimit = zFindLimit ? atoi(zFindLimit) : 0;
395
396 db_find_and_open_repository(0, 0);
397 if( g.argc<3 ){
398 goto tag_cmd_usage;
399 }
@@ -428,40 +431,51 @@
431 }else
432
433 if( strncmp(g.argv[2],"find",n)==0 ){
434 Stmt q;
435 const char *zType = find_option("type","t",1);
436 Blob sql = empty_blob;
437 if( zType==0 || zType[0]==0 ) zType = "*";
438 if( g.argc!=4 ){
439 usage("find ?--raw? ?-t|--type TYPE? ?-n|--limit #? TAGNAME");
440 }
441 if( fRaw ){
442 blob_appendf(&sql,
443 "SELECT blob.uuid FROM tagxref, blob"
444 " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
445 " AND tagxref.tagtype>0"
446 " AND blob.rid=tagxref.rid",
447 g.argv[3]
448 );
449 if(nFindLimit>0){
450 blob_appendf(&sql, " LIMIT %d", nFindLimit);
451 }
452 db_prepare(&q, "%s", blob_str(&sql));
453 blob_reset(&sql);
454 while( db_step(&q)==SQLITE_ROW ){
455 fossil_print("%s\n", db_column_text(&q, 0));
456 }
457 db_finalize(&q);
458 }else{
459 int tagid = db_int(0, "SELECT tagid FROM tag WHERE tagname='sym-%q'",
460 g.argv[3]);
461 if( tagid>0 ){
462 blob_appendf(&sql,
463 "%s"
464 " AND event.type GLOB '%q'"
465 " AND blob.rid IN ("
466 " SELECT rid FROM tagxref"
467 " WHERE tagtype>0 AND tagid=%d"
468 ")"
469 " ORDER BY event.mtime DESC",
470 timeline_query_for_tty(), zType, tagid
471 );
472 if(nFindLimit>0){
473 blob_appendf(&sql, " LIMIT %d", nFindLimit);
474 }
475 db_prepare(&q, "%s", blob_str(&sql));
476 blob_reset(&sql);
477 print_timeline(&q, 2000, 0);
478 db_finalize(&q);
479 }
480 }
481 }else
482
+243 -46
--- src/timeline.c
+++ src/timeline.c
@@ -245,11 +245,15 @@
245245
int prevWasDivider = 0; /* True if previous output row was <hr> */
246246
int fchngQueryInit = 0; /* True if fchngQuery is initialized */
247247
Stmt fchngQuery; /* Query for file changes on check-ins */
248248
static Stmt qbranch;
249249
int pendingEndTr = 0; /* True if a </td></tr> is needed */
250
-
250
+ int vid = 0; /* Current checkout version */
251
+
252
+ if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
253
+ vid = db_lget_int("checkout", 0);
254
+ }
251255
zPrevDate[0] = 0;
252256
mxWikiLen = db_get_int("timeline-max-comment", 0);
253257
if( tmFlags & TIMELINE_GRAPH ){
254258
pGraph = graph_init();
255259
/* style is not moved to css, because this is
@@ -318,11 +322,15 @@
318322
@ <div class="divider">%s(zPrevDate)</div>
319323
@ </td><td></td><td></td></tr>
320324
}
321325
memcpy(zTime, &zDate[11], 5);
322326
zTime[5] = 0;
323
- @ <tr>
327
+ if( rid == vid ){
328
+ @ <tr class="timelineCurrent">
329
+ }else {
330
+ @ <tr>
331
+ }
324332
@ <td class="timelineTime">%s(zTime)</td>
325333
@ <td class="timelineGraph">
326334
if( tmFlags & TIMELINE_UCOLOR ) zBgClr = zUser ? hash_color(zUser) : 0;
327335
if( zType[0]=='c'
328336
&& (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
@@ -1032,10 +1040,11 @@
10321040
const char *zTagName = P("t"); /* Show events with this tag */
10331041
const char *zBrName = P("r"); /* Show events related to this tag */
10341042
const char *zSearch = P("s"); /* Search string */
10351043
const char *zUses = P("uf"); /* Only show checkins hold this file */
10361044
const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */
1045
+ const char *zYearWeek = P("yw"); /* Show checkins for the given YYYY-WW (weak-of-year) */
10371046
int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
10381047
int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
10391048
int tagid; /* Tag ID */
10401049
int tmFlags; /* Timeline flags */
10411050
const char *zThisTag = 0; /* Suppress links to this tag */
@@ -1218,10 +1227,14 @@
12181227
}
12191228
if( zYearMonth ){
12201229
blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
12211230
zYearMonth);
12221231
}
1232
+ else if( zYearWeek ){
1233
+ blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1234
+ zYearWeek);
1235
+ }
12231236
if( tagid>0 ){
12241237
blob_appendf(&sql,
12251238
"AND (EXISTS(SELECT 1 FROM tagxref"
12261239
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
12271240
@@ -1350,10 +1363,12 @@
13501363
db_multi_exec("%s", blob_str(&sql));
13511364
13521365
n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
13531366
if( zYearMonth ){
13541367
blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1368
+ }else if( zYearWeek ){
1369
+ blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
13551370
}else if( zAfter==0 && zBefore==0 && zCirca==0 ){
13561371
blob_appendf(&desc, "%d most recent %ss", n, zEType);
13571372
}else{
13581373
blob_appendf(&desc, "%d %ss", n, zEType);
13591374
}
@@ -1829,36 +1844,64 @@
18291844
}
18301845
db_finalize(&q);
18311846
style_footer();
18321847
}
18331848
1834
-
1849
+/*
1850
+** Helper for stats_report_by_month_year(), which generates a list of
1851
+** week numbers. zTimeframe should be either a timeframe in the form YYYY
1852
+** or YYYY-MM.
1853
+*/
1854
+static void stats_report_output_week_links(const char * zTimeframe){
1855
+ Stmt stWeek = empty_Stmt;
1856
+ char yearPart[5] = {0,0,0,0,0};
1857
+ memcpy(yearPart, zTimeframe, 4);
1858
+ db_prepare(&stWeek,
1859
+ "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
1860
+ "count(*) AS n, "
1861
+ "substr(date(mtime),1,%d) AS ym "
1862
+ "FROM event "
1863
+ "WHERE ym=%Q AND mtime < current_timestamp "
1864
+ "GROUP BY wk ORDER BY wk",
1865
+ strlen(zTimeframe),
1866
+ zTimeframe);
1867
+ while( SQLITE_ROW == db_step(&stWeek) ){
1868
+ const char * zWeek = db_column_text(&stWeek,0);
1869
+ const int nCount = db_column_int(&stWeek,1);
1870
+ cgi_printf("<a href='%s/timeline?"
1871
+ "yw=%t-%t&n=%d'>%s</a>",
1872
+ g.zTop, yearPart, zWeek,
1873
+ nCount, zWeek);
1874
+ }
1875
+ db_finalize(&stWeek);
1876
+}
18351877
18361878
/*
1837
-** Implements the "byyear" and "bymonth" reports for /stats_report.
1879
+** Implements the "byyear" and "bymonth" reports for /reports.
18381880
** If includeMonth is true then it generates the "bymonth" report,
18391881
** else the "byyear" report. If zUserName is not NULL and not empty
18401882
** then the report is restricted to events created by the named user
18411883
** account.
18421884
*/
18431885
static void stats_report_by_month_year(char includeMonth,
1844
- char const * zUserName){
1886
+ char includeWeeks,
1887
+ const char * zUserName){
18451888
Stmt query = empty_Stmt;
1846
- int const nPixelsPerEvent = 1; /* for sizing the "graph" part */
18471889
int nRowNumber = 0; /* current TR number */
18481890
int nEventTotal = 0; /* Total event count */
18491891
int rowClass = 0; /* counter for alternating
18501892
row colors */
18511893
Blob sql = empty_blob; /* SQL */
1852
- char const * zTimeLabel = includeMonth ? "Year/Month" : "Year";
1894
+ const char * zTimeLabel = includeMonth ? "Year/Month" : "Year";
18531895
char zPrevYear[5] = {0}; /* For keeping track of when
18541896
we change years while looping */
1855
- int nEventsPerYear = 0; /* Total even count for the
1897
+ int nEventsPerYear = 0; /* Total event count for the
18561898
current year */
18571899
char showYearTotal = 0; /* Flag telling us when to show
18581900
the per-year event totals */
18591901
Blob header = empty_blob; /* Page header text */
1902
+ int nMaxEvents = 1; /* for calculating length of graph bars. */
18601903
18611904
blob_appendf(&header, "Timeline Events by year%s",
18621905
(includeMonth ? "/month" : ""));
18631906
blob_appendf(&sql,
18641907
"SELECT substr(date(mtime),1,%d) AS timeframe, "
@@ -1879,18 +1922,31 @@
18791922
@ <table class='statistics-report-table-events' border='0' cellpadding='2'
18801923
@ cellspacing='0' id='statsTable'>
18811924
@ <thead>
18821925
@ <th>%s(zTimeLabel)</th>
18831926
@ <th>Events</th>
1884
- @ <th><!-- relative commits graph --></th>
1927
+ @ <th width='90%%'><!-- relative commits graph --></th>
18851928
@ </thead><tbody>
18861929
blob_reset(&header);
1930
+ /*
1931
+ Run the query twice. The first time we calculate the maximum
1932
+ number of events for a given row. Maybe someone with better SQL
1933
+ Fu can re-implement this with a single query.
1934
+ */
1935
+ while( SQLITE_ROW == db_step(&query) ){
1936
+ const int nCount = db_column_int(&query, 1);
1937
+ if(nCount>nMaxEvents){
1938
+ nMaxEvents = nCount;
1939
+ }
1940
+ }
1941
+ db_reset(&query);
18871942
while( SQLITE_ROW == db_step(&query) ){
1888
- char const * zTimeframe = db_column_text(&query, 0);
1889
- int const nCount = db_column_int(&query, 1);
1890
- int const nSize = 1 + ((nPixelsPerEvent * nCount)
1891
- / (includeMonth ? 1 : 10));
1943
+ const char * zTimeframe = db_column_text(&query, 0);
1944
+ const int nCount = db_column_int(&query, 1);
1945
+ const int nSize = nCount
1946
+ ? (int)(100 * nCount / nMaxEvents)
1947
+ : 1;
18921948
showYearTotal = 0;
18931949
if(includeMonth){
18941950
/* For Month/year view, add a separator for each distinct year. */
18951951
if(!*zPrevYear ||
18961952
(0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
@@ -1906,17 +1962,17 @@
19061962
memcpy(zPrevYear,zTimeframe,4);
19071963
rowClass = ++nRowNumber % 2;
19081964
@ <tr class='row%d(rowClass)'>
19091965
@ <th colspan='3' class='statistics-report-row-year'>%s(zPrevYear)</th>
19101966
@ </tr>
1911
- }
1912
- }
1913
- rowClass = ++nRowNumber % 2;
1914
- nEventTotal += nCount;
1915
- nEventsPerYear += nCount;
1916
- @<tr class='row%d(rowClass)'>
1917
- @ <td>
1967
+ }
1968
+ }
1969
+ rowClass = ++nRowNumber % 2;
1970
+ nEventTotal += nCount;
1971
+ nEventsPerYear += nCount;
1972
+ @<tr class='row%d(rowClass)'>
1973
+ @ <td>
19181974
if(includeMonth){
19191975
cgi_printf("<a href='%s/timeline?"
19201976
"ym=%t&n=%d",
19211977
g.zTop, zTimeframe, nCount );
19221978
/* Reminder: n=nCount is not actually correct for bymonth unless
@@ -1925,57 +1981,68 @@
19251981
if( zUserName && *zUserName ){
19261982
cgi_printf("&u=%t", zUserName);
19271983
}
19281984
cgi_printf("' target='_new'>%s</a>",zTimeframe);
19291985
}else {
1930
- @ %s(zTimeframe)
1986
+ cgi_printf("<a href='?view=byweek&y=%s", zTimeframe);
1987
+ if(zUserName && *zUserName){
1988
+ cgi_printf("&u=%t", zUserName);
1989
+ }
1990
+ cgi_printf("'>%s</a>", zTimeframe);
19311991
}
19321992
@ </td><td>%d(nCount)</td>
19331993
@ <td>
19341994
@ <div class='statistics-report-graph-line'
1935
- @ style='height:16px;width:%d(nSize)px;'>
1995
+ @ style='height:16px;width:%d(nSize)%%;'>
19361996
@ </div></td>
19371997
@</tr>
1998
+ if(includeWeeks){
1999
+ /* This part works fine for months but it terribly slow (4.5s on my PC),
2000
+ so it's only shown for by-year for now. Suggestions/patches for
2001
+ a better/faster layout are welcomed. */
2002
+ @ <tr class='row%d(rowClass)'>
2003
+ @ <td colspan='2' class='statistics-report-week-number-label'>Week #:</td>
2004
+ @ <td class='statistics-report-week-of-year-list'>
2005
+ stats_report_output_week_links(zTimeframe);
2006
+ @ </td></tr>
2007
+ }
19382008
19392009
/*
19402010
Potential improvement: calculate the min/max event counts and
19412011
use percent-based graph bars.
19422012
*/
19432013
}
1944
-
2014
+ db_finalize(&query);
19452015
if(includeMonth && !showYearTotal && *zPrevYear){
19462016
/* Add final year total separator. */
19472017
rowClass = ++nRowNumber % 2;
19482018
@ <tr class='row%d(rowClass)'>
19492019
@ <td></td>
19502020
@ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
19512021
@</tr>
19522022
}
1953
-#if 0
1954
- rowClass = ++nRowNumber % 2;
1955
- @ <tr class='row%d(rowClass)'>
1956
- @ <td colspan='3'>Total events: %d(nEventTotal)</td>
1957
- @ </tr>
1958
-#endif
19592023
@ </tbody></table>
1960
- db_finalize(&query);
2024
+ if(nEventTotal){
2025
+ @ <br><div>Total events: %d(nEventTotal)</div>
2026
+ }
19612027
if( !includeMonth ){
19622028
output_table_sorting_javascript("statsTable","tnx");
19632029
}
19642030
}
19652031
19662032
/*
1967
-** Implements the "byuser" view for /stats_report.
2033
+** Implements the "byuser" view for /reports.
19682034
*/
19692035
static void stats_report_by_user(){
19702036
Stmt query = empty_Stmt;
1971
- int const nPixelsPerEvent = 1; /* for sizing the "graph" part */
19722037
int nRowNumber = 0; /* current TR number */
19732038
int nEventTotal = 0; /* Total event count */
19742039
int rowClass = 0; /* counter for alternating
19752040
row colors */
19762041
Blob sql = empty_blob; /* SQL */
2042
+ int nMaxEvents = 1; /* max number of events for
2043
+ all rows. */
19772044
blob_append(&sql,
19782045
"SELECT user, "
19792046
"COUNT(*) AS eventCount "
19802047
"FROM event "
19812048
"GROUP BY user ORDER BY eventCount DESC",
@@ -1986,26 +2053,35 @@
19862053
@ <table class='statistics-report-table-events' border='0'
19872054
@ cellpadding='2' cellspacing='0' id='statsTable'>
19882055
@ <thead><tr>
19892056
@ <th>User</th>
19902057
@ <th>Events</th>
1991
- @ <th><!-- relative commits graph --></th>
2058
+ @ <th width='90%%'><!-- relative commits graph --></th>
19922059
@ </tr></thead><tbody>
19932060
while( SQLITE_ROW == db_step(&query) ){
1994
- char const * zUser = db_column_text(&query, 0);
1995
- int const nCount = db_column_int(&query, 1);
1996
- int const nSize = 1+((nPixelsPerEvent * nCount) / 10);
1997
- if(!nCount) continue /* arguable! */;
2061
+ const int nCount = db_column_int(&query, 1);
2062
+ if(nCount>nMaxEvents){
2063
+ nMaxEvents = nCount;
2064
+ }
2065
+ }
2066
+ db_reset(&query);
2067
+ while( SQLITE_ROW == db_step(&query) ){
2068
+ const char * zUser = db_column_text(&query, 0);
2069
+ const int nCount = db_column_int(&query, 1);
2070
+ const int nSize = nCount
2071
+ ? (int)(100 * nCount / nMaxEvents)
2072
+ : 0;
2073
+ if(!nCount) continue /* arguable! Possible? */;
19982074
rowClass = ++nRowNumber % 2;
19992075
nEventTotal += nCount;
20002076
@<tr class='row%d(rowClass)'>
20012077
@ <td>
2002
- @ <a href="?view=bymonth&user=%h(zUser)" target="_new">%h(zUser)</a>
2078
+ @ <a href="?view=bymonth&user=%h(zUser)">%h(zUser)</a>
20032079
@ </td><td>%d(nCount)</td>
20042080
@ <td>
20052081
@ <div class='statistics-report-graph-line'
2006
- @ style='height:16px;width:%d(nSize)px;'>
2082
+ @ style='height:16px;width:%d(nSize)%%;'>
20072083
@ </div></td>
20082084
@</tr>
20092085
/*
20102086
Potential improvement: calculate the min/max event counts and
20112087
use percent-based graph bars.
@@ -2014,12 +2090,130 @@
20142090
@ </tbody></table>
20152091
db_finalize(&query);
20162092
output_table_sorting_javascript("statsTable","tnx");
20172093
}
20182094
2095
+
2096
+/*
2097
+** Helper for stats_report_by_month_year(), which generates a list of
2098
+** week numbers. zTimeframe should be either a timeframe in the form YYYY
2099
+** or YYYY-MM.
2100
+*/
2101
+static void stats_report_year_weeks(const char * zUserName){
2102
+ const char * zYear = P("y");
2103
+ int nYear = zYear ? strlen(zYear) : 0;
2104
+ int i = 0;
2105
+ Stmt qYears = empty_Stmt;
2106
+ char * zDefaultYear = NULL;
2107
+ Blob sql = empty_blob;
2108
+ int nMaxEvents = 1; /* max number of events for
2109
+ all rows. */
2110
+
2111
+ cgi_printf("Select year: ");
2112
+ blob_append(&sql,
2113
+ "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2114
+ "FROM event WHERE 1 ", -1);
2115
+ if(zUserName&&*zUserName){
2116
+ blob_appendf(&sql,"AND user=%Q ", zUserName);
2117
+ }
2118
+ blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2119
+ db_prepare(&qYears, blob_str(&sql));
2120
+ blob_reset(&sql);
2121
+ while( SQLITE_ROW == db_step(&qYears) ){
2122
+ const char * zT = db_column_text(&qYears, 0);
2123
+ if( i++ ){
2124
+ cgi_printf(" ");
2125
+ }
2126
+ cgi_printf("<a href='?view=byweek&y=%s", zT);
2127
+ if(zUserName && *zUserName){
2128
+ cgi_printf("&user=%t",zUserName);
2129
+ }
2130
+ cgi_printf("'>%s</a>",zT);
2131
+ }
2132
+ db_finalize(&qYears);
2133
+ cgi_printf("<br/>");
2134
+ if(!zYear || !*zYear){
2135
+ zDefaultYear = db_text("????", "SELECT strftime('%%Y')");
2136
+ zYear = zDefaultYear;
2137
+ nYear = 4;
2138
+ }
2139
+ if(4 == nYear){
2140
+ Stmt stWeek = empty_Stmt;
2141
+ int rowCount = 0;
2142
+ int total = 0;
2143
+ Blob header = empty_blob;
2144
+ blob_appendf(&header, "Timeline events for the calendar weeks "
2145
+ "of %h", zYear);
2146
+ blob_appendf(&sql,
2147
+ "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2148
+ "count(*) AS n "
2149
+ "FROM event "
2150
+ "WHERE %Q=substr(date(mtime),1,4) "
2151
+ "AND mtime < current_timestamp ",
2152
+ zYear);
2153
+ if(zUserName&&*zUserName){
2154
+ blob_appendf(&sql, " AND user=%Q ", zUserName);
2155
+ blob_appendf(&header," for user %h", zUserName);
2156
+ }
2157
+ blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
2158
+ cgi_printf("<h1>%h</h1>", blob_str(&header));
2159
+ blob_reset(&header);
2160
+ cgi_printf("<table class='statistics-report-table-events' "
2161
+ "border='0' cellpadding='2' width='100%%' "
2162
+ "cellspacing='0' id='statsTable'>");
2163
+ cgi_printf("<thead><tr>"
2164
+ "<th>Week</th>"
2165
+ "<th>Events</th>"
2166
+ "<th width='90%%'><!-- relative commits graph --></th>"
2167
+ "</tr></thead>"
2168
+ "<tbody>");
2169
+ db_prepare(&stWeek, blob_str(&sql));
2170
+ blob_reset(&sql);
2171
+ while( SQLITE_ROW == db_step(&stWeek) ){
2172
+ const int nCount = db_column_int(&stWeek, 1);
2173
+ if(nCount>nMaxEvents){
2174
+ nMaxEvents = nCount;
2175
+ }
2176
+ }
2177
+ db_reset(&stWeek);
2178
+ while( SQLITE_ROW == db_step(&stWeek) ){
2179
+ const char * zWeek = db_column_text(&stWeek,0);
2180
+ const int nCount = db_column_int(&stWeek,1);
2181
+ const int nSize = nCount
2182
+ ? (int)(100 * nCount / nMaxEvents)
2183
+ : 0;
2184
+ total += nCount;
2185
+ cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2186
+ cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d",
2187
+ g.zTop, zYear, zWeek, nCount);
2188
+ if(zUserName && *zUserName){
2189
+ cgi_printf("&u=%t",zUserName);
2190
+ }
2191
+ cgi_printf("'>%s</a></td>",zWeek);
2192
+
2193
+ cgi_printf("<td>%d</td>",nCount);
2194
+ cgi_printf("<td>");
2195
+ if(nCount){
2196
+ cgi_printf("<div class='statistics-report-graph-line'"
2197
+ "style='height:16px;width:%d%%;'></div>",
2198
+ nSize);
2199
+ }
2200
+ cgi_printf("</td></tr>");
2201
+ }
2202
+ db_finalize(&stWeek);
2203
+ free(zDefaultYear);
2204
+ cgi_printf("</tbody></table>");
2205
+ if(total){
2206
+ cgi_printf("<br><div>Total events: %d</div>",
2207
+ total);
2208
+ }
2209
+ output_table_sorting_javascript("statsTable","tnx");
2210
+ }
2211
+}
2212
+
20192213
/*
2020
-** WEBPAGE: stats_report
2214
+** WEBPAGE: reports
20212215
**
20222216
** Shows activity reports for the repository.
20232217
**
20242218
** Query Parameters:
20252219
**
@@ -2026,37 +2220,40 @@
20262220
** view=REPORT_NAME Valid values: bymonth, byyear, byuser
20272221
** user=NAME Restricts statistics to the given user
20282222
*/
20292223
void stats_report_page(){
20302224
HQuery url; /* URL for various branch links */
2031
- char const * zView = P("view"); /* Which view/report to show. */
2032
- char const *zUserName = P("user");
2033
- url_initialize(&url, "stats_report");
2225
+ const char * zView = P("view"); /* Which view/report to show. */
2226
+ const char *zUserName = P("user");
2227
+ if(!zUserName) zUserName = P("u");
2228
+ url_initialize(&url, "reports");
20342229
20352230
if(zUserName && *zUserName){
20362231
url_add_parameter(&url,"user", zUserName);
20372232
timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user");
20382233
}
20392234
timeline_submenu(&url, "By Year", "view", "byyear", 0);
20402235
timeline_submenu(&url, "By Month", "view", "bymonth", 0);
2236
+ timeline_submenu(&url, "By Week", "view", "byweek", 0);
20412237
timeline_submenu(&url, "By User", "view", "byuser", "user");
20422238
url_reset(&url);
20432239
style_header("Activity Reports");
20442240
if(0==fossil_strcmp(zView,"byyear")){
2045
- stats_report_by_month_year(0, zUserName);
2241
+ stats_report_by_month_year(0, 0, zUserName);
20462242
}else if(0==fossil_strcmp(zView,"bymonth")){
2047
- stats_report_by_month_year(1, zUserName);
2243
+ stats_report_by_month_year(1, 0, zUserName);
20482244
}else if(0==fossil_strcmp(zView,"byweek")){
2049
- @ TODO: by-week report.
2245
+ stats_report_year_weeks(zUserName);
20502246
}else if(0==fossil_strcmp(zView,"byuser")){
20512247
stats_report_by_user();
20522248
}else{
20532249
@ <h1>Select a report to show:</h1>
20542250
@ <ul>
20552251
@ <li><a href='?view=byyear'>Events by year</a></li>
20562252
@ <li><a href='?view=bymonth'>Events by month</a></li>
2253
+ @ <li><a href='?view=byweek'>Events by calendar week</a></li>
20572254
@ <li><a href='?view=byuser'>Events by user</a></li>
20582255
@ </ul>
20592256
}
20602257
20612258
style_footer();
20622259
}
20632260
--- src/timeline.c
+++ src/timeline.c
@@ -245,11 +245,15 @@
245 int prevWasDivider = 0; /* True if previous output row was <hr> */
246 int fchngQueryInit = 0; /* True if fchngQuery is initialized */
247 Stmt fchngQuery; /* Query for file changes on check-ins */
248 static Stmt qbranch;
249 int pendingEndTr = 0; /* True if a </td></tr> is needed */
250
 
 
 
 
251 zPrevDate[0] = 0;
252 mxWikiLen = db_get_int("timeline-max-comment", 0);
253 if( tmFlags & TIMELINE_GRAPH ){
254 pGraph = graph_init();
255 /* style is not moved to css, because this is
@@ -318,11 +322,15 @@
318 @ <div class="divider">%s(zPrevDate)</div>
319 @ </td><td></td><td></td></tr>
320 }
321 memcpy(zTime, &zDate[11], 5);
322 zTime[5] = 0;
323 @ <tr>
 
 
 
 
324 @ <td class="timelineTime">%s(zTime)</td>
325 @ <td class="timelineGraph">
326 if( tmFlags & TIMELINE_UCOLOR ) zBgClr = zUser ? hash_color(zUser) : 0;
327 if( zType[0]=='c'
328 && (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
@@ -1032,10 +1040,11 @@
1032 const char *zTagName = P("t"); /* Show events with this tag */
1033 const char *zBrName = P("r"); /* Show events related to this tag */
1034 const char *zSearch = P("s"); /* Search string */
1035 const char *zUses = P("uf"); /* Only show checkins hold this file */
1036 const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */
 
1037 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
1038 int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
1039 int tagid; /* Tag ID */
1040 int tmFlags; /* Timeline flags */
1041 const char *zThisTag = 0; /* Suppress links to this tag */
@@ -1218,10 +1227,14 @@
1218 }
1219 if( zYearMonth ){
1220 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1221 zYearMonth);
1222 }
 
 
 
 
1223 if( tagid>0 ){
1224 blob_appendf(&sql,
1225 "AND (EXISTS(SELECT 1 FROM tagxref"
1226 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1227
@@ -1350,10 +1363,12 @@
1350 db_multi_exec("%s", blob_str(&sql));
1351
1352 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1353 if( zYearMonth ){
1354 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
 
 
1355 }else if( zAfter==0 && zBefore==0 && zCirca==0 ){
1356 blob_appendf(&desc, "%d most recent %ss", n, zEType);
1357 }else{
1358 blob_appendf(&desc, "%d %ss", n, zEType);
1359 }
@@ -1829,36 +1844,64 @@
1829 }
1830 db_finalize(&q);
1831 style_footer();
1832 }
1833
1834
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1835
1836 /*
1837 ** Implements the "byyear" and "bymonth" reports for /stats_report.
1838 ** If includeMonth is true then it generates the "bymonth" report,
1839 ** else the "byyear" report. If zUserName is not NULL and not empty
1840 ** then the report is restricted to events created by the named user
1841 ** account.
1842 */
1843 static void stats_report_by_month_year(char includeMonth,
1844 char const * zUserName){
 
1845 Stmt query = empty_Stmt;
1846 int const nPixelsPerEvent = 1; /* for sizing the "graph" part */
1847 int nRowNumber = 0; /* current TR number */
1848 int nEventTotal = 0; /* Total event count */
1849 int rowClass = 0; /* counter for alternating
1850 row colors */
1851 Blob sql = empty_blob; /* SQL */
1852 char const * zTimeLabel = includeMonth ? "Year/Month" : "Year";
1853 char zPrevYear[5] = {0}; /* For keeping track of when
1854 we change years while looping */
1855 int nEventsPerYear = 0; /* Total even count for the
1856 current year */
1857 char showYearTotal = 0; /* Flag telling us when to show
1858 the per-year event totals */
1859 Blob header = empty_blob; /* Page header text */
 
1860
1861 blob_appendf(&header, "Timeline Events by year%s",
1862 (includeMonth ? "/month" : ""));
1863 blob_appendf(&sql,
1864 "SELECT substr(date(mtime),1,%d) AS timeframe, "
@@ -1879,18 +1922,31 @@
1879 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
1880 @ cellspacing='0' id='statsTable'>
1881 @ <thead>
1882 @ <th>%s(zTimeLabel)</th>
1883 @ <th>Events</th>
1884 @ <th><!-- relative commits graph --></th>
1885 @ </thead><tbody>
1886 blob_reset(&header);
 
 
 
 
 
 
 
 
 
 
 
 
1887 while( SQLITE_ROW == db_step(&query) ){
1888 char const * zTimeframe = db_column_text(&query, 0);
1889 int const nCount = db_column_int(&query, 1);
1890 int const nSize = 1 + ((nPixelsPerEvent * nCount)
1891 / (includeMonth ? 1 : 10));
 
1892 showYearTotal = 0;
1893 if(includeMonth){
1894 /* For Month/year view, add a separator for each distinct year. */
1895 if(!*zPrevYear ||
1896 (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
@@ -1906,17 +1962,17 @@
1906 memcpy(zPrevYear,zTimeframe,4);
1907 rowClass = ++nRowNumber % 2;
1908 @ <tr class='row%d(rowClass)'>
1909 @ <th colspan='3' class='statistics-report-row-year'>%s(zPrevYear)</th>
1910 @ </tr>
1911 }
1912 }
1913 rowClass = ++nRowNumber % 2;
1914 nEventTotal += nCount;
1915 nEventsPerYear += nCount;
1916 @<tr class='row%d(rowClass)'>
1917 @ <td>
1918 if(includeMonth){
1919 cgi_printf("<a href='%s/timeline?"
1920 "ym=%t&n=%d",
1921 g.zTop, zTimeframe, nCount );
1922 /* Reminder: n=nCount is not actually correct for bymonth unless
@@ -1925,57 +1981,68 @@
1925 if( zUserName && *zUserName ){
1926 cgi_printf("&u=%t", zUserName);
1927 }
1928 cgi_printf("' target='_new'>%s</a>",zTimeframe);
1929 }else {
1930 @ %s(zTimeframe)
 
 
 
 
1931 }
1932 @ </td><td>%d(nCount)</td>
1933 @ <td>
1934 @ <div class='statistics-report-graph-line'
1935 @ style='height:16px;width:%d(nSize)px;'>
1936 @ </div></td>
1937 @</tr>
 
 
 
 
 
 
 
 
 
 
1938
1939 /*
1940 Potential improvement: calculate the min/max event counts and
1941 use percent-based graph bars.
1942 */
1943 }
1944
1945 if(includeMonth && !showYearTotal && *zPrevYear){
1946 /* Add final year total separator. */
1947 rowClass = ++nRowNumber % 2;
1948 @ <tr class='row%d(rowClass)'>
1949 @ <td></td>
1950 @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
1951 @</tr>
1952 }
1953 #if 0
1954 rowClass = ++nRowNumber % 2;
1955 @ <tr class='row%d(rowClass)'>
1956 @ <td colspan='3'>Total events: %d(nEventTotal)</td>
1957 @ </tr>
1958 #endif
1959 @ </tbody></table>
1960 db_finalize(&query);
 
 
1961 if( !includeMonth ){
1962 output_table_sorting_javascript("statsTable","tnx");
1963 }
1964 }
1965
1966 /*
1967 ** Implements the "byuser" view for /stats_report.
1968 */
1969 static void stats_report_by_user(){
1970 Stmt query = empty_Stmt;
1971 int const nPixelsPerEvent = 1; /* for sizing the "graph" part */
1972 int nRowNumber = 0; /* current TR number */
1973 int nEventTotal = 0; /* Total event count */
1974 int rowClass = 0; /* counter for alternating
1975 row colors */
1976 Blob sql = empty_blob; /* SQL */
 
 
1977 blob_append(&sql,
1978 "SELECT user, "
1979 "COUNT(*) AS eventCount "
1980 "FROM event "
1981 "GROUP BY user ORDER BY eventCount DESC",
@@ -1986,26 +2053,35 @@
1986 @ <table class='statistics-report-table-events' border='0'
1987 @ cellpadding='2' cellspacing='0' id='statsTable'>
1988 @ <thead><tr>
1989 @ <th>User</th>
1990 @ <th>Events</th>
1991 @ <th><!-- relative commits graph --></th>
1992 @ </tr></thead><tbody>
1993 while( SQLITE_ROW == db_step(&query) ){
1994 char const * zUser = db_column_text(&query, 0);
1995 int const nCount = db_column_int(&query, 1);
1996 int const nSize = 1+((nPixelsPerEvent * nCount) / 10);
1997 if(!nCount) continue /* arguable! */;
 
 
 
 
 
 
 
 
 
1998 rowClass = ++nRowNumber % 2;
1999 nEventTotal += nCount;
2000 @<tr class='row%d(rowClass)'>
2001 @ <td>
2002 @ <a href="?view=bymonth&user=%h(zUser)" target="_new">%h(zUser)</a>
2003 @ </td><td>%d(nCount)</td>
2004 @ <td>
2005 @ <div class='statistics-report-graph-line'
2006 @ style='height:16px;width:%d(nSize)px;'>
2007 @ </div></td>
2008 @</tr>
2009 /*
2010 Potential improvement: calculate the min/max event counts and
2011 use percent-based graph bars.
@@ -2014,12 +2090,130 @@
2014 @ </tbody></table>
2015 db_finalize(&query);
2016 output_table_sorting_javascript("statsTable","tnx");
2017 }
2018
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2019 /*
2020 ** WEBPAGE: stats_report
2021 **
2022 ** Shows activity reports for the repository.
2023 **
2024 ** Query Parameters:
2025 **
@@ -2026,37 +2220,40 @@
2026 ** view=REPORT_NAME Valid values: bymonth, byyear, byuser
2027 ** user=NAME Restricts statistics to the given user
2028 */
2029 void stats_report_page(){
2030 HQuery url; /* URL for various branch links */
2031 char const * zView = P("view"); /* Which view/report to show. */
2032 char const *zUserName = P("user");
2033 url_initialize(&url, "stats_report");
 
2034
2035 if(zUserName && *zUserName){
2036 url_add_parameter(&url,"user", zUserName);
2037 timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user");
2038 }
2039 timeline_submenu(&url, "By Year", "view", "byyear", 0);
2040 timeline_submenu(&url, "By Month", "view", "bymonth", 0);
 
2041 timeline_submenu(&url, "By User", "view", "byuser", "user");
2042 url_reset(&url);
2043 style_header("Activity Reports");
2044 if(0==fossil_strcmp(zView,"byyear")){
2045 stats_report_by_month_year(0, zUserName);
2046 }else if(0==fossil_strcmp(zView,"bymonth")){
2047 stats_report_by_month_year(1, zUserName);
2048 }else if(0==fossil_strcmp(zView,"byweek")){
2049 @ TODO: by-week report.
2050 }else if(0==fossil_strcmp(zView,"byuser")){
2051 stats_report_by_user();
2052 }else{
2053 @ <h1>Select a report to show:</h1>
2054 @ <ul>
2055 @ <li><a href='?view=byyear'>Events by year</a></li>
2056 @ <li><a href='?view=bymonth'>Events by month</a></li>
 
2057 @ <li><a href='?view=byuser'>Events by user</a></li>
2058 @ </ul>
2059 }
2060
2061 style_footer();
2062 }
2063
--- src/timeline.c
+++ src/timeline.c
@@ -245,11 +245,15 @@
245 int prevWasDivider = 0; /* True if previous output row was <hr> */
246 int fchngQueryInit = 0; /* True if fchngQuery is initialized */
247 Stmt fchngQuery; /* Query for file changes on check-ins */
248 static Stmt qbranch;
249 int pendingEndTr = 0; /* True if a </td></tr> is needed */
250 int vid = 0; /* Current checkout version */
251
252 if( fossil_strcmp(g.zIpAddr, "127.0.0.1")==0 && db_open_local(0) ){
253 vid = db_lget_int("checkout", 0);
254 }
255 zPrevDate[0] = 0;
256 mxWikiLen = db_get_int("timeline-max-comment", 0);
257 if( tmFlags & TIMELINE_GRAPH ){
258 pGraph = graph_init();
259 /* style is not moved to css, because this is
@@ -318,11 +322,15 @@
322 @ <div class="divider">%s(zPrevDate)</div>
323 @ </td><td></td><td></td></tr>
324 }
325 memcpy(zTime, &zDate[11], 5);
326 zTime[5] = 0;
327 if( rid == vid ){
328 @ <tr class="timelineCurrent">
329 }else {
330 @ <tr>
331 }
332 @ <td class="timelineTime">%s(zTime)</td>
333 @ <td class="timelineGraph">
334 if( tmFlags & TIMELINE_UCOLOR ) zBgClr = zUser ? hash_color(zUser) : 0;
335 if( zType[0]=='c'
336 && (pGraph || zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0)
@@ -1032,10 +1040,11 @@
1040 const char *zTagName = P("t"); /* Show events with this tag */
1041 const char *zBrName = P("r"); /* Show events related to this tag */
1042 const char *zSearch = P("s"); /* Search string */
1043 const char *zUses = P("uf"); /* Only show checkins hold this file */
1044 const char *zYearMonth = P("ym"); /* Show checkins for the given YYYY-MM */
1045 const char *zYearWeek = P("yw"); /* Show checkins for the given YYYY-WW (weak-of-year) */
1046 int useDividers = P("nd")==0; /* Show dividers if "nd" is missing */
1047 int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
1048 int tagid; /* Tag ID */
1049 int tmFlags; /* Timeline flags */
1050 const char *zThisTag = 0; /* Suppress links to this tag */
@@ -1218,10 +1227,14 @@
1227 }
1228 if( zYearMonth ){
1229 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%m',event.mtime) ",
1230 zYearMonth);
1231 }
1232 else if( zYearWeek ){
1233 blob_appendf(&sql, " AND %Q=strftime('%%Y-%%W',event.mtime) ",
1234 zYearWeek);
1235 }
1236 if( tagid>0 ){
1237 blob_appendf(&sql,
1238 "AND (EXISTS(SELECT 1 FROM tagxref"
1239 " WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)", tagid);
1240
@@ -1350,10 +1363,12 @@
1363 db_multi_exec("%s", blob_str(&sql));
1364
1365 n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
1366 if( zYearMonth ){
1367 blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
1368 }else if( zYearWeek ){
1369 blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
1370 }else if( zAfter==0 && zBefore==0 && zCirca==0 ){
1371 blob_appendf(&desc, "%d most recent %ss", n, zEType);
1372 }else{
1373 blob_appendf(&desc, "%d %ss", n, zEType);
1374 }
@@ -1829,36 +1844,64 @@
1844 }
1845 db_finalize(&q);
1846 style_footer();
1847 }
1848
1849 /*
1850 ** Helper for stats_report_by_month_year(), which generates a list of
1851 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
1852 ** or YYYY-MM.
1853 */
1854 static void stats_report_output_week_links(const char * zTimeframe){
1855 Stmt stWeek = empty_Stmt;
1856 char yearPart[5] = {0,0,0,0,0};
1857 memcpy(yearPart, zTimeframe, 4);
1858 db_prepare(&stWeek,
1859 "SELECT DISTINCT strftime('%%W',mtime) AS wk, "
1860 "count(*) AS n, "
1861 "substr(date(mtime),1,%d) AS ym "
1862 "FROM event "
1863 "WHERE ym=%Q AND mtime < current_timestamp "
1864 "GROUP BY wk ORDER BY wk",
1865 strlen(zTimeframe),
1866 zTimeframe);
1867 while( SQLITE_ROW == db_step(&stWeek) ){
1868 const char * zWeek = db_column_text(&stWeek,0);
1869 const int nCount = db_column_int(&stWeek,1);
1870 cgi_printf("<a href='%s/timeline?"
1871 "yw=%t-%t&n=%d'>%s</a>",
1872 g.zTop, yearPart, zWeek,
1873 nCount, zWeek);
1874 }
1875 db_finalize(&stWeek);
1876 }
1877
1878 /*
1879 ** Implements the "byyear" and "bymonth" reports for /reports.
1880 ** If includeMonth is true then it generates the "bymonth" report,
1881 ** else the "byyear" report. If zUserName is not NULL and not empty
1882 ** then the report is restricted to events created by the named user
1883 ** account.
1884 */
1885 static void stats_report_by_month_year(char includeMonth,
1886 char includeWeeks,
1887 const char * zUserName){
1888 Stmt query = empty_Stmt;
 
1889 int nRowNumber = 0; /* current TR number */
1890 int nEventTotal = 0; /* Total event count */
1891 int rowClass = 0; /* counter for alternating
1892 row colors */
1893 Blob sql = empty_blob; /* SQL */
1894 const char * zTimeLabel = includeMonth ? "Year/Month" : "Year";
1895 char zPrevYear[5] = {0}; /* For keeping track of when
1896 we change years while looping */
1897 int nEventsPerYear = 0; /* Total event count for the
1898 current year */
1899 char showYearTotal = 0; /* Flag telling us when to show
1900 the per-year event totals */
1901 Blob header = empty_blob; /* Page header text */
1902 int nMaxEvents = 1; /* for calculating length of graph bars. */
1903
1904 blob_appendf(&header, "Timeline Events by year%s",
1905 (includeMonth ? "/month" : ""));
1906 blob_appendf(&sql,
1907 "SELECT substr(date(mtime),1,%d) AS timeframe, "
@@ -1879,18 +1922,31 @@
1922 @ <table class='statistics-report-table-events' border='0' cellpadding='2'
1923 @ cellspacing='0' id='statsTable'>
1924 @ <thead>
1925 @ <th>%s(zTimeLabel)</th>
1926 @ <th>Events</th>
1927 @ <th width='90%%'><!-- relative commits graph --></th>
1928 @ </thead><tbody>
1929 blob_reset(&header);
1930 /*
1931 Run the query twice. The first time we calculate the maximum
1932 number of events for a given row. Maybe someone with better SQL
1933 Fu can re-implement this with a single query.
1934 */
1935 while( SQLITE_ROW == db_step(&query) ){
1936 const int nCount = db_column_int(&query, 1);
1937 if(nCount>nMaxEvents){
1938 nMaxEvents = nCount;
1939 }
1940 }
1941 db_reset(&query);
1942 while( SQLITE_ROW == db_step(&query) ){
1943 const char * zTimeframe = db_column_text(&query, 0);
1944 const int nCount = db_column_int(&query, 1);
1945 const int nSize = nCount
1946 ? (int)(100 * nCount / nMaxEvents)
1947 : 1;
1948 showYearTotal = 0;
1949 if(includeMonth){
1950 /* For Month/year view, add a separator for each distinct year. */
1951 if(!*zPrevYear ||
1952 (0!=fossil_strncmp(zPrevYear,zTimeframe,4))){
@@ -1906,17 +1962,17 @@
1962 memcpy(zPrevYear,zTimeframe,4);
1963 rowClass = ++nRowNumber % 2;
1964 @ <tr class='row%d(rowClass)'>
1965 @ <th colspan='3' class='statistics-report-row-year'>%s(zPrevYear)</th>
1966 @ </tr>
1967 }
1968 }
1969 rowClass = ++nRowNumber % 2;
1970 nEventTotal += nCount;
1971 nEventsPerYear += nCount;
1972 @<tr class='row%d(rowClass)'>
1973 @ <td>
1974 if(includeMonth){
1975 cgi_printf("<a href='%s/timeline?"
1976 "ym=%t&n=%d",
1977 g.zTop, zTimeframe, nCount );
1978 /* Reminder: n=nCount is not actually correct for bymonth unless
@@ -1925,57 +1981,68 @@
1981 if( zUserName && *zUserName ){
1982 cgi_printf("&u=%t", zUserName);
1983 }
1984 cgi_printf("' target='_new'>%s</a>",zTimeframe);
1985 }else {
1986 cgi_printf("<a href='?view=byweek&y=%s", zTimeframe);
1987 if(zUserName && *zUserName){
1988 cgi_printf("&u=%t", zUserName);
1989 }
1990 cgi_printf("'>%s</a>", zTimeframe);
1991 }
1992 @ </td><td>%d(nCount)</td>
1993 @ <td>
1994 @ <div class='statistics-report-graph-line'
1995 @ style='height:16px;width:%d(nSize)%%;'>
1996 @ </div></td>
1997 @</tr>
1998 if(includeWeeks){
1999 /* This part works fine for months but it terribly slow (4.5s on my PC),
2000 so it's only shown for by-year for now. Suggestions/patches for
2001 a better/faster layout are welcomed. */
2002 @ <tr class='row%d(rowClass)'>
2003 @ <td colspan='2' class='statistics-report-week-number-label'>Week #:</td>
2004 @ <td class='statistics-report-week-of-year-list'>
2005 stats_report_output_week_links(zTimeframe);
2006 @ </td></tr>
2007 }
2008
2009 /*
2010 Potential improvement: calculate the min/max event counts and
2011 use percent-based graph bars.
2012 */
2013 }
2014 db_finalize(&query);
2015 if(includeMonth && !showYearTotal && *zPrevYear){
2016 /* Add final year total separator. */
2017 rowClass = ++nRowNumber % 2;
2018 @ <tr class='row%d(rowClass)'>
2019 @ <td></td>
2020 @ <td colspan='2'>Yearly total: %d(nEventsPerYear)</td>
2021 @</tr>
2022 }
 
 
 
 
 
 
2023 @ </tbody></table>
2024 if(nEventTotal){
2025 @ <br><div>Total events: %d(nEventTotal)</div>
2026 }
2027 if( !includeMonth ){
2028 output_table_sorting_javascript("statsTable","tnx");
2029 }
2030 }
2031
2032 /*
2033 ** Implements the "byuser" view for /reports.
2034 */
2035 static void stats_report_by_user(){
2036 Stmt query = empty_Stmt;
 
2037 int nRowNumber = 0; /* current TR number */
2038 int nEventTotal = 0; /* Total event count */
2039 int rowClass = 0; /* counter for alternating
2040 row colors */
2041 Blob sql = empty_blob; /* SQL */
2042 int nMaxEvents = 1; /* max number of events for
2043 all rows. */
2044 blob_append(&sql,
2045 "SELECT user, "
2046 "COUNT(*) AS eventCount "
2047 "FROM event "
2048 "GROUP BY user ORDER BY eventCount DESC",
@@ -1986,26 +2053,35 @@
2053 @ <table class='statistics-report-table-events' border='0'
2054 @ cellpadding='2' cellspacing='0' id='statsTable'>
2055 @ <thead><tr>
2056 @ <th>User</th>
2057 @ <th>Events</th>
2058 @ <th width='90%%'><!-- relative commits graph --></th>
2059 @ </tr></thead><tbody>
2060 while( SQLITE_ROW == db_step(&query) ){
2061 const int nCount = db_column_int(&query, 1);
2062 if(nCount>nMaxEvents){
2063 nMaxEvents = nCount;
2064 }
2065 }
2066 db_reset(&query);
2067 while( SQLITE_ROW == db_step(&query) ){
2068 const char * zUser = db_column_text(&query, 0);
2069 const int nCount = db_column_int(&query, 1);
2070 const int nSize = nCount
2071 ? (int)(100 * nCount / nMaxEvents)
2072 : 0;
2073 if(!nCount) continue /* arguable! Possible? */;
2074 rowClass = ++nRowNumber % 2;
2075 nEventTotal += nCount;
2076 @<tr class='row%d(rowClass)'>
2077 @ <td>
2078 @ <a href="?view=bymonth&user=%h(zUser)">%h(zUser)</a>
2079 @ </td><td>%d(nCount)</td>
2080 @ <td>
2081 @ <div class='statistics-report-graph-line'
2082 @ style='height:16px;width:%d(nSize)%%;'>
2083 @ </div></td>
2084 @</tr>
2085 /*
2086 Potential improvement: calculate the min/max event counts and
2087 use percent-based graph bars.
@@ -2014,12 +2090,130 @@
2090 @ </tbody></table>
2091 db_finalize(&query);
2092 output_table_sorting_javascript("statsTable","tnx");
2093 }
2094
2095
2096 /*
2097 ** Helper for stats_report_by_month_year(), which generates a list of
2098 ** week numbers. zTimeframe should be either a timeframe in the form YYYY
2099 ** or YYYY-MM.
2100 */
2101 static void stats_report_year_weeks(const char * zUserName){
2102 const char * zYear = P("y");
2103 int nYear = zYear ? strlen(zYear) : 0;
2104 int i = 0;
2105 Stmt qYears = empty_Stmt;
2106 char * zDefaultYear = NULL;
2107 Blob sql = empty_blob;
2108 int nMaxEvents = 1; /* max number of events for
2109 all rows. */
2110
2111 cgi_printf("Select year: ");
2112 blob_append(&sql,
2113 "SELECT DISTINCT substr(date(mtime),1,4) AS y "
2114 "FROM event WHERE 1 ", -1);
2115 if(zUserName&&*zUserName){
2116 blob_appendf(&sql,"AND user=%Q ", zUserName);
2117 }
2118 blob_append(&sql,"GROUP BY y ORDER BY y", -1);
2119 db_prepare(&qYears, blob_str(&sql));
2120 blob_reset(&sql);
2121 while( SQLITE_ROW == db_step(&qYears) ){
2122 const char * zT = db_column_text(&qYears, 0);
2123 if( i++ ){
2124 cgi_printf(" ");
2125 }
2126 cgi_printf("<a href='?view=byweek&y=%s", zT);
2127 if(zUserName && *zUserName){
2128 cgi_printf("&user=%t",zUserName);
2129 }
2130 cgi_printf("'>%s</a>",zT);
2131 }
2132 db_finalize(&qYears);
2133 cgi_printf("<br/>");
2134 if(!zYear || !*zYear){
2135 zDefaultYear = db_text("????", "SELECT strftime('%%Y')");
2136 zYear = zDefaultYear;
2137 nYear = 4;
2138 }
2139 if(4 == nYear){
2140 Stmt stWeek = empty_Stmt;
2141 int rowCount = 0;
2142 int total = 0;
2143 Blob header = empty_blob;
2144 blob_appendf(&header, "Timeline events for the calendar weeks "
2145 "of %h", zYear);
2146 blob_appendf(&sql,
2147 "SELECT DISTINCT strftime('%%%%W',mtime) AS wk, "
2148 "count(*) AS n "
2149 "FROM event "
2150 "WHERE %Q=substr(date(mtime),1,4) "
2151 "AND mtime < current_timestamp ",
2152 zYear);
2153 if(zUserName&&*zUserName){
2154 blob_appendf(&sql, " AND user=%Q ", zUserName);
2155 blob_appendf(&header," for user %h", zUserName);
2156 }
2157 blob_appendf(&sql, "GROUP BY wk ORDER BY wk DESC");
2158 cgi_printf("<h1>%h</h1>", blob_str(&header));
2159 blob_reset(&header);
2160 cgi_printf("<table class='statistics-report-table-events' "
2161 "border='0' cellpadding='2' width='100%%' "
2162 "cellspacing='0' id='statsTable'>");
2163 cgi_printf("<thead><tr>"
2164 "<th>Week</th>"
2165 "<th>Events</th>"
2166 "<th width='90%%'><!-- relative commits graph --></th>"
2167 "</tr></thead>"
2168 "<tbody>");
2169 db_prepare(&stWeek, blob_str(&sql));
2170 blob_reset(&sql);
2171 while( SQLITE_ROW == db_step(&stWeek) ){
2172 const int nCount = db_column_int(&stWeek, 1);
2173 if(nCount>nMaxEvents){
2174 nMaxEvents = nCount;
2175 }
2176 }
2177 db_reset(&stWeek);
2178 while( SQLITE_ROW == db_step(&stWeek) ){
2179 const char * zWeek = db_column_text(&stWeek,0);
2180 const int nCount = db_column_int(&stWeek,1);
2181 const int nSize = nCount
2182 ? (int)(100 * nCount / nMaxEvents)
2183 : 0;
2184 total += nCount;
2185 cgi_printf("<tr class='row%d'>", ++rowCount % 2 );
2186 cgi_printf("<td><a href='%s/timeline?yw=%t-%s&n=%d",
2187 g.zTop, zYear, zWeek, nCount);
2188 if(zUserName && *zUserName){
2189 cgi_printf("&u=%t",zUserName);
2190 }
2191 cgi_printf("'>%s</a></td>",zWeek);
2192
2193 cgi_printf("<td>%d</td>",nCount);
2194 cgi_printf("<td>");
2195 if(nCount){
2196 cgi_printf("<div class='statistics-report-graph-line'"
2197 "style='height:16px;width:%d%%;'></div>",
2198 nSize);
2199 }
2200 cgi_printf("</td></tr>");
2201 }
2202 db_finalize(&stWeek);
2203 free(zDefaultYear);
2204 cgi_printf("</tbody></table>");
2205 if(total){
2206 cgi_printf("<br><div>Total events: %d</div>",
2207 total);
2208 }
2209 output_table_sorting_javascript("statsTable","tnx");
2210 }
2211 }
2212
2213 /*
2214 ** WEBPAGE: reports
2215 **
2216 ** Shows activity reports for the repository.
2217 **
2218 ** Query Parameters:
2219 **
@@ -2026,37 +2220,40 @@
2220 ** view=REPORT_NAME Valid values: bymonth, byyear, byuser
2221 ** user=NAME Restricts statistics to the given user
2222 */
2223 void stats_report_page(){
2224 HQuery url; /* URL for various branch links */
2225 const char * zView = P("view"); /* Which view/report to show. */
2226 const char *zUserName = P("user");
2227 if(!zUserName) zUserName = P("u");
2228 url_initialize(&url, "reports");
2229
2230 if(zUserName && *zUserName){
2231 url_add_parameter(&url,"user", zUserName);
2232 timeline_submenu(&url, "(Remove User Flag)", "view", zView, "user");
2233 }
2234 timeline_submenu(&url, "By Year", "view", "byyear", 0);
2235 timeline_submenu(&url, "By Month", "view", "bymonth", 0);
2236 timeline_submenu(&url, "By Week", "view", "byweek", 0);
2237 timeline_submenu(&url, "By User", "view", "byuser", "user");
2238 url_reset(&url);
2239 style_header("Activity Reports");
2240 if(0==fossil_strcmp(zView,"byyear")){
2241 stats_report_by_month_year(0, 0, zUserName);
2242 }else if(0==fossil_strcmp(zView,"bymonth")){
2243 stats_report_by_month_year(1, 0, zUserName);
2244 }else if(0==fossil_strcmp(zView,"byweek")){
2245 stats_report_year_weeks(zUserName);
2246 }else if(0==fossil_strcmp(zView,"byuser")){
2247 stats_report_by_user();
2248 }else{
2249 @ <h1>Select a report to show:</h1>
2250 @ <ul>
2251 @ <li><a href='?view=byyear'>Events by year</a></li>
2252 @ <li><a href='?view=bymonth'>Events by month</a></li>
2253 @ <li><a href='?view=byweek'>Events by calendar week</a></li>
2254 @ <li><a href='?view=byuser'>Events by user</a></li>
2255 @ </ul>
2256 }
2257
2258 style_footer();
2259 }
2260
--- src/translate.c
+++ src/translate.c
@@ -30,10 +30,25 @@
3030
**
3131
** This tool allows us to put raw HTML, without the special codes, in
3232
** the middle of a C program. This program then translates the text
3333
** into standard C by inserting all necessary backslashes and other
3434
** punctuation.
35
+**
36
+** Enhancement #1:
37
+**
38
+** If the last non-whitespace character prior to the first "@" of a
39
+** @-block is "=" or "," then the @-block is a string literal initializer
40
+** rather than text that is to be output via cgi_printf(). Render it
41
+** as such.
42
+**
43
+** Enhancement #2:
44
+**
45
+** Comments of the form: "/* @-comment: CC" cause CC to become a
46
+** comment character for the @-substitution. Typical values for CC are
47
+** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48
+** Lines of subsequent @-blocks that begin with CC are omitted from the
49
+** output.
3550
**
3651
*/
3752
#include <stdio.h>
3853
#include <ctype.h>
3954
#include <stdlib.h>
4055
--- src/translate.c
+++ src/translate.c
@@ -30,10 +30,25 @@
30 **
31 ** This tool allows us to put raw HTML, without the special codes, in
32 ** the middle of a C program. This program then translates the text
33 ** into standard C by inserting all necessary backslashes and other
34 ** punctuation.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35 **
36 */
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <stdlib.h>
40
--- src/translate.c
+++ src/translate.c
@@ -30,10 +30,25 @@
30 **
31 ** This tool allows us to put raw HTML, without the special codes, in
32 ** the middle of a C program. This program then translates the text
33 ** into standard C by inserting all necessary backslashes and other
34 ** punctuation.
35 **
36 ** Enhancement #1:
37 **
38 ** If the last non-whitespace character prior to the first "@" of a
39 ** @-block is "=" or "," then the @-block is a string literal initializer
40 ** rather than text that is to be output via cgi_printf(). Render it
41 ** as such.
42 **
43 ** Enhancement #2:
44 **
45 ** Comments of the form: "/* @-comment: CC" cause CC to become a
46 ** comment character for the @-substitution. Typical values for CC are
47 ** "--" (for SQL text) or "#" (for TCL script) or "//" (for C++ code).
48 ** Lines of subsequent @-blocks that begin with CC are omitted from the
49 ** output.
50 **
51 */
52 #include <stdio.h>
53 #include <ctype.h>
54 #include <stdlib.h>
55
+2 -2
--- src/vfile.c
+++ src/vfile.c
@@ -213,11 +213,11 @@
213213
blob_zero(&fileCksum);
214214
}
215215
if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
216216
blob_reset(&origCksum);
217217
blob_reset(&fileCksum);
218
- }else if( (chnged==0 || chnged==2)
218
+ }else if( (chnged==0 || chnged==2 || chnged==4)
219219
&& (useMtime==0 || currentMtime!=oldMtime) ){
220220
/* For files that were formerly believed to be unchanged or that were
221221
** changed by merging, if their mtime changes, or unconditionally
222222
** if --sha1sum is used, check to see if they have been edited by
223223
** looking at their SHA1 sum */
@@ -230,11 +230,11 @@
230230
chnged = 1;
231231
}
232232
blob_reset(&origCksum);
233233
blob_reset(&fileCksum);
234234
}
235
- if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2) ){
235
+ if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){
236236
i64 desiredMtime;
237237
if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
238238
if( currentMtime!=desiredMtime ){
239239
file_set_mtime(zName, desiredMtime);
240240
currentMtime = file_wd_mtime(zName);
241241
--- src/vfile.c
+++ src/vfile.c
@@ -213,11 +213,11 @@
213 blob_zero(&fileCksum);
214 }
215 if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
216 blob_reset(&origCksum);
217 blob_reset(&fileCksum);
218 }else if( (chnged==0 || chnged==2)
219 && (useMtime==0 || currentMtime!=oldMtime) ){
220 /* For files that were formerly believed to be unchanged or that were
221 ** changed by merging, if their mtime changes, or unconditionally
222 ** if --sha1sum is used, check to see if they have been edited by
223 ** looking at their SHA1 sum */
@@ -230,11 +230,11 @@
230 chnged = 1;
231 }
232 blob_reset(&origCksum);
233 blob_reset(&fileCksum);
234 }
235 if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2) ){
236 i64 desiredMtime;
237 if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
238 if( currentMtime!=desiredMtime ){
239 file_set_mtime(zName, desiredMtime);
240 currentMtime = file_wd_mtime(zName);
241
--- src/vfile.c
+++ src/vfile.c
@@ -213,11 +213,11 @@
213 blob_zero(&fileCksum);
214 }
215 if( blob_compare(&fileCksum, &origCksum)==0 ) chnged = 0;
216 blob_reset(&origCksum);
217 blob_reset(&fileCksum);
218 }else if( (chnged==0 || chnged==2 || chnged==4)
219 && (useMtime==0 || currentMtime!=oldMtime) ){
220 /* For files that were formerly believed to be unchanged or that were
221 ** changed by merging, if their mtime changes, or unconditionally
222 ** if --sha1sum is used, check to see if they have been edited by
223 ** looking at their SHA1 sum */
@@ -230,11 +230,11 @@
230 chnged = 1;
231 }
232 blob_reset(&origCksum);
233 blob_reset(&fileCksum);
234 }
235 if( (cksigFlags & CKSIG_SETMTIME) && (chnged==0 || chnged==2 || chnged==4) ){
236 i64 desiredMtime;
237 if( mtime_of_manifest_file(vid,rid,&desiredMtime)==0 ){
238 if( currentMtime!=desiredMtime ){
239 file_set_mtime(zName, desiredMtime);
240 currentMtime = file_wd_mtime(zName);
241
+9 -3
--- src/wiki.c
+++ src/wiki.c
@@ -178,14 +178,20 @@
178178
if( !g.perm.RdWiki ){ login_needed(); return; }
179179
zPageName = P("name");
180180
if( zPageName==0 ){
181181
style_header("Wiki");
182182
@ <ul>
183
+ { char *zWikiHomePageName = db_get("index-page",0);
184
+ if( zWikiHomePageName ){
185
+ @ <li> %z(href("%R%s",zWikiHomePageName))
186
+ @ %h(zWikiHomePageName)</a> wiki home page.</li>
187
+ }
188
+ }
183189
{ char *zHomePageName = db_get("project-name",0);
184190
if( zHomePageName ){
185191
@ <li> %z(href("%R/wiki?name=%t",zHomePageName))
186
- @ %h(zHomePageName)</a> wiki home page.</li>
192
+ @ %h(zHomePageName)</a> project home page.</li>
187193
}
188194
}
189195
@ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
190196
@ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
191197
@ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
@@ -786,13 +792,13 @@
786792
blob_init(&w2, pW2->zWiki, -1);
787793
}
788794
blob_zero(&d);
789795
diffFlags = construct_diff_flags(1,0);
790796
text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
791
- @ <div class="udiff">
797
+ @ <pre class="udiff">
792798
@ %s(blob_str(&d))
793
- @ </div>
799
+ @ <pre>
794800
manifest_destroy(pW1);
795801
manifest_destroy(pW2);
796802
style_footer();
797803
}
798804
799805
--- src/wiki.c
+++ src/wiki.c
@@ -178,14 +178,20 @@
178 if( !g.perm.RdWiki ){ login_needed(); return; }
179 zPageName = P("name");
180 if( zPageName==0 ){
181 style_header("Wiki");
182 @ <ul>
 
 
 
 
 
 
183 { char *zHomePageName = db_get("project-name",0);
184 if( zHomePageName ){
185 @ <li> %z(href("%R/wiki?name=%t",zHomePageName))
186 @ %h(zHomePageName)</a> wiki home page.</li>
187 }
188 }
189 @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
190 @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
191 @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
@@ -786,13 +792,13 @@
786 blob_init(&w2, pW2->zWiki, -1);
787 }
788 blob_zero(&d);
789 diffFlags = construct_diff_flags(1,0);
790 text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
791 @ <div class="udiff">
792 @ %s(blob_str(&d))
793 @ </div>
794 manifest_destroy(pW1);
795 manifest_destroy(pW2);
796 style_footer();
797 }
798
799
--- src/wiki.c
+++ src/wiki.c
@@ -178,14 +178,20 @@
178 if( !g.perm.RdWiki ){ login_needed(); return; }
179 zPageName = P("name");
180 if( zPageName==0 ){
181 style_header("Wiki");
182 @ <ul>
183 { char *zWikiHomePageName = db_get("index-page",0);
184 if( zWikiHomePageName ){
185 @ <li> %z(href("%R%s",zWikiHomePageName))
186 @ %h(zWikiHomePageName)</a> wiki home page.</li>
187 }
188 }
189 { char *zHomePageName = db_get("project-name",0);
190 if( zHomePageName ){
191 @ <li> %z(href("%R/wiki?name=%t",zHomePageName))
192 @ %h(zHomePageName)</a> project home page.</li>
193 }
194 }
195 @ <li> %z(href("%R/timeline?y=w"))Recent changes</a> to wiki pages.</li>
196 @ <li> %z(href("%R/wiki_rules"))Formatting rules</a> for wiki.</li>
197 @ <li> Use the %z(href("%R/wiki?name=Sandbox"))Sandbox</a>
@@ -786,13 +792,13 @@
792 blob_init(&w2, pW2->zWiki, -1);
793 }
794 blob_zero(&d);
795 diffFlags = construct_diff_flags(1,0);
796 text_diff(&w2, &w1, &d, 0, diffFlags | DIFF_HTML | DIFF_LINENO);
797 @ <pre class="udiff">
798 @ %s(blob_str(&d))
799 @ <pre>
800 manifest_destroy(pW1);
801 manifest_destroy(pW2);
802 style_footer();
803 }
804
805
+36 -6
--- src/xfer.c
+++ src/xfer.c
@@ -46,10 +46,11 @@
4646
int nDeltaSent; /* Number of deltas sent */
4747
int nFileRcvd; /* Number of files received */
4848
int nDeltaRcvd; /* Number of deltas received */
4949
int nDanglingFile; /* Number of dangling deltas received */
5050
int mxSend; /* Stop sending "file" with pOut reaches this size */
51
+ int resync; /* Send igot cards for all holdings */
5152
u8 syncPrivate; /* True to enable syncing private content */
5253
u8 nextIsPrivate; /* If true, next "file" received is a private */
5354
time_t maxTime; /* Time when this transfer should be finished */
5455
};
5556
@@ -736,21 +737,37 @@
736737
** Return the number of cards sent.
737738
*/
738739
static int send_unclustered(Xfer *pXfer){
739740
Stmt q;
740741
int cnt = 0;
741
- db_prepare(&q,
742
- "SELECT uuid FROM unclustered JOIN blob USING(rid)"
743
- " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
744
- " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
745
- " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
746
- );
742
+ if( pXfer->resync ){
743
+ db_prepare(&q,
744
+ "SELECT uuid, rid FROM blob"
745
+ " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
746
+ " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
747
+ " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
748
+ " AND blob.rid<=%d"
749
+ " ORDER BY blob.rid DESC",
750
+ pXfer->resync
751
+ );
752
+ }else{
753
+ db_prepare(&q,
754
+ "SELECT uuid FROM unclustered JOIN blob USING(rid)"
755
+ " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
756
+ " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
757
+ " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
758
+ );
759
+ }
747760
while( db_step(&q)==SQLITE_ROW ){
748761
blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
749762
cnt++;
763
+ if( pXfer->resync && pXfer->mxSend<blob_size(pXfer->pOut) ){
764
+ pXfer->resync = db_column_int(&q, 1)-1;
765
+ }
750766
}
751767
db_finalize(&q);
768
+ if( cnt==0 ) pXfer->resync = 0;
752769
return cnt;
753770
}
754771
755772
/*
756773
** Send an igot message for every artifact.
@@ -1195,10 +1212,17 @@
11951212
server_private_xfer_not_authorized();
11961213
}else{
11971214
xfer.syncPrivate = 1;
11981215
}
11991216
}
1217
+ /* pragma send-catalog
1218
+ **
1219
+ ** Send igot cards for all known artifacts.
1220
+ */
1221
+ if( blob_eq(&xfer.aToken[1], "send-catalog") ){
1222
+ xfer.resync = 0x7fffffff;
1223
+ }
12001224
}else
12011225
12021226
/* Unknown message
12031227
*/
12041228
{
@@ -1292,10 +1316,11 @@
12921316
#define SYNC_PUSH 0x0001
12931317
#define SYNC_PULL 0x0002
12941318
#define SYNC_CLONE 0x0004
12951319
#define SYNC_PRIVATE 0x0008
12961320
#define SYNC_VERBOSE 0x0010
1321
+#define SYNC_RESYNC 0x0020
12971322
#endif
12981323
12991324
/*
13001325
** Sync to the host identified in g.urlName and g.urlPath. This
13011326
** routine is called by the client.
@@ -1380,15 +1405,20 @@
13801405
zOpType = "Clone";
13811406
}else if( syncFlags & SYNC_PULL ){
13821407
blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
13831408
nCardSent++;
13841409
zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";
1410
+ if( (syncFlags & SYNC_RESYNC)!=0 && nCycle<2 ){
1411
+ blob_appendf(&send, "pragma send-catalog\n");
1412
+ nCardSent++;
1413
+ }
13851414
}
13861415
if( syncFlags & SYNC_PUSH ){
13871416
blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
13881417
nCardSent++;
13891418
if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1419
+ if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
13901420
}
13911421
manifest_crosslink_begin();
13921422
transport_global_startup();
13931423
if( syncFlags & SYNC_VERBOSE ){
13941424
fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
13951425
--- src/xfer.c
+++ src/xfer.c
@@ -46,10 +46,11 @@
46 int nDeltaSent; /* Number of deltas sent */
47 int nFileRcvd; /* Number of files received */
48 int nDeltaRcvd; /* Number of deltas received */
49 int nDanglingFile; /* Number of dangling deltas received */
50 int mxSend; /* Stop sending "file" with pOut reaches this size */
 
51 u8 syncPrivate; /* True to enable syncing private content */
52 u8 nextIsPrivate; /* If true, next "file" received is a private */
53 time_t maxTime; /* Time when this transfer should be finished */
54 };
55
@@ -736,21 +737,37 @@
736 ** Return the number of cards sent.
737 */
738 static int send_unclustered(Xfer *pXfer){
739 Stmt q;
740 int cnt = 0;
741 db_prepare(&q,
742 "SELECT uuid FROM unclustered JOIN blob USING(rid)"
743 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
744 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
745 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
746 );
 
 
 
 
 
 
 
 
 
 
 
 
747 while( db_step(&q)==SQLITE_ROW ){
748 blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
749 cnt++;
 
 
 
750 }
751 db_finalize(&q);
 
752 return cnt;
753 }
754
755 /*
756 ** Send an igot message for every artifact.
@@ -1195,10 +1212,17 @@
1195 server_private_xfer_not_authorized();
1196 }else{
1197 xfer.syncPrivate = 1;
1198 }
1199 }
 
 
 
 
 
 
 
1200 }else
1201
1202 /* Unknown message
1203 */
1204 {
@@ -1292,10 +1316,11 @@
1292 #define SYNC_PUSH 0x0001
1293 #define SYNC_PULL 0x0002
1294 #define SYNC_CLONE 0x0004
1295 #define SYNC_PRIVATE 0x0008
1296 #define SYNC_VERBOSE 0x0010
 
1297 #endif
1298
1299 /*
1300 ** Sync to the host identified in g.urlName and g.urlPath. This
1301 ** routine is called by the client.
@@ -1380,15 +1405,20 @@
1380 zOpType = "Clone";
1381 }else if( syncFlags & SYNC_PULL ){
1382 blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
1383 nCardSent++;
1384 zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";
 
 
 
 
1385 }
1386 if( syncFlags & SYNC_PUSH ){
1387 blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
1388 nCardSent++;
1389 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
 
1390 }
1391 manifest_crosslink_begin();
1392 transport_global_startup();
1393 if( syncFlags & SYNC_VERBOSE ){
1394 fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
1395
--- src/xfer.c
+++ src/xfer.c
@@ -46,10 +46,11 @@
46 int nDeltaSent; /* Number of deltas sent */
47 int nFileRcvd; /* Number of files received */
48 int nDeltaRcvd; /* Number of deltas received */
49 int nDanglingFile; /* Number of dangling deltas received */
50 int mxSend; /* Stop sending "file" with pOut reaches this size */
51 int resync; /* Send igot cards for all holdings */
52 u8 syncPrivate; /* True to enable syncing private content */
53 u8 nextIsPrivate; /* If true, next "file" received is a private */
54 time_t maxTime; /* Time when this transfer should be finished */
55 };
56
@@ -736,21 +737,37 @@
737 ** Return the number of cards sent.
738 */
739 static int send_unclustered(Xfer *pXfer){
740 Stmt q;
741 int cnt = 0;
742 if( pXfer->resync ){
743 db_prepare(&q,
744 "SELECT uuid, rid FROM blob"
745 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
746 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
747 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
748 " AND blob.rid<=%d"
749 " ORDER BY blob.rid DESC",
750 pXfer->resync
751 );
752 }else{
753 db_prepare(&q,
754 "SELECT uuid FROM unclustered JOIN blob USING(rid)"
755 " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid)"
756 " AND NOT EXISTS(SELECT 1 FROM phantom WHERE rid=blob.rid)"
757 " AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)"
758 );
759 }
760 while( db_step(&q)==SQLITE_ROW ){
761 blob_appendf(pXfer->pOut, "igot %s\n", db_column_text(&q, 0));
762 cnt++;
763 if( pXfer->resync && pXfer->mxSend<blob_size(pXfer->pOut) ){
764 pXfer->resync = db_column_int(&q, 1)-1;
765 }
766 }
767 db_finalize(&q);
768 if( cnt==0 ) pXfer->resync = 0;
769 return cnt;
770 }
771
772 /*
773 ** Send an igot message for every artifact.
@@ -1195,10 +1212,17 @@
1212 server_private_xfer_not_authorized();
1213 }else{
1214 xfer.syncPrivate = 1;
1215 }
1216 }
1217 /* pragma send-catalog
1218 **
1219 ** Send igot cards for all known artifacts.
1220 */
1221 if( blob_eq(&xfer.aToken[1], "send-catalog") ){
1222 xfer.resync = 0x7fffffff;
1223 }
1224 }else
1225
1226 /* Unknown message
1227 */
1228 {
@@ -1292,10 +1316,11 @@
1316 #define SYNC_PUSH 0x0001
1317 #define SYNC_PULL 0x0002
1318 #define SYNC_CLONE 0x0004
1319 #define SYNC_PRIVATE 0x0008
1320 #define SYNC_VERBOSE 0x0010
1321 #define SYNC_RESYNC 0x0020
1322 #endif
1323
1324 /*
1325 ** Sync to the host identified in g.urlName and g.urlPath. This
1326 ** routine is called by the client.
@@ -1380,15 +1405,20 @@
1405 zOpType = "Clone";
1406 }else if( syncFlags & SYNC_PULL ){
1407 blob_appendf(&send, "pull %s %s\n", zSCode, zPCode);
1408 nCardSent++;
1409 zOpType = (syncFlags & SYNC_PUSH)?"Sync":"Pull";
1410 if( (syncFlags & SYNC_RESYNC)!=0 && nCycle<2 ){
1411 blob_appendf(&send, "pragma send-catalog\n");
1412 nCardSent++;
1413 }
1414 }
1415 if( syncFlags & SYNC_PUSH ){
1416 blob_appendf(&send, "push %s %s\n", zSCode, zPCode);
1417 nCardSent++;
1418 if( (syncFlags & SYNC_PULL)==0 ) zOpType = "Push";
1419 if( (syncFlags & SYNC_RESYNC)!=0 ) xfer.resync = 0x7fffffff;
1420 }
1421 manifest_crosslink_begin();
1422 transport_global_startup();
1423 if( syncFlags & SYNC_VERBOSE ){
1424 fossil_print(zLabelFormat, "", "Bytes", "Cards", "Artifacts", "Deltas");
1425
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -2,11 +2,11 @@
22
33
This page contains list of URLs of interesting diffs.
44
Click on all URLs, one by one, to verify
55
the correct operation of the diff logic.
66
7
- * <a href="../../../info/030035345c#chunk59" target="testwindow">
7
+ * <a href="../../../info/030035345c#chunk73" target="testwindow">
88
Multiple edits on a single line.</a> This is an SQLite version
99
update diff. It is a large diff and contains many other interesting
1010
features. Scan the whole diff.
1111
* <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
1212
target="testwindow">Tricky alignment and multiple edits per line</a>.
@@ -15,12 +15,12 @@
1515
* <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
1616
target="testwindow">Column alignment with multibyte characters.</a>
1717
The edit of a line with multibyte characters is the first chunk.
1818
* <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
1919
target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20
- slow prior to the preformance enhancement change [9e15437e97].
21
- * <a href="../../../info/bda00cbada#chunk42" target="testwindow">
20
+ slow prior to the performance enhancement change [9e15437e97].
21
+ * <a href="../../../info/bda00cbada#chunk49" target="testwindow">
2222
A difficult indentation change.
2323
* <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
2424
target="testwindow">Another tricky indentation.</a> Notice especially
2525
lines 59398 and 59407 on the left.
2626
* <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
2727
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -2,11 +2,11 @@
2
3 This page contains list of URLs of interesting diffs.
4 Click on all URLs, one by one, to verify
5 the correct operation of the diff logic.
6
7 * <a href="../../../info/030035345c#chunk59" target="testwindow">
8 Multiple edits on a single line.</a> This is an SQLite version
9 update diff. It is a large diff and contains many other interesting
10 features. Scan the whole diff.
11 * <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
12 target="testwindow">Tricky alignment and multiple edits per line</a>.
@@ -15,12 +15,12 @@
15 * <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
16 target="testwindow">Column alignment with multibyte characters.</a>
17 The edit of a line with multibyte characters is the first chunk.
18 * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
19 target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20 slow prior to the preformance enhancement change [9e15437e97].
21 * <a href="../../../info/bda00cbada#chunk42" target="testwindow">
22 A difficult indentation change.
23 * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
24 target="testwindow">Another tricky indentation.</a> Notice especially
25 lines 59398 and 59407 on the left.
26 * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
27
--- test/diff-test-1.wiki
+++ test/diff-test-1.wiki
@@ -2,11 +2,11 @@
2
3 This page contains list of URLs of interesting diffs.
4 Click on all URLs, one by one, to verify
5 the correct operation of the diff logic.
6
7 * <a href="../../../info/030035345c#chunk73" target="testwindow">
8 Multiple edits on a single line.</a> This is an SQLite version
9 update diff. It is a large diff and contains many other interesting
10 features. Scan the whole diff.
11 * <a href="../../../fdiff?v1=6da016415dc52d61&v2=af6df3466e3c4a88"
12 target="testwindow">Tricky alignment and multiple edits per line</a>.
@@ -15,12 +15,12 @@
15 * <a href="../../../fdiff?v1=d1c60722e0b9d775&v2=58d1a8991bacb113"
16 target="testwindow">Column alignment with multibyte characters.</a>
17 The edit of a line with multibyte characters is the first chunk.
18 * <a href="../../../fdiff?v1=57b0d8183cab0e3d&v2=37b3ef49d73cdfe6"
19 target="testwindow">Large diff of sqlite3.c</a>. This diff was very
20 slow prior to the performance enhancement change [9e15437e97].
21 * <a href="../../../info/bda00cbada#chunk49" target="testwindow">
22 A difficult indentation change.
23 * <a href="../../../fdiff?v1=955cc67ace8fb622&v2=e2e1c87b86664b45#chunk13"
24 target="testwindow">Another tricky indentation.</a> Notice especially
25 lines 59398 and 59407 on the left.
26 * <a href="../../../fdiff?v2=955cc67ace8fb622&v1=e2e1c87b86664b45#chunk13"
27
+14 -14
--- test/merge1.test
+++ test/merge1.test
@@ -44,13 +44,13 @@
4444
222 - The second line program line in code - 2222
4545
333 - This is a test OF THE merging algohm - 3333
4646
444 - If all goes well, we will be pleased - 4444
4747
555 - we think it well and other stuff too - 5555
4848
}
49
-fossil test-3 t1 t3 t2 a32
49
+fossil 3-way-merge t1 t3 t2 a32
5050
test merge1-1.1 {[same_file t23 a32]}
51
-fossil test-3 t1 t2 t3 a23
51
+fossil 3-way-merge t1 t2 t3 a23
5252
test merge1-1.2 {[same_file t23 a23]}
5353
5454
write_file_indented t1 {
5555
111 - This is line one of the demo program - 1111
5656
222 - The second line program line in code - 2222
@@ -96,13 +96,13 @@
9696
222 - The second line program line in code - 2222
9797
333 - This is a test of the merging algohm - 3333
9898
444 - If all goes well, we will be pleased - 4444
9999
555 - we think it well and other stuff too - 5555
100100
}
101
-fossil test-3 t1 t3 t2 a32
101
+fossil 3-way-merge t1 t3 t2 a32
102102
test merge1-2.1 {[same_file t32 a32]}
103
-fossil test-3 t1 t2 t3 a23
103
+fossil 3-way-merge t1 t2 t3 a23
104104
test merge1-2.2 {[same_file t23 a23]}
105105
106106
write_file_indented t1 {
107107
111 - This is line one of the demo program - 1111
108108
222 - The second line program line in code - 2222
@@ -129,13 +129,13 @@
129129
222 - The second line program line in code - 2222
130130
333 - This is a test of the merging algohm - 3333
131131
444 - If all goes well, we will be pleased - 4444
132132
555 - we think it well and other stuff too - 5555
133133
}
134
-fossil test-3 t1 t3 t2 a32
134
+fossil 3-way-merge t1 t3 t2 a32
135135
test merge1-3.1 {[same_file t23 a32]}
136
-fossil test-3 t1 t2 t3 a23
136
+fossil 3-way-merge t1 t2 t3 a23
137137
test merge1-3.2 {[same_file t23 a23]}
138138
139139
write_file_indented t1 {
140140
111 - This is line one of the demo program - 1111
141141
222 - The second line program line in code - 2222
@@ -181,13 +181,13 @@
181181
222 - The second line program line in code - 2222
182182
333 - This is a test of the merging algohm - 3333
183183
444 - If all goes well, we will be pleased - 4444
184184
555 - we think it well and other stuff too - 5555
185185
}
186
-fossil test-3 t1 t3 t2 a32
186
+fossil 3-way-merge t1 t3 t2 a32
187187
test merge1-4.1 {[same_file t32 a32]}
188
-fossil test-3 t1 t2 t3 a23
188
+fossil 3-way-merge t1 t2 t3 a23
189189
test merge1-4.2 {[same_file t23 a23]}
190190
191191
write_file_indented t1 {
192192
111 - This is line one of the demo program - 1111
193193
222 - The second line program line in code - 2222
@@ -214,13 +214,13 @@
214214
333 - This is a test of the merging algohm - 3333
215215
444 - If all goes well, we will be pleased - 4444
216216
555 - we think it well and other stuff too - 5555
217217
666 - Extra line at the end of the file wi - 6666
218218
}
219
-fossil test-3 t1 t3 t2 a32
219
+fossil 3-way-merge t1 t3 t2 a32
220220
test merge1-5.1 {[same_file t32 a32]}
221
-fossil test-3 t1 t2 t3 a23
221
+fossil 3-way-merge t1 t2 t3 a23
222222
test merge1-5.2 {[same_file t32 a23]}
223223
224224
write_file_indented t1 {
225225
111 - This is line one of the demo program - 1111
226226
222 - The second line program line in code - 2222
@@ -243,13 +243,13 @@
243243
write_file_indented t32 {
244244
111 - This is line one of the demo program - 1111
245245
333 - This is a test of the merging algohm - 3333
246246
555 - we think it well and other stuff too - 5555
247247
}
248
-fossil test-3 t1 t3 t2 a32
248
+fossil 3-way-merge t1 t3 t2 a32
249249
test merge1-6.1 {[same_file t32 a32]}
250
-fossil test-3 t1 t2 t3 a23
250
+fossil 3-way-merge t1 t2 t3 a23
251251
test merge1-6.2 {[same_file t32 a23]}
252252
253253
write_file_indented t1 {
254254
abcd
255255
efgh
@@ -328,11 +328,11 @@
328328
KLMN
329329
OPQR
330330
STUV
331331
XYZ.
332332
}
333
-fossil test-3 t1 t2 t3 a23
333
+fossil 3-way-merge t1 t2 t3 a23
334334
test merge1-7.1 {[same_file t23 a23]}
335335
336336
write_file_indented t2 {
337337
abcd
338338
efgh 2
@@ -396,7 +396,7 @@
396396
KLMN
397397
OPQR
398398
STUV
399399
XYZ.
400400
}
401
-fossil test-3 t1 t2 t3 a23
401
+fossil 3-way-merge t1 t2 t3 a23
402402
test merge1-7.2 {[same_file t23 a23]}
403403
--- test/merge1.test
+++ test/merge1.test
@@ -44,13 +44,13 @@
44 222 - The second line program line in code - 2222
45 333 - This is a test OF THE merging algohm - 3333
46 444 - If all goes well, we will be pleased - 4444
47 555 - we think it well and other stuff too - 5555
48 }
49 fossil test-3 t1 t3 t2 a32
50 test merge1-1.1 {[same_file t23 a32]}
51 fossil test-3 t1 t2 t3 a23
52 test merge1-1.2 {[same_file t23 a23]}
53
54 write_file_indented t1 {
55 111 - This is line one of the demo program - 1111
56 222 - The second line program line in code - 2222
@@ -96,13 +96,13 @@
96 222 - The second line program line in code - 2222
97 333 - This is a test of the merging algohm - 3333
98 444 - If all goes well, we will be pleased - 4444
99 555 - we think it well and other stuff too - 5555
100 }
101 fossil test-3 t1 t3 t2 a32
102 test merge1-2.1 {[same_file t32 a32]}
103 fossil test-3 t1 t2 t3 a23
104 test merge1-2.2 {[same_file t23 a23]}
105
106 write_file_indented t1 {
107 111 - This is line one of the demo program - 1111
108 222 - The second line program line in code - 2222
@@ -129,13 +129,13 @@
129 222 - The second line program line in code - 2222
130 333 - This is a test of the merging algohm - 3333
131 444 - If all goes well, we will be pleased - 4444
132 555 - we think it well and other stuff too - 5555
133 }
134 fossil test-3 t1 t3 t2 a32
135 test merge1-3.1 {[same_file t23 a32]}
136 fossil test-3 t1 t2 t3 a23
137 test merge1-3.2 {[same_file t23 a23]}
138
139 write_file_indented t1 {
140 111 - This is line one of the demo program - 1111
141 222 - The second line program line in code - 2222
@@ -181,13 +181,13 @@
181 222 - The second line program line in code - 2222
182 333 - This is a test of the merging algohm - 3333
183 444 - If all goes well, we will be pleased - 4444
184 555 - we think it well and other stuff too - 5555
185 }
186 fossil test-3 t1 t3 t2 a32
187 test merge1-4.1 {[same_file t32 a32]}
188 fossil test-3 t1 t2 t3 a23
189 test merge1-4.2 {[same_file t23 a23]}
190
191 write_file_indented t1 {
192 111 - This is line one of the demo program - 1111
193 222 - The second line program line in code - 2222
@@ -214,13 +214,13 @@
214 333 - This is a test of the merging algohm - 3333
215 444 - If all goes well, we will be pleased - 4444
216 555 - we think it well and other stuff too - 5555
217 666 - Extra line at the end of the file wi - 6666
218 }
219 fossil test-3 t1 t3 t2 a32
220 test merge1-5.1 {[same_file t32 a32]}
221 fossil test-3 t1 t2 t3 a23
222 test merge1-5.2 {[same_file t32 a23]}
223
224 write_file_indented t1 {
225 111 - This is line one of the demo program - 1111
226 222 - The second line program line in code - 2222
@@ -243,13 +243,13 @@
243 write_file_indented t32 {
244 111 - This is line one of the demo program - 1111
245 333 - This is a test of the merging algohm - 3333
246 555 - we think it well and other stuff too - 5555
247 }
248 fossil test-3 t1 t3 t2 a32
249 test merge1-6.1 {[same_file t32 a32]}
250 fossil test-3 t1 t2 t3 a23
251 test merge1-6.2 {[same_file t32 a23]}
252
253 write_file_indented t1 {
254 abcd
255 efgh
@@ -328,11 +328,11 @@
328 KLMN
329 OPQR
330 STUV
331 XYZ.
332 }
333 fossil test-3 t1 t2 t3 a23
334 test merge1-7.1 {[same_file t23 a23]}
335
336 write_file_indented t2 {
337 abcd
338 efgh 2
@@ -396,7 +396,7 @@
396 KLMN
397 OPQR
398 STUV
399 XYZ.
400 }
401 fossil test-3 t1 t2 t3 a23
402 test merge1-7.2 {[same_file t23 a23]}
403
--- test/merge1.test
+++ test/merge1.test
@@ -44,13 +44,13 @@
44 222 - The second line program line in code - 2222
45 333 - This is a test OF THE merging algohm - 3333
46 444 - If all goes well, we will be pleased - 4444
47 555 - we think it well and other stuff too - 5555
48 }
49 fossil 3-way-merge t1 t3 t2 a32
50 test merge1-1.1 {[same_file t23 a32]}
51 fossil 3-way-merge t1 t2 t3 a23
52 test merge1-1.2 {[same_file t23 a23]}
53
54 write_file_indented t1 {
55 111 - This is line one of the demo program - 1111
56 222 - The second line program line in code - 2222
@@ -96,13 +96,13 @@
96 222 - The second line program line in code - 2222
97 333 - This is a test of the merging algohm - 3333
98 444 - If all goes well, we will be pleased - 4444
99 555 - we think it well and other stuff too - 5555
100 }
101 fossil 3-way-merge t1 t3 t2 a32
102 test merge1-2.1 {[same_file t32 a32]}
103 fossil 3-way-merge t1 t2 t3 a23
104 test merge1-2.2 {[same_file t23 a23]}
105
106 write_file_indented t1 {
107 111 - This is line one of the demo program - 1111
108 222 - The second line program line in code - 2222
@@ -129,13 +129,13 @@
129 222 - The second line program line in code - 2222
130 333 - This is a test of the merging algohm - 3333
131 444 - If all goes well, we will be pleased - 4444
132 555 - we think it well and other stuff too - 5555
133 }
134 fossil 3-way-merge t1 t3 t2 a32
135 test merge1-3.1 {[same_file t23 a32]}
136 fossil 3-way-merge t1 t2 t3 a23
137 test merge1-3.2 {[same_file t23 a23]}
138
139 write_file_indented t1 {
140 111 - This is line one of the demo program - 1111
141 222 - The second line program line in code - 2222
@@ -181,13 +181,13 @@
181 222 - The second line program line in code - 2222
182 333 - This is a test of the merging algohm - 3333
183 444 - If all goes well, we will be pleased - 4444
184 555 - we think it well and other stuff too - 5555
185 }
186 fossil 3-way-merge t1 t3 t2 a32
187 test merge1-4.1 {[same_file t32 a32]}
188 fossil 3-way-merge t1 t2 t3 a23
189 test merge1-4.2 {[same_file t23 a23]}
190
191 write_file_indented t1 {
192 111 - This is line one of the demo program - 1111
193 222 - The second line program line in code - 2222
@@ -214,13 +214,13 @@
214 333 - This is a test of the merging algohm - 3333
215 444 - If all goes well, we will be pleased - 4444
216 555 - we think it well and other stuff too - 5555
217 666 - Extra line at the end of the file wi - 6666
218 }
219 fossil 3-way-merge t1 t3 t2 a32
220 test merge1-5.1 {[same_file t32 a32]}
221 fossil 3-way-merge t1 t2 t3 a23
222 test merge1-5.2 {[same_file t32 a23]}
223
224 write_file_indented t1 {
225 111 - This is line one of the demo program - 1111
226 222 - The second line program line in code - 2222
@@ -243,13 +243,13 @@
243 write_file_indented t32 {
244 111 - This is line one of the demo program - 1111
245 333 - This is a test of the merging algohm - 3333
246 555 - we think it well and other stuff too - 5555
247 }
248 fossil 3-way-merge t1 t3 t2 a32
249 test merge1-6.1 {[same_file t32 a32]}
250 fossil 3-way-merge t1 t2 t3 a23
251 test merge1-6.2 {[same_file t32 a23]}
252
253 write_file_indented t1 {
254 abcd
255 efgh
@@ -328,11 +328,11 @@
328 KLMN
329 OPQR
330 STUV
331 XYZ.
332 }
333 fossil 3-way-merge t1 t2 t3 a23
334 test merge1-7.1 {[same_file t23 a23]}
335
336 write_file_indented t2 {
337 abcd
338 efgh 2
@@ -396,7 +396,7 @@
396 KLMN
397 OPQR
398 STUV
399 XYZ.
400 }
401 fossil 3-way-merge t1 t2 t3 a23
402 test merge1-7.2 {[same_file t23 a23]}
403
--- test/merge2.test
+++ test/merge2.test
@@ -31,11 +31,11 @@
3131
write_file t3 [set f3 [random_changes $f1 2 4 2 0.1]]
3232
expr {srand($i*2+1)}
3333
write_file t23 [random_changes $f2 2 4 2 0.1]
3434
expr {srand($i*2)}
3535
write_file t32 [random_changes $f3 2 4 0 0.1]
36
- fossil test-3-way-merge t1 t2 t3 a23
36
+ fossil 3-way-merge t1 t2 t3 a23
3737
test merge-$base-$i-23 {[same_file a23 t23]}
38
- fossil test-3-way-merge t1 t3 t2 a32
38
+ fossil 3-way-merge t1 t3 t2 a32
3939
test merge-$base-$i-32 {[same_file a32 t32]}
4040
}
4141
}
4242
--- test/merge2.test
+++ test/merge2.test
@@ -31,11 +31,11 @@
31 write_file t3 [set f3 [random_changes $f1 2 4 2 0.1]]
32 expr {srand($i*2+1)}
33 write_file t23 [random_changes $f2 2 4 2 0.1]
34 expr {srand($i*2)}
35 write_file t32 [random_changes $f3 2 4 0 0.1]
36 fossil test-3-way-merge t1 t2 t3 a23
37 test merge-$base-$i-23 {[same_file a23 t23]}
38 fossil test-3-way-merge t1 t3 t2 a32
39 test merge-$base-$i-32 {[same_file a32 t32]}
40 }
41 }
42
--- test/merge2.test
+++ test/merge2.test
@@ -31,11 +31,11 @@
31 write_file t3 [set f3 [random_changes $f1 2 4 2 0.1]]
32 expr {srand($i*2+1)}
33 write_file t23 [random_changes $f2 2 4 2 0.1]
34 expr {srand($i*2)}
35 write_file t32 [random_changes $f3 2 4 0 0.1]
36 fossil 3-way-merge t1 t2 t3 a23
37 test merge-$base-$i-23 {[same_file a23 t23]}
38 fossil 3-way-merge t1 t3 t2 a32
39 test merge-$base-$i-32 {[same_file a32 t32]}
40 }
41 }
42
--- test/merge3.test
+++ test/merge3.test
@@ -20,11 +20,11 @@
2020
2121
proc merge-test {testid basis v1 v2 result} {
2222
write_file t1 [join [string trim $basis] \n]\n
2323
write_file t2 [join [string trim $v1] \n]\n
2424
write_file t3 [join [string trim $v2] \n]\n
25
- fossil test-3-way-merge t1 t2 t3 t4
25
+ fossil 3-way-merge t1 t2 t3 t4
2626
set x [read_file t4]
2727
regsub -all {<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+} $x \
2828
{MINE:} x
2929
regsub -all {======= COMMON ANCESTOR content follows =+} $x {COM:} x
3030
regsub -all {======= MERGED IN content follows =+} $x {YOURS:} x
3131
--- test/merge3.test
+++ test/merge3.test
@@ -20,11 +20,11 @@
20
21 proc merge-test {testid basis v1 v2 result} {
22 write_file t1 [join [string trim $basis] \n]\n
23 write_file t2 [join [string trim $v1] \n]\n
24 write_file t3 [join [string trim $v2] \n]\n
25 fossil test-3-way-merge t1 t2 t3 t4
26 set x [read_file t4]
27 regsub -all {<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+} $x \
28 {MINE:} x
29 regsub -all {======= COMMON ANCESTOR content follows =+} $x {COM:} x
30 regsub -all {======= MERGED IN content follows =+} $x {YOURS:} x
31
--- test/merge3.test
+++ test/merge3.test
@@ -20,11 +20,11 @@
20
21 proc merge-test {testid basis v1 v2 result} {
22 write_file t1 [join [string trim $basis] \n]\n
23 write_file t2 [join [string trim $v1] \n]\n
24 write_file t3 [join [string trim $v2] \n]\n
25 fossil 3-way-merge t1 t2 t3 t4
26 set x [read_file t4]
27 regsub -all {<<<<<<< BEGIN MERGE CONFLICT: local copy shown first <+} $x \
28 {MINE:} x
29 regsub -all {======= COMMON ANCESTOR content follows =+} $x {COM:} x
30 regsub -all {======= MERGED IN content follows =+} $x {YOURS:} x
31
--- test/merge4.test
+++ test/merge4.test
@@ -20,12 +20,12 @@
2020
2121
proc merge-test {testid basis v1 v2 result1 result2} {
2222
write_file t1 [join [string trim $basis] \n]\n
2323
write_file t2 [join [string trim $v1] \n]\n
2424
write_file t3 [join [string trim $v2] \n]\n
25
- fossil test-3-way-merge t1 t2 t3 t4
26
- fossil test-3-way-merge t1 t3 t2 t5
25
+ fossil 3-way-merge t1 t2 t3 t4
26
+ fossil 3-way-merge t1 t3 t2 t5
2727
set x [read_file t4]
2828
regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $x {>} x
2929
regsub -all {=======.*=======} $x {=} x
3030
regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
3131
set x [split [string trim $x] \n]
3232
--- test/merge4.test
+++ test/merge4.test
@@ -20,12 +20,12 @@
20
21 proc merge-test {testid basis v1 v2 result1 result2} {
22 write_file t1 [join [string trim $basis] \n]\n
23 write_file t2 [join [string trim $v1] \n]\n
24 write_file t3 [join [string trim $v2] \n]\n
25 fossil test-3-way-merge t1 t2 t3 t4
26 fossil test-3-way-merge t1 t3 t2 t5
27 set x [read_file t4]
28 regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $x {>} x
29 regsub -all {=======.*=======} $x {=} x
30 regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
31 set x [split [string trim $x] \n]
32
--- test/merge4.test
+++ test/merge4.test
@@ -20,12 +20,12 @@
20
21 proc merge-test {testid basis v1 v2 result1 result2} {
22 write_file t1 [join [string trim $basis] \n]\n
23 write_file t2 [join [string trim $v1] \n]\n
24 write_file t3 [join [string trim $v2] \n]\n
25 fossil 3-way-merge t1 t2 t3 t4
26 fossil 3-way-merge t1 t3 t2 t5
27 set x [read_file t4]
28 regsub -all {<<<<<<< BEGIN MERGE CONFLICT.*<<} $x {>} x
29 regsub -all {=======.*=======} $x {=} x
30 regsub -all {>>>>>>> END MERGE CONFLICT.*>>>>} $x {<} x
31 set x [split [string trim $x] \n]
32
+10 -4
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
2626
TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
2727
LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
2828
2929
SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
3030
31
-SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
31
+SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
3232
33
-OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
33
+OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
3434
3535
3636
RC=$(DMDIR)\bin\rcc
3737
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
3838
@@ -46,11 +46,11 @@
4646
4747
$(OBJDIR)\fossil.res: $B\win\fossil.rc
4848
$(RC) $(RCFLAGS) -o$@ $**
4949
5050
$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51
- +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
51
+ +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
5252
+echo fossil >> $@
5353
+echo fossil >> $@
5454
+echo $(LIBS) >> $@
5555
+echo. >> $@
5656
+echo fossil >> $@
@@ -440,10 +440,16 @@
440440
$(OBJDIR)\login$O : login_.c login.h
441441
$(TCC) -o$@ -c login_.c
442442
443443
login_.c : $(SRCDIR)\login.c
444444
+translate$E $** > $@
445
+
446
+$(OBJDIR)\lookslike$O : lookslike_.c lookslike.h
447
+ $(TCC) -o$@ -c lookslike_.c
448
+
449
+lookslike_.c : $(SRCDIR)\lookslike.c
450
+ +translate$E $** > $@
445451
446452
$(OBJDIR)\main$O : main_.c main.h
447453
$(TCC) -o$@ -c main_.c
448454
449455
main_.c : $(SRCDIR)\main.c
@@ -748,7 +754,7 @@
748754
749755
zip_.c : $(SRCDIR)\zip.c
750756
+translate$E $** > $@
751757
752758
headers: makeheaders$E page_index.h VERSION.h
753
- +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
759
+ +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
754760
@copy /Y nul: headers
755761
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
30
31 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
32
33 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
34
35
36 RC=$(DMDIR)\bin\rcc
37 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
38
@@ -46,11 +46,11 @@
46
47 $(OBJDIR)\fossil.res: $B\win\fossil.rc
48 $(RC) $(RCFLAGS) -o$@ $**
49
50 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51 +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
52 +echo fossil >> $@
53 +echo fossil >> $@
54 +echo $(LIBS) >> $@
55 +echo. >> $@
56 +echo fossil >> $@
@@ -440,10 +440,16 @@
440 $(OBJDIR)\login$O : login_.c login.h
441 $(TCC) -o$@ -c login_.c
442
443 login_.c : $(SRCDIR)\login.c
444 +translate$E $** > $@
 
 
 
 
 
 
445
446 $(OBJDIR)\main$O : main_.c main.h
447 $(TCC) -o$@ -c main_.c
448
449 main_.c : $(SRCDIR)\main.c
@@ -748,7 +754,7 @@
748
749 zip_.c : $(SRCDIR)\zip.c
750 +translate$E $** > $@
751
752 headers: makeheaders$E page_index.h VERSION.h
753 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
754 @copy /Y nul: headers
755
--- win/Makefile.dmc
+++ win/Makefile.dmc
@@ -26,13 +26,13 @@
26 TCC = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
27 LIBS = $(DMDIR)\extra\lib\ zlib wsock32 advapi32
28
29 SQLITE_OPTIONS = -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT3 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0
30
31 SRC = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c
32
33 OBJ = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O
34
35
36 RC=$(DMDIR)\bin\rcc
37 RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__
38
@@ -46,11 +46,11 @@
46
47 $(OBJDIR)\fossil.res: $B\win\fossil.rc
48 $(RC) $(RCFLAGS) -o$@ $**
49
50 $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
51 +echo add allrepo attach bag bisect blob branch browse captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
52 +echo fossil >> $@
53 +echo fossil >> $@
54 +echo $(LIBS) >> $@
55 +echo. >> $@
56 +echo fossil >> $@
@@ -440,10 +440,16 @@
440 $(OBJDIR)\login$O : login_.c login.h
441 $(TCC) -o$@ -c login_.c
442
443 login_.c : $(SRCDIR)\login.c
444 +translate$E $** > $@
445
446 $(OBJDIR)\lookslike$O : lookslike_.c lookslike.h
447 $(TCC) -o$@ -c lookslike_.c
448
449 lookslike_.c : $(SRCDIR)\lookslike.c
450 +translate$E $** > $@
451
452 $(OBJDIR)\main$O : main_.c main.h
453 $(TCC) -o$@ -c main_.c
454
455 main_.c : $(SRCDIR)\main.c
@@ -748,7 +754,7 @@
754
755 zip_.c : $(SRCDIR)\zip.c
756 +translate$E $** > $@
757
758 headers: makeheaders$E page_index.h VERSION.h
759 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
760 @copy /Y nul: headers
761
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -298,10 +298,11 @@
298298
$(SRCDIR)/json_timeline.c \
299299
$(SRCDIR)/json_user.c \
300300
$(SRCDIR)/json_wiki.c \
301301
$(SRCDIR)/leaf.c \
302302
$(SRCDIR)/login.c \
303
+ $(SRCDIR)/lookslike.c \
303304
$(SRCDIR)/main.c \
304305
$(SRCDIR)/manifest.c \
305306
$(SRCDIR)/markdown.c \
306307
$(SRCDIR)/markdown_html.c \
307308
$(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
406407
$(OBJDIR)/json_timeline_.c \
407408
$(OBJDIR)/json_user_.c \
408409
$(OBJDIR)/json_wiki_.c \
409410
$(OBJDIR)/leaf_.c \
410411
$(OBJDIR)/login_.c \
412
+ $(OBJDIR)/lookslike_.c \
411413
$(OBJDIR)/main_.c \
412414
$(OBJDIR)/manifest_.c \
413415
$(OBJDIR)/markdown_.c \
414416
$(OBJDIR)/markdown_html_.c \
415417
$(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
514516
$(OBJDIR)/json_timeline.o \
515517
$(OBJDIR)/json_user.o \
516518
$(OBJDIR)/json_wiki.o \
517519
$(OBJDIR)/leaf.o \
518520
$(OBJDIR)/login.o \
521
+ $(OBJDIR)/lookslike.o \
519522
$(OBJDIR)/main.o \
520523
$(OBJDIR)/manifest.o \
521524
$(OBJDIR)/markdown.o \
522525
$(OBJDIR)/markdown_html.o \
523526
$(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
735738
$(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
736739
$(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
737740
$(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
738741
$(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
739742
$(OBJDIR)/login_.c:$(OBJDIR)/login.h \
743
+ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \
740744
$(OBJDIR)/main_.c:$(OBJDIR)/main.h \
741745
$(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
742746
$(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
743747
$(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
744748
$(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
12341238
12351239
$(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
12361240
$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
12371241
12381242
$(OBJDIR)/login.h: $(OBJDIR)/headers
1243
+
1244
+$(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
1245
+ $(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
1246
+
1247
+$(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
1248
+ $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
1249
+
1250
+$(OBJDIR)/lookslike.h: $(OBJDIR)/headers
12391251
12401252
$(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
12411253
$(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
12421254
12431255
$(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
12441256
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -298,10 +298,11 @@
298 $(SRCDIR)/json_timeline.c \
299 $(SRCDIR)/json_user.c \
300 $(SRCDIR)/json_wiki.c \
301 $(SRCDIR)/leaf.c \
302 $(SRCDIR)/login.c \
 
303 $(SRCDIR)/main.c \
304 $(SRCDIR)/manifest.c \
305 $(SRCDIR)/markdown.c \
306 $(SRCDIR)/markdown_html.c \
307 $(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
406 $(OBJDIR)/json_timeline_.c \
407 $(OBJDIR)/json_user_.c \
408 $(OBJDIR)/json_wiki_.c \
409 $(OBJDIR)/leaf_.c \
410 $(OBJDIR)/login_.c \
 
411 $(OBJDIR)/main_.c \
412 $(OBJDIR)/manifest_.c \
413 $(OBJDIR)/markdown_.c \
414 $(OBJDIR)/markdown_html_.c \
415 $(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
514 $(OBJDIR)/json_timeline.o \
515 $(OBJDIR)/json_user.o \
516 $(OBJDIR)/json_wiki.o \
517 $(OBJDIR)/leaf.o \
518 $(OBJDIR)/login.o \
 
519 $(OBJDIR)/main.o \
520 $(OBJDIR)/manifest.o \
521 $(OBJDIR)/markdown.o \
522 $(OBJDIR)/markdown_html.o \
523 $(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
735 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
736 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
737 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
738 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
739 $(OBJDIR)/login_.c:$(OBJDIR)/login.h \
 
740 $(OBJDIR)/main_.c:$(OBJDIR)/main.h \
741 $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
742 $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
743 $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
744 $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
1234
1235 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
1236 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
1237
1238 $(OBJDIR)/login.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1239
1240 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
1241 $(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
1242
1243 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
1244
--- win/Makefile.mingw
+++ win/Makefile.mingw
@@ -298,10 +298,11 @@
298 $(SRCDIR)/json_timeline.c \
299 $(SRCDIR)/json_user.c \
300 $(SRCDIR)/json_wiki.c \
301 $(SRCDIR)/leaf.c \
302 $(SRCDIR)/login.c \
303 $(SRCDIR)/lookslike.c \
304 $(SRCDIR)/main.c \
305 $(SRCDIR)/manifest.c \
306 $(SRCDIR)/markdown.c \
307 $(SRCDIR)/markdown_html.c \
308 $(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
407 $(OBJDIR)/json_timeline_.c \
408 $(OBJDIR)/json_user_.c \
409 $(OBJDIR)/json_wiki_.c \
410 $(OBJDIR)/leaf_.c \
411 $(OBJDIR)/login_.c \
412 $(OBJDIR)/lookslike_.c \
413 $(OBJDIR)/main_.c \
414 $(OBJDIR)/manifest_.c \
415 $(OBJDIR)/markdown_.c \
416 $(OBJDIR)/markdown_html_.c \
417 $(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
516 $(OBJDIR)/json_timeline.o \
517 $(OBJDIR)/json_user.o \
518 $(OBJDIR)/json_wiki.o \
519 $(OBJDIR)/leaf.o \
520 $(OBJDIR)/login.o \
521 $(OBJDIR)/lookslike.o \
522 $(OBJDIR)/main.o \
523 $(OBJDIR)/manifest.o \
524 $(OBJDIR)/markdown.o \
525 $(OBJDIR)/markdown_html.o \
526 $(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
738 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
739 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
740 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
741 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
742 $(OBJDIR)/login_.c:$(OBJDIR)/login.h \
743 $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \
744 $(OBJDIR)/main_.c:$(OBJDIR)/main.h \
745 $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
746 $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
747 $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
748 $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
1238
1239 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
1240 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
1241
1242 $(OBJDIR)/login.h: $(OBJDIR)/headers
1243
1244 $(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
1245 $(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
1246
1247 $(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
1248 $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
1249
1250 $(OBJDIR)/lookslike.h: $(OBJDIR)/headers
1251
1252 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
1253 $(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
1254
1255 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
1256
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -298,10 +298,11 @@
298298
$(SRCDIR)/json_timeline.c \
299299
$(SRCDIR)/json_user.c \
300300
$(SRCDIR)/json_wiki.c \
301301
$(SRCDIR)/leaf.c \
302302
$(SRCDIR)/login.c \
303
+ $(SRCDIR)/lookslike.c \
303304
$(SRCDIR)/main.c \
304305
$(SRCDIR)/manifest.c \
305306
$(SRCDIR)/markdown.c \
306307
$(SRCDIR)/markdown_html.c \
307308
$(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
406407
$(OBJDIR)/json_timeline_.c \
407408
$(OBJDIR)/json_user_.c \
408409
$(OBJDIR)/json_wiki_.c \
409410
$(OBJDIR)/leaf_.c \
410411
$(OBJDIR)/login_.c \
412
+ $(OBJDIR)/lookslike_.c \
411413
$(OBJDIR)/main_.c \
412414
$(OBJDIR)/manifest_.c \
413415
$(OBJDIR)/markdown_.c \
414416
$(OBJDIR)/markdown_html_.c \
415417
$(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
514516
$(OBJDIR)/json_timeline.o \
515517
$(OBJDIR)/json_user.o \
516518
$(OBJDIR)/json_wiki.o \
517519
$(OBJDIR)/leaf.o \
518520
$(OBJDIR)/login.o \
521
+ $(OBJDIR)/lookslike.o \
519522
$(OBJDIR)/main.o \
520523
$(OBJDIR)/manifest.o \
521524
$(OBJDIR)/markdown.o \
522525
$(OBJDIR)/markdown_html.o \
523526
$(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
735738
$(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
736739
$(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
737740
$(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
738741
$(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
739742
$(OBJDIR)/login_.c:$(OBJDIR)/login.h \
743
+ $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \
740744
$(OBJDIR)/main_.c:$(OBJDIR)/main.h \
741745
$(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
742746
$(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
743747
$(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
744748
$(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
12341238
12351239
$(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
12361240
$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
12371241
12381242
$(OBJDIR)/login.h: $(OBJDIR)/headers
1243
+
1244
+$(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
1245
+ $(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
1246
+
1247
+$(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
1248
+ $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
1249
+
1250
+$(OBJDIR)/lookslike.h: $(OBJDIR)/headers
12391251
12401252
$(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
12411253
$(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
12421254
12431255
$(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
12441256
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -298,10 +298,11 @@
298 $(SRCDIR)/json_timeline.c \
299 $(SRCDIR)/json_user.c \
300 $(SRCDIR)/json_wiki.c \
301 $(SRCDIR)/leaf.c \
302 $(SRCDIR)/login.c \
 
303 $(SRCDIR)/main.c \
304 $(SRCDIR)/manifest.c \
305 $(SRCDIR)/markdown.c \
306 $(SRCDIR)/markdown_html.c \
307 $(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
406 $(OBJDIR)/json_timeline_.c \
407 $(OBJDIR)/json_user_.c \
408 $(OBJDIR)/json_wiki_.c \
409 $(OBJDIR)/leaf_.c \
410 $(OBJDIR)/login_.c \
 
411 $(OBJDIR)/main_.c \
412 $(OBJDIR)/manifest_.c \
413 $(OBJDIR)/markdown_.c \
414 $(OBJDIR)/markdown_html_.c \
415 $(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
514 $(OBJDIR)/json_timeline.o \
515 $(OBJDIR)/json_user.o \
516 $(OBJDIR)/json_wiki.o \
517 $(OBJDIR)/leaf.o \
518 $(OBJDIR)/login.o \
 
519 $(OBJDIR)/main.o \
520 $(OBJDIR)/manifest.o \
521 $(OBJDIR)/markdown.o \
522 $(OBJDIR)/markdown_html.o \
523 $(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
735 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
736 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
737 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
738 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
739 $(OBJDIR)/login_.c:$(OBJDIR)/login.h \
 
740 $(OBJDIR)/main_.c:$(OBJDIR)/main.h \
741 $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
742 $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
743 $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
744 $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
1234
1235 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
1236 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
1237
1238 $(OBJDIR)/login.h: $(OBJDIR)/headers
 
 
 
 
 
 
 
 
1239
1240 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
1241 $(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
1242
1243 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
1244
--- win/Makefile.mingw.mistachkin
+++ win/Makefile.mingw.mistachkin
@@ -298,10 +298,11 @@
298 $(SRCDIR)/json_timeline.c \
299 $(SRCDIR)/json_user.c \
300 $(SRCDIR)/json_wiki.c \
301 $(SRCDIR)/leaf.c \
302 $(SRCDIR)/login.c \
303 $(SRCDIR)/lookslike.c \
304 $(SRCDIR)/main.c \
305 $(SRCDIR)/manifest.c \
306 $(SRCDIR)/markdown.c \
307 $(SRCDIR)/markdown_html.c \
308 $(SRCDIR)/md5.c \
@@ -406,10 +407,11 @@
407 $(OBJDIR)/json_timeline_.c \
408 $(OBJDIR)/json_user_.c \
409 $(OBJDIR)/json_wiki_.c \
410 $(OBJDIR)/leaf_.c \
411 $(OBJDIR)/login_.c \
412 $(OBJDIR)/lookslike_.c \
413 $(OBJDIR)/main_.c \
414 $(OBJDIR)/manifest_.c \
415 $(OBJDIR)/markdown_.c \
416 $(OBJDIR)/markdown_html_.c \
417 $(OBJDIR)/md5_.c \
@@ -514,10 +516,11 @@
516 $(OBJDIR)/json_timeline.o \
517 $(OBJDIR)/json_user.o \
518 $(OBJDIR)/json_wiki.o \
519 $(OBJDIR)/leaf.o \
520 $(OBJDIR)/login.o \
521 $(OBJDIR)/lookslike.o \
522 $(OBJDIR)/main.o \
523 $(OBJDIR)/manifest.o \
524 $(OBJDIR)/markdown.o \
525 $(OBJDIR)/markdown_html.o \
526 $(OBJDIR)/md5.o \
@@ -735,10 +738,11 @@
738 $(OBJDIR)/json_timeline_.c:$(OBJDIR)/json_timeline.h \
739 $(OBJDIR)/json_user_.c:$(OBJDIR)/json_user.h \
740 $(OBJDIR)/json_wiki_.c:$(OBJDIR)/json_wiki.h \
741 $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h \
742 $(OBJDIR)/login_.c:$(OBJDIR)/login.h \
743 $(OBJDIR)/lookslike_.c:$(OBJDIR)/lookslike.h \
744 $(OBJDIR)/main_.c:$(OBJDIR)/main.h \
745 $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h \
746 $(OBJDIR)/markdown_.c:$(OBJDIR)/markdown.h \
747 $(OBJDIR)/markdown_html_.c:$(OBJDIR)/markdown_html.h \
748 $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h \
@@ -1234,10 +1238,18 @@
1238
1239 $(OBJDIR)/login.o: $(OBJDIR)/login_.c $(OBJDIR)/login.h $(SRCDIR)/config.h
1240 $(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c
1241
1242 $(OBJDIR)/login.h: $(OBJDIR)/headers
1243
1244 $(OBJDIR)/lookslike_.c: $(SRCDIR)/lookslike.c $(OBJDIR)/translate
1245 $(TRANSLATE) $(SRCDIR)/lookslike.c >$(OBJDIR)/lookslike_.c
1246
1247 $(OBJDIR)/lookslike.o: $(OBJDIR)/lookslike_.c $(OBJDIR)/lookslike.h $(SRCDIR)/config.h
1248 $(XTCC) -o $(OBJDIR)/lookslike.o -c $(OBJDIR)/lookslike_.c
1249
1250 $(OBJDIR)/lookslike.h: $(OBJDIR)/headers
1251
1252 $(OBJDIR)/main_.c: $(SRCDIR)/main.c $(OBJDIR)/translate
1253 $(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c
1254
1255 $(OBJDIR)/main.o: $(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
1256
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,10 +116,11 @@
116116
json_timeline_.c \
117117
json_user_.c \
118118
json_wiki_.c \
119119
leaf_.c \
120120
login_.c \
121
+ lookslike_.c \
121122
main_.c \
122123
manifest_.c \
123124
markdown_.c \
124125
markdown_html_.c \
125126
md5_.c \
@@ -224,10 +225,11 @@
224225
$(OX)\json_timeline$O \
225226
$(OX)\json_user$O \
226227
$(OX)\json_wiki$O \
227228
$(OX)\leaf$O \
228229
$(OX)\login$O \
230
+ $(OX)\lookslike$O \
229231
$(OX)\main$O \
230232
$(OX)\manifest$O \
231233
$(OX)\markdown$O \
232234
$(OX)\markdown_html$O \
233235
$(OX)\md5$O \
@@ -350,10 +352,11 @@
350352
echo $(OX)\json_timeline.obj >> $@
351353
echo $(OX)\json_user.obj >> $@
352354
echo $(OX)\json_wiki.obj >> $@
353355
echo $(OX)\leaf.obj >> $@
354356
echo $(OX)\login.obj >> $@
357
+ echo $(OX)\lookslike.obj >> $@
355358
echo $(OX)\main.obj >> $@
356359
echo $(OX)\manifest.obj >> $@
357360
echo $(OX)\markdown.obj >> $@
358361
echo $(OX)\markdown_html.obj >> $@
359362
echo $(OX)\md5.obj >> $@
@@ -809,10 +812,16 @@
809812
$(OX)\login$O : login_.c login.h
810813
$(TCC) /Fo$@ -c login_.c
811814
812815
login_.c : $(SRCDIR)\login.c
813816
translate$E $** > $@
817
+
818
+$(OX)\lookslike$O : lookslike_.c lookslike.h
819
+ $(TCC) /Fo$@ -c lookslike_.c
820
+
821
+lookslike_.c : $(SRCDIR)\lookslike.c
822
+ translate$E $** > $@
814823
815824
$(OX)\main$O : main_.c main.h
816825
$(TCC) /Fo$@ -c main_.c
817826
818827
main_.c : $(SRCDIR)\main.c
@@ -1174,10 +1183,11 @@
11741183
json_timeline_.c:json_timeline.h \
11751184
json_user_.c:json_user.h \
11761185
json_wiki_.c:json_wiki.h \
11771186
leaf_.c:leaf.h \
11781187
login_.c:login.h \
1188
+ lookslike_.c:lookslike.h \
11791189
main_.c:main.h \
11801190
manifest_.c:manifest.h \
11811191
markdown_.c:markdown.h \
11821192
markdown_html_.c:markdown_html.h \
11831193
md5_.c:md5.h \
11841194
11851195
ADDED www/adding_code.wiki
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,10 +116,11 @@
116 json_timeline_.c \
117 json_user_.c \
118 json_wiki_.c \
119 leaf_.c \
120 login_.c \
 
121 main_.c \
122 manifest_.c \
123 markdown_.c \
124 markdown_html_.c \
125 md5_.c \
@@ -224,10 +225,11 @@
224 $(OX)\json_timeline$O \
225 $(OX)\json_user$O \
226 $(OX)\json_wiki$O \
227 $(OX)\leaf$O \
228 $(OX)\login$O \
 
229 $(OX)\main$O \
230 $(OX)\manifest$O \
231 $(OX)\markdown$O \
232 $(OX)\markdown_html$O \
233 $(OX)\md5$O \
@@ -350,10 +352,11 @@
350 echo $(OX)\json_timeline.obj >> $@
351 echo $(OX)\json_user.obj >> $@
352 echo $(OX)\json_wiki.obj >> $@
353 echo $(OX)\leaf.obj >> $@
354 echo $(OX)\login.obj >> $@
 
355 echo $(OX)\main.obj >> $@
356 echo $(OX)\manifest.obj >> $@
357 echo $(OX)\markdown.obj >> $@
358 echo $(OX)\markdown_html.obj >> $@
359 echo $(OX)\md5.obj >> $@
@@ -809,10 +812,16 @@
809 $(OX)\login$O : login_.c login.h
810 $(TCC) /Fo$@ -c login_.c
811
812 login_.c : $(SRCDIR)\login.c
813 translate$E $** > $@
 
 
 
 
 
 
814
815 $(OX)\main$O : main_.c main.h
816 $(TCC) /Fo$@ -c main_.c
817
818 main_.c : $(SRCDIR)\main.c
@@ -1174,10 +1183,11 @@
1174 json_timeline_.c:json_timeline.h \
1175 json_user_.c:json_user.h \
1176 json_wiki_.c:json_wiki.h \
1177 leaf_.c:leaf.h \
1178 login_.c:login.h \
 
1179 main_.c:main.h \
1180 manifest_.c:manifest.h \
1181 markdown_.c:markdown.h \
1182 markdown_html_.c:markdown_html.h \
1183 md5_.c:md5.h \
1184
1185 DDED www/adding_code.wiki
--- win/Makefile.msc
+++ win/Makefile.msc
@@ -116,10 +116,11 @@
116 json_timeline_.c \
117 json_user_.c \
118 json_wiki_.c \
119 leaf_.c \
120 login_.c \
121 lookslike_.c \
122 main_.c \
123 manifest_.c \
124 markdown_.c \
125 markdown_html_.c \
126 md5_.c \
@@ -224,10 +225,11 @@
225 $(OX)\json_timeline$O \
226 $(OX)\json_user$O \
227 $(OX)\json_wiki$O \
228 $(OX)\leaf$O \
229 $(OX)\login$O \
230 $(OX)\lookslike$O \
231 $(OX)\main$O \
232 $(OX)\manifest$O \
233 $(OX)\markdown$O \
234 $(OX)\markdown_html$O \
235 $(OX)\md5$O \
@@ -350,10 +352,11 @@
352 echo $(OX)\json_timeline.obj >> $@
353 echo $(OX)\json_user.obj >> $@
354 echo $(OX)\json_wiki.obj >> $@
355 echo $(OX)\leaf.obj >> $@
356 echo $(OX)\login.obj >> $@
357 echo $(OX)\lookslike.obj >> $@
358 echo $(OX)\main.obj >> $@
359 echo $(OX)\manifest.obj >> $@
360 echo $(OX)\markdown.obj >> $@
361 echo $(OX)\markdown_html.obj >> $@
362 echo $(OX)\md5.obj >> $@
@@ -809,10 +812,16 @@
812 $(OX)\login$O : login_.c login.h
813 $(TCC) /Fo$@ -c login_.c
814
815 login_.c : $(SRCDIR)\login.c
816 translate$E $** > $@
817
818 $(OX)\lookslike$O : lookslike_.c lookslike.h
819 $(TCC) /Fo$@ -c lookslike_.c
820
821 lookslike_.c : $(SRCDIR)\lookslike.c
822 translate$E $** > $@
823
824 $(OX)\main$O : main_.c main.h
825 $(TCC) /Fo$@ -c main_.c
826
827 main_.c : $(SRCDIR)\main.c
@@ -1174,10 +1183,11 @@
1183 json_timeline_.c:json_timeline.h \
1184 json_user_.c:json_user.h \
1185 json_wiki_.c:json_wiki.h \
1186 leaf_.c:leaf.h \
1187 login_.c:login.h \
1188 lookslike_.c:lookslike.h \
1189 main_.c:main.h \
1190 manifest_.c:manifest.h \
1191 markdown_.c:markdown.h \
1192 markdown_html_.c:markdown_html.h \
1193 md5_.c:md5.h \
1194
1195 DDED www/adding_code.wiki
--- a/www/adding_code.wiki
+++ b/www/adding_code.wiki
@@ -0,0 +1 @@
1
+at the
--- a/www/adding_code.wiki
+++ b/www/adding_code.wiki
@@ -0,0 +1 @@
 
--- a/www/adding_code.wiki
+++ b/www/adding_code.wiki
@@ -0,0 +1 @@
1 at the
--- www/build.wiki
+++ www/build.wiki
@@ -122,10 +122,17 @@
122122
you, or for some other reason you want to know how to build
123123
Fossil manually, then refer to the
124124
[./makefile.wiki | Fossil Build Process] document which describes
125125
in detail what the makefiles do behind the scenes.
126126
127
+<li><p>
128
+ The fossil executable is self-contained and stand-alone and usually
129
+ requires no special libraries or other software to be installed. However,
130
+ the "--tk" option to the [/help/diff|diff command] requires that Tcl/Tk
131
+ be installed on the local machine. You can get Tcl/Tk from
132
+ [http://www.activestate.com/activetcl|ActiveState].
133
+
127134
<li><p>
128135
To build on older Macs (circa 2002, MacOS 10.2) edit the Makefile
129136
generated by configure to add the following lines:
130137
<blockquote><pre>
131138
TCC += -DSQLITE_WITHOUT_ZONEMALLOC
132139
--- www/build.wiki
+++ www/build.wiki
@@ -122,10 +122,17 @@
122 you, or for some other reason you want to know how to build
123 Fossil manually, then refer to the
124 [./makefile.wiki | Fossil Build Process] document which describes
125 in detail what the makefiles do behind the scenes.
126
 
 
 
 
 
 
 
127 <li><p>
128 To build on older Macs (circa 2002, MacOS 10.2) edit the Makefile
129 generated by configure to add the following lines:
130 <blockquote><pre>
131 TCC += -DSQLITE_WITHOUT_ZONEMALLOC
132
--- www/build.wiki
+++ www/build.wiki
@@ -122,10 +122,17 @@
122 you, or for some other reason you want to know how to build
123 Fossil manually, then refer to the
124 [./makefile.wiki | Fossil Build Process] document which describes
125 in detail what the makefiles do behind the scenes.
126
127 <li><p>
128 The fossil executable is self-contained and stand-alone and usually
129 requires no special libraries or other software to be installed. However,
130 the "--tk" option to the [/help/diff|diff command] requires that Tcl/Tk
131 be installed on the local machine. You can get Tcl/Tk from
132 [http://www.activestate.com/activetcl|ActiveState].
133
134 <li><p>
135 To build on older Macs (circa 2002, MacOS 10.2) edit the Makefile
136 generated by configure to add the following lines:
137 <blockquote><pre>
138 TCC += -DSQLITE_WITHOUT_ZONEMALLOC
139
--- www/changes.wiki
+++ www/changes.wiki
@@ -3,10 +3,16 @@
33
<h2>Changes For Version 1.27 (as yet unreleased)</h2>
44
* Enhance the [/help?cmd=changes | fossil changes],
55
[/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
66
[/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
77
to restrict operation to files and directories named on the command-line.
8
+ * New --integrate option to [/help?cmd=merge | fossil merge], which
9
+ automatically closes the merged branch when committing.
10
+ * Renamed <tt>/stats_report</tt> page to [/reports]. Graph width is now
11
+ relative, not absolute.
12
+ * Added <tt>yw=YYYY-WW</tt> (year-week) filter to timeline to limit the results
13
+ to a specific year and calendar week number, e.g. [/timeline?yw=2013-01].
814
915
<h2>Changes For Version 1.26 (2013-06-18)</h2>
1016
* The argument to the --port option for the [/help?cmd=ui | fossil ui] and
1117
[/help?cmd=server | fossil server] commands can take an IP address in addition
1218
to the port number, causing Fossil to bind to just that one IP address.
1319
--- www/changes.wiki
+++ www/changes.wiki
@@ -3,10 +3,16 @@
3 <h2>Changes For Version 1.27 (as yet unreleased)</h2>
4 * Enhance the [/help?cmd=changes | fossil changes],
5 [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
6 [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
7 to restrict operation to files and directories named on the command-line.
 
 
 
 
 
 
8
9 <h2>Changes For Version 1.26 (2013-06-18)</h2>
10 * The argument to the --port option for the [/help?cmd=ui | fossil ui] and
11 [/help?cmd=server | fossil server] commands can take an IP address in addition
12 to the port number, causing Fossil to bind to just that one IP address.
13
--- www/changes.wiki
+++ www/changes.wiki
@@ -3,10 +3,16 @@
3 <h2>Changes For Version 1.27 (as yet unreleased)</h2>
4 * Enhance the [/help?cmd=changes | fossil changes],
5 [/help?cmd=clean | fossil clean], [/help?cmd=extras | fossil extras],
6 [/help?cmd=ls | fossil ls] and [/help?cmd=status | fossil status] commands
7 to restrict operation to files and directories named on the command-line.
8 * New --integrate option to [/help?cmd=merge | fossil merge], which
9 automatically closes the merged branch when committing.
10 * Renamed <tt>/stats_report</tt> page to [/reports]. Graph width is now
11 relative, not absolute.
12 * Added <tt>yw=YYYY-WW</tt> (year-week) filter to timeline to limit the results
13 to a specific year and calendar week number, e.g. [/timeline?yw=2013-01].
14
15 <h2>Changes For Version 1.26 (2013-06-18)</h2>
16 * The argument to the --port option for the [/help?cmd=ui | fossil ui] and
17 [/help?cmd=server | fossil server] commands can take an IP address in addition
18 to the port number, causing Fossil to bind to just that one IP address.
19
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -78,5 +78,6 @@
7878
<h2>5.0 See Also</h2>
7979
8080
* [./build.wiki | How To Compile And Install Fossil]
8181
* [./makefile.wiki | The Fossil Build Process]
8282
* [./tech_overview.wiki | A Technical Overview of Fossil]
83
+ * [./adding_code.wiki | Adding Features To Fossil]
8384
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -78,5 +78,6 @@
78 <h2>5.0 See Also</h2>
79
80 * [./build.wiki | How To Compile And Install Fossil]
81 * [./makefile.wiki | The Fossil Build Process]
82 * [./tech_overview.wiki | A Technical Overview of Fossil]
 
83
--- www/contribute.wiki
+++ www/contribute.wiki
@@ -78,5 +78,6 @@
78 <h2>5.0 See Also</h2>
79
80 * [./build.wiki | How To Compile And Install Fossil]
81 * [./makefile.wiki | The Fossil Build Process]
82 * [./tech_overview.wiki | A Technical Overview of Fossil]
83 * [./adding_code.wiki | Adding Features To Fossil]
84
+4 -4
--- www/faq.tcl
+++ www/faq.tcl
@@ -37,13 +37,11 @@
3737
} {
3838
There are lots of ways:
3939
4040
When you are checking in a new change using the <b>[/help/commit|commit]</b>
4141
command, you can add the option "--branch <i>BRANCH-NAME</i>" to
42
- make the new check-in be the first check-in for a new branch. You can
43
- also add the "--bgcolor <i>COLOR</i>" option to give the branch a
44
- specific background color on timelines.
42
+ make the new check-in be the first check-in for a new branch.
4543
4644
If you want to create a new branch whose initial content is the
4745
same as an existing check-in, use this command:
4846
4947
<blockquote>
@@ -70,11 +68,13 @@
7068
} {
7169
There are several ways:
7270
7371
When you are checking in a new change using the <b>[/help/commit|commit]</b>
7472
command, you can add a tag to that check-in using the
75
- "--tag <i>TAGNAME</i>" command-line option.
73
+ "--tag <i>TAGNAME</i>" command-line option. You can repeat the --tag
74
+ option to give a check-in multiple tags. Tags need not be unique. So,
75
+ for example, it is common to give every released version a "release" tag.
7676
7777
If you want add a tag to an existing check-in, you can use the
7878
<b>[/help/tag|tag]</b> command. For example:
7979
8080
<blockquote>
8181
--- www/faq.tcl
+++ www/faq.tcl
@@ -37,13 +37,11 @@
37 } {
38 There are lots of ways:
39
40 When you are checking in a new change using the <b>[/help/commit|commit]</b>
41 command, you can add the option "--branch <i>BRANCH-NAME</i>" to
42 make the new check-in be the first check-in for a new branch. You can
43 also add the "--bgcolor <i>COLOR</i>" option to give the branch a
44 specific background color on timelines.
45
46 If you want to create a new branch whose initial content is the
47 same as an existing check-in, use this command:
48
49 <blockquote>
@@ -70,11 +68,13 @@
70 } {
71 There are several ways:
72
73 When you are checking in a new change using the <b>[/help/commit|commit]</b>
74 command, you can add a tag to that check-in using the
75 "--tag <i>TAGNAME</i>" command-line option.
 
 
76
77 If you want add a tag to an existing check-in, you can use the
78 <b>[/help/tag|tag]</b> command. For example:
79
80 <blockquote>
81
--- www/faq.tcl
+++ www/faq.tcl
@@ -37,13 +37,11 @@
37 } {
38 There are lots of ways:
39
40 When you are checking in a new change using the <b>[/help/commit|commit]</b>
41 command, you can add the option "--branch <i>BRANCH-NAME</i>" to
42 make the new check-in be the first check-in for a new branch.
 
 
43
44 If you want to create a new branch whose initial content is the
45 same as an existing check-in, use this command:
46
47 <blockquote>
@@ -70,11 +68,13 @@
68 } {
69 There are several ways:
70
71 When you are checking in a new change using the <b>[/help/commit|commit]</b>
72 command, you can add a tag to that check-in using the
73 "--tag <i>TAGNAME</i>" command-line option. You can repeat the --tag
74 option to give a check-in multiple tags. Tags need not be unique. So,
75 for example, it is common to give every released version a "release" tag.
76
77 If you want add a tag to an existing check-in, you can use the
78 <b>[/help/tag|tag]</b> command. For example:
79
80 <blockquote>
81
+4 -4
--- www/faq.wiki
+++ www/faq.wiki
@@ -41,13 +41,11 @@
4141
4242
<blockquote>There are lots of ways:
4343
4444
When you are checking in a new change using the <b>[/help/commit|commit]</b>
4545
command, you can add the option "--branch <i>BRANCH-NAME</i>" to
46
-make the new check-in be the first check-in for a new branch. You can
47
-also add the "--bgcolor <i>COLOR</i>" option to give the branch a
48
-specific background color on timelines.
46
+make the new check-in be the first check-in for a new branch.
4947
5048
If you want to create a new branch whose initial content is the
5149
same as an existing check-in, use this command:
5250
5351
<blockquote>
@@ -73,11 +71,13 @@
7371
7472
<blockquote>There are several ways:
7573
7674
When you are checking in a new change using the <b>[/help/commit|commit]</b>
7775
command, you can add a tag to that check-in using the
78
-"--tag <i>TAGNAME</i>" command-line option.
76
+"--tag <i>TAGNAME</i>" command-line option. You can repeat the --tag
77
+option to give a check-in multiple tags. Tags need not be unique. So,
78
+for example, it is common to give every released version a "release" tag.
7979
8080
If you want add a tag to an existing check-in, you can use the
8181
<b>[/help/tag|tag]</b> command. For example:
8282
8383
<blockquote>
8484
--- www/faq.wiki
+++ www/faq.wiki
@@ -41,13 +41,11 @@
41
42 <blockquote>There are lots of ways:
43
44 When you are checking in a new change using the <b>[/help/commit|commit]</b>
45 command, you can add the option "--branch <i>BRANCH-NAME</i>" to
46 make the new check-in be the first check-in for a new branch. You can
47 also add the "--bgcolor <i>COLOR</i>" option to give the branch a
48 specific background color on timelines.
49
50 If you want to create a new branch whose initial content is the
51 same as an existing check-in, use this command:
52
53 <blockquote>
@@ -73,11 +71,13 @@
73
74 <blockquote>There are several ways:
75
76 When you are checking in a new change using the <b>[/help/commit|commit]</b>
77 command, you can add a tag to that check-in using the
78 "--tag <i>TAGNAME</i>" command-line option.
 
 
79
80 If you want add a tag to an existing check-in, you can use the
81 <b>[/help/tag|tag]</b> command. For example:
82
83 <blockquote>
84
--- www/faq.wiki
+++ www/faq.wiki
@@ -41,13 +41,11 @@
41
42 <blockquote>There are lots of ways:
43
44 When you are checking in a new change using the <b>[/help/commit|commit]</b>
45 command, you can add the option "--branch <i>BRANCH-NAME</i>" to
46 make the new check-in be the first check-in for a new branch.
 
 
47
48 If you want to create a new branch whose initial content is the
49 same as an existing check-in, use this command:
50
51 <blockquote>
@@ -73,11 +71,13 @@
71
72 <blockquote>There are several ways:
73
74 When you are checking in a new change using the <b>[/help/commit|commit]</b>
75 command, you can add a tag to that check-in using the
76 "--tag <i>TAGNAME</i>" command-line option. You can repeat the --tag
77 option to give a check-in multiple tags. Tags need not be unique. So,
78 for example, it is common to give every released version a "release" tag.
79
80 If you want add a tag to an existing check-in, you can use the
81 <b>[/help/tag|tag]</b> command. For example:
82
83 <blockquote>
84
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -296,11 +296,11 @@
296296
<b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br />
297297
<b>U</b> <i>user-name</i><br />
298298
<b>Z</b> <i>checksum</i><br />
299299
</blockquote>
300300
301
-A control artifact must have one D card and one Z card and
301
+A control artifact must have one D card, one U card, one Z card and
302302
one or more T cards. No other cards or other text is
303303
allowed in a control artifact. Control artifacts might be PGP
304304
clearsigned.
305305
306306
The D card and the Z card of a control artifact are the same
307307
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -296,11 +296,11 @@
296 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br />
297 <b>U</b> <i>user-name</i><br />
298 <b>Z</b> <i>checksum</i><br />
299 </blockquote>
300
301 A control artifact must have one D card and one Z card and
302 one or more T cards. No other cards or other text is
303 allowed in a control artifact. Control artifacts might be PGP
304 clearsigned.
305
306 The D card and the Z card of a control artifact are the same
307
--- www/fileformat.wiki
+++ www/fileformat.wiki
@@ -296,11 +296,11 @@
296 <b>T</b> (<b>+</b>|<b>-</b>|<b>*</b>)<i>tag-name artifact-id ?value?</i><br />
297 <b>U</b> <i>user-name</i><br />
298 <b>Z</b> <i>checksum</i><br />
299 </blockquote>
300
301 A control artifact must have one D card, one U card, one Z card and
302 one or more T cards. No other cards or other text is
303 allowed in a control artifact. Control artifacts might be PGP
304 clearsigned.
305
306 The D card and the Z card of a control artifact are the same
307
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -35,11 +35,11 @@
3535
<h3>3.1 Feature Set</h3>
3636
3737
Git provides file versioning services only, whereas Fossil adds an
3838
integrated [./wikitheory.wiki | wiki],
3939
[./bugtheory.wiki | ticketing &amp; bug tracking],
40
-[./embedddeddoc.wiki | embedded documentation], and
40
+[./embeddeddoc.wiki | embedded documentation], and
4141
[./event.wiki | News/Blog features].
4242
These additional capabilities are available for Git as 3rd-party
4343
user-installed add-ons, but with Fossil they are integrated into
4444
the design. One way to describe Fossil is that it is
4545
"[https://github.com/ | github]-in-a-box".
@@ -74,11 +74,11 @@
7474
until they reach the master branch.
7575
7676
Fossil is designed for smaller and non-hierarchical teams where all
7777
developers are operating directly on the master branch, or at most
7878
a small number of well defined branches.
79
-The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy
79
+The [./concepts.wiki#workflow | autosync] mode of Fossil makes it easy
8080
for multiple developers to work on a single branch and maintain
8181
linear development on that branch and avoid needless forking
8282
and merging.
8383
8484
<h3>3.3 Branches</h3>
@@ -115,13 +115,18 @@
115115
The Git approach scales much better for large projects like the Linux
116116
kernel with thousands of contributors who in many cases don't even know
117117
each others names. The integrators serve a gatekeeper role to help keep
118118
undesirable code out of the official Linux source tree. On the other hand,
119119
not many projects are as big or as loosely organized as the Linux kernel.
120
-Most project, have a small team of developers who all know each other
120
+Most projects have a small team of developers who all know each other
121121
well and trust each other, and who enjoy working together collaboratively
122122
without the overhead and hierarchy of integrators.
123
+
124
+One consequence of the "everybody-sees-everything" focus of Fossil is that
125
+branch names are global and are part of the distributed and synchronized
126
+content of a Fossil repository, rather than being private and user-specific
127
+as they are in Git.
123128
124129
<h3>3.4 Complexity</h3>
125130
126131
Git is a complex system. It can be tricky to use and requires a fair
127132
amount of knowledge and experience to master. Fossil strives to be
@@ -139,19 +144,20 @@
139144
Git requires the developer to maintain a more complex mental model than
140145
most other DVCSes. Git takes longer to learn. And you have to spend
141146
more time thinking about what you are doing with Git.
142147
143148
Fossil strives for simplicity. Fossil wants to be easy to learn and to
144
-require little thinking about how to operating it. Reports from the
145
-field indicate that Fossil is mostly successful at this effort.
149
+require little thinking about how to operating it.
150
+[./quotes.wiki | Reports from the field]
151
+indicate that Fossil is mostly successful at this effort.
146152
147153
<h3>3.5 Web Interface</h3>
148154
149155
Git has a web interface, but it requires a fair amount of setup and an
150156
external web server. Fossil comes with a fully functional
151157
[./webui.wiki | built-in web-server]
152
-and a really simple mechanism (the "<tt>fossil ui</tt>" command) to
158
+and a really simple mechanism (the "[/help/ui|fossil ui]" command) to
153159
automatically start the web server and bring up a web browser to navigate
154160
it. The web interface for Fossil is not only easier to set up, it is also
155161
more powerful and easier to use. The web interface to Fossil is a practical
156162
replacement to the 3rd-party "GUI Tools" that users often employ to operate
157163
Git.
@@ -188,22 +194,29 @@
188194
<h3>3.8 Audit Trail</h3>
189195
190196
Git features the "rebase" command which can be used to change the
191197
sequence of check-ins in the repository. Rebase can be used to "clean up"
192198
a complex sequence of check-ins to make their intent easier for others
193
-to understand. From another point of view, rebase can be used to
194
-"rewrite history" - to do what
195
-[http://en.wikipedia.org/wiki/Winston_Smith | Winston Smith] did for
196
-a living in Orwell's novel
197
-[http://en.wikipedia.org/wiki/Nineteen_Eighty-Four | 1984].
198
-
199
-Fossil deliberately avoids rewriting history. Fossil strives to follow
200
-the accountants philosophy of never erasing anything. Mistakes are fixed
201
-by entering a correction, with an explanation of why the correction is
202
-needed. This can make the history of a project messy, but it also
203
-makes it more honest. The lack of a "rebase" function is considered
204
-a feature of Fossil, not a bug.
199
+to understand. This is important if you view the history of a project
200
+as part of the documentation for the project.
201
+
202
+Fossil takes an opposing view. Fossil views history as sacrosanct and
203
+stubornly refuses to change it.
204
+Fossil allows mistakes to be corrected (for example, check-in comments
205
+can be revised, and check-ins can be moved onto new branches even after
206
+the check-in has occurred) but the correction is an addition to the respository
207
+and the original actions are preserved and displayed alongside
208
+the corrections, thus preserving an historically accurate audit trail.
209
+This is analogous to an accountant marking through an incorrect
210
+entry in a ledger and writing in a correction beside it, rather than
211
+erasing and incorrect entry.
212
+
213
+To put it another way, Git remembers what you should have done whereas
214
+Fossil remembers what you actually did.
215
+
216
+The lack of a "rebase" command and the inability to rewrite history
217
+is considered a feature of Fossil, not an omission or bug.
205218
206219
<h3>3.9 License</h3>
207220
208221
Both Git and Fossil are open-source. Git is under
209222
[http://www.gnu.org/licenses/gpl.html | GPL] whereas Fossil is
210223
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -35,11 +35,11 @@
35 <h3>3.1 Feature Set</h3>
36
37 Git provides file versioning services only, whereas Fossil adds an
38 integrated [./wikitheory.wiki | wiki],
39 [./bugtheory.wiki | ticketing &amp; bug tracking],
40 [./embedddeddoc.wiki | embedded documentation], and
41 [./event.wiki | News/Blog features].
42 These additional capabilities are available for Git as 3rd-party
43 user-installed add-ons, but with Fossil they are integrated into
44 the design. One way to describe Fossil is that it is
45 "[https://github.com/ | github]-in-a-box".
@@ -74,11 +74,11 @@
74 until they reach the master branch.
75
76 Fossil is designed for smaller and non-hierarchical teams where all
77 developers are operating directly on the master branch, or at most
78 a small number of well defined branches.
79 The [concepts.wiki#workflow | autosync] mode of Fossil makes it easy
80 for multiple developers to work on a single branch and maintain
81 linear development on that branch and avoid needless forking
82 and merging.
83
84 <h3>3.3 Branches</h3>
@@ -115,13 +115,18 @@
115 The Git approach scales much better for large projects like the Linux
116 kernel with thousands of contributors who in many cases don't even know
117 each others names. The integrators serve a gatekeeper role to help keep
118 undesirable code out of the official Linux source tree. On the other hand,
119 not many projects are as big or as loosely organized as the Linux kernel.
120 Most project, have a small team of developers who all know each other
121 well and trust each other, and who enjoy working together collaboratively
122 without the overhead and hierarchy of integrators.
 
 
 
 
 
123
124 <h3>3.4 Complexity</h3>
125
126 Git is a complex system. It can be tricky to use and requires a fair
127 amount of knowledge and experience to master. Fossil strives to be
@@ -139,19 +144,20 @@
139 Git requires the developer to maintain a more complex mental model than
140 most other DVCSes. Git takes longer to learn. And you have to spend
141 more time thinking about what you are doing with Git.
142
143 Fossil strives for simplicity. Fossil wants to be easy to learn and to
144 require little thinking about how to operating it. Reports from the
145 field indicate that Fossil is mostly successful at this effort.
 
146
147 <h3>3.5 Web Interface</h3>
148
149 Git has a web interface, but it requires a fair amount of setup and an
150 external web server. Fossil comes with a fully functional
151 [./webui.wiki | built-in web-server]
152 and a really simple mechanism (the "<tt>fossil ui</tt>" command) to
153 automatically start the web server and bring up a web browser to navigate
154 it. The web interface for Fossil is not only easier to set up, it is also
155 more powerful and easier to use. The web interface to Fossil is a practical
156 replacement to the 3rd-party "GUI Tools" that users often employ to operate
157 Git.
@@ -188,22 +194,29 @@
188 <h3>3.8 Audit Trail</h3>
189
190 Git features the "rebase" command which can be used to change the
191 sequence of check-ins in the repository. Rebase can be used to "clean up"
192 a complex sequence of check-ins to make their intent easier for others
193 to understand. From another point of view, rebase can be used to
194 "rewrite history" - to do what
195 [http://en.wikipedia.org/wiki/Winston_Smith | Winston Smith] did for
196 a living in Orwell's novel
197 [http://en.wikipedia.org/wiki/Nineteen_Eighty-Four | 1984].
198
199 Fossil deliberately avoids rewriting history. Fossil strives to follow
200 the accountants philosophy of never erasing anything. Mistakes are fixed
201 by entering a correction, with an explanation of why the correction is
202 needed. This can make the history of a project messy, but it also
203 makes it more honest. The lack of a "rebase" function is considered
204 a feature of Fossil, not a bug.
 
 
 
 
 
 
 
205
206 <h3>3.9 License</h3>
207
208 Both Git and Fossil are open-source. Git is under
209 [http://www.gnu.org/licenses/gpl.html | GPL] whereas Fossil is
210
--- www/fossil-v-git.wiki
+++ www/fossil-v-git.wiki
@@ -35,11 +35,11 @@
35 <h3>3.1 Feature Set</h3>
36
37 Git provides file versioning services only, whereas Fossil adds an
38 integrated [./wikitheory.wiki | wiki],
39 [./bugtheory.wiki | ticketing &amp; bug tracking],
40 [./embeddeddoc.wiki | embedded documentation], and
41 [./event.wiki | News/Blog features].
42 These additional capabilities are available for Git as 3rd-party
43 user-installed add-ons, but with Fossil they are integrated into
44 the design. One way to describe Fossil is that it is
45 "[https://github.com/ | github]-in-a-box".
@@ -74,11 +74,11 @@
74 until they reach the master branch.
75
76 Fossil is designed for smaller and non-hierarchical teams where all
77 developers are operating directly on the master branch, or at most
78 a small number of well defined branches.
79 The [./concepts.wiki#workflow | autosync] mode of Fossil makes it easy
80 for multiple developers to work on a single branch and maintain
81 linear development on that branch and avoid needless forking
82 and merging.
83
84 <h3>3.3 Branches</h3>
@@ -115,13 +115,18 @@
115 The Git approach scales much better for large projects like the Linux
116 kernel with thousands of contributors who in many cases don't even know
117 each others names. The integrators serve a gatekeeper role to help keep
118 undesirable code out of the official Linux source tree. On the other hand,
119 not many projects are as big or as loosely organized as the Linux kernel.
120 Most projects have a small team of developers who all know each other
121 well and trust each other, and who enjoy working together collaboratively
122 without the overhead and hierarchy of integrators.
123
124 One consequence of the "everybody-sees-everything" focus of Fossil is that
125 branch names are global and are part of the distributed and synchronized
126 content of a Fossil repository, rather than being private and user-specific
127 as they are in Git.
128
129 <h3>3.4 Complexity</h3>
130
131 Git is a complex system. It can be tricky to use and requires a fair
132 amount of knowledge and experience to master. Fossil strives to be
@@ -139,19 +144,20 @@
144 Git requires the developer to maintain a more complex mental model than
145 most other DVCSes. Git takes longer to learn. And you have to spend
146 more time thinking about what you are doing with Git.
147
148 Fossil strives for simplicity. Fossil wants to be easy to learn and to
149 require little thinking about how to operating it.
150 [./quotes.wiki | Reports from the field]
151 indicate that Fossil is mostly successful at this effort.
152
153 <h3>3.5 Web Interface</h3>
154
155 Git has a web interface, but it requires a fair amount of setup and an
156 external web server. Fossil comes with a fully functional
157 [./webui.wiki | built-in web-server]
158 and a really simple mechanism (the "[/help/ui|fossil ui]" command) to
159 automatically start the web server and bring up a web browser to navigate
160 it. The web interface for Fossil is not only easier to set up, it is also
161 more powerful and easier to use. The web interface to Fossil is a practical
162 replacement to the 3rd-party "GUI Tools" that users often employ to operate
163 Git.
@@ -188,22 +194,29 @@
194 <h3>3.8 Audit Trail</h3>
195
196 Git features the "rebase" command which can be used to change the
197 sequence of check-ins in the repository. Rebase can be used to "clean up"
198 a complex sequence of check-ins to make their intent easier for others
199 to understand. This is important if you view the history of a project
200 as part of the documentation for the project.
201
202 Fossil takes an opposing view. Fossil views history as sacrosanct and
203 stubornly refuses to change it.
204 Fossil allows mistakes to be corrected (for example, check-in comments
205 can be revised, and check-ins can be moved onto new branches even after
206 the check-in has occurred) but the correction is an addition to the respository
207 and the original actions are preserved and displayed alongside
208 the corrections, thus preserving an historically accurate audit trail.
209 This is analogous to an accountant marking through an incorrect
210 entry in a ledger and writing in a correction beside it, rather than
211 erasing and incorrect entry.
212
213 To put it another way, Git remembers what you should have done whereas
214 Fossil remembers what you actually did.
215
216 The lack of a "rebase" command and the inability to rewrite history
217 is considered a feature of Fossil, not an omission or bug.
218
219 <h3>3.9 License</h3>
220
221 Both Git and Fossil are open-source. Git is under
222 [http://www.gnu.org/licenses/gpl.html | GPL] whereas Fossil is
223
+5 -3
--- www/hints.wiki
+++ www/hints.wiki
@@ -1,8 +1,8 @@
11
<title>Fossil Tips And Usage Hints</title>
22
3
- 1. Click on nodes of any timeline graph to see diffs between two
3
+ 1. Click on nodes of any timeline graph to see diffs between the two
44
selected versions.
55
66
2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
77
to get a pop-up
88
window containing a complete side-by-side diff. (NB: The pop-up
@@ -14,13 +14,15 @@
1414
3. The "[/help?cmd=clean | fossil clean -f]" command makes a great
1515
alternative to "make clean".
1616
1717
4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
1818
edits in any of your Fossil projects. Use
19
- "[/help?cmd=all | fossil all sync]" on your laptop
19
+ "[/help?cmd=all | fossil all pull]" on your laptop
2020
prior to going off network (for example, on a long plane ride)
21
- to make sure you have all of content local.
21
+ to make sure you have all the latest content locally. Then run
22
+ "[/help/all|fossil all push]" when you get back online to upload
23
+ your changes.
2224
2325
5. Sub-menu options on Timelines lets you select either 20 or 200
2426
records. But you can manual edit the "n=" query parameter in the
2527
URL to get any number of records you desire. To see a complete
2628
timeline graph, set n to some ridiculously large value like 10000000.
2729
--- www/hints.wiki
+++ www/hints.wiki
@@ -1,8 +1,8 @@
1 <title>Fossil Tips And Usage Hints</title>
2
3 1. Click on nodes of any timeline graph to see diffs between two
4 selected versions.
5
6 2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
7 to get a pop-up
8 window containing a complete side-by-side diff. (NB: The pop-up
@@ -14,13 +14,15 @@
14 3. The "[/help?cmd=clean | fossil clean -f]" command makes a great
15 alternative to "make clean".
16
17 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
18 edits in any of your Fossil projects. Use
19 "[/help?cmd=all | fossil all sync]" on your laptop
20 prior to going off network (for example, on a long plane ride)
21 to make sure you have all of content local.
 
 
22
23 5. Sub-menu options on Timelines lets you select either 20 or 200
24 records. But you can manual edit the "n=" query parameter in the
25 URL to get any number of records you desire. To see a complete
26 timeline graph, set n to some ridiculously large value like 10000000.
27
--- www/hints.wiki
+++ www/hints.wiki
@@ -1,8 +1,8 @@
1 <title>Fossil Tips And Usage Hints</title>
2
3 1. Click on nodes of any timeline graph to see diffs between the two
4 selected versions.
5
6 2. Add the "--tk" option to "[/help?cmd=diff | fossil diff]" commands
7 to get a pop-up
8 window containing a complete side-by-side diff. (NB: The pop-up
@@ -14,13 +14,15 @@
14 3. The "[/help?cmd=clean | fossil clean -f]" command makes a great
15 alternative to "make clean".
16
17 4. Use "[/help?cmd=all | fossil all changes]" to look for any uncommitted
18 edits in any of your Fossil projects. Use
19 "[/help?cmd=all | fossil all pull]" on your laptop
20 prior to going off network (for example, on a long plane ride)
21 to make sure you have all the latest content locally. Then run
22 "[/help/all|fossil all push]" when you get back online to upload
23 your changes.
24
25 5. Sub-menu options on Timelines lets you select either 20 or 200
26 records. But you can manual edit the "n=" query parameter in the
27 URL to get any number of records you desire. To see a complete
28 timeline graph, set n to some ridiculously large value like 10000000.
29
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -12,10 +12,11 @@
1212
So must people do not need to be concerned with the
1313
build complexities of Fossil. But hard-core developers who desire
1414
a deep understanding of how Fossil is put together can benefit
1515
from reviewing this article.
1616
17
+<a name="srctour"></a>
1718
<h1>2.0 Source Code Tour</h1>
1819
1920
The source code for Fossil is found in the
2021
[/dir?ci=trunk&name=src | src/] subdirectory of the
2122
source tree. The src/ subdirectory contains all code, including
@@ -117,10 +118,11 @@
117118
directories right. The point is that the manifest.uuid, manifest, and
118119
VERSION files
119120
in the root of the source tree are the three arguments and
120121
the generated VERSION.h file appears on standard output.
121122
123
+<a name="preprocessing"></a>
122124
<h1>4.0 Preprocessing</h1>
123125
124126
There are three preprocessors for the Fossil sources. The mkindex
125127
and translate preprocessors can be run in any order. The makeheaders
126128
preprocessor must be run after translate.
@@ -236,5 +238,10 @@
236238
Fossil needs to be linked against [http://www.zlib.net | zlib]. If
237239
the HTTPS option is enabled, then it will also need to link against
238240
the appropriate SSL implementation. And, of course, Fossil needs to
239241
link against the standard C library. No other libraries or external
240242
dependences are used.
243
+
244
+<h1>7.0 See Also</h1>
245
+
246
+ * [./tech_overview.wiki | A Technical Overview Of Fossil]
247
+ * [./adding_code.wiki | How To Add Features To Fossil]
241248
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -12,10 +12,11 @@
12 So must people do not need to be concerned with the
13 build complexities of Fossil. But hard-core developers who desire
14 a deep understanding of how Fossil is put together can benefit
15 from reviewing this article.
16
 
17 <h1>2.0 Source Code Tour</h1>
18
19 The source code for Fossil is found in the
20 [/dir?ci=trunk&name=src | src/] subdirectory of the
21 source tree. The src/ subdirectory contains all code, including
@@ -117,10 +118,11 @@
117 directories right. The point is that the manifest.uuid, manifest, and
118 VERSION files
119 in the root of the source tree are the three arguments and
120 the generated VERSION.h file appears on standard output.
121
 
122 <h1>4.0 Preprocessing</h1>
123
124 There are three preprocessors for the Fossil sources. The mkindex
125 and translate preprocessors can be run in any order. The makeheaders
126 preprocessor must be run after translate.
@@ -236,5 +238,10 @@
236 Fossil needs to be linked against [http://www.zlib.net | zlib]. If
237 the HTTPS option is enabled, then it will also need to link against
238 the appropriate SSL implementation. And, of course, Fossil needs to
239 link against the standard C library. No other libraries or external
240 dependences are used.
 
 
 
 
 
241
--- www/makefile.wiki
+++ www/makefile.wiki
@@ -12,10 +12,11 @@
12 So must people do not need to be concerned with the
13 build complexities of Fossil. But hard-core developers who desire
14 a deep understanding of how Fossil is put together can benefit
15 from reviewing this article.
16
17 <a name="srctour"></a>
18 <h1>2.0 Source Code Tour</h1>
19
20 The source code for Fossil is found in the
21 [/dir?ci=trunk&name=src | src/] subdirectory of the
22 source tree. The src/ subdirectory contains all code, including
@@ -117,10 +118,11 @@
118 directories right. The point is that the manifest.uuid, manifest, and
119 VERSION files
120 in the root of the source tree are the three arguments and
121 the generated VERSION.h file appears on standard output.
122
123 <a name="preprocessing"></a>
124 <h1>4.0 Preprocessing</h1>
125
126 There are three preprocessors for the Fossil sources. The mkindex
127 and translate preprocessors can be run in any order. The makeheaders
128 preprocessor must be run after translate.
@@ -236,5 +238,10 @@
238 Fossil needs to be linked against [http://www.zlib.net | zlib]. If
239 the HTTPS option is enabled, then it will also need to link against
240 the appropriate SSL implementation. And, of course, Fossil needs to
241 link against the standard C library. No other libraries or external
242 dependences are used.
243
244 <h1>7.0 See Also</h1>
245
246 * [./tech_overview.wiki | A Technical Overview Of Fossil]
247 * [./adding_code.wiki | How To Add Features To Fossil]
248
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -5,10 +5,12 @@
55
#
66
# tclsh mkindex.tcl >permutedindex.wiki
77
#
88
99
set doclist {
10
+ adding_code.wiki {Adding New Features To Fossil}
11
+ adding_code.wiki {Hacking Fossil}
1012
antibot.wiki {Defense against Spiders and Bots}
1113
bugtheory.wiki {Bug Tracking In Fossil}
1214
branching.wiki {Branching, Forking, Merging, and Tagging}
1315
build.wiki {Compiling and Installing Fossil}
1416
checkin_names.wiki {Checkin And Version Names}
1517
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -5,10 +5,12 @@
5 #
6 # tclsh mkindex.tcl >permutedindex.wiki
7 #
8
9 set doclist {
 
 
10 antibot.wiki {Defense against Spiders and Bots}
11 bugtheory.wiki {Bug Tracking In Fossil}
12 branching.wiki {Branching, Forking, Merging, and Tagging}
13 build.wiki {Compiling and Installing Fossil}
14 checkin_names.wiki {Checkin And Version Names}
15
--- www/mkindex.tcl
+++ www/mkindex.tcl
@@ -5,10 +5,12 @@
5 #
6 # tclsh mkindex.tcl >permutedindex.wiki
7 #
8
9 set doclist {
10 adding_code.wiki {Adding New Features To Fossil}
11 adding_code.wiki {Hacking Fossil}
12 antibot.wiki {Defense against Spiders and Bots}
13 bugtheory.wiki {Bug Tracking In Fossil}
14 branching.wiki {Branching, Forking, Merging, and Tagging}
15 build.wiki {Compiling and Installing Fossil}
16 checkin_names.wiki {Checkin And Version Names}
17
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -13,10 +13,11 @@
1313
<h2>Permuted Index:</h2>
1414
<ul>
1515
<li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Update and Running in</a></li>
1616
<li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
1717
<li><a href="tech_overview.wiki">A Technical Overview Of The Design And Implementation Of Fossil</a></li>
18
+<li><a href="adding_code.wiki">Adding New Features To Fossil</a></li>
1819
<li><a href="antibot.wiki">against Spiders and Bots &mdash; Defense</a></li>
1920
<li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
2021
<li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
2122
<li><a href="fiveminutes.wiki">as a Single User &mdash; Update and Running in 5 Minutes</a></li>
2223
<li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
@@ -61,10 +62,11 @@
6162
<li><a href="embeddeddoc.wiki">Embedded Project Documentation</a></li>
6263
<li><a href="delta_encoder_algorithm.wiki">Encoding Algorithm &mdash; Fossil Delta</a></li>
6364
<li><a href="event.wiki">Events</a></li>
6465
<li><a href="inout.wiki">Export To And From Git &mdash; Import And</a></li>
6566
<li><a href="fossil-from-msvc.wiki">Express 2010 IDE &mdash; Integrating Fossil in the Microsoft</a></li>
67
+<li><a href="adding_code.wiki">Features To Fossil &mdash; Adding New</a></li>
6668
<li><a href="fileformat.wiki">File Format &mdash; Fossil</a></li>
6769
<li><a href="branching.wiki">Forking, Merging, and Tagging &mdash; Branching,</a></li>
6870
<li><a href="delta_format.wiki">Format &mdash; Fossil Delta</a></li>
6971
<li><a href="fileformat.wiki">Format &mdash; Fossil File</a></li>
7072
<li><a href="changes.wiki">Fossil Changelog</a></li>
@@ -86,10 +88,11 @@
8688
<li><a href="fossil-v-git.wiki">Git &mdash; Fossil Versus</a></li>
8789
<li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
8890
<li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
8991
<li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
9092
<li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
93
+<li><a href="adding_code.wiki">Hacking Fossil</a></li>
9194
<li><a href="hints.wiki">Hints &mdash; Fossil Tips And Usage</a></li>
9295
<li><a href="index.wiki">Home Page</a></li>
9396
<li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
9497
<li><a href="server.wiki">How To Configure A Fossil Server</a></li>
9598
<li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
@@ -104,10 +107,11 @@
104107
<li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
105108
<li><a href="branching.wiki">Merging, and Tagging &mdash; Branching, Forking,</a></li>
106109
<li><a href="fossil-from-msvc.wiki">Microsoft Express 2010 IDE &mdash; Integrating Fossil in the</a></li>
107110
<li><a href="fiveminutes.wiki">Minutes as a Single User &mdash; Update and Running in 5</a></li>
108111
<li><a href="checkin_names.wiki">Names &mdash; Checkin And Version</a></li>
112
+<li><a href="adding_code.wiki">New Features To Fossil &mdash; Adding</a></li>
109113
<li><a href="newrepo.wiki">New Fossil Repository &mdash; How To Create A</a></li>
110114
<li><a href="foss-cklist.wiki">Open-Source Projects &mdash; Checklist For Successful</a></li>
111115
<li><a href="pop.wiki">Operations &mdash; Principles Of</a></li>
112116
<li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil &mdash; A Technical</a></li>
113117
<li><a href="index.wiki">Page &mdash; Home</a></li>
114118
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -13,10 +13,11 @@
13 <h2>Permuted Index:</h2>
14 <ul>
15 <li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Update and Running in</a></li>
16 <li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
17 <li><a href="tech_overview.wiki">A Technical Overview Of The Design And Implementation Of Fossil</a></li>
 
18 <li><a href="antibot.wiki">against Spiders and Bots &mdash; Defense</a></li>
19 <li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
20 <li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
21 <li><a href="fiveminutes.wiki">as a Single User &mdash; Update and Running in 5 Minutes</a></li>
22 <li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
@@ -61,10 +62,11 @@
61 <li><a href="embeddeddoc.wiki">Embedded Project Documentation</a></li>
62 <li><a href="delta_encoder_algorithm.wiki">Encoding Algorithm &mdash; Fossil Delta</a></li>
63 <li><a href="event.wiki">Events</a></li>
64 <li><a href="inout.wiki">Export To And From Git &mdash; Import And</a></li>
65 <li><a href="fossil-from-msvc.wiki">Express 2010 IDE &mdash; Integrating Fossil in the Microsoft</a></li>
 
66 <li><a href="fileformat.wiki">File Format &mdash; Fossil</a></li>
67 <li><a href="branching.wiki">Forking, Merging, and Tagging &mdash; Branching,</a></li>
68 <li><a href="delta_format.wiki">Format &mdash; Fossil Delta</a></li>
69 <li><a href="fileformat.wiki">Format &mdash; Fossil File</a></li>
70 <li><a href="changes.wiki">Fossil Changelog</a></li>
@@ -86,10 +88,11 @@
86 <li><a href="fossil-v-git.wiki">Git &mdash; Fossil Versus</a></li>
87 <li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
88 <li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
89 <li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
90 <li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
 
91 <li><a href="hints.wiki">Hints &mdash; Fossil Tips And Usage</a></li>
92 <li><a href="index.wiki">Home Page</a></li>
93 <li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
94 <li><a href="server.wiki">How To Configure A Fossil Server</a></li>
95 <li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
@@ -104,10 +107,11 @@
104 <li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
105 <li><a href="branching.wiki">Merging, and Tagging &mdash; Branching, Forking,</a></li>
106 <li><a href="fossil-from-msvc.wiki">Microsoft Express 2010 IDE &mdash; Integrating Fossil in the</a></li>
107 <li><a href="fiveminutes.wiki">Minutes as a Single User &mdash; Update and Running in 5</a></li>
108 <li><a href="checkin_names.wiki">Names &mdash; Checkin And Version</a></li>
 
109 <li><a href="newrepo.wiki">New Fossil Repository &mdash; How To Create A</a></li>
110 <li><a href="foss-cklist.wiki">Open-Source Projects &mdash; Checklist For Successful</a></li>
111 <li><a href="pop.wiki">Operations &mdash; Principles Of</a></li>
112 <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil &mdash; A Technical</a></li>
113 <li><a href="index.wiki">Page &mdash; Home</a></li>
114
--- www/permutedindex.wiki
+++ www/permutedindex.wiki
@@ -13,10 +13,11 @@
13 <h2>Permuted Index:</h2>
14 <ul>
15 <li><a href="fiveminutes.wiki">5 Minutes as a Single User &mdash; Update and Running in</a></li>
16 <li><a href="fossil-from-msvc.wiki">2010 IDE &mdash; Integrating Fossil in the Microsoft Express</a></li>
17 <li><a href="tech_overview.wiki">A Technical Overview Of The Design And Implementation Of Fossil</a></li>
18 <li><a href="adding_code.wiki">Adding New Features To Fossil</a></li>
19 <li><a href="antibot.wiki">against Spiders and Bots &mdash; Defense</a></li>
20 <li><a href="copyright-release.html">Agreement &mdash; Contributor License</a></li>
21 <li><a href="delta_encoder_algorithm.wiki">Algorithm &mdash; Fossil Delta Encoding</a></li>
22 <li><a href="fiveminutes.wiki">as a Single User &mdash; Update and Running in 5 Minutes</a></li>
23 <li><a href="faq.wiki">Asked Questions &mdash; Frequently</a></li>
@@ -61,10 +62,11 @@
62 <li><a href="embeddeddoc.wiki">Embedded Project Documentation</a></li>
63 <li><a href="delta_encoder_algorithm.wiki">Encoding Algorithm &mdash; Fossil Delta</a></li>
64 <li><a href="event.wiki">Events</a></li>
65 <li><a href="inout.wiki">Export To And From Git &mdash; Import And</a></li>
66 <li><a href="fossil-from-msvc.wiki">Express 2010 IDE &mdash; Integrating Fossil in the Microsoft</a></li>
67 <li><a href="adding_code.wiki">Features To Fossil &mdash; Adding New</a></li>
68 <li><a href="fileformat.wiki">File Format &mdash; Fossil</a></li>
69 <li><a href="branching.wiki">Forking, Merging, and Tagging &mdash; Branching,</a></li>
70 <li><a href="delta_format.wiki">Format &mdash; Fossil Delta</a></li>
71 <li><a href="fileformat.wiki">Format &mdash; Fossil File</a></li>
72 <li><a href="changes.wiki">Fossil Changelog</a></li>
@@ -86,10 +88,11 @@
88 <li><a href="fossil-v-git.wiki">Git &mdash; Fossil Versus</a></li>
89 <li><a href="inout.wiki">Git &mdash; Import And Export To And From</a></li>
90 <li><a href="quotes.wiki">Git, and DVCSes in General &mdash; Quotes: What People Are Saying About Fossil,</a></li>
91 <li><a href="quickstart.wiki">Guide &mdash; Fossil Quick Start</a></li>
92 <li><a href="style.wiki">Guidelines &mdash; Source Code Style</a></li>
93 <li><a href="adding_code.wiki">Hacking Fossil</a></li>
94 <li><a href="hints.wiki">Hints &mdash; Fossil Tips And Usage</a></li>
95 <li><a href="index.wiki">Home Page</a></li>
96 <li><a href="selfhost.wiki">Hosting Repositories &mdash; Fossil Self</a></li>
97 <li><a href="server.wiki">How To Configure A Fossil Server</a></li>
98 <li><a href="newrepo.wiki">How To Create A New Fossil Repository</a></li>
@@ -104,10 +107,11 @@
107 <li><a href="password.wiki">Management And Authentication &mdash; Password</a></li>
108 <li><a href="branching.wiki">Merging, and Tagging &mdash; Branching, Forking,</a></li>
109 <li><a href="fossil-from-msvc.wiki">Microsoft Express 2010 IDE &mdash; Integrating Fossil in the</a></li>
110 <li><a href="fiveminutes.wiki">Minutes as a Single User &mdash; Update and Running in 5</a></li>
111 <li><a href="checkin_names.wiki">Names &mdash; Checkin And Version</a></li>
112 <li><a href="adding_code.wiki">New Features To Fossil &mdash; Adding</a></li>
113 <li><a href="newrepo.wiki">New Fossil Repository &mdash; How To Create A</a></li>
114 <li><a href="foss-cklist.wiki">Open-Source Projects &mdash; Checklist For Successful</a></li>
115 <li><a href="pop.wiki">Operations &mdash; Principles Of</a></li>
116 <li><a href="tech_overview.wiki">Overview Of The Design And Implementation Of Fossil &mdash; A Technical</a></li>
117 <li><a href="index.wiki">Page &mdash; Home</a></li>
118
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -173,13 +173,21 @@
173173
</blockquote>
174174
175175
<p>You will be prompted for check-in comments using whatever editor
176176
is specified by your VISUAL or EDITOR environment variable.</p>
177177
178
+ In the default configuration, the [/help/commit|commit]
179
+ command will also automatically [/help/push|push] your changes, but that
180
+ feature can be disabled. (More information about
181
+ [./concepts.wiki#workflow|autosync] and how to disable it.)
182
+ Remember that your coworkers can not see your changes until you
183
+ commit and push them.</p>
184
+
178185
<h2>Sharing Changes</h2>
179186
180
- <p>The changes you [/help/commit | commit] are only
187
+ <p>When [./concepts.wiki#workflow|autosync] is turned off,
188
+ the changes you [/help/commit | commit] are only
181189
on your local repository.
182190
To share those changes with other repositories, do:</p>
183191
184192
<blockquote>
185193
<b>[/help/push | fossil push]</b> <i>URL</i>
@@ -212,10 +220,17 @@
212220
date/time stamp. ([./checkin_names.wiki | more info])
213221
If you omit
214222
the <i>VERSION</i>, then fossil moves you to the
215223
latest version of the branch your are currently on.</p>
216224
225
+ <p>The default behaviors is for [./concepts.wiki#workflow|autosync] to
226
+ be turned on. That means that a [/help/pull|pull] automatically occurs
227
+ when you run [/help/update|update] and a [/help/push|push] happens
228
+ automatically after you [/help/commit|commit]. So in normal practice,
229
+ the push, pull, and sync commands are rarely used. But it is important
230
+ to know about them, all the same.</p>
231
+
217232
<h2>Branching And Merging</h2>
218233
219234
<p>Use the --branch option to the [/help/commit | commit] command
220235
to start a new branch. Note that in Fossil, branches are normally
221236
created when you commit, not before you start editing. You can
@@ -222,36 +237,43 @@
222237
use the [/help/branch | branch new] command to create a new branch
223238
before you start editing, if you want, but most people just wait
224239
until they are ready to commit.
225240
226241
To merge two branches back together, first
227
- [/help/update | update] to the leaf of one branch. Then do a
228
- [/help/merge | merge] of the leaf of the other branch:</p>
242
+ [/help/update | update] to the branch you want to merge into.
243
+ Then do a [/help/merge|merge] another branch that you want to incorporate
244
+ the changes from. For example, to merge "featureX" changes into "trunk"
245
+ do this:</p>
229246
230247
<blockquote>
231
- <b>[/help/merge | fossil merge]</b> <i>VERSION</i>
248
+ <b>fossil [/help/update|update] trunk</b><br>
249
+ <b>fossil [/help/merge|merge] featureX</b><br>
250
+ <i># make sure the merge didn't break anything...</i><br>
251
+ <b>fossil [/help/commit|commit]
232252
</blockquote>
233253
234
- <p>The <i>VERSION</i> can be any of the forms allowed for
235
- [/help/update | update].
236
- After performing the merge, you will normally want to test it to
237
- make sure it does not break anything, then
238
- [/help/commit | commit] your changes.
239
- In the default configuration, the [/help/commit|commit]
240
- command will also automatically [/help/push|push] your changes, but that
241
- feature can be disabled. (More information about
242
- [./concepts.wiki#workflow|autosync] and how to disable it.)
243
- Remember that your coworkers can not see your changes until you
244
- commit and push them.</p>
245
-
246
- <p>The merge command has options to cherrypick individual
247
- changes, or to back out individual changes.</p>
248
-
249
- <p>Note that the merge command changes only your local check-out.
250
- The merge command does <em>not</em> modify the repository in any way.
251
- You must do a separate [/help/commit | commit] after the merge in order
252
- to put the merged code back into the repository.</p>
254
+ <p>The argument to the [/help/merge|merge] command can be any of the
255
+ version identifier forms that work for [/help/update|update].
256
+ ([./checkin_names.wiki|more info].)
257
+ The merge command has options to cherrypick individual
258
+ changes, or to back out individual changes, if you don't want to
259
+ do a full merge.</p>
260
+
261
+ The merge command puts all changes in your working check-out.
262
+ No changes are made to the repository.
263
+ You must run [/help/commit|commit] separately
264
+ to add the merge changes into your repository to make them persistent
265
+ and so that your coworkers can see them.
266
+ But before you do that, you will normally want to run a few tests
267
+ to verify that the merge didn't cause logic breaks in your code.
268
+
269
+ The same branch can be merged multiple times without trouble. Fossil
270
+ automatically keeps up with things and avoids conflicts when doing
271
+ multiple merges. So even if you have merged the featureX branch
272
+ into trunk previously, you can do so again and Fossil will automatically
273
+ know to pull in only those changes that have occurred since the previous
274
+ merge.
253275
254276
<p>If a merge or update doesn't work out (perhaps something breaks or
255277
there are many merge conflicts) then you back up using:</p>
256278
257279
<blockquote>
@@ -280,11 +302,11 @@
280302
<b>[/help/ui | fossil ui]</b> <i>repository-filename</i>
281303
</blockquote>
282304
283305
<p>The <b>ui</b> command is intended for accessing the web interface
284306
from a local desktop. The <b>ui</b> command binds to the loopback IP
285
- address only (and is thus makes the web interface visible only on the
307
+ address only (and thus makes the web interface visible only on the
286308
local machine) and it automatically start your web browser pointing at the
287309
server. For cross-machine collaboration, use the <b>server</b> command,
288310
which binds on all IP addresses and does not try to start a web browser.
289311
You can omit the <i>repository-filename</i> if you are within
290312
a checked-out local tree. The <b>server</b> uses port 8080 by default
@@ -321,11 +343,11 @@
321343
<p>Adjust the paths to suit your installation, of course. Notice that
322344
fossil runs as root. This is not required - you can run it as an
323345
unprivileged user. But it is more secure to run fossil as root.
324346
When you do run fossil as root, it automatically puts itself in a
325347
chroot jail in the same directory as the repository, then drops
326
- root privileges prior to reading any information from the request.</p>
348
+ root privileges prior to reading any information from the socket.</p>
327349
328350
<a name="proxy"></a>
329351
<h2>HTTP Proxies</h2>
330352
331353
<p>If you are behind a restrictive firewall that requires you to use
@@ -369,8 +391,11 @@
369391
<b>fossil sync http://192.168.1.36:8080/ --proxy off</b>
370392
</blockquote>
371393
372394
<h2>More Hints</h2>
373395
374
- <p>A [/help | complete list of commands] is available.
396
+ <p>A [/help | complete list of commands] is available, as is the
397
+ [./hints.wiki|helpful hints] document. See the
398
+ [./permutedindex.wiki#pindex|permuted index] for additional
399
+ documentation.
375400
376401
<p>Explore and have fun!</p>
377402
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -173,13 +173,21 @@
173 </blockquote>
174
175 <p>You will be prompted for check-in comments using whatever editor
176 is specified by your VISUAL or EDITOR environment variable.</p>
177
 
 
 
 
 
 
 
178 <h2>Sharing Changes</h2>
179
180 <p>The changes you [/help/commit | commit] are only
 
181 on your local repository.
182 To share those changes with other repositories, do:</p>
183
184 <blockquote>
185 <b>[/help/push | fossil push]</b> <i>URL</i>
@@ -212,10 +220,17 @@
212 date/time stamp. ([./checkin_names.wiki | more info])
213 If you omit
214 the <i>VERSION</i>, then fossil moves you to the
215 latest version of the branch your are currently on.</p>
216
 
 
 
 
 
 
 
217 <h2>Branching And Merging</h2>
218
219 <p>Use the --branch option to the [/help/commit | commit] command
220 to start a new branch. Note that in Fossil, branches are normally
221 created when you commit, not before you start editing. You can
@@ -222,36 +237,43 @@
222 use the [/help/branch | branch new] command to create a new branch
223 before you start editing, if you want, but most people just wait
224 until they are ready to commit.
225
226 To merge two branches back together, first
227 [/help/update | update] to the leaf of one branch. Then do a
228 [/help/merge | merge] of the leaf of the other branch:</p>
 
 
229
230 <blockquote>
231 <b>[/help/merge | fossil merge]</b> <i>VERSION</i>
 
 
 
232 </blockquote>
233
234 <p>The <i>VERSION</i> can be any of the forms allowed for
235 [/help/update | update].
236 After performing the merge, you will normally want to test it to
237 make sure it does not break anything, then
238 [/help/commit | commit] your changes.
239 In the default configuration, the [/help/commit|commit]
240 command will also automatically [/help/push|push] your changes, but that
241 feature can be disabled. (More information about
242 [./concepts.wiki#workflow|autosync] and how to disable it.)
243 Remember that your coworkers can not see your changes until you
244 commit and push them.</p>
245
246 <p>The merge command has options to cherrypick individual
247 changes, or to back out individual changes.</p>
248
249 <p>Note that the merge command changes only your local check-out.
250 The merge command does <em>not</em> modify the repository in any way.
251 You must do a separate [/help/commit | commit] after the merge in order
252 to put the merged code back into the repository.</p>
 
 
253
254 <p>If a merge or update doesn't work out (perhaps something breaks or
255 there are many merge conflicts) then you back up using:</p>
256
257 <blockquote>
@@ -280,11 +302,11 @@
280 <b>[/help/ui | fossil ui]</b> <i>repository-filename</i>
281 </blockquote>
282
283 <p>The <b>ui</b> command is intended for accessing the web interface
284 from a local desktop. The <b>ui</b> command binds to the loopback IP
285 address only (and is thus makes the web interface visible only on the
286 local machine) and it automatically start your web browser pointing at the
287 server. For cross-machine collaboration, use the <b>server</b> command,
288 which binds on all IP addresses and does not try to start a web browser.
289 You can omit the <i>repository-filename</i> if you are within
290 a checked-out local tree. The <b>server</b> uses port 8080 by default
@@ -321,11 +343,11 @@
321 <p>Adjust the paths to suit your installation, of course. Notice that
322 fossil runs as root. This is not required - you can run it as an
323 unprivileged user. But it is more secure to run fossil as root.
324 When you do run fossil as root, it automatically puts itself in a
325 chroot jail in the same directory as the repository, then drops
326 root privileges prior to reading any information from the request.</p>
327
328 <a name="proxy"></a>
329 <h2>HTTP Proxies</h2>
330
331 <p>If you are behind a restrictive firewall that requires you to use
@@ -369,8 +391,11 @@
369 <b>fossil sync http://192.168.1.36:8080/ --proxy off</b>
370 </blockquote>
371
372 <h2>More Hints</h2>
373
374 <p>A [/help | complete list of commands] is available.
 
 
 
375
376 <p>Explore and have fun!</p>
377
--- www/quickstart.wiki
+++ www/quickstart.wiki
@@ -173,13 +173,21 @@
173 </blockquote>
174
175 <p>You will be prompted for check-in comments using whatever editor
176 is specified by your VISUAL or EDITOR environment variable.</p>
177
178 In the default configuration, the [/help/commit|commit]
179 command will also automatically [/help/push|push] your changes, but that
180 feature can be disabled. (More information about
181 [./concepts.wiki#workflow|autosync] and how to disable it.)
182 Remember that your coworkers can not see your changes until you
183 commit and push them.</p>
184
185 <h2>Sharing Changes</h2>
186
187 <p>When [./concepts.wiki#workflow|autosync] is turned off,
188 the changes you [/help/commit | commit] are only
189 on your local repository.
190 To share those changes with other repositories, do:</p>
191
192 <blockquote>
193 <b>[/help/push | fossil push]</b> <i>URL</i>
@@ -212,10 +220,17 @@
220 date/time stamp. ([./checkin_names.wiki | more info])
221 If you omit
222 the <i>VERSION</i>, then fossil moves you to the
223 latest version of the branch your are currently on.</p>
224
225 <p>The default behaviors is for [./concepts.wiki#workflow|autosync] to
226 be turned on. That means that a [/help/pull|pull] automatically occurs
227 when you run [/help/update|update] and a [/help/push|push] happens
228 automatically after you [/help/commit|commit]. So in normal practice,
229 the push, pull, and sync commands are rarely used. But it is important
230 to know about them, all the same.</p>
231
232 <h2>Branching And Merging</h2>
233
234 <p>Use the --branch option to the [/help/commit | commit] command
235 to start a new branch. Note that in Fossil, branches are normally
236 created when you commit, not before you start editing. You can
@@ -222,36 +237,43 @@
237 use the [/help/branch | branch new] command to create a new branch
238 before you start editing, if you want, but most people just wait
239 until they are ready to commit.
240
241 To merge two branches back together, first
242 [/help/update | update] to the branch you want to merge into.
243 Then do a [/help/merge|merge] another branch that you want to incorporate
244 the changes from. For example, to merge "featureX" changes into "trunk"
245 do this:</p>
246
247 <blockquote>
248 <b>fossil [/help/update|update] trunk</b><br>
249 <b>fossil [/help/merge|merge] featureX</b><br>
250 <i># make sure the merge didn't break anything...</i><br>
251 <b>fossil [/help/commit|commit]
252 </blockquote>
253
254 <p>The argument to the [/help/merge|merge] command can be any of the
255 version identifier forms that work for [/help/update|update].
256 ([./checkin_names.wiki|more info].)
257 The merge command has options to cherrypick individual
258 changes, or to back out individual changes, if you don't want to
259 do a full merge.</p>
260
261 The merge command puts all changes in your working check-out.
262 No changes are made to the repository.
263 You must run [/help/commit|commit] separately
264 to add the merge changes into your repository to make them persistent
265 and so that your coworkers can see them.
266 But before you do that, you will normally want to run a few tests
267 to verify that the merge didn't cause logic breaks in your code.
268
269 The same branch can be merged multiple times without trouble. Fossil
270 automatically keeps up with things and avoids conflicts when doing
271 multiple merges. So even if you have merged the featureX branch
272 into trunk previously, you can do so again and Fossil will automatically
273 know to pull in only those changes that have occurred since the previous
274 merge.
275
276 <p>If a merge or update doesn't work out (perhaps something breaks or
277 there are many merge conflicts) then you back up using:</p>
278
279 <blockquote>
@@ -280,11 +302,11 @@
302 <b>[/help/ui | fossil ui]</b> <i>repository-filename</i>
303 </blockquote>
304
305 <p>The <b>ui</b> command is intended for accessing the web interface
306 from a local desktop. The <b>ui</b> command binds to the loopback IP
307 address only (and thus makes the web interface visible only on the
308 local machine) and it automatically start your web browser pointing at the
309 server. For cross-machine collaboration, use the <b>server</b> command,
310 which binds on all IP addresses and does not try to start a web browser.
311 You can omit the <i>repository-filename</i> if you are within
312 a checked-out local tree. The <b>server</b> uses port 8080 by default
@@ -321,11 +343,11 @@
343 <p>Adjust the paths to suit your installation, of course. Notice that
344 fossil runs as root. This is not required - you can run it as an
345 unprivileged user. But it is more secure to run fossil as root.
346 When you do run fossil as root, it automatically puts itself in a
347 chroot jail in the same directory as the repository, then drops
348 root privileges prior to reading any information from the socket.</p>
349
350 <a name="proxy"></a>
351 <h2>HTTP Proxies</h2>
352
353 <p>If you are behind a restrictive firewall that requires you to use
@@ -369,8 +391,11 @@
391 <b>fossil sync http://192.168.1.36:8080/ --proxy off</b>
392 </blockquote>
393
394 <h2>More Hints</h2>
395
396 <p>A [/help | complete list of commands] is available, as is the
397 [./hints.wiki|helpful hints] document. See the
398 [./permutedindex.wiki#pindex|permuted index] for additional
399 documentation.
400
401 <p>Explore and have fun!</p>
402
+2 -1
--- www/server.wiki
+++ www/server.wiki
@@ -107,11 +107,12 @@
107107
<h2>Various security concerns with hosted repositories</h2><blockquote>
108108
<p>
109109
There are two main concerns relating to usage of Fossil for sharing sensitive information (source or any other data):
110110
<ul>
111111
<li>Interception of the Fossil synchronization stream, thereby capturing data, and
112
-</ul>Direct access to the Fossil repository on the server
112
+<li>Direct access to the Fossil repository on the server
113
+</ul>
113114
</p>
114115
<p>
115116
Regarding the first, it is adequate to secure the server using SSL, and disallowing any non-SSL access. The data stream will be encrypted by the HTTPS protocol, rendering the data reasonably secure. The truly paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is quite a bit more difficult and cumbersome to set up (particularly for a larger number of users).
116117
</p>
117118
<p>
118119
--- www/server.wiki
+++ www/server.wiki
@@ -107,11 +107,12 @@
107 <h2>Various security concerns with hosted repositories</h2><blockquote>
108 <p>
109 There are two main concerns relating to usage of Fossil for sharing sensitive information (source or any other data):
110 <ul>
111 <li>Interception of the Fossil synchronization stream, thereby capturing data, and
112 </ul>Direct access to the Fossil repository on the server
 
113 </p>
114 <p>
115 Regarding the first, it is adequate to secure the server using SSL, and disallowing any non-SSL access. The data stream will be encrypted by the HTTPS protocol, rendering the data reasonably secure. The truly paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is quite a bit more difficult and cumbersome to set up (particularly for a larger number of users).
116 </p>
117 <p>
118
--- www/server.wiki
+++ www/server.wiki
@@ -107,11 +107,12 @@
107 <h2>Various security concerns with hosted repositories</h2><blockquote>
108 <p>
109 There are two main concerns relating to usage of Fossil for sharing sensitive information (source or any other data):
110 <ul>
111 <li>Interception of the Fossil synchronization stream, thereby capturing data, and
112 <li>Direct access to the Fossil repository on the server
113 </ul>
114 </p>
115 <p>
116 Regarding the first, it is adequate to secure the server using SSL, and disallowing any non-SSL access. The data stream will be encrypted by the HTTPS protocol, rendering the data reasonably secure. The truly paranoid may wish to deploy <i>ssh</i> encrypted tunnels, but that is quite a bit more difficult and cumbersome to set up (particularly for a larger number of users).
117 </p>
118 <p>
119
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -332,5 +332,11 @@
332332
333333
Note that the stash, the undo stack, and the state of the bisect command
334334
are all contained within the checkout database. That means that the
335335
fossil close command will delete all stash content, the undo stack, and
336336
the bisect state. The close command is not undoable. Use it with care.
337
+
338
+<h2>3.0 See Also</h2>
339
+
340
+ * [./makefile.wiki | The Fossil Build Process]
341
+ * [./contribute.wiki | How To Contribute Code To Fossil]
342
+ * [./adding_code.wiki | Adding New Features To Fossil]
337343
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -332,5 +332,11 @@
332
333 Note that the stash, the undo stack, and the state of the bisect command
334 are all contained within the checkout database. That means that the
335 fossil close command will delete all stash content, the undo stack, and
336 the bisect state. The close command is not undoable. Use it with care.
 
 
 
 
 
 
337
--- www/tech_overview.wiki
+++ www/tech_overview.wiki
@@ -332,5 +332,11 @@
332
333 Note that the stash, the undo stack, and the state of the bisect command
334 are all contained within the checkout database. That means that the
335 fossil close command will delete all stash content, the undo stack, and
336 the bisect state. The close command is not undoable. Use it with care.
337
338 <h2>3.0 See Also</h2>
339
340 * [./makefile.wiki | The Fossil Build Process]
341 * [./contribute.wiki | How To Contribute Code To Fossil]
342 * [./adding_code.wiki | Adding New Features To Fossil]
343

Keyboard Shortcuts

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